Skip to content

Add debug features including DebugFAB and DebugSheet components, and … - #171

Merged
Jamie-Poeffel merged 1 commit into
devfrom
feature/debug
Apr 30, 2026
Merged

Jamie-Poeffel merged 1 commit into
devfrom
feature/debug

Conversation

@Jamie-Poeffel

@Jamie-Poeffel Jamie-Poeffel commented Apr 30, 2026 •

Copy link
Copy Markdown
Collaborator

…integrate debugging context for enhanced development insights

Summary by CodeRabbit

  • New Features
    • Added development-only debug panel accessible via floating action button, enabling real-time monitoring of application state and operations across protected screens
    • Introduced structured event logging system for tracking application lifecycle and state changes
    • Implemented context-based debug registration system for coordinating debug information display

…integrate debugging context for enhanced development insights
@coderabbitai

coderabbitai Bot commented Apr 30, 2026 •

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

A 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

Cohort / File(s) Summary
Debug Infrastructure
components/debug/DebugContext.tsx, components/debug/DebugFAB.tsx
Implements DebugProvider context with stable registration methods for sections, logs, and actions. Exports hooks (useDebugSection, useDebugLog, useDebugActions, useDebugCtx) for screen integration. DebugFAB renders a settings button (dev-only) that navigates to the debug sheet.
Debug UI
app/(protected)/debugSheet.tsx
New debug display component with tabbed interface for viewing registered data sections, actions, and timestamped logs. Includes empty states and log count badge on the logs tab.
Layout & Navigation
app/(protected)/_layout.tsx
Wraps navigator stack with DebugProvider and adds debugSheet route for debug sheet navigation.
Screen Integration
app/(protected)/(tabs)/index.tsx, app/(protected)/videocall/index.tsx, app/(protected)/videocall/(pages)/ConnectingScreen.tsx
Integrates debug hooks to register state sections and actions. Home screen displays plan, call limits, and availability. VideoCall registers matchmaking, call, socket, and ICE states plus debug actions. DebugFAB rendered in relevant screen branches. Connecting screen adds idle-state hint for developers.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • #163: Modifies VideoCall component lifecycle and UI structure while this PR adds debug instrumentation to the same component.
  • #154: Changes home screen (index.tsx) call-gating logic that overlaps with debug section registration in this PR.
  • #166: Refactors same UI components (videocall and home screens) for payments/subscriptions alongside this PR's debug instrumentation.

Suggested labels

enhancement

Suggested reviewers

  • LuisAll12
  • GRuoss

Poem

🐰 A little debug system hops to life,
With hooks and logs to end our strife,
A gear button shines with dev delight,
Showing all our secrets, oh so bright! ⚙️✨

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 6.67% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding debug features with DebugFAB and DebugSheet components, matching the primary objective and file changes in the changeset.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/debug

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
Review rate limit: 0/1 reviews remaining, refill in 60 minutes.

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

@Jamie-Poeffel
Jamie-Poeffel marked this pull request as ready for review April 30, 2026 12:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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 | 🟠 Major

Remove duplicate video producer creation at lines 412–415.

The sendTransport.produce({ track: videoTrack }) block is executed twice in succession, creating redundant producers and overwriting videoProducerRef.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

📥 Commits

Reviewing files that changed from the base of the PR and between c780515 and 7fe440a.

📒 Files selected for processing (7)
  • app/(protected)/(tabs)/index.tsx
  • app/(protected)/_layout.tsx
  • app/(protected)/debugSheet.tsx
  • app/(protected)/videocall/(pages)/ConnectingScreen.tsx
  • app/(protected)/videocall/index.tsx
  • components/debug/DebugContext.tsx
  • components/debug/DebugFAB.tsx

Comment on lines +39 to +49
<Stack.Screen
name="debugSheet"
options={{
headerShown: false,
presentation: "formSheet",
gestureEnabled: true,
sheetGrabberVisible: true,
sheetAllowedDetents: [0.6, 1],
sheetInitialDetentIndex: 0,
}}
/>

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.

Suggested change
<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.

Comment on lines +103 to +105
{matchState === "idle" && (
<Text style={s.hint}>[DEV] Your state is idle</Text>
)}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

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.

Comment on lines +40 to +48
const [debugTick, setDebugTick] = useState(0);
const _rawLog = useDebugLog("VideoCall");
const log = useCallback(
(msg: string) => {
_rawLog(msg);
setDebugTick((t) => t + 1);
},
[_rawLog],
);

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

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.

Suggested change
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.

@GRuoss
GRuoss self-requested a review April 30, 2026 12:46

@GRuoss GRuoss left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GJ

@Jamie-Poeffel
Jamie-Poeffel merged commit cc372d7 into dev Apr 30, 2026
3 checks passed
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