From 20bb20510e8fb0d85ba2642b75521a348876ea76 Mon Sep 17 00:00:00 2001 From: Claude Date: Sat, 24 Oct 2026 10:00:01 +0000 Subject: [PATCH] Lighten render row and attach menu text, keep trailing spaces in narration, pin project header Co-Authored-By: Claude Sonnet 5.5 Claude-Session: https://claude.ai/code/session_01K8ut4dqzBJUxaL3PeTVnKD --- .../src/components/AssistantAttachments.tsx | 2 +- frontend/src/components/RenderPanel.tsx | 5 +- frontend/src/spec/edits.test.ts | 5 + frontend/src/spec/edits.ts | 5 +- frontend/src/views/ProjectView.tsx | 110 +++++++++--------- 5 files changed, 71 insertions(+), 56 deletions(-) diff --git a/frontend/src/components/AssistantAttachments.tsx b/frontend/src/components/AssistantAttachments.tsx index 83e3d72..ed23cd2 100644 --- a/frontend/src/components/AssistantAttachments.tsx +++ b/frontend/src/components/AssistantAttachments.tsx @@ -216,7 +216,7 @@ export function AttachControls() { } const item = - 'flex w-full items-center gap-2 px-2 py-1.5 text-left text-xs hover:bg-gray-50 dark:hover:bg-gray-700' + 'flex w-full items-center gap-2 px-2 py-1.5 text-left text-xs text-gray-800 dark:text-gray-100 hover:bg-gray-50 dark:hover:bg-gray-700' return (
diff --git a/frontend/src/components/RenderPanel.tsx b/frontend/src/components/RenderPanel.tsx index 1082875..714ced1 100644 --- a/frontend/src/components/RenderPanel.tsx +++ b/frontend/src/components/RenderPanel.tsx @@ -205,7 +205,10 @@ export default function RenderPanel({ projectId, dirty, version }: Props) { {renders.length > 0 && (
    {renders.map((render) => ( -
  • +
  • {render.preview ? 'Preview' : 'Render'} v{render.version} diff --git a/frontend/src/spec/edits.test.ts b/frontend/src/spec/edits.test.ts index c5a60b2..348654b 100644 --- a/frontend/src/spec/edits.test.ts +++ b/frontend/src/spec/edits.test.ts @@ -74,6 +74,11 @@ describe('narration as text', () => { expect(scene.narration?.beats.map((b) => b.id)).toEqual(['b1', 'b2', 'b3']) }) + it('keeps a space typed at the end of a paragraph', () => { + const scene = withNarrationText(spec().segments[1], 'One two ') + expect(narrationText(scene)).toBe('One two ') + }) + it('keeps one empty beat when the box is cleared', () => { const scene = withNarrationText(spec().segments[1], '') expect(scene.narration?.beats).toEqual([{ id: 'b1', text: '' }]) diff --git a/frontend/src/spec/edits.ts b/frontend/src/spec/edits.ts index e367f00..b3fcbd0 100644 --- a/frontend/src/spec/edits.ts +++ b/frontend/src/spec/edits.ts @@ -84,7 +84,10 @@ export function narrationText(segment: Segment): string { export function withNarrationText(segment: Segment, text: string): Segment { const existing = segment.narration?.beats ?? [] - const paragraphs = text.split(/\n\s*\n/).map((p) => p.trim()) + // Not trimmed: this runs on every keystroke and the box shows the result back, so + // trimming would eat the space just typed at the end of a paragraph. Only a + // paragraph of nothing but whitespace is normalised, to empty. + const paragraphs = text.split(/\n\s*\n/).map((p) => (p.trim() === '' ? '' : p)) // An emptied box is one empty beat, not none, so the scene keeps a place to type. const kept = paragraphs.filter((p, i) => p !== '' || i === 0) const taken = new Set(existing.map((b) => b.id)) diff --git a/frontend/src/views/ProjectView.tsx b/frontend/src/views/ProjectView.tsx index 5b714fe..8dfadf5 100644 --- a/frontend/src/views/ProjectView.tsx +++ b/frontend/src/views/ProjectView.tsx @@ -115,41 +115,67 @@ export default function ProjectView() { } return ( -
    -
    - - - - edit({ ...draft, title: e.target.value })} - /> - {dirty && ( - + )} + - )} -
    + +

    + Version {project.version} + {source?.kind === 'note' && + ' · pushed from Gecko Notes; edited only here from now on'} + {source?.kind === 'brief' && ' · drafted from a prompt'} +

    + +
    - - {saving ? 'Saving…' : dirty ? 'Save' : 'Saved'} - + {TABS.map((t) => ( + + ))} +
    -

    - Version {project.version} - {source?.kind === 'note' && - ' · pushed from Gecko Notes; edited only here from now on'} - {source?.kind === 'brief' && ' · drafted from a prompt'} -

    - {project.pending_note_media > 0 && (

    @@ -193,28 +219,6 @@ export default function ProjectView() { )} -

    - {TABS.map((t) => ( - - ))} -
    - {tab === 'scenes' && toFind.length > 0 && (