mirror of
https://github.com/Sea-Haven-Industries/shoc-frontend-new.git
synced 2026-09-30 08:03:13 +00:00
Photos up to 10 MB (JPG/PNG/HEIC), videos up to 100 MB and 90 s (MP4/MOV), at most 10 photos and 3 videos per work order, pre-validated with stable generic messages on the Photos & Videos modal, the Completion Doc media tab, Extra Docs and the vendor portal. Video duration is read from metadata when the browser can; unreadable metadata never blocks. Mobile MIME variants (empty type, octet-stream with a video extension, QuickTime) stay accepted. The signed completion PDF keeps its 50 MB cap.
36 lines
1.1 KiB
TypeScript
36 lines
1.1 KiB
TypeScript
/**
|
|
* Best-effort client-side video duration probe. Resolves null when the browser
|
|
* cannot decode the container's metadata — callers must not block the upload in
|
|
* that case (SH-116: duration is a client-side check only).
|
|
*/
|
|
export const VIDEO_DURATION_PROBE_TIMEOUT_MS = 10_000;
|
|
|
|
export function probeVideoDurationSeconds(file: File): Promise<number | null> {
|
|
return new Promise((resolve) => {
|
|
const url = URL.createObjectURL(file);
|
|
const video = document.createElement("video");
|
|
let settled = false;
|
|
|
|
const done = (value: number | null) => {
|
|
if (settled) return;
|
|
settled = true;
|
|
video.removeAttribute("src");
|
|
video.load();
|
|
URL.revokeObjectURL(url);
|
|
resolve(value);
|
|
};
|
|
|
|
const timeout = window.setTimeout(() => done(null), VIDEO_DURATION_PROBE_TIMEOUT_MS);
|
|
|
|
video.preload = "metadata";
|
|
video.onloadedmetadata = () => {
|
|
window.clearTimeout(timeout);
|
|
done(Number.isFinite(video.duration) ? video.duration : null);
|
|
};
|
|
video.onerror = () => {
|
|
window.clearTimeout(timeout);
|
|
done(null);
|
|
};
|
|
video.src = url;
|
|
});
|
|
}
|