summaryrefslogtreecommitdiff
path: root/apps/web/src/lib/commands/media
diff options
context:
space:
mode:
authorMaze Winther <mazewinther@gmail.com>2026-03-25 16:47:22 +0100
committerMaze Winther <mazewinther@gmail.com>2026-03-29 15:48:22 +0200
commit8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch)
treee9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/lib/commands/media
parent39ea298a9ccba3104c549c0ca079c231981811f5 (diff)
downloadopencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/lib/commands/media')
-rw-r--r--apps/web/src/lib/commands/media/add-media-asset.ts34
-rw-r--r--apps/web/src/lib/commands/media/remove-media-asset.ts34
2 files changed, 57 insertions, 11 deletions
diff --git a/apps/web/src/lib/commands/media/add-media-asset.ts b/apps/web/src/lib/commands/media/add-media-asset.ts
index ddcca426..a3dec0e6 100644
--- a/apps/web/src/lib/commands/media/add-media-asset.ts
+++ b/apps/web/src/lib/commands/media/add-media-asset.ts
@@ -1,8 +1,10 @@
import { Command } from "@/lib/commands/base-command";
import { EditorCore } from "@/core";
-import type { MediaAsset } from "@/types/assets";
+import { toast } from "sonner";
+import type { MediaAsset } from "@/lib/media/types";
import { generateUUID } from "@/utils/id";
import { storageService } from "@/services/storage/service";
+import { hasMediaId } from "@/lib/timeline/element-utils";
export class AddMediaAssetCommand extends Command {
private assetId: string;
@@ -37,6 +39,36 @@ export class AddMediaAssetCommand extends Command {
})
.catch((error) => {
console.error("Failed to save media item:", error);
+
+ const currentAssets = editor.media.getAssets();
+ editor.media.setAssets({
+ assets: currentAssets.filter((asset) => asset.id !== this.assetId),
+ });
+
+ const currentTracks = editor.timeline.getTracks();
+ const orphanedElements: Array<{ trackId: string; elementId: string }> =
+ [];
+
+ for (const track of currentTracks) {
+ for (const element of track.elements) {
+ if (hasMediaId(element) && element.mediaId === this.assetId) {
+ orphanedElements.push({
+ trackId: track.id,
+ elementId: element.id,
+ });
+ }
+ }
+ }
+
+ if (orphanedElements.length > 0) {
+ editor.timeline.deleteElements({ elements: orphanedElements });
+ }
+
+ if (storageService.isQuotaExceededError({ error })) {
+ toast.error("Not enough browser storage", {
+ description: error instanceof Error ? error.message : undefined,
+ });
+ }
});
}
diff --git a/apps/web/src/lib/commands/media/remove-media-asset.ts b/apps/web/src/lib/commands/media/remove-media-asset.ts
index ee9ffa2d..f519baef 100644
--- a/apps/web/src/lib/commands/media/remove-media-asset.ts
+++ b/apps/web/src/lib/commands/media/remove-media-asset.ts
@@ -1,10 +1,10 @@
import { Command } from "@/lib/commands/base-command";
import { EditorCore } from "@/core";
-import type { MediaAsset } from "@/types/assets";
+import type { MediaAsset } from "@/lib/media/types";
import { storageService } from "@/services/storage/service";
import { videoCache } from "@/services/video-cache/service";
import { hasMediaId } from "@/lib/timeline/element-utils";
-import type { TimelineTrack } from "@/types/timeline";
+import type { TimelineTrack } from "@/lib/timeline";
export class RemoveMediaAssetCommand extends Command {
private savedAssets: MediaAsset[] | null = null;
@@ -33,6 +33,13 @@ export class RemoveMediaAssetCommand extends Command {
return;
}
+ if (this.removedAsset.url) {
+ URL.revokeObjectURL(this.removedAsset.url);
+ }
+ if (this.removedAsset.thumbnailUrl) {
+ URL.revokeObjectURL(this.removedAsset.thumbnailUrl);
+ }
+
videoCache.clearVideo({ mediaId: this.assetId });
editor.media.setAssets({
@@ -63,23 +70,30 @@ export class RemoveMediaAssetCommand extends Command {
undo(): void {
const editor = EditorCore.getInstance();
- if (this.savedAssets) {
- editor.media.setAssets({ assets: this.savedAssets });
- }
+ if (this.savedAssets && this.removedAsset) {
+ const restoredAsset: MediaAsset = {
+ ...this.removedAsset,
+ url: URL.createObjectURL(this.removedAsset.file),
+ };
- if (this.savedTracks) {
- editor.timeline.updateTracks(this.savedTracks);
- }
+ editor.media.setAssets({
+ assets: this.savedAssets.map((a) =>
+ a.id === this.assetId ? restoredAsset : a,
+ ),
+ });
- if (this.removedAsset) {
storageService
.saveMediaAsset({
projectId: this.projectId,
- mediaAsset: this.removedAsset,
+ mediaAsset: restoredAsset,
})
.catch((error) => {
console.error("Failed to restore media item on undo:", error);
});
}
+
+ if (this.savedTracks) {
+ editor.timeline.updateTracks(this.savedTracks);
+ }
}
}