From 6661d8e4c5fd701914b75256406cdfe2dbfdb95b Mon Sep 17 00:00:00 2001 From: Joery <44531907+Joery-M@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:45:36 +0200 Subject: [PATCH 1/4] feat: Partially implemented autosave, need to come back --- packages/safelight/src/stores/useProject.ts | 17 +++++++++++++++++ packages/shared/src/Project/SimpleProject.ts | 8 ++++++++ packages/shared/src/base/Project.ts | 8 +++++++- 3 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/safelight/src/stores/useProject.ts b/packages/safelight/src/stores/useProject.ts index 8f6fa84f..119b6f5b 100644 --- a/packages/safelight/src/stores/useProject.ts +++ b/packages/safelight/src/stores/useProject.ts @@ -48,10 +48,26 @@ export const useProject = defineStore('Project', () => { }); } + watch( + project, + () => { + project.value?.onDeepChange.next(); + }, + { + flush: 'post', + deep: true + } + ); + function save() { if (project.value) Storage.getStorage().SaveProject(project.value); } + function beforeDestroy() { + save(); + project.value?.onDeepChange.complete(); + } + return { project, setProject, @@ -61,6 +77,7 @@ export const useProject = defineStore('Project', () => { timelineViewStart, timelineViewEnd, save, + beforeDestroy, openProject, new: { newSimpleProject diff --git a/packages/shared/src/Project/SimpleProject.ts b/packages/shared/src/Project/SimpleProject.ts index 18a7f6f2..a937ea71 100644 --- a/packages/shared/src/Project/SimpleProject.ts +++ b/packages/shared/src/Project/SimpleProject.ts @@ -15,6 +15,14 @@ export default class SimpleProject extends BaseProject { public timelines = shallowReactive([]); public timeline = computed(() => this.timelines.at(this.selectedTimelineIndex.value)!); + constructor() { + super(); + + this.onDeepChange.subscribe(() => { + console.log('Change'); + }); + } + public usesMedia(media: Media) { return this.timelines.some((timeline) => timeline.usesMedia(media)); } diff --git a/packages/shared/src/base/Project.ts b/packages/shared/src/base/Project.ts index 2b953103..6ba6295f 100644 --- a/packages/shared/src/base/Project.ts +++ b/packages/shared/src/base/Project.ts @@ -1,4 +1,5 @@ -import type { ComputedRef, Ref, ShallowReactive } from 'vue'; +import { Subject } from 'rxjs'; +import { ref, type ComputedRef, type Ref, type ShallowReactive } from 'vue'; import type Media from '../Media/Media'; import type SimpleProject from '../Project/SimpleProject'; import type BaseTimeline from './Timeline'; @@ -14,6 +15,11 @@ export default abstract class BaseProject { public abstract timelines: ShallowReactive; public abstract timeline: ComputedRef; + /** + * Triggered when this class has been changed + */ + public onDeepChange = new Subject(); + isBaseProject = (): this is BaseProject => this.type == 'Base'; isSimpleProject = (): this is SimpleProject => this.type == 'Simple'; } From f6047042b9e565b73f48a12f9285169901a3c407 Mon Sep 17 00:00:00 2001 From: Joery Date: Mon, 22 Apr 2024 17:25:30 +0200 Subject: [PATCH 2/4] feat: Implemented more of autosave Added Subject for onDeepChange and destroy$. These will be called externally. Saving is currently pretty crude, might want to check out other projects. Or maybe first measure how fast saving with iDB is. --- packages/safelight/src/stores/currentProject.ts | 2 ++ packages/safelight/src/views/Editor/Editor.vue | 10 +++++++++- packages/shared/src/Project/SimpleProject.ts | 6 ++++-- packages/shared/src/Storage/MediaManager.ts | 4 ++-- packages/shared/src/base/Project.ts | 3 +++ .../GetVideoInfo.ts => Files/GetFileInfo.ts} | 17 +++++++---------- 6 files changed, 27 insertions(+), 15 deletions(-) rename packages/shared/src/helpers/{Video/GetVideoInfo.ts => Files/GetFileInfo.ts} (72%) diff --git a/packages/safelight/src/stores/currentProject.ts b/packages/safelight/src/stores/currentProject.ts index 0858246e..a7583861 100644 --- a/packages/safelight/src/stores/currentProject.ts +++ b/packages/safelight/src/stores/currentProject.ts @@ -124,6 +124,8 @@ export class CurrentProject { public static async beforeExit(clearSession = true) { if (this.project.value) { + this.project.value.destroy$.next(); + this.project.value.destroy$.complete(); if (clearSession) this.clearSessionProject(); await this.save(); this.project.value = undefined; diff --git a/packages/safelight/src/views/Editor/Editor.vue b/packages/safelight/src/views/Editor/Editor.vue index 0a09ecdc..5d6b6cfa 100644 --- a/packages/safelight/src/views/Editor/Editor.vue +++ b/packages/safelight/src/views/Editor/Editor.vue @@ -21,7 +21,6 @@ @change=" (newName) => { CurrentProject.project.value!.name.value = newName; - CurrentProject.save(); } " /> @@ -135,6 +134,15 @@ function showNoProjectDialog() { function clearSelection() { document.getSelection()?.removeAllRanges(); } +watch( + CurrentProject.project, + (project) => { + if (project && CurrentProject.isLoaded.value) { + project.onDeepChange.next(); + } + }, + { deep: true } +); onBeforeUnmount(async () => { if (CurrentProject.isLoaded.value) { diff --git a/packages/shared/src/Project/SimpleProject.ts b/packages/shared/src/Project/SimpleProject.ts index 99bbd2dc..1a74a4f1 100644 --- a/packages/shared/src/Project/SimpleProject.ts +++ b/packages/shared/src/Project/SimpleProject.ts @@ -1,6 +1,8 @@ +import { debounceTime, takeUntil } from 'rxjs'; import { v4 as uuidv4 } from 'uuid'; import { computed, ref, shallowReactive } from 'vue'; import BaseProject, { type ProjectType } from '../base/Project'; +import { Storage } from '../base/Storage'; import Media from '../Media/Media'; import SimpleTimeline, { type SimpleTimelineConfig } from '../Timeline/SimpleTimeline'; @@ -17,8 +19,8 @@ export default class SimpleProject extends BaseProject { constructor() { super(); - this.onDeepChange.subscribe(() => { - console.log('Change'); + this.onDeepChange.pipe(takeUntil(this.destroy$), debounceTime(1000)).subscribe(() => { + Storage.getStorage().SaveProject(this); }); } diff --git a/packages/shared/src/Storage/MediaManager.ts b/packages/shared/src/Storage/MediaManager.ts index d5a7b838..170c4682 100644 --- a/packages/shared/src/Storage/MediaManager.ts +++ b/packages/shared/src/Storage/MediaManager.ts @@ -5,7 +5,7 @@ import { Observable } from 'rxjs'; import { v4 as uuidv4 } from 'uuid'; import { Storage } from '../base/Storage'; import { generateMediaThumbnail } from '../helpers/Video/GenerateMediaThumbnail'; -import { getVideoInfo } from '../helpers/Video/GetVideoInfo'; +import { getFileInfo } from '../helpers/Files/GetFileInfo'; import { MediaType, type AudioTrackInfo, @@ -69,7 +69,7 @@ export default class MediaManager { type: 'fileInfo', hashProgress: 1 }); - const fileInfo = await getVideoInfo(file); + const fileInfo = await getFileInfo(file); // Get thumbnail subscriber.next({ diff --git a/packages/shared/src/base/Project.ts b/packages/shared/src/base/Project.ts index 10991d54..3e0cfaba 100644 --- a/packages/shared/src/base/Project.ts +++ b/packages/shared/src/base/Project.ts @@ -1,3 +1,4 @@ +import { Subject } from 'rxjs'; import { ref, type ComputedRef, type Ref, type ShallowReactive } from 'vue'; import type Media from '../Media/Media'; import type SimpleProject from '../Project/SimpleProject'; @@ -19,6 +20,8 @@ export default abstract class BaseProject { */ public onDeepChange = new Subject(); + public destroy$ = new Subject(); + isBaseProject = (): this is BaseProject => this.type == 'Base'; isSimpleProject = (): this is SimpleProject => this.type == 'Simple'; } diff --git a/packages/shared/src/helpers/Video/GetVideoInfo.ts b/packages/shared/src/helpers/Files/GetFileInfo.ts similarity index 72% rename from packages/shared/src/helpers/Video/GetVideoInfo.ts rename to packages/shared/src/helpers/Files/GetFileInfo.ts index 719e95ae..e9d945c6 100644 --- a/packages/shared/src/helpers/Video/GetVideoInfo.ts +++ b/packages/shared/src/helpers/Files/GetFileInfo.ts @@ -1,13 +1,8 @@ import MediaInfoFactory, { type MediaInfoType, type ReadChunkFunc } from 'mediainfo.js'; import MediaInfoWasmUrl from 'mediainfo.js/MediaInfoModule.wasm?url'; -import MimeMatcher from 'mime-matcher'; -export async function getVideoInfo(file: File) { +export async function getFileInfo(file: File) { return new Promise((resolve, reject) => { - const isVideo = new MimeMatcher('video/*').match(file.type); - - if (!isVideo) reject('File is not a video'); - const readChunk: ReadChunkFunc = (chunkSize, offset) => new Promise((resolve, reject) => { const reader = new FileReader(); @@ -25,10 +20,12 @@ export async function getVideoInfo(file: File) { locateFile(_url, _scriptDirectory) { return MediaInfoWasmUrl; } - }).then(async (mediaInfo) => { - const data = await mediaInfo.analyzeData(() => file.size, readChunk); + }) + .then(async (mediaInfo) => { + const data = await mediaInfo.analyzeData(() => file.size, readChunk); - resolve(data); - }); + resolve(data); + }) + .catch(reject); }); } From ef13df32f0d1906cd8148ab15fa467a83fe1e2ca Mon Sep 17 00:00:00 2001 From: Joery Date: Tue, 23 Apr 2024 15:35:18 +0200 Subject: [PATCH 3/4] refactor: Moved save and loadFile to project Also added interfaces projects can implement, and which can be checked for --- .eslintrc.json | 3 +- .../src/components/Editor/Library/Library.vue | 11 +++- .../components/Editor/Library/LibraryItem.vue | 3 +- packages/safelight/src/injections.ts | 6 -- .../safelight/src/stores/currentProject.ts | 42 ++----------- packages/safelight/tsconfig.app.json | 3 +- packages/shared/package.json | 1 + packages/shared/src/Project/SimpleProject.ts | 61 +++++++++++++++++-- packages/shared/src/base/Project.ts | 42 ++++++++++++- pnpm-lock.yaml | 3 + 10 files changed, 119 insertions(+), 56 deletions(-) delete mode 100644 packages/safelight/src/injections.ts diff --git a/.eslintrc.json b/.eslintrc.json index c4428a8b..958bcd18 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -37,6 +37,7 @@ "vue/no-v-for-template-key": "off", "vue/no-v-model-argument": "off", "no-async-promise-executor": "off", - "no-undef": "off" + "no-undef": "off", + "no-dupe-class-members": "off" } } diff --git a/packages/safelight/src/components/Editor/Library/Library.vue b/packages/safelight/src/components/Editor/Library/Library.vue index 1d4390d3..d5ee4f25 100644 --- a/packages/safelight/src/components/Editor/Library/Library.vue +++ b/packages/safelight/src/components/Editor/Library/Library.vue @@ -94,6 +94,7 @@