From dc0b57cd6a5517dc6b57c6ebd1d0f6f7c8ee5e40 Mon Sep 17 00:00:00 2001 From: Maze Winther Date: Sun, 8 Feb 2026 18:01:45 +0100 Subject: [PATCH] refactor: replace text-specific update command with generic --- .../panels/properties/text-properties.tsx | 30 +++++++++---------- .../web/src/core/managers/timeline-manager.ts | 24 +++------------ .../lib/commands/timeline/element/index.ts | 2 +- ...date-text-element.ts => update-element.ts} | 23 +++----------- 4 files changed, 24 insertions(+), 55 deletions(-) rename apps/web/src/lib/commands/timeline/element/{update-text-element.ts => update-element.ts} (62%) diff --git a/apps/web/src/components/editor/panels/properties/text-properties.tsx b/apps/web/src/components/editor/panels/properties/text-properties.tsx index 8f40910b..43c1eb26 100644 --- a/apps/web/src/components/editor/panels/properties/text-properties.tsx +++ b/apps/web/src/components/editor/panels/properties/text-properties.tsx @@ -59,7 +59,7 @@ export function TextProperties({ const fontSize = Number.isNaN(parsed) ? element.fontSize : clamp({ value: parsed, min: MIN_FONT_SIZE, max: MAX_FONT_SIZE }); - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { fontSize }, @@ -73,7 +73,7 @@ export function TextProperties({ ? element.fontSize : clamp({ value: parsed, min: MIN_FONT_SIZE, max: MAX_FONT_SIZE }); setFontSizeInput(fontSize.toString()); - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { fontSize }, @@ -88,7 +88,7 @@ export function TextProperties({ const opacityPercent = Number.isNaN(parsed) ? Math.round(element.opacity * 100) : clamp({ value: parsed, min: 0, max: 100 }); - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { opacity: opacityPercent / 100 }, @@ -102,7 +102,7 @@ export function TextProperties({ ? Math.round(element.opacity * 100) : clamp({ value: parsed, min: 0, max: 100 }); setOpacityInput(opacityPercent.toString()); - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { opacity: opacityPercent / 100 }, @@ -113,7 +113,7 @@ export function TextProperties({ if (color !== "transparent") { lastSelectedColor.current = color; } - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { backgroundColor: color }, @@ -126,7 +126,7 @@ export function TextProperties({ isTransparent: boolean; }) => { const newColor = isTransparent ? "transparent" : lastSelectedColor.current; - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { backgroundColor: newColor }, @@ -154,7 +154,7 @@ export function TextProperties({ defaultValue={element.content} className="bg-panel-accent min-h-20" onChange={(e) => - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { content: e.target.value }, @@ -167,7 +167,7 @@ export function TextProperties({ - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { fontFamily: value }, @@ -186,7 +186,7 @@ export function TextProperties({ } size="sm" onClick={() => - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { @@ -205,7 +205,7 @@ export function TextProperties({ } size="sm" onClick={() => - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { @@ -228,7 +228,7 @@ export function TextProperties({ } size="sm" onClick={() => - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { @@ -251,7 +251,7 @@ export function TextProperties({ } size="sm" onClick={() => - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { @@ -279,7 +279,7 @@ export function TextProperties({ max={MAX_FONT_SIZE} step={1} onValueChange={([value]) => { - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { fontSize: value }, @@ -310,7 +310,7 @@ export function TextProperties({ string: (element.color || "FFFFFF").replace("#", ""), })} onChange={(color) => { - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { color: `#${color}` }, @@ -330,7 +330,7 @@ export function TextProperties({ max={100} step={1} onValueChange={([value]) => { - editor.timeline.updateTextElement({ + editor.timeline.updateElement({ trackId, elementId: element.id, updates: { opacity: value / 100 }, diff --git a/apps/web/src/core/managers/timeline-manager.ts b/apps/web/src/core/managers/timeline-manager.ts index 867df3a8..22cba52d 100644 --- a/apps/web/src/core/managers/timeline-manager.ts +++ b/apps/web/src/core/managers/timeline-manager.ts @@ -2,7 +2,6 @@ import type { EditorCore } from "@/core"; import type { TrackType, TimelineTrack, - TextElement, TimelineElement, ClipboardItem, } from "@/types/timeline"; @@ -19,7 +18,7 @@ import { DuplicateElementsCommand, ToggleElementsVisibilityCommand, ToggleElementsMutedCommand, - UpdateTextElementCommand, + UpdateElementCommand, SplitElementsCommand, PasteCommand, UpdateElementStartTimeCommand, @@ -199,31 +198,16 @@ export class TimelineManager { this.editor.command.execute({ command }); } - updateTextElement({ + updateElement({ trackId, elementId, updates, }: { trackId: string; elementId: string; - updates: Partial< - Pick< - TextElement, - | "content" - | "fontSize" - | "fontFamily" - | "color" - | "backgroundColor" - | "textAlign" - | "fontWeight" - | "fontStyle" - | "textDecoration" - | "transform" - | "opacity" - > - >; + updates: Partial>; }): void { - const command = new UpdateTextElementCommand(trackId, elementId, updates); + const command = new UpdateElementCommand(trackId, elementId, updates); this.editor.command.execute({ command }); } diff --git a/apps/web/src/lib/commands/timeline/element/index.ts b/apps/web/src/lib/commands/timeline/element/index.ts index 8b719afa..3f10baa4 100644 --- a/apps/web/src/lib/commands/timeline/element/index.ts +++ b/apps/web/src/lib/commands/timeline/element/index.ts @@ -5,7 +5,7 @@ export { UpdateElementTrimCommand } from "./update-element-trim"; export { UpdateElementDurationCommand } from "./update-element-duration"; export { UpdateElementStartTimeCommand } from "./update-element-start-time"; export { SplitElementsCommand } from "./split-elements"; -export { UpdateTextElementCommand } from "./update-text-element"; +export { UpdateElementCommand } from "./update-element"; export { ToggleElementsVisibilityCommand } from "./toggle-elements-visibility"; export { ToggleElementsMutedCommand } from "./toggle-elements-muted"; export { MoveElementCommand } from "./move-elements"; diff --git a/apps/web/src/lib/commands/timeline/element/update-text-element.ts b/apps/web/src/lib/commands/timeline/element/update-element.ts similarity index 62% rename from apps/web/src/lib/commands/timeline/element/update-text-element.ts rename to apps/web/src/lib/commands/timeline/element/update-element.ts index e3cc4a32..4ee54726 100644 --- a/apps/web/src/lib/commands/timeline/element/update-text-element.ts +++ b/apps/web/src/lib/commands/timeline/element/update-element.ts @@ -1,27 +1,14 @@ import { Command } from "@/lib/commands/base-command"; -import type { TextElement, TimelineTrack } from "@/types/timeline"; +import type { TimelineTrack } from "@/types/timeline"; import { EditorCore } from "@/core"; -export class UpdateTextElementCommand extends Command { +export class UpdateElementCommand extends Command { private savedState: TimelineTrack[] | null = null; constructor( private trackId: string, private elementId: string, - private updates: Partial< - Pick< - TextElement, - | "content" - | "fontSize" - | "fontFamily" - | "color" - | "backgroundColor" - | "textAlign" - | "fontWeight" - | "fontStyle" - | "textDecoration" - > - >, + private updates: Partial>, ) { super(); } @@ -33,9 +20,7 @@ export class UpdateTextElementCommand extends Command { const updatedTracks = this.savedState.map((t) => { if (t.id !== this.trackId) return t; const newElements = t.elements.map((el) => - el.id === this.elementId && el.type === "text" - ? { ...el, ...this.updates } - : el, + el.id === this.elementId ? { ...el, ...this.updates } : el, ); return { ...t, elements: newElements } as typeof t; });