From 946524d6e98c30d3780f27d53808e61c8ceedbfe Mon Sep 17 00:00:00 2001 From: Joery <44531907+Joery-M@users.noreply.github.com> Date: Sun, 21 Apr 2024 00:00:50 +0200 Subject: [PATCH 1/3] feat: Changed project to be stored in a global static class Added methods from useProject to global CurrentProject. fixed some styling with the library. Added menu bar useProject has had all of its methods removed. the only thing its keeping is isLoaded --- .vscode/extensions.json | 4 +- .../src/components/Editor/Library/Library.vue | 36 +++--- .../components/Editor/Library/LibraryItem.vue | 28 ++-- .../src/components/InplaceRename.vue | 2 +- .../Menu/ProjectList/ProjectList.vue | 10 +- .../safelight/src/stores/currentProject.ts | 100 +++++++++++++++ packages/safelight/src/stores/useProject.ts | 105 +-------------- .../safelight/src/views/Editor/Editor.vue | 121 ++++++++++++------ packages/shared/src/Project/SimpleProject.ts | 1 - .../shared/src/Storage/IndexedDbStorage.ts | 4 +- packages/shared/src/base/Project.ts | 4 +- .../shared/src/helpers/Video/GetVideoInfo.ts | 5 +- 12 files changed, 231 insertions(+), 189 deletions(-) create mode 100644 packages/safelight/src/stores/currentProject.ts diff --git a/.vscode/extensions.json b/.vscode/extensions.json index 3afc69ef..fa9e40a7 100644 --- a/.vscode/extensions.json +++ b/.vscode/extensions.json @@ -4,6 +4,8 @@ "esbenp.prettier-vscode", "bradlc.vscode-tailwindcss", "vivaxy.vscode-conventional-commits", - "vue.volar" + "vue.volar", + "github.vscode-pull-request-github", + "github.vscode-github-actions" ] } diff --git a/packages/safelight/src/components/Editor/Library/Library.vue b/packages/safelight/src/components/Editor/Library/Library.vue index 20baf034..e3f992c9 100644 --- a/packages/safelight/src/components/Editor/Library/Library.vue +++ b/packages/safelight/src/components/Editor/Library/Library.vue @@ -73,7 +73,9 @@ class="grid h-full select-none place-items-center opacity-60" @dblclick="fileDialogOpenDblClick" > - + @@ -90,7 +92,7 @@ import InputGroupAddon from 'primevue/inputgroupaddon'; useDropZone(document.body, { onDrop(files) { - files?.forEach(project.loadFile); + files?.forEach(CurrentProject.loadFile); }, dataTypes(types) { return !types.some((val) => { @@ -109,29 +111,32 @@ fileDialog.onChange((fileList) => { const item = fileList.item(i); if (item) { - project.loadFile(item); + CurrentProject.loadFile(item); } } }); -const project = useProject(); -const media = project.project!.media; - const search = ref(''); const sortBy = ref('Name'); const sortDescending = ref(false); const sortedAndFiltered = shallowRef([]); -watchDebounced([media, search, sortBy, sortDescending], sortAndFilter, { - deep: true, - debounce: 100, - maxWait: 1000, - immediate: true -}); +watchDebounced( + [CurrentProject.project.value?.media, search, sortBy, sortDescending], + sortAndFilter, + { + deep: true, + debounce: 100, + maxWait: 1000, + immediate: true + } +); function sortAndFilter() { - const filtered = media.filter((elem) => { + if (!CurrentProject.project.value) return; + + const filtered = CurrentProject.project.value.media.filter((elem) => { if (search.value.length == 0) { return true; } @@ -173,11 +178,6 @@ type sortOptions = 'Name' | 'Duration' | 'File type' | 'Media type'; diff --git a/packages/safelight/src/components/InplaceRename.vue b/packages/safelight/src/components/InplaceRename.vue index 5becf148..da8edb4b 100644 --- a/packages/safelight/src/components/InplaceRename.vue +++ b/packages/safelight/src/components/InplaceRename.vue @@ -1,6 +1,6 @@ @@ -29,7 +29,7 @@ @@ -41,12 +41,10 @@ import { Storage, type StoredProject } from '@safelight/shared/base/Storage'; import { DateTime } from 'luxon'; import type { MenuItem } from 'primevue/menuitem'; -const project = useProject(); - const projectTypes: MenuItem[] = [ { label: 'Simple', - command: project.new.newSimpleProject + command: () => CurrentProject.newSimpleProject() }, { label: 'Test', command() {} } ] as const; @@ -81,7 +79,7 @@ function formatDateTime(dt: string) { } async function setProjectName(newName: string, project: StoredProject) { - const storage = await getStorageControllerForProject(project); + const storage = await CurrentProject.getStorageControllerForProject(project); await storage?.UpdateStoredProject({ id: project.id, name: newName }); loadList(); } diff --git a/packages/safelight/src/stores/currentProject.ts b/packages/safelight/src/stores/currentProject.ts new file mode 100644 index 00000000..86c10311 --- /dev/null +++ b/packages/safelight/src/stores/currentProject.ts @@ -0,0 +1,100 @@ +import { router } from '@/main'; +import type BaseProject from '@safelight/shared/base/Project'; +import BaseStorageController, { Storage, type StoredProject } from '@safelight/shared/base/Storage'; +import MediaManager from '@safelight/shared/Storage/MediaManager'; + +// --- +// +// A global `shallowRef` is used to keep state for reasons outlined in #14 +// +// --- + +export class CurrentProject { + public static project = shallowRef(); + + public static async openProject(selectedProject: StoredProject, goToEditor = true) { + const storageType = await this.getStorageControllerForProject(selectedProject); + if (!storageType) { + throw new Error('Could not find storage controller for project type'); + } + + Storage.setStorage(storageType); + + const project = await Storage.getStorage().LoadProject(selectedProject.id); + + if (project) { + this.setProject(project); + if (goToEditor) await this.toEditor(); + } else { + console.error('Could not load project'); + } + } + + public static async toEditor() { + await router.push('/editor'); + } + + public static async newSimpleProject(goToEditor = true) { + const IndexedDbStorageController = ( + await import('@safelight/shared/Storage/IndexedDbStorage') + ).default; + Storage.setStorage(new IndexedDbStorageController()); + const SimpleProject = (await import('@safelight/shared/Project/SimpleProject')).default; + this.setProject(new SimpleProject()); + + if (goToEditor) await this.toEditor(); + } + + public static async getStorageControllerForProject( + project: StoredProject + ): Promise { + if (project.type == 'Simple') { + return new (await import('@safelight/shared/Storage/IndexedDbStorage')).default(); + } else { + console.error('Project type not supported'); + } + } + + public static setProject(newProject: BaseProject) { + this.project.value = newProject; + const projectStore = useProject(); + projectStore.isLoaded = true; + + useSessionStorage('project', '').value = newProject.id; + } + + // Might want to move this to BaseProject or SimpleProject + public static loadFile(file: File) { + return new Promise((resolve) => { + const storingProcessing = useObservable(MediaManager.StoreMedia(file)); + watch(storingProcessing, (s) => { + console.log(s?.type, s?.hashProgress); + }); + + watch(storingProcessing, async () => { + if (storingProcessing.value && storingProcessing.value.type == 'done') { + const existingMedia = this.project.value!.media.some( + (m) => m.id == storingProcessing.value!.id + ); + + if (!existingMedia) { + const media = await Storage.getStorage().LoadMedia( + storingProcessing.value.id! + ); + + if (media) { + this.project.value!.media.push(media); + this.save(); + } + } + + resolve(); + } + }); + }); + } + + public static async save() { + if (this.project.value) await Storage.getStorage().SaveProject(this.project.value); + } +} diff --git a/packages/safelight/src/stores/useProject.ts b/packages/safelight/src/stores/useProject.ts index 8f6fa84f..f8b9a03d 100644 --- a/packages/safelight/src/stores/useProject.ts +++ b/packages/safelight/src/stores/useProject.ts @@ -1,113 +1,10 @@ -import { router } from '@/main'; -import type BaseProject from '@safelight/shared/base/Project'; -import BaseStorageController, { Storage, type StoredProject } from '@safelight/shared/base/Storage'; -import MediaManager from '@safelight/shared/Storage/MediaManager'; - export const useProject = defineStore('Project', () => { const cursor = ref(0); - const timelineViewStart = ref(0); - const timelineViewEnd = ref(0); - const project = shallowRef(); const isLoaded = ref(false); - function setProject(newProject: BaseProject) { - project.value = newProject; - isLoaded.value = true; - - useSessionStorage('project', '').value = newProject.id; - } - - function loadFile(file: File) { - return new Promise((resolve) => { - const storingProcessing = useObservable(MediaManager.StoreMedia(file)); - watch(storingProcessing, (s) => { - console.log(s?.type, s?.hashProgress); - }); - - watch(storingProcessing, async () => { - if (storingProcessing.value && storingProcessing.value.type == 'done') { - const existingMedia = project.value!.media.some( - (m) => m.id == storingProcessing.value!.id - ); - - if (!existingMedia) { - const media = await Storage.getStorage().LoadMedia( - storingProcessing.value.id! - ); - - if (media) { - project.value!.media.push(media); - save(); - } - } - - resolve(); - } - }); - }); - } - - function save() { - if (project.value) Storage.getStorage().SaveProject(project.value); - } - return { - project, - setProject, - loadFile, isLoaded, - cursor, - timelineViewStart, - timelineViewEnd, - save, - openProject, - new: { - newSimpleProject - } + cursor }; }); - -async function newSimpleProject() { - const IndexedDbStorageController = (await import('@safelight/shared/Storage/IndexedDbStorage')) - .default; - Storage.setStorage(new IndexedDbStorageController()); - const projectStore = useProject(); - const SimpleProject = (await import('@safelight/shared/Project/SimpleProject')).default; - projectStore.setProject(new SimpleProject()); - - await toEditor(); -} - -export async function getStorageControllerForProject( - project: StoredProject -): Promise { - if (project.type == 'Simple') { - return new (await import('@safelight/shared/Storage/IndexedDbStorage')).default(); - } else { - console.error('Project type not supported'); - } -} - -async function openProject(selectedProject: StoredProject) { - const storageType = await getStorageControllerForProject(selectedProject); - if (!storageType) { - throw new Error('Could not find storage controller for project type'); - } - - const projectStore = useProject(); - Storage.setStorage(storageType); - - const project = await Storage.getStorage().LoadProject(selectedProject.id); - - if (project) { - projectStore.setProject(project); - await toEditor(); - } else { - console.error('Could not load project'); - } -} - -async function toEditor() { - await router.push('/editor'); -} diff --git a/packages/safelight/src/views/Editor/Editor.vue b/packages/safelight/src/views/Editor/Editor.vue index 7a9e4c23..11243ec5 100644 --- a/packages/safelight/src/views/Editor/Editor.vue +++ b/packages/safelight/src/views/Editor/Editor.vue @@ -1,64 +1,105 @@ - - diff --git a/packages/safelight/src/components/Editor/Library/LibraryItem.vue b/packages/safelight/src/components/Editor/Library/LibraryItem.vue index 60bbb85d..26767d8e 100644 --- a/packages/safelight/src/components/Editor/Library/LibraryItem.vue +++ b/packages/safelight/src/components/Editor/Library/LibraryItem.vue @@ -36,8 +36,23 @@ - - + + - + diff --git a/packages/safelight/src/views/dev/Packages.vue b/packages/safelight/src/views/dev/Packages.vue index 8469db6c..d73826b4 100644 --- a/packages/safelight/src/views/dev/Packages.vue +++ b/packages/safelight/src/views/dev/Packages.vue @@ -95,7 +95,7 @@ :title="'Open code repository for ' + item.from" role="link" @click=" - openUrl(item.repository.replace('git+', '')) + openUrl(item.repository!.replace('git+', '')) " >