Skip to content

Commit a9c07a3

Browse files
committed
WIP: collaboration
1 parent 2cc50c4 commit a9c07a3

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+9909
-6812
lines changed

docs/.vitepress/theme/index.ts

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,17 @@
11
import 'virtual:uno.css'
22
import './custom.css'
33

4+
import { setupApp } from 'app-video-editor'
45
import type { Theme } from 'vitepress'
56
import DefaultTheme from 'vitepress/theme'
6-
import { createI18n } from 'vue-i18n-lite'
7-
8-
import { win } from 'shared/utils'
9-
import de from 'webgl-video-editor/locales/de.json'
10-
import en from 'webgl-video-editor/locales/en.json'
117

128
import Layout from './Layout.vue'
139

1410
const theme: Theme = {
1511
extends: DefaultTheme,
1612
Layout,
1713
enhanceApp({ app }) {
18-
app.use(
19-
createI18n({
20-
locale: (win as Partial<typeof win>).navigator?.language.replace(/-.*/, ''),
21-
fallbackLocale: 'en',
22-
messages: {
23-
en: {
24-
...en,
25-
restore_failed: `Couldn't restore video editor content.`,
26-
load_demo_video: 'Load demo video',
27-
},
28-
de: {
29-
...de,
30-
restore_failed: `Der Inhalt des Videoeditors konnte nicht wiederhergestellt werden.`,
31-
load_demo_video: 'Beispielfilm laden',
32-
},
33-
},
34-
}),
35-
)
14+
app.use(setupApp)
3615
},
3716
}
3817
export default theme

docs/package.json

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
"@gltf-transform/core": "catalog:",
77
"@gltf-transform/extensions": "catalog:",
88
"@gltf-transform/functions": "catalog:",
9-
"@vueuse/core": "^13.4.0",
10-
"gltf-ar-effects": "workspace:",
9+
"@vueuse/core": "catalog:",
10+
"app-video-editor": "workspace:^",
11+
"gltf-ar-effects": "workspace:^",
1112
"media-trimmer": "workspace:^",
1213
"webgl-effects": "workspace:^",
1314
"webgl-media-editor": "workspace:^",
14-
"webgl-video-editor": "workspace:^"
15+
"webgl-video-editor": "workspace:^",
16+
"y-indexeddb": "catalog:",
17+
"y-webrtc": "catalog:",
18+
"yjs": "catalog:"
1519
}
1620
}

docs/video-editor-demo/demo-movie.ts

Lines changed: 0 additions & 157 deletions
This file was deleted.
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import { getCurrentScope, markRaw, onScopeDispose, ref, type Ref } from 'vue'
2+
import { IndexeddbPersistence } from 'y-indexeddb'
3+
import { WebrtcProvider } from 'y-webrtc'
4+
import * as Y from 'yjs'
5+
6+
import { promiseWithResolvers } from 'shared/utils'
7+
import { INITIAL_DOC_UPDATE_BASE64 } from 'webgl-video-editor/store/constants.js'
8+
import { VideoEditorYjsStore } from 'webgl-video-editor/store/yjs.js'
9+
10+
const DOC_NAME = 'video-editor-demo-doc'
11+
12+
export const useVideoEditorStore = (ydoc: Y.Doc): Ref<VideoEditorYjsStore | undefined> => {
13+
const store = ref<VideoEditorYjsStore>()
14+
if (import.meta.env.SSR) return store
15+
16+
const scope = getCurrentScope()
17+
18+
ydoc.transact(() => {
19+
Y.applyUpdate(
20+
ydoc,
21+
Uint8Array.from(atob(INITIAL_DOC_UPDATE_BASE64), (c) => c.charCodeAt(0)),
22+
)
23+
}, {})
24+
25+
const idbPromise = promiseWithResolvers()
26+
27+
void navigator.locks.request(DOC_NAME, async () => {
28+
if (!scope?.active) return
29+
30+
const { promise, resolve } = promiseWithResolvers()
31+
32+
const idb = new IndexeddbPersistence(DOC_NAME, ydoc)
33+
await idb.whenSynced
34+
idbPromise.resolve()
35+
36+
scope.run(() => {
37+
onScopeDispose(() => {
38+
resolve()
39+
void idb.destroy()
40+
})
41+
})
42+
43+
await promise
44+
})
45+
46+
const webrtc = new WebrtcProvider(DOC_NAME, ydoc)
47+
48+
void Promise.race([
49+
idbPromise.promise,
50+
new Promise<unknown>((resolve) => {
51+
ydoc.once('sync', resolve)
52+
webrtc.once('peers', () => ydoc.once('update', resolve))
53+
}),
54+
]).then(() => {
55+
store.value = markRaw(new VideoEditorYjsStore(ydoc))
56+
})
57+
58+
onScopeDispose(() => {
59+
webrtc.destroy()
60+
})
61+
62+
return store
63+
}

docs/video-editor.md

Lines changed: 7 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,16 @@ pageClass: demo-page video-editor-demo-page
66
---
77

88
<script setup lang="ts">
9-
import VideoEditorDemo from './video-editor-demo/video-editor-demo.vue'
9+
import * as Y from 'yjs'
10+
11+
import { VideoEditorApp } from 'app-video-editor'
12+
import { useVideoEditorStore } from './video-editor-demo/video-editor-demo-store'
13+
14+
const store = useVideoEditorStore(new Y.Doc())
1015
</script>
1116

1217
<div class="demo-container">
1318
<ClientOnly>
14-
<VideoEditorDemo />
19+
<VideoEditorApp v-if="store" :store class="demo-container" />
1520
</ClientOnly>
1621
</div>
17-
18-
<style scoped>
19-
.video-editor {
20-
height: 100%
21-
}
22-
23-
.demo-video-button {
24-
position: absolute;
25-
left: 1rem;
26-
display: flex;
27-
gap: 0.675rem;
28-
align-items: center;
29-
justify-content: center;
30-
min-width: var(--clip-height);
31-
height: var(--clip-height);
32-
padding: 0.675rem 0.875rem;
33-
color: var(--white-3);
34-
cursor: pointer;
35-
background-color: rgb(255 255 255 / 3%);
36-
border: dashed;
37-
border-color: rgb(255 255 255 / 12%);
38-
border-radius: 0.625rem;
39-
translate: var(--track-width);
40-
41-
font-size: 14px;
42-
font-weight: 500;
43-
line-height: 17px;
44-
}
45-
</style>

env.d.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
/// <reference types="vite/client" />
33
/// <reference types="vitest/client" />
44
/// <reference types="vitest/config" />
5+
/// <reference types="webxdc-types/global" />
56
/// <reference types="./auto-imports" />
67

78
// remote assets

package.json

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,17 @@
2626
"author": "Taye Adeyemi",
2727
"license": "AGPL-3.0-only",
2828
"dependencies": {
29+
"@unocss/reset": "^66.4.2",
2930
"compare-palettes": "workspace:^",
3031
"filesize": "^10.1.6",
3132
"gltf-ar-effects": "workspace:^",
3233
"reactive-effects": "workspace:^",
3334
"shared": "workspace:^",
3435
"uid": "catalog:",
3536
"vitest": "^3.2.4",
36-
"vue": "^3.5.17",
37-
"vue-i18n-lite": "^1.0.2"
37+
"vue": "catalog:",
38+
"vue-i18n-lite": "catalog:",
39+
"webgl-video-editor": "workspace:^"
3840
},
3941
"devDependencies": {
4042
"@esbuild-plugins/node-globals-polyfill": "^0.2.3",
@@ -119,7 +121,7 @@
119121
"terser": "^5.43.1",
120122
"throttle-debounce": "catalog:",
121123
"tsx": "^4.20.3",
122-
"typescript": "^5.8.3",
124+
"typescript": "^5.9.2",
123125
"typescript-eslint": "^8.35.0",
124126
"unocss": "^66.3.2",
125127
"unplugin-auto-import": "^19.3.0",
@@ -128,7 +130,10 @@
128130
"vite-bundle-analyzer": "^0.23.0",
129131
"vite-plugin-remote-assets": "^2.0.0",
130132
"vitepress": "2.0.0-alpha.2",
131-
"vue-tsc": "^2.2.10"
133+
"vue-tsc": "^2.2.10",
134+
"webxdc-types": "^1.0.1",
135+
"yjs": "catalog:",
136+
"yjs-orderedtree": "catalog:"
132137
},
133138
"lint-staged": {
134139
"**/*.((ts|js|cjs)?(x)|vue)": [

0 commit comments

Comments
 (0)