feat(webui): render video media attachments
Add signed media URLs to live WebSocket replies and teach the WebUI to classify and render video attachments, so bot-sent videos can play inline in both live chats and session history. Made-with: Cursor
This commit is contained in:
@@ -0,0 +1,59 @@
|
||||
import type { UIMediaAttachment, UIMediaKind } from "@/lib/types";
|
||||
|
||||
const IMAGE_EXTENSIONS = new Set([
|
||||
".png",
|
||||
".jpg",
|
||||
".jpeg",
|
||||
".gif",
|
||||
".webp",
|
||||
".bmp",
|
||||
".ico",
|
||||
".tif",
|
||||
".tiff",
|
||||
]);
|
||||
|
||||
const VIDEO_EXTENSIONS = new Set([
|
||||
".mp4",
|
||||
".webm",
|
||||
".mov",
|
||||
".m4v",
|
||||
".avi",
|
||||
".mkv",
|
||||
".3gp",
|
||||
]);
|
||||
|
||||
function cleanPath(value: string): string {
|
||||
return value.split(/[?#]/, 1)[0]?.toLowerCase() ?? "";
|
||||
}
|
||||
|
||||
function extensionOf(value?: string): string {
|
||||
if (!value) return "";
|
||||
const path = cleanPath(value);
|
||||
const dot = path.lastIndexOf(".");
|
||||
if (dot < 0) return "";
|
||||
return path.slice(dot);
|
||||
}
|
||||
|
||||
export function inferMediaKind(media: { url?: string; name?: string }): UIMediaKind {
|
||||
const url = media.url ?? "";
|
||||
if (url.startsWith("data:image/")) return "image";
|
||||
if (url.startsWith("data:video/")) return "video";
|
||||
|
||||
const ext = extensionOf(media.name) || extensionOf(url);
|
||||
if (IMAGE_EXTENSIONS.has(ext)) return "image";
|
||||
if (VIDEO_EXTENSIONS.has(ext)) return "video";
|
||||
return "file";
|
||||
}
|
||||
|
||||
export function toMediaAttachment(media: {
|
||||
url?: string;
|
||||
name?: string;
|
||||
kind?: UIMediaKind;
|
||||
}): UIMediaAttachment {
|
||||
return {
|
||||
kind: media.kind ?? inferMediaKind(media),
|
||||
url: media.url,
|
||||
name: media.name,
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user