Skip to content

fix: persist context bar settings across restarts#67

Merged
gnoviawan merged 1 commit intodevfrom
fix/context-bar-settings-persistence
Mar 9, 2026
Merged

fix: persist context bar settings across restarts#67
gnoviawan merged 1 commit intodevfrom
fix/context-bar-settings-persistence

Conversation

@gnoviawan
Copy link
Owner

@gnoviawan gnoviawan commented Mar 9, 2026

Summary

  • flush pending debounced persistence writes before app close so context bar settings are not lost on shutdown
  • move context bar setting updates into a dedicated hook and expose flushPendingWrites on the shared persistence API contract
  • add regression coverage for debounce flushing, startup loading, popover updates, and close-flow persistence behavior

Test plan

  • npm --prefix \"E:/open-source/PecutAPP/termul-fix-context-bar-settings-persistence\" test -- src/renderer/lib/__tests__/tauri-persistence-api.test.ts src/renderer/hooks/use-context-bar-settings.test.ts src/renderer/lib/__tests__/api-bridge.test.ts src/renderer/components/ContextBarSettingsPopover.test.tsx src/renderer/TauriApp.test.tsx src/renderer/layouts/WorkspaceLayout.close-persistence.test.tsx src/renderer/App.test.tsx
  • npm --prefix \"E:/open-source/PecutAPP/termul-fix-context-bar-settings-persistence\" run typecheck

🤖 Generated with Claude Code

Summary by CodeRabbit

Release Notes

  • New Features

    • Improved context bar settings persistence with debounced write system for better performance
    • Added pending write flushing mechanism to ensure data is saved before app closes
  • Bug Fixes

    • Fixed potential data loss by ensuring all pending persistence operations complete before closing the application
  • Tests

    • Added comprehensive test coverage for context bar settings management and app close persistence behavior

Flush pending debounced persistence writes before app close and route context bar setting updates through a dedicated hook so the latest settings survive shutdown.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@coderabbitai
Copy link

coderabbitai bot commented Mar 9, 2026

📝 Walkthrough

Walkthrough

This PR implements context bar settings persistence with debounced writes. It adds a new hook to manage setting updates, introduces a debounced write system in the persistence API with a flush mechanism, updates the context bar popover component to use the hook, integrates flush-before-close logic into the app close flow, and provides comprehensive test coverage across all new functionality.

Changes

Cohort / File(s) Summary
Context Bar Settings Hooks
src/renderer/hooks/use-context-bar-settings.ts, src/renderer/hooks/use-context-bar-settings.test.ts
Added useUpdateContextBarSetting() hook to toggle and persist individual settings via debounced writes; hook test verifies restore/fallback/merge/persist behaviors and single-setting update flows.
Context Bar UI Component
src/renderer/components/ContextBarSettingsPopover.tsx, src/renderer/components/ContextBarSettingsPopover.test.tsx
Refactored popover to call useUpdateContextBarSetting() instead of managing local persistence logic; test validates trigger rendering, popover opening, and four toggle switches each invoke updater once with correct keys.
App Initialization & Persistence
src/renderer/App.test.tsx, src/renderer/TauriApp.test.tsx
Added tests verifying App and TauriApp load context bar settings on mount via useContextBarSettings hook and persistence API read with CONTEXT_BAR_SETTINGS_KEY.
Persistence API Core
src/renderer/lib/tauri-persistence-api.ts, src/renderer/lib/tauri-persistence-api.test.ts, src/renderer/lib/__tests__/api-bridge.test.ts, src/shared/types/ipc.types.ts
Introduced debounced write batching system with per-key coalescing, resolvers, and flush logic; added flushPendingWrites() method to persistenceApi interface and implementation; tests verify coalescing, promise resolution, and flush ordering.
App Close Behavior
src/renderer/layouts/WorkspaceLayout.tsx, src/renderer/layouts/WorkspaceLayout.close-persistence.test.tsx
Integrated closeAppWithPersistenceFlush() callback into close flow to flush pending writes before signaling window close; test verifies flush is called with/without dirty files and handles flush failures gracefully.

Sequence Diagrams

sequenceDiagram
    participant App as App/TauriApp
    participant Hook as useContextBarSettings
    participant PersistenceAPI as Persistence API
    participant Store as Settings Store
    
    App->>Hook: Mount component
    Hook->>PersistenceAPI: read(CONTEXT_BAR_SETTINGS_KEY)
    PersistenceAPI-->>Hook: Return persisted settings or defaults
    Hook->>Store: Update store with loaded settings
    Hook->>App: Mark isLoaded=true
    Note over App,Store: Settings ready for UI
Loading
sequenceDiagram
    participant User as User
    participant UI as ContextBarSettingsPopover
    participant Hook as useUpdateContextBarSetting
    participant PersistenceAPI as Persistence API (Debounced)
    participant Store as Settings Store
    
    User->>UI: Toggle switch
    UI->>Hook: Call updater(settingKey)
    Hook->>Store: Toggle setting value
    Hook->>PersistenceAPI: writeDebounced(KEY, settings)
    Note over PersistenceAPI: Schedule debounce timer (if first call for KEY)
    PersistenceAPI-->>Hook: Return promise
    Hook-->>UI: Promise resolves
    Note over PersistenceAPI: On debounce timer: flush writes, resolve all pending promises
Loading
sequenceDiagram
    participant Window as Window Close Event
    participant WorkspaceLayout as WorkspaceLayout
    participant PersistenceAPI as Persistence API
    participant WindowAPI as Window API
    
    Window->>WorkspaceLayout: Close requested
    WorkspaceLayout->>WorkspaceLayout: Check dirty files
    alt No dirty files
        WorkspaceLayout->>PersistenceAPI: flushPendingWrites()
        PersistenceAPI-->>WorkspaceLayout: Flush completes (or fails)
    else Has dirty files
        WorkspaceLayout->>WorkspaceLayout: Prompt user (save/discard)
        Note over WorkspaceLayout: After user chooses...
        WorkspaceLayout->>PersistenceAPI: flushPendingWrites()
        PersistenceAPI-->>WorkspaceLayout: Flush completes (or fails)
    end
    WorkspaceLayout->>WindowAPI: respondToClose('close')
    Note over Window,WindowAPI: App closes
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related issues

Possibly related PRs

Poem

🐰 A rabbit hops through debounced writes so bright,
Flushing writes before the close, all done just right!
Settings batched and coalesced with care,
Promise resolvers waiting in the air!
The context bar remembers, fresh and free,
Persistence magic—hooray for thee! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 23.08% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'fix: persist context bar settings across restarts' directly and clearly describes the main objective of the PR—ensuring context bar settings persist across application restarts.

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

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch fix/context-bar-settings-persistence

Tip

Try Coding Plans. Let us write the prompt for your AI agent so you can ship faster (with fewer bugs).
Share your feedback on Discord.


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.

@gnoviawan gnoviawan marked this pull request as ready for review March 9, 2026 07:53
@gnoviawan gnoviawan added phase-1 Phase 1: Stability & Polish (v0.3.1) v0.3.1 labels Mar 9, 2026
Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

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

🧹 Nitpick comments (1)
src/renderer/TauriApp.test.tsx (1)

10-14: Partial mock may cause issues if other persistenceApi methods are called.

The mock only provides read, but if TauriApp or any of its non-mocked children call other persistenceApi methods (like writeDebounced or flushPendingWrites), the test will fail with "undefined is not a function" errors.

Consider extending the mock to include other commonly used methods, or verify that all code paths calling other methods are properly mocked out:

💡 Suggested mock expansion
 vi.mock('@/lib/api', () => ({
   persistenceApi: {
-    read: mockPersistenceRead
+    read: mockPersistenceRead,
+    writeDebounced: vi.fn(() => Promise.resolve({ success: true, data: undefined })),
+    flushPendingWrites: vi.fn(() => Promise.resolve({ success: true, data: undefined }))
   }
 }))
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/TauriApp.test.tsx` around lines 10 - 14, The test mock for
persistenceApi only defines read, which can cause failures if TauriApp or its
children call other methods; update the vi.mock in TauriApp.test.tsx to provide
stub implementations (e.g., vi.fn()) for other commonly used persistenceApi
methods such as writeDebounced, flushPendingWrites, write, readAll/getAll (and
any other methods used by components), or switch to a full module mock that
delegates to the real module while overriding read; reference the mocked object
name persistenceApi and the test file's vi.mock block when making the change.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/renderer/TauriApp.test.tsx`:
- Around line 10-14: The test mock for persistenceApi only defines read, which
can cause failures if TauriApp or its children call other methods; update the
vi.mock in TauriApp.test.tsx to provide stub implementations (e.g., vi.fn()) for
other commonly used persistenceApi methods such as writeDebounced,
flushPendingWrites, write, readAll/getAll (and any other methods used by
components), or switch to a full module mock that delegates to the real module
while overriding read; reference the mocked object name persistenceApi and the
test file's vi.mock block when making the change.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 40818b09-0f06-4f3b-9bb9-37b650abfb79

📥 Commits

Reviewing files that changed from the base of the PR and between 5f0bc22 and 770042e.

📒 Files selected for processing (12)
  • src/renderer/App.test.tsx
  • src/renderer/TauriApp.test.tsx
  • src/renderer/components/ContextBarSettingsPopover.test.tsx
  • src/renderer/components/ContextBarSettingsPopover.tsx
  • src/renderer/hooks/use-context-bar-settings.test.ts
  • src/renderer/hooks/use-context-bar-settings.ts
  • src/renderer/layouts/WorkspaceLayout.close-persistence.test.tsx
  • src/renderer/layouts/WorkspaceLayout.tsx
  • src/renderer/lib/__tests__/api-bridge.test.ts
  • src/renderer/lib/__tests__/tauri-persistence-api.test.ts
  • src/renderer/lib/tauri-persistence-api.ts
  • src/shared/types/ipc.types.ts

@gnoviawan gnoviawan merged commit e527ed7 into dev Mar 9, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

phase-1 Phase 1: Stability & Polish (v0.3.1) v0.3.1

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant