transcript editor analytics + new design #1490
Conversation
📝 WalkthroughWalkthroughNarrowed the command-palette modal sizing; added userId-backed analytics and UI tweaks for transcript edit/speaker actions; and emitted recording start/stop analytics from the ListenButton, wiring userId into start/stop event payloads. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant CP as CommandPalette
participant DOM as Document
U->>CP: Open palette
CP->>DOM: Append <style> (override dialog width 590px, max-width 80vw)
U->>CP: Close palette
CP->>DOM: Remove injected <style>
sequenceDiagram
autonumber
participant U as User
participant TV as TranscriptView
participant AN as Analytics
U->>TV: Click "Edit"/"Save"
TV->>TV: Toggle edit state, update UI
TV->>AN: track("transcript_toggle_edit", { distinct_id?: userId, ... })
U->>TV: Apply speaker change
TV->>AN: track("transcript_speaker_change", { distinct_id?: userId, speaker })
sequenceDiagram
autonumber
participant U as User
participant LB as ListenButton
participant AN as Analytics
U->>LB: Start recording
LB->>AN: track("recording_start_session", { distinct_id?: userId, session_id })
U->>LB: Stop recording
LB->>AN: track("recording_stop_session", { distinct_id?: userId, session_id })
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Pre-merge checks and finishing touches❌ Failed checks (2 warnings)
✅ Passed checks (1 passed)
✨ Finishing touches
🧪 Generate unit tests
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. Comment |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (1)
apps/desktop/src/components/right-panel/views/transcript-view.tsx (1)
162-162: Remove debug console logs before merge.The debug console logs should be removed from production code to avoid cluttering the console output.
- console.log("user is toggling edit");- console.log("user is making changes");Also applies to: 188-188
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
apps/desktop/src/components/command-palette.tsx(1 hunks)apps/desktop/src/components/right-panel/views/transcript-view.tsx(7 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop/src/components/right-panel/views/transcript-view.tsxapps/desktop/src/components/command-palette.tsx
🧬 Code graph analysis (1)
apps/desktop/src/components/right-panel/views/transcript-view.tsx (1)
apps/desktop/src/contexts/hypr.tsx (1)
useHypr(63-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (windows, windows-latest)
- GitHub Check: ci (macos, macos-14)
🔇 Additional comments (8)
apps/desktop/src/components/command-palette.tsx (1)
322-323: LGTM! Dialog width adjustment is well-implemented.The dynamic style injection approach correctly adjusts the dialog width on open and cleans up on close. The narrower width (590px) and reduced max-width (80vw) provide better focus for search results.
apps/desktop/src/components/right-panel/views/transcript-view.tsx (7)
20-20: LGTM! Analytics dependency added correctly.The import follows the established plugin import pattern in the codebase.
97-97: LGTM! UserId extraction for analytics.Correctly extracts userId from the Hypr context to enable user-specific analytics tracking.
174-181: LGTM! Analytics event tracking for edit toggle.The analytics event is correctly triggered when entering edit mode (toggling from false to true), with proper userId validation.
185-185: Verify dependency array includes sessionId.The
handeToggleEditcallback includesuserIdin dependencies but also usessessionIdandqueryClient. Ensure all dependencies are included to prevent stale closures.Based on my research on React useCallback dependency arrays, the dependency array is crucial, and omitting necessary dependencies can cause bugs. In the dependency array, include all values from the component scope that the callback function depends on.
The
handeToggleEditcallback usessessionIdandqueryClientfrom the component scope but doesn't include them in the dependency array. Apply this fix:- }, [editorWords, userId]); + }, [sessionId, queryClient, editorWords, userId]);
227-235: LGTM! UI changes improve accessibility.The changes from icon-based to text-based edit toggle improve accessibility and user clarity. The styling adjustments and size change from "icon" to "sm" are appropriate for the text content.
244-246: LGTM! Layout adjustment for edit toggle.The additional container wrapper properly positions the edit toggle in the header layout.
533-538: LGTM! Analytics event for speaker changes.The analytics event is correctly triggered when applying speaker changes, with proper userId validation.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
apps/desktop/src/components/editor-area/note-header/listen-button.tsx (3)
105-110: Add session context to start eventIncluding sessionId helps correlate start/stop and de‑dupe. If your analytics API follows PostHog/Segment shape, add properties.
- if (!isOnboarding && userId) { - analyticsCommands.event({ - event: "recording_start_session", - distinct_id: userId, - }); - } + if (!isOnboarding && userId) { + analyticsCommands.event({ + event: "recording_start_session", + distinct_id: userId, + properties: { session_id: sessionId }, + }); + }Confirm the expected payload shape (e.g., properties vs. traits) for @hypr/plugin-analytics.
245-245: Gate stop analytics for onboarding (symmetry with start)Currently start is gated on !isOnboarding but stop is not. Mirror the gate to avoid onboarding noise.
-function WhenActive({ sessionId }: { sessionId: string }) { - const { userId } = useHypr(); +function WhenActive({ sessionId }: { sessionId: string }) { + const { onboardingSessionId, userId } = useHypr(); + const isOnboarding = sessionId === onboardingSessionId;
262-267: Add onboarding gate + session context to stop eventKeep analytics consistent with start and include sessionId for correlation.
- if (userId) { - analyticsCommands.event({ - event: "recording_stop_session", - distinct_id: userId, - }); - } + if (!isOnboarding && userId) { + analyticsCommands.event({ + event: "recording_stop_session", + distinct_id: userId, + properties: { session_id: sessionId }, + }); + }
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
apps/desktop/src/locales/en/messages.pois excluded by!**/*.poapps/desktop/src/locales/ko/messages.pois excluded by!**/*.po
📒 Files selected for processing (1)
apps/desktop/src/components/editor-area/note-header/listen-button.tsx(5 hunks)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop/src/components/editor-area/note-header/listen-button.tsx
🧬 Code graph analysis (1)
apps/desktop/src/components/editor-area/note-header/listen-button.tsx (1)
apps/desktop/src/contexts/hypr.tsx (1)
useHypr(63-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
- GitHub Check: ci (macos, macos-14)
- GitHub Check: ci (windows, windows-latest)
🔇 Additional comments (2)
apps/desktop/src/components/editor-area/note-header/listen-button.tsx (2)
21-21: Analytics import — LGTMImport is used below; no unused import issues.
53-53: Propagate userId — looks good; confirm it’s non‑PIIIf userId can be email/phone, this may be a compliance risk. Ensure it’s an opaque ID and allowed per your analytics policy.
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Nitpick comments (3)
apps/desktop/src/components/right-panel/views/transcript-view.tsx (3)
161-185: Emit edit-toggle analytics on both enter and exitCurrently logs only when entering edit mode (
!v). Emit on exit as well for symmetry and better funnels.Apply this diff:
const handeToggleEdit = useCallback(() => { setEditable((v) => { if (v) { + if (userId) { + analyticsCommands.event({ + event: "transcript_toggle_edit", + distinct_id: userId, + }); + } dbCommands.getSession({ id: sessionId }).then((session) => { if (session) { dbCommands.upsertSession({ ...session, words: editorWords }).then(() => { queryClient.invalidateQueries({ queryKey: ["session", "words", sessionId], }); }); } }); } else { if (userId) { analyticsCommands.event({ event: "transcript_toggle_edit", distinct_id: userId, }); } } return !v; }); - }, [editorWords, userId]); + }, [editorWords, userId, sessionId, queryClient]);
184-184: CompleteuseCallbackdeps
handeToggleEditcapturessessionIdandqueryClient; add them to the deps to avoid stale closures.Apply this diff:
- }, [editorWords, userId]); + }, [editorWords, userId, sessionId, queryClient]);
161-161: Typo: renamehandeToggleEdit→handleToggleEditImproves readability and consistency.
Apply this diff:
- const handeToggleEdit = useCallback(() => { + const handleToggleEdit = useCallback(() => { @@ - onClick={handeToggleEdit} + onClick={handleToggleEdit}Also applies to: 224-229
📜 Review details
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (2)
apps/desktop/src/locales/en/messages.pois excluded by!**/*.poapps/desktop/src/locales/ko/messages.pois excluded by!**/*.po
📒 Files selected for processing (2)
apps/desktop/src/components/editor-area/note-header/listen-button.tsx(5 hunks)apps/desktop/src/components/right-panel/views/transcript-view.tsx(6 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- apps/desktop/src/components/editor-area/note-header/listen-button.tsx
🧰 Additional context used
📓 Path-based instructions (1)
**/*.{js,ts,tsx,rs}
⚙️ CodeRabbit configuration file
**/*.{js,ts,tsx,rs}: 1. Do not add any error handling. Keep the existing one.
2. No unused imports, variables, or functions.
3. For comments, keep it minimal. It should be about "Why", not "What".
Files:
apps/desktop/src/components/right-panel/views/transcript-view.tsx
🧬 Code graph analysis (1)
apps/desktop/src/components/right-panel/views/transcript-view.tsx (1)
apps/desktop/src/contexts/hypr.tsx (1)
useHypr(63-69)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (1)
- GitHub Check: ci (macos, macos-14)
🔇 Additional comments (6)
apps/desktop/src/components/right-panel/views/transcript-view.tsx (6)
20-20: LGTM: analytics import and aliasingThe
analyticsCommandsimport is clear and used; no unused imports introduced.
97-97: LGTM: userId consumption for analyticsSafe extraction via
useHypr()and guarded use downstream.
225-233: LGTM: Edit/Save button UI tweakSizing and label swap look good; semantics preserved.
242-244: LGTM: header layout wrapperThe extra container aligns the toggle cleanly without affecting interaction.
531-536: LGTM: speaker-change analyticsEvent emission is gated on
userId; minimal and consistent with the rest.
133-141: Remove invalid second arg to useQueryuseQuery (React Query v4/v5) accepts a single options object — remove the extraneous second argument
queryClient.File: apps/desktop/src/components/right-panel/views/transcript-view.tsx (lines 133-141)
- const audioExist = useQuery( - { - refetchInterval: 2500, - enabled: !!sessionId, - queryKey: ["audio", sessionId, "exist"], - queryFn: () => miscCommands.audioExist(sessionId), - }, - queryClient, - ); + const audioExist = useQuery({ + refetchInterval: 2500, + enabled: !!sessionId, + queryKey: ["audio", sessionId, "exist"], + queryFn: () => miscCommands.audioExist(sessionId), + });I ran the provided ripgrep search in the sandbox and it produced no matches — please run the rg command locally/CI to confirm there are no other occurrences.
No description provided.