Skip to content

fix(network): footer Local toggle was dead in Tauri (window.confirm no-op) - #169

Merged
debpalash merged 1 commit into
mainfrom
fix/footer-local-toggle
May 30, 2026
Merged

fix(network): footer Local toggle was dead in Tauri (window.confirm no-op)#169
debpalash merged 1 commit into
mainfrom
fix/footer-local-toggle

Conversation

@debpalash

@debpalash debpalash commented May 30, 2026

Copy link
Copy Markdown
Owner

The footer Local pill did nothing because enable() gated on window.confirm(...), which is a no-op in the Tauri webview (returns false) — so it bailed before calling the (working) enable endpoint. Replaced with a reliable in-app confirm popover (Cancel / Enable).

The backend was never the problem — verified on a live instance that POST /system/network/enable opens a real TCP listener on the configured share port (5050) with real LAN/Tailscale addresses + PIN. This was purely the frontend confirm. Adds a regression test for Local → confirm → Enable → POST.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Added an in-app confirmation panel when enabling network sharing with dedicated Enable and Cancel action buttons.
  • Bug Fixes

    • Improved network sharing toggle compatibility in environments where browser confirmation dialogs are unavailable by replacing them with an in-app UI.

Review Change Stack

The footer Local/Network pill called window.confirm() before enabling, but
window.confirm is a no-op in the Tauri webview (returns false), so the enable
action was silently swallowed — the button appeared to do nothing. Replace it
with a reliable in-app confirm popover (Cancel/Enable). The backend endpoint
was always working (verified: enable opens a real listener on the share port).
Adds a regression test for the Local -> confirm -> Enable -> POST flow.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor
📝 Walkthrough

Walkthrough

NetworkToggle component replaces browser window.confirm with an in-app confirmation panel for enabling network sharing. Changes introduce a confirmation state variable, update the enable function flow, add confirmation UI styling and button interactions, and validate the flow with an end-to-end test.

Changes

In-app confirmation for network sharing enable

Layer / File(s) Summary
Confirmation state and styling
frontend/src/components/NetworkToggle.jsx, frontend/src/components/NetworkToggle.css
confirming state variable tracks whether the enable confirmation panel is displayed. New CSS classes style the confirmation action container (.net-toggle__confirm-actions) and two buttons: .net-toggle__enable (accent-green with hover styling) and .net-toggle__cancel (transparent with border).
Enable flow refactoring
frontend/src/components/NetworkToggle.jsx
enable() function removes window.confirm dependency; now assumes confirmation has occurred, sets busy state, calls /system/network/enable API, transitions to details panel, and handles errors via toast notification with final busy state reset.
Toggle button interaction and confirmation UI
frontend/src/components/NetworkToggle.jsx
Main button click handler now toggles the confirmation panel when sharing is disabled or opens the details panel when already enabled. Confirmation panel markup is added with Cancel and Enable action buttons that reference the enable state.
Confirmation flow testing
frontend/src/components/NetworkToggle.test.jsx
fireEvent is imported alongside existing testing-library utilities. New end-to-end test simulates Local state → click Local button to open in-app confirmation → click Enable, stubs global.fetch to return success, and asserts POST request is made to /system/network/enable.

🎯 2 (Simple) | ⏱️ ~12 minutes

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description provides a clear explanation of the problem and solution, but the provided description does not follow the template structure with required sections like Summary, Changes, Type, Testing, and Checklist. Reorganize the description to match the template: add a Summary section, list key Changes, select a Type checkbox, document Testing approach, and complete the Checklist with relevant items.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and specifically summarizes the main change: fixing the non-functional Local toggle in Tauri by replacing window.confirm (which is a no-op) with an in-app confirmation UI.
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 fix/footer-local-toggle

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


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.

@greptile-apps

greptile-apps Bot commented May 30, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

Fixes the broken "Local" footer pill in the Tauri desktop app by replacing the window.confirm() call (which is a no-op in Tauri's webview and always returned false) with an in-app confirm popover backed by a new confirming React state. A regression test verifies the full Local → confirm → Enable → POST flow without any dependency on window.confirm.

  • NetworkToggle.jsx: adds confirming state, renders a cancel/enable popover when !st.enabled && confirming, and calls enable() only after the user explicitly clicks the Enable button inside the popover.
  • NetworkToggle.css: adds button styles for the two new confirm actions, consistent with the existing design tokens.
  • NetworkToggle.test.jsx: adds a focused regression test with proper global.fetch save/restore; test correctly asserts the POST reaches the enable endpoint.

Confidence Score: 4/5

Safe to merge — the fix is minimal and targeted, the backend is unaffected, and the regression test correctly validates the full user flow.

The logic change is small and correct: state transitions are sound, error and busy handling work as expected, and the test suite exercises the exact path that was broken. The one open item is that the confirm popover has no Escape key handler or focus-on-open behaviour, which matters for keyboard and screen-reader users but does not affect functional correctness.

NetworkToggle.jsx — the confirm panel could benefit from focus management (autoFocus on Cancel, Escape dismiss) before this UI pattern is reused elsewhere.

Important Files Changed

Filename Overview
frontend/src/components/NetworkToggle.jsx Replaces window.confirm() with an in-app confirm popover using a new confirming state; logic is correct, error/busy handling is sound, no regressions introduced.
frontend/src/components/NetworkToggle.css Adds button styles for the new confirm popover actions; clean and self-contained, consistent with existing design tokens.
frontend/src/components/NetworkToggle.test.jsx Adds regression test covering Local → confirm popover → Enable → POST flow; beforeEach/afterEach correctly saves and restores global.fetch, fetch mock is complete and correctly asserts on the POST endpoint.

Sequence Diagram

sequenceDiagram
    participant User
    participant Pill as Local Pill Button
    participant Panel as Confirm Popover
    participant API as Backend API

    User->>Pill: click (network disabled)
    Pill->>Panel: setConfirming(true)
    Panel-->>User: Show "Share on your network?" panel

    alt User clicks Cancel
        User->>Panel: click Cancel
        Panel->>Pill: setConfirming(false)
    else User clicks Enable
        User->>Panel: click Enable
        Panel->>API: POST /system/network/enable
        API-->>Panel: "{ enabled: true, pin, share_port, lan_addresses }"
        Panel->>Pill: setSt(...), setConfirming(false), setOpen(true)
        Pill-->>User: Pill shows "Network" (on state)
        Panel-->>User: Show network details panel (QR, PIN, addresses)
    else API call fails
        API-->>Panel: error
        Panel-->>User: toast.error("Could not enable sharing")
        Note over Panel: confirming stays true — user can retry or cancel
    end
Loading

Fix All in Claude Code

Reviews (1): Last reviewed commit: "fix(network): footer Local toggle dead i..." | Re-trigger Greptile

Comment on lines +64 to +76
{!st.enabled && confirming && (
<div className="net-toggle__panel net-toggle__panel--confirm">
<div className="net-toggle__panel-title">Share on your network?</div>
<p className="net-toggle__hint">
Other devices on your Wi-Fi/Ethernet will be able to reach OmniVoice
using the access PIN shown once it's on.
</p>
<div className="net-toggle__confirm-actions">
<button type="button" className="net-toggle__cancel" onClick={() => setConfirming(false)} disabled={busy}>Cancel</button>
<button type="button" className="net-toggle__enable" onClick={enable} disabled={busy}>{busy ? 'Enabling…' : 'Enable'}</button>
</div>
</div>
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Confirm panel lacks focus management and Escape dismiss

When the confirm panel mounts, focus stays on the pill button. Keyboard users must tab through to reach Cancel/Enable, and there is no Escape handler to close the panel. A screen reader also has no role="dialog" or aria-labelledby to announce the prompt. While the pill-click toggle and Cancel button do dismiss it, adding autoFocus to the Cancel button and a keydown listener for Escape would bring this in line with accessibility expectations for a confirmation flow.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Fix in Claude Code

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@frontend/src/components/NetworkToggle.jsx`:
- Around line 64-76: The confirmation panel in NetworkToggle.jsx currently
contains hardcoded strings; replace them with i18n keys by calling the
translation function (t) for the title, description, and button labels used in
the JSX: replace "Share on your network?" and the long description with
t('networkToggle.confirm.title') and t('networkToggle.confirm.description'), and
replace "Cancel", "Enable", and "Enabling…" with
t('networkToggle.confirm.cancel'), t('networkToggle.confirm.enable') and
t('networkToggle.confirm.enabling') respectively; ensure the component
imports/receives the t function (or use the existing i18n hook) and add the
corresponding keys to the locale files so the confirming panel (rendered when
!st.enabled && confirming) uses translated strings while preserving the existing
handlers setConfirming, enable, and the busy state.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: a48bb277-a2ab-4640-ac2d-ce3fb6f2cbe0

📥 Commits

Reviewing files that changed from the base of the PR and between e3d7815 and 7e40e8b.

📒 Files selected for processing (3)
  • frontend/src/components/NetworkToggle.css
  • frontend/src/components/NetworkToggle.jsx
  • frontend/src/components/NetworkToggle.test.jsx

Comment on lines +64 to +76
{!st.enabled && confirming && (
<div className="net-toggle__panel net-toggle__panel--confirm">
<div className="net-toggle__panel-title">Share on your network?</div>
<p className="net-toggle__hint">
Other devices on your Wi-Fi/Ethernet will be able to reach OmniVoice
using the access PIN shown once it's on.
</p>
<div className="net-toggle__confirm-actions">
<button type="button" className="net-toggle__cancel" onClick={() => setConfirming(false)} disabled={busy}>Cancel</button>
<button type="button" className="net-toggle__enable" onClick={enable} disabled={busy}>{busy ? 'Enabling…' : 'Enable'}</button>
</div>
</div>
)}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Hardcoded UI text violates i18n guideline.

The confirmation panel contains hardcoded English strings ("Share on your network?", "Other devices on your Wi-Fi/Ethernet will be able to reach OmniVoice using the access PIN shown once it's on.", "Cancel", "Enable", "Enabling…") that must go through the i18n translation layer using t('...') keys. As per coding guidelines, all user-facing text in frontend/src/**/*.{vue,ts,tsx,js,jsx} must use the i18n translation layer, never hardcode text.

🌐 Example refactor to use i18n

First, add translation keys to your locale files (e.g., locales/en.json):

{
  "networkToggle.confirm.title": "Share on your network?",
  "networkToggle.confirm.description": "Other devices on your Wi-Fi/Ethernet will be able to reach OmniVoice using the access PIN shown once it's on.",
  "networkToggle.confirm.cancel": "Cancel",
  "networkToggle.confirm.enable": "Enable",
  "networkToggle.confirm.enabling": "Enabling…"
}

Then update the component to use t():

+import { useTranslation } from 'react-i18next';  // or your i18n library

 export default function NetworkToggle() {
+  const { t } = useTranslation();
   const [st, setSt] = useState({ enabled: false });
   // ...
   
   {!st.enabled && confirming && (
     <div className="net-toggle__panel net-toggle__panel--confirm">
-      <div className="net-toggle__panel-title">Share on your network?</div>
+      <div className="net-toggle__panel-title">{t('networkToggle.confirm.title')}</div>
       <p className="net-toggle__hint">
-        Other devices on your Wi-Fi/Ethernet will be able to reach OmniVoice
-        using the access PIN shown once it's on.
+        {t('networkToggle.confirm.description')}
       </p>
       <div className="net-toggle__confirm-actions">
-        <button type="button" className="net-toggle__cancel" onClick={() => setConfirming(false)} disabled={busy}>Cancel</button>
+        <button type="button" className="net-toggle__cancel" onClick={() => setConfirming(false)} disabled={busy}>{t('networkToggle.confirm.cancel')}</button>
-        <button type="button" className="net-toggle__enable" onClick={enable} disabled={busy}>{busy ? 'Enabling…' : 'Enable'}</button>
+        <button type="button" className="net-toggle__enable" onClick={enable} disabled={busy}>{busy ? t('networkToggle.confirm.enabling') : t('networkToggle.confirm.enable')}</button>
       </div>
     </div>
   )}

As per coding guidelines: All user-facing text in the UI must go through the i18n translation layer using t('...') keys in locales/*.json files, never hardcode non-English text.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@frontend/src/components/NetworkToggle.jsx` around lines 64 - 76, The
confirmation panel in NetworkToggle.jsx currently contains hardcoded strings;
replace them with i18n keys by calling the translation function (t) for the
title, description, and button labels used in the JSX: replace "Share on your
network?" and the long description with t('networkToggle.confirm.title') and
t('networkToggle.confirm.description'), and replace "Cancel", "Enable", and
"Enabling…" with t('networkToggle.confirm.cancel'),
t('networkToggle.confirm.enable') and t('networkToggle.confirm.enabling')
respectively; ensure the component imports/receives the t function (or use the
existing i18n hook) and add the corresponding keys to the locale files so the
confirming panel (rendered when !st.enabled && confirming) uses translated
strings while preserving the existing handlers setConfirming, enable, and the
busy state.

@debpalash
debpalash merged commit 3901a3c into main May 30, 2026
15 checks passed
@debpalash
debpalash deleted the fix/footer-local-toggle branch June 12, 2026 10:10
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.

1 participant