diff options
| author | Maze Winther <mazewinther@gmail.com> | 2026-03-25 16:47:22 +0100 |
|---|---|---|
| committer | Maze Winther <mazewinther@gmail.com> | 2026-03-29 15:48:22 +0200 |
| commit | 8db3bead13441a5882d8689dfc6a9f09c82375d9 (patch) | |
| tree | e9d0cafa93904ffcbec3188c37961bcc16c6422d /apps/web/src/lib/media/upload-toast.ts | |
| parent | 39ea298a9ccba3104c549c0ca079c231981811f5 (diff) | |
| download | opencut-8db3bead13441a5882d8689dfc6a9f09c82375d9.tar.gz | |
feat: masks, properties refactor, shaders, storage migrations, and more
Diffstat (limited to 'apps/web/src/lib/media/upload-toast.ts')
| -rw-r--r-- | apps/web/src/lib/media/upload-toast.ts | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/apps/web/src/lib/media/upload-toast.ts b/apps/web/src/lib/media/upload-toast.ts new file mode 100644 index 00000000..e5c5ee28 --- /dev/null +++ b/apps/web/src/lib/media/upload-toast.ts @@ -0,0 +1,51 @@ +import { toast } from "sonner"; + +export interface MediaUploadToastResult { + uploadedCount: number; + assetNames?: string[]; +} + +function getAssetLabel({ count }: { count: number }): string { + return count === 1 ? "media asset" : "media assets"; +} + +function waitForNextPaint(): Promise<void> { + return new Promise((resolve) => { + requestAnimationFrame(() => { + requestAnimationFrame(() => resolve()); + }); + }); +} + +export async function showMediaUploadToast<T extends MediaUploadToastResult>({ + filesCount, + promise, +}: { + filesCount: number; + promise: Promise<T> | (() => Promise<T>); +}) { + const run = typeof promise === "function" ? promise : () => promise; + const toastPromise = toast.promise(async () => { + await waitForNextPaint(); + return run(); + }, { + loading: `Uploading ${getAssetLabel({ count: filesCount })}...`, + success: ({ uploadedCount, assetNames }) => { + if (uploadedCount === 1) { + const assetName = assetNames?.[0]; + return assetName + ? `${assetName} has been uploaded` + : "1 media asset has been uploaded"; + } + + if (uploadedCount > 1) { + return `${uploadedCount} media assets have been uploaded`; + } + + return "No media assets were uploaded"; + }, + error: `Failed to upload ${getAssetLabel({ count: filesCount })}`, + }); + + return toastPromise.unwrap(); +} |
