import type { ComposerFileAttachment } from "../../composerDraftStore";import { type ChatImageAttachment, isVideoAttachment } from "../../types"; export interface ExpandedImageItem { src: string; name: string; type?: "video";} export interface ExpandedImagePreview { images: ExpandedImageItem[]; index: number;} export function attachVideoThumbnail(video: HTMLVideoElement, file: File): () => void { const url = URL.createObjectURL(file); video.src = url; return () => URL.revokeObjectURL(url);} export async function downloadVideoPreview(src: string, name: string): Promise<void> { const response = await fetch(src); if (!response.ok) throw new Error(`Could not download video (${response.status}).`); const url = URL.createObjectURL(await response.blob()); const anchor = document.createElement("a"); anchor.href = url; anchor.download = name; anchor.click(); setTimeout(() => URL.revokeObjectURL(url), 30_000);} export function buildExpandedImagePreview( images: ReadonlyArray<ChatImageAttachment | ComposerFileAttachment>, selectedImageId: string,): ExpandedImagePreview | null { const selected = images.find((image) => image.id === selectedImageId); if (selected?.type === "file" && selected.file && isVideoAttachment(selected)) { return { images: [{ src: URL.createObjectURL(selected.file), name: selected.name, type: "video" }], index: 0, }; } const previewableImages = images.flatMap((image) => image.type === "image" && image.previewUrl ? [{ id: image.id, src: image.previewUrl, name: image.name }] : [], ); if (previewableImages.length === 0) { return null; } const selectedIndex = previewableImages.findIndex((image) => image.id === selectedImageId); if (selectedIndex < 0) { return null; } return { images: previewableImages.map((image) => ({ src: image.src, name: image.name, })), index: selectedIndex, };}
import type { ComposerFileAttachment } from "../../composerDraftStore";
import { type ChatImageAttachment, isVideoAttachment } from "../../types";
export interface ExpandedImageItem {
src: string;
name: string;
type?: "video";
}
export interface ExpandedImagePreview {
images: ExpandedImageItem[];
index: number;
}
export function attachVideoThumbnail(video: HTMLVideoElement, file: File): () => void {
const url = URL.createObjectURL(file);
video.src = url;
return () => URL.revokeObjectURL(url);
}
export async function downloadVideoPreview(src: string, name: string): Promise<void> {
const response = await fetch(src);
if (!response.ok) throw new Error(`Could not download video (${response.status}).`);
const url = URL.createObjectURL(await response.blob());
const anchor = document.createElement("a");
anchor.href = url;
anchor.download = name;
anchor.click();
setTimeout(() => URL.revokeObjectURL(url), 30_000);
}
export function buildExpandedImagePreview(
images: ReadonlyArray<ChatImageAttachment | ComposerFileAttachment>,
selectedImageId: string,
): ExpandedImagePreview | null {
const selected = images.find((image) => image.id === selectedImageId);
if (selected?.type === "file" && selected.file && isVideoAttachment(selected)) {
return {
images: [{ src: URL.createObjectURL(selected.file), name: selected.name, type: "video" }],
index: 0,
};
}
const previewableImages = images.flatMap((image) =>
image.type === "image" && image.previewUrl
? [{ id: image.id, src: image.previewUrl, name: image.name }]
: [],
);
if (previewableImages.length === 0) {
return null;
}
const selectedIndex = previewableImages.findIndex((image) => image.id === selectedImageId);
if (selectedIndex < 0) {
return null;
}
return {
images: previewableImages.map((image) => ({
src: image.src,
name: image.name,
})),
index: selectedIndex,
};
}