File size: 2,968 Bytes
6277fde 884fa04 6277fde | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 | /**
* Human-readable labels for edit-history field names and JSON diff paths.
*
* Top-level fields are the DB column names (e.g. `remotion_code`,
* `preferred_layout`). Diff paths are dotted keys from inside a JSON field's
* descriptor (e.g. `title.fontSize`, `series.0.color`). Anything not explicitly
* mapped falls back to a prettified version of the raw key.
*/
// Top-level DB field → label.
const FIELD_LABELS: Record<string, string> = {
title: "Title",
display_text: "On-screen text",
narration_text: "Narration",
visual_description: "Visual description",
remotion_code: "Scene Props",
duration_seconds: "Duration",
extra_hold_seconds: "Hold time",
bgm_volume: "Music volume",
preferred_layout: "Layout",
is_active: "Scene",
scene_deleted: "Scene",
scene_order: "Scene order",
// Project-level
name: "Project name",
accent_color: "Accent color",
bg_color: "Background color",
text_color: "Text color",
font_family: "Font",
captions_enabled: "Captions",
caption_position: "Caption position",
caption_font_family: "Caption font",
caption_font_size: "Caption size",
caption_offset: "Caption offset position",
bgm_track_id: "Music track",
playback_speed: "Playback speed",
logo_position: "Logo position",
logo_opacity: "Logo opacity",
logo_size: "Logo size",
};
// Common keys inside JSON descriptors (remotion_code) → label.
const PATH_KEY_LABELS: Record<string, string> = {
title: "Title",
subtitle: "Subtitle",
body: "Body",
content: "Content",
heading: "Heading",
caption: "Caption",
source: "Source",
footer: "Footer",
label: "Label",
value: "Value",
fontSize: "Font size",
titleFontSize: "Title size",
subtitleFontSize: "Subtitle size",
bodyFontSize: "Body size",
contentFontSize: "Content size",
headingFontSize: "Heading size",
fontFamily: "Font",
textColor: "Text color",
bgColor: "Background color",
accentColor: "Accent color",
color: "Color",
imageUrl: "Image",
imageBox: "Image box",
chartType: "Chart type",
layout: "Layout",
};
/** camelCase / snake_case / kebab → "Title Case" words. */
function prettify(key: string): string {
const spaced = key
.replace(/([a-z0-9])([A-Z])/g, "$1 $2") // camelCase → camel Case
.replace(/[_-]+/g, " ")
.trim();
if (!spaced) return key;
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
}
/** Label for a top-level edit field name. */
export function fieldLabel(name: string | null): string {
if (!name) return "Field";
return FIELD_LABELS[name] ?? prettify(name);
}
/** Label for a dotted JSON diff path (each segment mapped; array indices → "#n"). */
export function pathLabel(path: string): string {
if (!path) return "";
return path
.split(".")
.map((seg) => {
if (/^\d+$/.test(seg)) return `#${Number(seg) + 1}`; // array index → 1-based
return PATH_KEY_LABELS[seg] ?? prettify(seg);
})
.join(" › ");
}
|