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(" › ");
}