feat(backgrounds): accept webm custom call backgrounds (#2377)

This commit is contained in:
Hampus authored and GitHub committed 2026-09-02 17:30:50 +02:00
1 parent f57dc77c6d
commit cadab239a2
4 files changed
+33 -20

No files matched your search

@@ -179,8 +179,8 @@ interface BuiltInBackground {
type BackgroundItemType = BuiltInBackground | BackgroundImage;
const MAX_FILE_SIZE = 10 * 1024 * 1024;
const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4'];
const ALLOWED_FILE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'mp4'];
const ALLOWED_MIME_TYPES = ['image/jpeg', 'image/png', 'image/gif', 'image/webp', 'video/mp4', 'video/webm'];
const ALLOWED_FILE_EXTENSIONS = ['jpg', 'jpeg', 'png', 'gif', 'webp', 'mp4', 'webm'];
function isAllowedBackgroundFile(file: File): boolean {
if (ALLOWED_MIME_TYPES.includes(file.type)) {
@@ -8,21 +8,29 @@ export interface NativeBackgroundMediaSource {
mediaKind: VoiceBackgroundMediaKind;
}
interface BackgroundImageRead {
cancelled: boolean;
promise: Promise<string | null>;
export interface BackgroundMediaObjectURL {
url: string;
mediaKind: VoiceBackgroundMediaKind;
}
const resolvedUrls = new Map<string, string>();
interface BackgroundImageRead {
cancelled: boolean;
promise: Promise<BackgroundMediaObjectURL | null>;
}
const resolvedMedia = new Map<string, BackgroundMediaObjectURL>();
const pendingReads = new Map<string, BackgroundImageRead>();
async function readBackgroundImageObjectURL(id: string): Promise<string | null> {
async function readBackgroundMediaObjectURL(id: string): Promise<BackgroundMediaObjectURL | null> {
const readVoiceBackgroundMedia = getElectronAPI()?.readVoiceBackgroundMedia;
if (!readVoiceBackgroundMedia) return null;
const media = await readVoiceBackgroundMedia(id);
if (!media?.dataUrl) return null;
const response = await fetch(media.dataUrl);
return URL.createObjectURL(await response.blob());
return {
url: URL.createObjectURL(await response.blob()),
mediaKind: media.mediaKind,
};
}
export async function saveBackgroundImage(id: string, blob: Blob): Promise<NativeBackgroundMediaSource> {
@@ -50,14 +58,14 @@ export async function deleteBackgroundImage(id: string): Promise<void> {
}
export function getCachedBackgroundImageURL(id: string): string | null {
return resolvedUrls.get(id) ?? null;
return resolvedMedia.get(id)?.url ?? null;
}
export function releaseBackgroundImageURL(id: string): void {
const resolved = resolvedUrls.get(id);
const resolved = resolvedMedia.get(id);
if (resolved != null) {
URL.revokeObjectURL(resolved);
resolvedUrls.delete(id);
URL.revokeObjectURL(resolved.url);
resolvedMedia.delete(id);
}
const pending = pendingReads.get(id);
if (pending != null) {
@@ -66,21 +74,21 @@ export function releaseBackgroundImageURL(id: string): void {
}
}
export async function getBackgroundImageURL(id: string): Promise<string | null> {
const resolved = resolvedUrls.get(id);
export async function getBackgroundMediaObjectURL(id: string): Promise<BackgroundMediaObjectURL | null> {
const resolved = resolvedMedia.get(id);
if (resolved != null) return resolved;
const inFlight = pendingReads.get(id);
if (inFlight != null) return inFlight.promise;
const read: BackgroundImageRead = {cancelled: false, promise: Promise.resolve(null)};
read.promise = readBackgroundImageObjectURL(id).then(
(url) => {
read.promise = readBackgroundMediaObjectURL(id).then(
(media) => {
if (read.cancelled) {
if (url != null) URL.revokeObjectURL(url);
if (media != null) URL.revokeObjectURL(media.url);
return null;
}
pendingReads.delete(id);
if (url != null) resolvedUrls.set(id, url);
return url;
if (media != null) resolvedMedia.set(id, media);
return media;
},
(error: unknown) => {
if (!read.cancelled) pendingReads.delete(id);
@@ -90,3 +98,7 @@ export async function getBackgroundImageURL(id: string): Promise<string | null>
pendingReads.set(id, read);
return read.promise;
}
export async function getBackgroundImageURL(id: string): Promise<string | null> {
return (await getBackgroundMediaObjectURL(id))?.url ?? null;
}