Add centralized saveMedia helpers for image, video, and file downloads.
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 2s
All checks were successful
Trigger cinny-mobile / dispatch (push) Successful in 2s
Platforms can register a custom saver; viewers share one download/save path instead of FileSaver call sites.
This commit is contained in:
55
src/app/utils/saveMedia.ts
Normal file
55
src/app/utils/saveMedia.ts
Normal file
@@ -0,0 +1,55 @@
|
||||
import FileSaver from 'file-saver';
|
||||
import { downloadMedia } from './matrix';
|
||||
import { getCurrentAccessToken } from './auth';
|
||||
|
||||
export type MediaSaver = (blob: Blob, filename: string) => void | Promise<void>;
|
||||
|
||||
let customMediaSaver: MediaSaver | null = null;
|
||||
|
||||
const defaultMediaSaver: MediaSaver = (blob, filename) => {
|
||||
FileSaver.saveAs(blob, filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Register a platform-specific media saver (Android MediaStore, Electron dialog, etc.).
|
||||
* Pass null to restore the default FileSaver path.
|
||||
*
|
||||
* Platforms should call this once at startup (mobile overlay / desktop shell entry).
|
||||
*/
|
||||
export const registerMediaSaver = (saver: MediaSaver | null): void => {
|
||||
customMediaSaver = saver;
|
||||
};
|
||||
|
||||
/**
|
||||
* Persist a Blob to disk via the registered platform saver, or FileSaver by default.
|
||||
*/
|
||||
export const saveMediaBlob = async (blob: Blob, filename: string): Promise<void> => {
|
||||
const saver = customMediaSaver ?? defaultMediaSaver;
|
||||
await saver(blob, filename);
|
||||
};
|
||||
|
||||
/**
|
||||
* Fetch media (auth download or blob:/data:/http URL) and save it via [saveMediaBlob].
|
||||
*/
|
||||
export const downloadAndSaveMedia = async (
|
||||
src: string,
|
||||
filename: string,
|
||||
accessToken?: string | null
|
||||
): Promise<void> => {
|
||||
let blob: Blob;
|
||||
try {
|
||||
if (src.startsWith('blob:') || src.startsWith('data:')) {
|
||||
const res = await fetch(src);
|
||||
if (!res.ok) throw new Error(`Failed to fetch ${src}`);
|
||||
blob = await res.blob();
|
||||
} else {
|
||||
blob = await downloadMedia(src, accessToken ?? getCurrentAccessToken());
|
||||
}
|
||||
} catch (error) {
|
||||
console.warn('[saveMedia] downloadMedia failed, trying fetch fallback:', error);
|
||||
const res = await fetch(src);
|
||||
if (!res.ok) throw error;
|
||||
blob = await res.blob();
|
||||
}
|
||||
await saveMediaBlob(blob, filename);
|
||||
};
|
||||
Reference in New Issue
Block a user