Skip to content

Conversation

@yujonglee
Copy link
Contributor

No description provided.

@yujonglee yujonglee merged commit ef8594b into main Nov 8, 2025
3 checks passed
@coderabbitai
Copy link

coderabbitai bot commented Nov 8, 2025

Caution

Review failed

The pull request is closed.

📝 Walkthrough

Walkthrough

This PR restructures the desktop application's transcript rendering pipeline with virtualized scrolling, refactors editor state management to use store-based initialization, simplifies the streaming status component, adds debug seed data generation, and applies consistent patterns for debounced editor updates across TipTap and note editors.

Changes

Cohort / File(s) Summary
Desktop app initialization
apps/desktop/index.html
Un-commented react-scan auto.global.js script tag to enable external library.
Enhanced note editor state management
apps/desktop/src/components/main/body/sessions/note-input/enhanced/editor.tsx
Replaced useCell-based content retrieval with store-based approach; added initialContent state synchronized via useEffect; renamed change handler and updated NoteEditor props.
Streaming UI refactor
apps/desktop/src/components/main/body/sessions/note-input/enhanced/streaming.tsx
Simplified Status component signature to accept only taskId; moved cancel/isGenerating retrieval to internal hooks; converted container from motion.div to motion.button; unified click/cancel handlers.
Note input header
apps/desktop/src/components/main/body/sessions/note-input/header.tsx
Removed enhanced_md cell retrieval and hasContent flag computation from useEnhanceLogic hook.
Raw note editor
apps/desktop/src/components/main/body/sessions/note-input/raw.tsx
Introduced store-based initialContent state; replaced handleRawChange with useSetPartialRowCallback; added memoized mentionConfig via useMemo.
Transcript rendering pipeline refactor
apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/hooks.ts, apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/render-transcript.tsx, apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/segment-renderer.tsx, apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/word-span.tsx, apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/utils.ts, apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/index.tsx
Added transcript utility hooks (useFinalWords, useFinalSpeakerHints, useTranscriptOffset, useSessionSpeakers, useScrollDetection, useAutoScroll); introduced virtualized RenderTranscript component with dynamic overscan; created SegmentRenderer and WordSpan components with audio playback highlighting; added getWordHighlightState utility; refactored TranscriptContainer with callback refs and new rendering structure.
Transcript editor operations consolidation
apps/desktop/src/components/main/body/sessions/note-input/transcript/editor.tsx (removed), apps/desktop/src/components/main/body/sessions/note-input/transcript/viewer.tsx (removed), apps/desktop/src/components/main/body/sessions/note-input/transcript/index.tsx
Removed standalone TranscriptEditor and TranscriptViewer components; consolidated edit operations (handleDeleteWord, handleAssignSpeaker) into Transcript component; unified rendering to always use TranscriptContainer with conditional operations prop.
Transcript styling adjustments
apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/segment-header.tsx
Removed sticky positioning and background utility classes from segment headers.
Tab styling refinement
apps/desktop/src/components/main/body/shared.tsx
Refined TabItemBase styling logic to handle active+selected, active-only, selected-only, and default states with distinct border and close-button color combinations.
Backend client initialization
crates/am/src/lib.rs
Updated test client URL to include "/v1" path and added init sequence call before assertions.
Whisper client streaming
owhisper/owhisper-client/src/lib.rs
Added "0.0.0.0" to local address check; refactored test from dual-input to single-input streaming; updated model and chunk parameters.
TipTap editor debouncing
packages/tiptap/package.json, packages/tiptap/src/editor/index.tsx
Added requestidlecallback-polyfill and usehooks-ts dependencies; introduced debounced update handler with requestIdleCallback for deferred change callback execution.
Debug seed generation
apps/desktop/src/devtool/seed/versions/debug.ts, apps/desktop/src/devtool/seed/versions/index.ts, apps/desktop/src/devtool/seed/index.ts
Created debug seed module with deterministic Faker-based data generation for transcripts, words, and sessions; exported debugSeed for seed system integration.

Sequence Diagram(s)

sequenceDiagram
    participant Store
    participant Component as Enhanced/Raw Editor
    participant NoteEditor
    participant User

    rect rgb(240, 248, 255)
    Note over Store,User: Store-based Initialization Pattern
    Component->>Store: useStore() on mount
    Store-->>Component: Store instance
    Component->>Component: useEffect trigger
    Component->>Store: getCell("sessions", sessionId, "content_field")
    Store-->>Component: Initial content value
    Component->>Component: setInitialContent(value)
    end

    rect rgb(245, 245, 220)
    Note over Component,NoteEditor: Render & Sync
    Component->>NoteEditor: Pass initialContent + handleChange
    NoteEditor->>User: Display editor
    User->>NoteEditor: Edit content
    NoteEditor->>Component: onUpdate → handleChange(markdown)
    Component->>Store: setPartialRow() [via callback]
    Store-->>Component: Store updated
    end
Loading
sequenceDiagram
    participant RenderTranscript
    participant VirtualizedSegments as Virtualizer
    participant SegmentRenderer
    participant WordSpan
    participant AudioContext as useAudioPlayer

    rect rgb(240, 248, 255)
    Note over RenderTranscript,AudioContext: Transcript Rendering with Virtualization
    RenderTranscript->>RenderTranscript: useFinalWords()
    RenderTranscript->>RenderTranscript: useFinalSpeakerHints()
    RenderTranscript->>RenderTranscript: buildSegments()
    RenderTranscript->>VirtualizedSegments: Pass segments + metadata
    end

    rect rgb(255, 250, 205)
    Note over VirtualizedSegments,WordSpan: Dynamic Rendering
    VirtualizedSegments->>VirtualizedSegments: Compute visible items
    loop For each visible segment
        VirtualizedSegments->>SegmentRenderer: Render segment
        SegmentRenderer->>AudioContext: Query currentMs, seek
        loop For each word in segment
            SegmentRenderer->>WordSpan: Pass word + highlight state
            WordSpan->>WordSpan: getWordHighlightState(editable, audioExists, currentMs, timing)
            WordSpan-->>SegmentRenderer: Render with highlight/operations
        end
    end
    end

    rect rgb(220, 240, 220)
    Note over WordSpan,AudioContext: User Interaction
    WordSpan->>WordSpan: User clicks word
    WordSpan->>AudioContext: seekAndPlay(wordStartMs)
    AudioContext-->>WordSpan: Audio seeks & plays
    end
Loading
sequenceDiagram
    participant StreamingView
    participant Status
    participant useAITaskTask as Hook
    participant Task

    rect rgb(255, 245, 240)
    Note over StreamingView,Status: Before: Prop-driven Status
    StreamingView->>Hook: useAITaskTask(taskId)
    Hook-->>StreamingView: {cancel, isGenerating, ...}
    StreamingView->>Status: Pass taskId, cancel, isGenerating
    end

    rect rgb(240, 255, 240)
    Note over StreamingView,Status: After: Self-contained Status
    StreamingView->>Status: Pass taskId only
    Status->>Hook: useAITaskTask(taskId)
    Hook-->>Status: {cancel, isGenerating, currentStep, ...}
    Status->>Status: Render button if isGenerating
    Status->>Task: onClick → cancel()
    end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~40 minutes

Areas requiring extra attention:

  • Transcript virtualization logic (render-transcript.tsx): Custom memoization comparator, dynamic overscan calculations, stable item key generation, and virtualizer lifecycle management need careful review for performance correctness.
  • Hook dependencies and store access patterns (hooks.ts): Multiple new hooks with shared store/index access; verify dependency arrays are correct and no stale closures exist across the transcript rendering pipeline.
  • State synchronization in editors (enhanced/editor.tsx, raw.tsx): Confirm initialContent state properly syncs with store changes and that the useEffect dependencies prevent unnecessary re-renders or infinite loops.
  • Component consolidation (transcript/index.tsx): Verify handleDeleteWord and handleAssignSpeaker operations correctly integrate with TranscriptContainer and that checkpoint logging works as expected.
  • Status component simplification (streaming.tsx): Confirm the simplified click handler and null-return logic don't introduce race conditions or missed updates during generation state changes.

Possibly related PRs

  • Transcript viewer final #1603: Implements the transcript segmentation/renderer pipeline (useSegments, buildSegments, SegmentRenderer/WordSpan) with overlapping transcript viewer rendering logic.
  • Got enhancing working in desktop2 #1596: Modifies the enhanced note editor flow, streaming UI, AI task handling (taskId, useAITask), and GenerateButton integrations in the same enhancement/streaming components.
  • v1: New headers + React19 #1540: Updates TipTap package dependencies and editor source files, paralleling the debounced onUpdate and new requestIdleCallback integration in this PR.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix-transcript-perf

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 6249208 and 4c91c4e.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (23)
  • apps/desktop/index.html (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/enhanced/editor.tsx (2 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/enhanced/streaming.tsx (4 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/header.tsx (0 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/raw.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/editor.tsx (0 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/index.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/hooks.ts (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/index.tsx (3 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/render-transcript.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/segment-header.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/segment-renderer.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/utils.ts (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/shared/word-span.tsx (1 hunks)
  • apps/desktop/src/components/main/body/sessions/note-input/transcript/viewer.tsx (0 hunks)
  • apps/desktop/src/components/main/body/shared.tsx (2 hunks)
  • apps/desktop/src/devtool/seed/index.ts (1 hunks)
  • apps/desktop/src/devtool/seed/versions/debug.ts (1 hunks)
  • apps/desktop/src/devtool/seed/versions/index.ts (1 hunks)
  • crates/am/src/lib.rs (1 hunks)
  • owhisper/owhisper-client/src/lib.rs (3 hunks)
  • packages/tiptap/package.json (1 hunks)
  • packages/tiptap/src/editor/index.tsx (2 hunks)

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@yujonglee yujonglee deleted the fix-transcript-perf branch November 8, 2025 06:17
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants