ai-chatbot/lib/canvas/video-canvas-markers.ts
Your Name e054dcabcc
Some checks failed
Lint / build (20) (push) Has been cancelled
Playwright Tests / test (push) Has been cancelled
feat: update canvas and flow board features
2026-04-11 22:28:18 +08:00

178 lines
5.1 KiB
TypeScript

export const VIDEO_CANVAS_MARKER_METADATA_KEY = "videoCanvasMarkers";
export type VideoCanvasMarkerColorId =
| "red"
| "orange"
| "yellow"
| "green"
| "blue"
| "purple"
| "gray";
export type VideoCanvasTaskMarkerId =
| "todo"
| "quarter"
| "half"
| "mostly"
| "blocked"
| "done";
export type VideoCanvasSymbolMarkerId =
| "idea"
| "question"
| "warning"
| "pin"
| "heart"
| "bolt";
export type VideoCanvasMarkerKey =
| "tagColor"
| "priority"
| "task"
| "flagColor"
| "starColor"
| "avatarColor"
| "symbol";
export type VideoCanvasMarkerValue =
| VideoCanvasMarkerColorId
| VideoCanvasTaskMarkerId
| VideoCanvasSymbolMarkerId
| number;
export interface VideoCanvasMarkerState {
tagColor?: VideoCanvasMarkerColorId;
priority?: number;
task?: VideoCanvasTaskMarkerId;
flagColor?: VideoCanvasMarkerColorId;
starColor?: VideoCanvasMarkerColorId;
avatarColor?: VideoCanvasMarkerColorId;
symbol?: VideoCanvasSymbolMarkerId;
}
export const VIDEO_CANVAS_MARKER_COLORS: Array<{
id: VideoCanvasMarkerColorId;
label: string;
color: string;
soft: string;
}> = [
{ id: "red", label: "红色", color: "#ef4444", soft: "#fee2e2" },
{ id: "orange", label: "橙色", color: "#f97316", soft: "#ffedd5" },
{ id: "yellow", label: "黄色", color: "#eab308", soft: "#fef9c3" },
{ id: "green", label: "绿色", color: "#10b981", soft: "#d1fae5" },
{ id: "blue", label: "蓝色", color: "#5b76fe", soft: "#e0e7ff" },
{ id: "purple", label: "紫色", color: "#7c3aed", soft: "#ede9fe" },
{ id: "gray", label: "灰色", color: "#9ca3af", soft: "#f3f4f6" },
];
export const VIDEO_CANVAS_PRIORITY_MARKERS = VIDEO_CANVAS_MARKER_COLORS.map(
(entry, index) => ({
...entry,
value: index + 1,
})
);
export const VIDEO_CANVAS_TASK_MARKERS: Array<{
id: VideoCanvasTaskMarkerId;
label: string;
progress: number;
}> = [
{ id: "todo", label: "未开始", progress: 0 },
{ id: "quarter", label: "25%", progress: 25 },
{ id: "half", label: "50%", progress: 50 },
{ id: "mostly", label: "75%", progress: 75 },
{ id: "blocked", label: "暂停", progress: 88 },
{ id: "done", label: "完成", progress: 100 },
];
export const VIDEO_CANVAS_SYMBOL_MARKERS: Array<{
id: VideoCanvasSymbolMarkerId;
label: string;
color: string;
soft: string;
}> = [
{ id: "idea", label: "想法", color: "#f59e0b", soft: "#fef3c7" },
{ id: "question", label: "疑问", color: "#3b82f6", soft: "#dbeafe" },
{ id: "warning", label: "注意", color: "#ef4444", soft: "#fee2e2" },
{ id: "pin", label: "固定", color: "#64748b", soft: "#f1f5f9" },
{ id: "heart", label: "喜欢", color: "#ec4899", soft: "#fce7f3" },
{ id: "bolt", label: "灵感", color: "#8b5cf6", soft: "#ede9fe" },
];
const MARKER_COLOR_IDS = new Set(
VIDEO_CANVAS_MARKER_COLORS.map((entry) => entry.id)
);
const TASK_MARKER_IDS = new Set(
VIDEO_CANVAS_TASK_MARKERS.map((entry) => entry.id)
);
const SYMBOL_MARKER_IDS = new Set(
VIDEO_CANVAS_SYMBOL_MARKERS.map((entry) => entry.id)
);
function isRecord(value: unknown): value is Record<string, unknown> {
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
}
function normalizeMarkerColorId(value: unknown) {
const id = typeof value === "string" ? value.trim() : "";
return MARKER_COLOR_IDS.has(id as VideoCanvasMarkerColorId)
? (id as VideoCanvasMarkerColorId)
: undefined;
}
function normalizeTaskMarkerId(value: unknown) {
const id = typeof value === "string" ? value.trim() : "";
return TASK_MARKER_IDS.has(id as VideoCanvasTaskMarkerId)
? (id as VideoCanvasTaskMarkerId)
: undefined;
}
function normalizeSymbolMarkerId(value: unknown) {
const id = typeof value === "string" ? value.trim() : "";
return SYMBOL_MARKER_IDS.has(id as VideoCanvasSymbolMarkerId)
? (id as VideoCanvasSymbolMarkerId)
: undefined;
}
export function normalizeVideoCanvasMarkers(
value: unknown
): VideoCanvasMarkerState {
if (!isRecord(value)) {
return {};
}
const priority = Number(value.priority);
return {
tagColor: normalizeMarkerColorId(value.tagColor),
priority:
Number.isInteger(priority) && priority >= 1 && priority <= 7
? priority
: undefined,
task: normalizeTaskMarkerId(value.task),
flagColor: normalizeMarkerColorId(value.flagColor),
starColor: normalizeMarkerColorId(value.starColor),
avatarColor: normalizeMarkerColorId(value.avatarColor),
symbol: normalizeSymbolMarkerId(value.symbol),
};
}
export function compactVideoCanvasMarkers(
markers: VideoCanvasMarkerState
): VideoCanvasMarkerState {
return Object.fromEntries(
Object.entries(markers).filter(([, value]) => value !== undefined)
) as VideoCanvasMarkerState;
}
export function getVideoCanvasMarkerColor(id?: VideoCanvasMarkerColorId) {
return VIDEO_CANVAS_MARKER_COLORS.find((entry) => entry.id === id) || null;
}
export function getVideoCanvasTaskMarker(id?: VideoCanvasTaskMarkerId) {
return VIDEO_CANVAS_TASK_MARKERS.find((entry) => entry.id === id) || null;
}
export function getVideoCanvasSymbolMarker(id?: VideoCanvasSymbolMarkerId) {
return VIDEO_CANVAS_SYMBOL_MARKERS.find((entry) => entry.id === id) || null;
}