diff --git a/packages/safelight/package.json b/packages/safelight/package.json index ef603e1d..3a20c5dc 100644 --- a/packages/safelight/package.json +++ b/packages/safelight/package.json @@ -31,6 +31,7 @@ "change-case": "^5.4.3", "dexie": "^3.2.7", "ffprobe-wasm": "^0.3.1", + "fuzzysearch": "^1.0.3", "hash-wasm": "^4.11.0", "lodash": "^4.17.21", "luxon": "^3.4.4", @@ -50,6 +51,7 @@ "@iconify-json/ph": "^1.1.11", "@tsconfig/node20": "^20.1.2", "@types/dom-webcodecs": "^0.1.11", + "@types/fuzzysearch": "^1.0.2", "@types/luxon": "^3.4.2", "@types/node": "^20.11.30", "@types/uuid": "^9.0.8", diff --git a/packages/safelight/src/components/Editor/Library/Library.vue b/packages/safelight/src/components/Editor/Library/Library.vue index ace25dde..7dba6409 100644 --- a/packages/safelight/src/components/Editor/Library/Library.vue +++ b/packages/safelight/src/components/Editor/Library/Library.vue @@ -1,50 +1,156 @@ + + diff --git a/packages/safelight/src/controllers/Media/Media.ts b/packages/safelight/src/controllers/Media/Media.ts index c9f624fd..87a00ac3 100644 --- a/packages/safelight/src/controllers/Media/Media.ts +++ b/packages/safelight/src/controllers/Media/Media.ts @@ -10,10 +10,11 @@ export default class Media { * @description The duration of this media item. By default it is set to 5 seconds, which will apply to images * @default 5000 */ - public duration = ref(5000); + public duration = ref(0); public fileInfo = ref(); - constructor(public mediaId: string) { + constructor(mediaId: string) { + this.id.value = mediaId; db.media.get({ id: mediaId }).then((med) => { if (med) { this.name.value = med.name; @@ -25,10 +26,6 @@ export default class Media { this.id.value = med.id; this.loaded.value = true; - - setInterval(() => { - this.duration.value += 100; - }, 1000); } }); } diff --git a/packages/safelight/src/controllers/Project/SimpleProject.ts b/packages/safelight/src/controllers/Project/SimpleProject.ts index af98671c..208bb38c 100644 --- a/packages/safelight/src/controllers/Project/SimpleProject.ts +++ b/packages/safelight/src/controllers/Project/SimpleProject.ts @@ -6,9 +6,9 @@ export default class SimpleProject extends BaseProject { public name = 'Untitled'; public type: ProjectType = 'Simple'; - public media: Media[] = []; + public media: Media[] = reactive([]); public timelines: SimpleTimeline[] = []; - public activeTimeline: number; + public activeTimeline: SimpleTimeline; constructor() { super(); @@ -16,6 +16,6 @@ export default class SimpleProject extends BaseProject { const tl = new SimpleTimeline(); this.timelines = [tl]; - this.activeTimeline = 0; + this.activeTimeline = tl; } } diff --git a/packages/safelight/src/main.ts b/packages/safelight/src/main.ts index 3b95960e..ab259c0c 100644 --- a/packages/safelight/src/main.ts +++ b/packages/safelight/src/main.ts @@ -4,8 +4,9 @@ import { createRouter, createWebHistory } from 'vue-router/auto'; import App from './App.vue'; import PrimeVue, { type PrimeVueConfiguration } from 'primevue/config'; -import 'primevue/resources/themes/aura-dark-amber/theme.css'; import 'primevue/resources/primevue.min.css'; +import 'primevue/resources/themes/aura-dark-amber/theme.css'; +import Tooltip from 'primevue/tooltip'; // eslint-disable-next-line @typescript-eslint/ban-ts-comment //@ts-ignore // import SafelightTheme from '@/@core/Safelight'; @@ -28,4 +29,7 @@ app.use(PrimeVue, { ripple: false } as PrimeVueConfiguration); +// Directives +app.directive('tooltip', Tooltip); + app.mount('#app'); diff --git a/packages/safelight/src/style.scss b/packages/safelight/src/style.scss index 2b3f952f..d56fdc37 100644 --- a/packages/safelight/src/style.scss +++ b/packages/safelight/src/style.scss @@ -1,46 +1,7 @@ @tailwind components; @tailwind utilities; -// body { -// @apply m-0 h-screen w-screen text-white bg-surface-900 overflow-hidden; -// #app { -// @apply overflow-auto; -// } -// } - -// #app { -// @apply w-full h-full -// } - -// h1 { -// @apply text-3xl mb-4; -// } - -// h2 { -// @apply text-2xl mb-4; -// } - -// h3 { -// @apply text-xl; -// } - -// h4 { -// @apply text-lg; -// } - -// h5 { -// @apply text-sm; -// } - -// h6 { -// @apply text-xs; -// } - - -// input { -// @apply text-black -// } /* color palette from */ :root { --vt-c-white: #ffffff; @@ -100,8 +61,11 @@ body { line-height: 1.6; font-family: Inter, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Fira Sans', 'Droid Sans', 'Helvetica Neue', sans-serif; - font-size: 15px; text-rendering: optimizeLegibility; -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; +} + +html { + font-size: 14px; } \ No newline at end of file diff --git a/packages/safelight/src/views/Editor/Editor.vue b/packages/safelight/src/views/Editor/Editor.vue index f069bfd1..4fdbdd14 100644 --- a/packages/safelight/src/views/Editor/Editor.vue +++ b/packages/safelight/src/views/Editor/Editor.vue @@ -12,15 +12,17 @@ :timeline="project.activeTimeline" class="min-h-100 w-full" /> - - + + + + + - + @@ -37,7 +39,6 @@ import Media from '@/controllers/Media/Media'; import { PhUpload } from '@phosphor-icons/vue'; import { useObservable } from '@vueuse/rxjs'; import MimeMatcher from 'mime-matcher'; -import type { UnwrapRef } from 'vue'; const fileDialog = useFileDialog({ accept: 'image/*,video/*' @@ -54,7 +55,7 @@ const dropZone = useDropZone(document.body, { } }); -const project = useProject(); +const project = new SimpleProject(); const loading = ref(false); fileDialog.onChange((fileList) => { @@ -67,7 +68,7 @@ fileDialog.onChange((fileList) => { if (file) promises.push(loadFile(file)); } - Promise.all(promises).then(() => { + Promise.all(promises).finally(() => { loading.value = false; }); }); @@ -82,13 +83,13 @@ function loadFile(file: File) { watch(storingProcessing, () => { if (storingProcessing.value && storingProcessing.value.type == 'done') { const existingMedia = project.media.some( - (m) => m.id == storingProcessing.value!.id + (m) => m.id.value == storingProcessing.value!.id ); if (!existingMedia) { const media = new Media(storingProcessing.value.id!); - project.media.push(media as unknown as UnwrapRef); + project.media.push(media); project.activeTimeline.createTimelineItem(media); } @@ -100,7 +101,7 @@ function loadFile(file: File) { onBeforeUnmount(() => { // reset store, which currently tries to call 'this', trying to reference the store - project.$dispose(); + // project.$dispose(); }); diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 63945aaf..4c78acb0 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -147,6 +147,9 @@ importers: ffprobe-wasm: specifier: ^0.3.1 version: 0.3.1 + fuzzysearch: + specifier: ^1.0.3 + version: 1.0.3 hash-wasm: specifier: ^4.11.0 version: 4.11.0 @@ -199,6 +202,9 @@ importers: '@types/dom-webcodecs': specifier: ^0.1.11 version: 0.1.11 + '@types/fuzzysearch': + specifier: ^1.0.2 + version: 1.0.2 '@types/luxon': specifier: ^3.4.2 version: 3.4.2 @@ -1590,6 +1596,10 @@ packages: /@types/estree@1.0.5: resolution: {integrity: sha512-/kYRxGDLWzHOB7q+wtSUQlFrtcdUccpfy+X+9iMBpHK8QLLhx2wIPYuS5DYtR9Wa/YlZAbIovy7qVdB1Aq6Lyw==} + /@types/fuzzysearch@1.0.2: + resolution: {integrity: sha512-G2M0M7acg75BzTtUv1qmPFMe7nTwX1K2AEKNeBO8zW0o+H2oTmyir7IJ2v0UW8pZkY4nHgHALvgpWQpB9WXPpg==} + dev: true + /@types/http-cache-semantics@4.0.4: resolution: {integrity: sha512-1m0bIFVc7eJWyve9S0RnuRgcQqF/Xd5QsUZAZeQFr1Q3/p9JWoQQEqmVy+DPTNpGXwhgIetAoYF8JSc33q29QA==} dev: true @@ -3709,6 +3719,10 @@ packages: /function-bind@1.1.2: resolution: {integrity: sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==} + /fuzzysearch@1.0.3: + resolution: {integrity: sha512-s+kNWQuI3mo9OALw0HJ6YGmMbLqEufCh2nX/zzV5CrICQ/y4AwPxM+6TIiF9ItFCHXFCyM/BfCCmN57NTIJuPg==} + dev: false + /geckodriver@4.3.3: resolution: {integrity: sha512-we2c2COgxFkLVuoknJNx+ioP+7VDq0sr6SCqWHTzlA4kzIbzR0EQ1Pps34s8WrsOnQqPC8a4sZV9dRPROOrkSg==} engines: {node: ^16.13 || >=18 || >=20}
{{ media.name }}