ldc-groupe/resources/ts/back/Components/Inputs/Video/VideoUtils.tsx

115 lines
3.4 KiB
TypeScript

import { z } from "zod";
export const videoDetails = {
width: "1008",
height: "567",
minDim: "100",
maxDim: "1008",
};
/**
* Extract YouTube video ID from a URL or a raw ID.
*/
export const extractYoutubeId = (input: string): string | null => {
const trimmed = input.trim();
// Direct ID (11 chars)
if (/^[a-zA-Z0-9_-]{11}$/.test(trimmed)) return trimmed;
// youtube.com/watch?v=ID
const watchMatch = trimmed.match(/[?&]v=([a-zA-Z0-9_-]{11})/);
if (watchMatch) return watchMatch[1];
// youtu.be/ID
const shortMatch = trimmed.match(/youtu\.be\/([a-zA-Z0-9_-]{11})/);
if (shortMatch) return shortMatch[1];
// youtube.com/embed/ID
const embedMatch = trimmed.match(/youtube\.com\/embed\/([a-zA-Z0-9_-]{11})/);
if (embedMatch) return embedMatch[1];
return null;
};
/**
* Extract Vimeo video ID from a URL or a raw ID.
*/
export const extractVimeoId = (input: string): string | null => {
const trimmed = input.trim();
// Direct numeric ID
if (/^\d+$/.test(trimmed)) return trimmed;
// vimeo.com/ID or vimeo.com/video/ID
const match = trimmed.match(/vimeo\.com\/(?:video\/)?(\d+)/);
if (match) return match[1];
return null;
};
/**
* Build the iframe src URL for YouTube or Vimeo with options.
*/
export const buildVideoSrc = (attrs: {
videoId?: string | null;
isMuted?: boolean;
hasControls?: boolean;
provider: number;
}): string => {
const params = new URLSearchParams();
const query = params.toString();
if (attrs.provider == 1) {
if (attrs.isMuted) params.set("mute", "1");
params.set("controls", attrs.hasControls ? "1" : "0");
return `https://www.youtube.com/embed/${attrs.videoId}${query ? `?${query}` : ""}`;
}
if (attrs.provider == 2) {
if (attrs.isMuted) params.set("muted", "1");
if (!attrs.hasControls) params.set("controls", "0");
return `https://player.vimeo.com/video/${attrs.videoId}${query ? `?${query}` : ""}`;
}
return "";
};
/**
* Zod schema for video caption input.
*/
export const videoTextSchema = ({
hasCaption,
transValidationCaption,
transValidationAlt,
}: {
hasCaption: boolean;
transValidationCaption: { min: string; max: string; string: string, boolean: string };
transValidationAlt: {
min: string;
max: string;
string: string;
};
}) => {
const altRules = z
.string({ message: transValidationAlt.string })
.min(3, transValidationAlt.min)
.max(255, transValidationAlt.max);
const captionRules = z
.string({ message: transValidationCaption.string })
.min(3, transValidationCaption.min)
.max(255, transValidationCaption.max);
const isBool = z.boolean({ message: transValidationCaption.boolean });
return z.object({
caption: hasCaption ? captionRules : z.null(),
isMuted: isBool,
hasControls: isBool,
canFullScreen: isBool,
alt: altRules
});
};
export const isBoolsSchema = (transValidation: { isMuted: string; hasControls: string; canFullScreen: string }) => {
const isMuted = z.boolean({ message: transValidation.isMuted });
const hasControls = z.boolean({ message: transValidation.hasControls });
const canFullScreen = z.boolean({ message: transValidation.canFullScreen });
return z.object({
isMuted: isMuted,
hasControls: hasControls,
canFullScreen: canFullScreen,
});
};