Add debug features including DebugFAB and DebugSheet components, and … - #171
Conversation
…integrate debugging context for enhanced development insights
📝 WalkthroughWalkthroughA debug instrumentation system is introduced across the app. New debug context, hooks, and UI components enable screens to register debug sections, logs, and actions. A floating action button provides access to a debug sheet that displays registered data during development. The system is integrated into home, protected layout, and video call screens. Changes
Sequence DiagramsequenceDiagram
actor User as Developer/User
participant FAB as DebugFAB
participant Screen as Screen Component<br/>(Home, VideoCall, etc)
participant Context as DebugProvider<br/>Context
participant Sheet as DebugSheet
Screen->>Context: Register debug section/<br/>action/log via hook
Note over Context: Store in state<br/>(sections, actions, logs)
User->>FAB: Press settings button
FAB->>Sheet: Navigate to debug sheet
Sheet->>Context: Read current state
Note over Context: Return sections,<br/>actions, logs
Sheet->>Sheet: Render tabs & data
Sheet->>User: Display registered state
Note over Sheet: Data sections, Actions,<br/>Timestamped logs
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Suggested labels
Suggested reviewers
Poem
🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Review rate limit: 0/1 reviews remaining, refill in 60 minutes.Comment |
There was a problem hiding this comment.
Actionable comments posted: 3
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (1)
app/(protected)/videocall/index.tsx (1)
404-415:⚠️ Potential issue | 🟠 MajorRemove duplicate video producer creation at lines 412–415.
The
sendTransport.produce({ track: videoTrack })block is executed twice in succession, creating redundant producers and overwritingvideoProducerRef.current. The second occurrence should be removed.Suggested fix
const audioTrack = localStream.getAudioTracks()[0]; const videoTrack = localStream.getVideoTracks()[0]; if (audioTrack) await sendTransport.produce({ track: audioTrack }); if (videoTrack) { const producer = await sendTransport.produce({ track: videoTrack }); videoProducerRef.current = producer; } log("[WebRTC] ✅ producing audio + video"); - if (videoTrack) { - const producer = await sendTransport.produce({ track: videoTrack }); - videoProducerRef.current = producer; - }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@app/`(protected)/videocall/index.tsx around lines 404 - 415, The code creates the video producer twice by calling sendTransport.produce({ track: videoTrack }) two times and overwrites videoProducerRef.current; remove the second duplicate block so you only call sendTransport.produce once when videoTrack exists, assign its returned producer to videoProducerRef.current, and keep the existing audio production logic (localStream.getAudioTracks()[0] -> sendTransport.produce) intact; update the section around the videoTrack handling in the function that references localStream, sendTransport.produce, and videoProducerRef.current.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@app/`(protected)/_layout.tsx:
- Around line 39-49: The debugSheet Stack.Screen is being registered
unconditionally; wrap the Stack.Screen with a development-only check (e.g.,
__DEV__ or process.env.NODE_ENV === 'development') so that the screen with name
"debugSheet" and the options (presentation, sheetGrabberVisible,
sheetAllowedDetents, etc.) is only added to the navigator in development builds;
update the _layout component where Stack.Screen is declared to conditionally
render the debugSheet entry so production navigation cannot reach the blank
sheet.
In `@app/`(protected)/videocall/(pages)/ConnectingScreen.tsx:
- Around line 103-105: The idle debug Text is rendered for all users; wrap the
JSX that checks matchState === "idle" so it only renders in development builds
(e.g., add a guard using the React Native __DEV__ flag or a NODE_ENV check).
Update the conditional around the Text in ConnectingScreen.tsx (the matchState
=== "idle" block that renders s.hint) to require both matchState === "idle" &&
__DEV__ (or process.env.NODE_ENV === "development") so the debug hint is shown
only in dev builds.
In `@app/`(protected)/videocall/index.tsx:
- Around line 40-48: The debug logger currently calls setDebugTick on every log
which forces rerenders in production; change the implementation so logging still
calls _rawLog but avoid state updates unless debugging is enabled—use a ref
(e.g., useRef for debugTick) or gate setDebugTick behind a debug flag (e.g.,
process.env.NODE_ENV !== 'production' or a dedicated isDebug flag) so the log
callback (log) only updates React state when debugging is active and otherwise
only calls _rawLog.
---
Outside diff comments:
In `@app/`(protected)/videocall/index.tsx:
- Around line 404-415: The code creates the video producer twice by calling
sendTransport.produce({ track: videoTrack }) two times and overwrites
videoProducerRef.current; remove the second duplicate block so you only call
sendTransport.produce once when videoTrack exists, assign its returned producer
to videoProducerRef.current, and keep the existing audio production logic
(localStream.getAudioTracks()[0] -> sendTransport.produce) intact; update the
section around the videoTrack handling in the function that references
localStream, sendTransport.produce, and videoProducerRef.current.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: dd811b27-6a03-460f-b8ac-4e9e24a03593
📒 Files selected for processing (7)
app/(protected)/(tabs)/index.tsxapp/(protected)/_layout.tsxapp/(protected)/debugSheet.tsxapp/(protected)/videocall/(pages)/ConnectingScreen.tsxapp/(protected)/videocall/index.tsxcomponents/debug/DebugContext.tsxcomponents/debug/DebugFAB.tsx
| <Stack.Screen | ||
| name="debugSheet" | ||
| options={{ | ||
| headerShown: false, | ||
| presentation: "formSheet", | ||
| gestureEnabled: true, | ||
| sheetGrabberVisible: true, | ||
| sheetAllowedDetents: [0.6, 1], | ||
| sheetInitialDetentIndex: 0, | ||
| }} | ||
| /> |
There was a problem hiding this comment.
Register debugSheet screen only in development.
Right now the route exists in production navigation too, which can open a blank sheet when hit directly.
Suggested fix
- <Stack.Screen
- name="debugSheet"
- options={{
- headerShown: false,
- presentation: "formSheet",
- gestureEnabled: true,
- sheetGrabberVisible: true,
- sheetAllowedDetents: [0.6, 1],
- sheetInitialDetentIndex: 0,
- }}
- />
+ {__DEV__ && (
+ <Stack.Screen
+ name="debugSheet"
+ options={{
+ headerShown: false,
+ presentation: "formSheet",
+ gestureEnabled: true,
+ sheetGrabberVisible: true,
+ sheetAllowedDetents: [0.6, 1],
+ sheetInitialDetentIndex: 0,
+ }}
+ />
+ )}📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| <Stack.Screen | |
| name="debugSheet" | |
| options={{ | |
| headerShown: false, | |
| presentation: "formSheet", | |
| gestureEnabled: true, | |
| sheetGrabberVisible: true, | |
| sheetAllowedDetents: [0.6, 1], | |
| sheetInitialDetentIndex: 0, | |
| }} | |
| /> | |
| {__DEV__ && ( | |
| <Stack.Screen | |
| name="debugSheet" | |
| options={{ | |
| headerShown: false, | |
| presentation: "formSheet", | |
| gestureEnabled: true, | |
| sheetGrabberVisible: true, | |
| sheetAllowedDetents: [0.6, 1], | |
| sheetInitialDetentIndex: 0, | |
| }} | |
| /> | |
| )} |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/`(protected)/_layout.tsx around lines 39 - 49, The debugSheet
Stack.Screen is being registered unconditionally; wrap the Stack.Screen with a
development-only check (e.g., __DEV__ or process.env.NODE_ENV === 'development')
so that the screen with name "debugSheet" and the options (presentation,
sheetGrabberVisible, sheetAllowedDetents, etc.) is only added to the navigator
in development builds; update the _layout component where Stack.Screen is
declared to conditionally render the debugSheet entry so production navigation
cannot reach the blank sheet.
| {matchState === "idle" && ( | ||
| <Text style={s.hint}>[DEV] Your state is idle</Text> | ||
| )} |
There was a problem hiding this comment.
Gate the idle debug hint to dev builds only.
This currently renders debug copy to real users whenever state is idle.
Suggested fix
- {matchState === "idle" && (
+ {__DEV__ && matchState === "idle" && (
<Text style={s.hint}>[DEV] Your state is idle</Text>
)}🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/`(protected)/videocall/(pages)/ConnectingScreen.tsx around lines 103 -
105, The idle debug Text is rendered for all users; wrap the JSX that checks
matchState === "idle" so it only renders in development builds (e.g., add a
guard using the React Native __DEV__ flag or a NODE_ENV check). Update the
conditional around the Text in ConnectingScreen.tsx (the matchState === "idle"
block that renders s.hint) to require both matchState === "idle" && __DEV__ (or
process.env.NODE_ENV === "development") so the debug hint is shown only in dev
builds.
| const [debugTick, setDebugTick] = useState(0); | ||
| const _rawLog = useDebugLog("VideoCall"); | ||
| const log = useCallback( | ||
| (msg: string) => { | ||
| _rawLog(msg); | ||
| setDebugTick((t) => t + 1); | ||
| }, | ||
| [_rawLog], | ||
| ); |
There was a problem hiding this comment.
Avoid production rerenders from the debug logger.
Line 45 updates state on every log() call even in production, which adds unnecessary rerender churn on a hot path.
Suggested fix
const log = useCallback(
(msg: string) => {
+ if (!__DEV__) return;
_rawLog(msg);
setDebugTick((t) => t + 1);
},
[_rawLog],
);📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| const [debugTick, setDebugTick] = useState(0); | |
| const _rawLog = useDebugLog("VideoCall"); | |
| const log = useCallback( | |
| (msg: string) => { | |
| _rawLog(msg); | |
| setDebugTick((t) => t + 1); | |
| }, | |
| [_rawLog], | |
| ); | |
| const [debugTick, setDebugTick] = useState(0); | |
| const _rawLog = useDebugLog("VideoCall"); | |
| const log = useCallback( | |
| (msg: string) => { | |
| if (!__DEV__) return; | |
| _rawLog(msg); | |
| setDebugTick((t) => t + 1); | |
| }, | |
| [_rawLog], | |
| ); |
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@app/`(protected)/videocall/index.tsx around lines 40 - 48, The debug logger
currently calls setDebugTick on every log which forces rerenders in production;
change the implementation so logging still calls _rawLog but avoid state updates
unless debugging is enabled—use a ref (e.g., useRef for debugTick) or gate
setDebugTick behind a debug flag (e.g., process.env.NODE_ENV !== 'production' or
a dedicated isDebug flag) so the log callback (log) only updates React state
when debugging is active and otherwise only calls _rawLog.
…integrate debugging context for enhanced development insights
Summary by CodeRabbit