feat: implemented initial version of hiding feature#744
Open
akramj13 wants to merge 2 commits into
Open
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new persisted preference that lets users hide Cotabby’s menu bar status item while keeping the app running, with a reopen “recovery” path that surfaces Settings when the user relaunches Cotabby without the icon visible.
Changes:
- Introduces
isMenuBarIconVisibleacross settings data/model/store and persists it toUserDefaults. - Conditionally inserts/removes the
MenuBarExtrascene via a scene-level@AppStorageprojection. - Implements reopen handling to open Settings when the app is reopened while the menu bar icon is hidden, plus updates/expands test coverage.
Reviewed changes
Copilot reviewed 9 out of 9 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| Cotabby/App/Core/CotabbyApp.swift | Makes the menu bar scene optional via MenuBarExtra(isInserted:) driven by @AppStorage. |
| Cotabby/App/Core/AppDelegate.swift | Adds applicationShouldHandleReopen recovery behavior when the icon is hidden. |
| Cotabby/Models/SuggestionSettingsData.swift | Extends the durable settings payload with isMenuBarIconVisible. |
| Cotabby/Models/SuggestionSettingsModel.swift | Adds published state + setter that persists isMenuBarIconVisible. |
| Cotabby/Support/SuggestionSettingsStore.swift | Adds the new defaults key, load defaulting behavior, and save plumbing. |
| Cotabby/UI/Settings/Panes/AppearancePaneView.swift | Adds the Settings toggle and binding for menu bar icon visibility. |
| Cotabby/UI/Settings/SettingsIndex.swift | Adds a new searchable SettingsItem entry for the toggle. |
| CotabbyTests/SuggestionSettingsModelTests.swift | Extends model round-trip tests to include the new preference. |
| CotabbyTests/SuggestionSettingsStoreTests.swift | Adds default + round-trip persistence tests for the new preference. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Comment on lines
+55
to
+62
| private var menuBarIconVisibilityBinding: Binding<Bool> { | ||
| Binding( | ||
| get: { isMenuBarIconVisible }, | ||
| set: { visible in | ||
| isMenuBarIconVisible = visible | ||
| appDelegate.suggestionSettings.setMenuBarIconVisible(visible) | ||
| } | ||
| ) |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request adds a new user preference to allow hiding Cotabby's menu bar icon while keeping the app running in the background. It introduces a toggle in Settings for controlling the visibility of the menu bar status item, ensures the app remains accessible by showing Settings when relaunched with the icon hidden, and persists this preference across launches. The implementation spans UI, model, persistence, and test updates.
Menu Bar Icon Visibility Preference:
isMenuBarIconVisibleproperty toSuggestionSettingsDataandSuggestionSettingsModel, with corresponding getter, setter, and persistence logic inSuggestionSettingsStore.CotabbyAppto conditionally insert theMenuBarExtrascene based on the new preference, using a SwiftUI binding that syncs with the settings model and persists changes.SettingsItemto support the new toggle, including title, icon, description, search terms, and categorization under the Appearance section.App Behavior and Recovery:
applicationShouldHandleReopeninAppDelegateto show Settings if the app is reopened while the menu bar icon is hidden, ensuring users can always access the app's UI.Testing and Persistence:
Solves #742
Greptile Summary
This PR adds a user preference to hide Cotabby's menu bar status item while keeping the suggestion pipeline running, with a recovery path via
applicationShouldHandleReopenthat opens Settings when the user relaunches the app with the icon hidden.isMenuBarIconVisibleis added toSuggestionSettingsData,SuggestionSettingsModel, andSuggestionSettingsStoreusing the same pattern as existing boolean preferences, with a default oftrueso existing users are unaffected.CotabbyAppuses@AppStorageon the same UserDefaults key the store writes, soMenuBarExtra(isInserted:)reacts immediately when the settings model persists the change — no bespoke notification plumbing required.AppDelegate.applicationShouldHandleReopencorrectly checksisMenuBarIconVisiblebefore opening Settings, and guards onflagto avoid acting when Settings is already on-screen;SettingsItemandAppearancePaneVieware updated with search terms, icon, and description.Confidence Score: 5/5
Safe to merge — the change is well-scoped, defaults preserve existing user state, and the recovery path is correctly gated.
The feature is implemented consistently with existing boolean preferences across all layers (data, model, store, UI, tests). The @AppStorage/UserDefaults synchronization is sound, the applicationShouldHandleReopen logic correctly handles both the hidden-icon recovery case and the already-open-window guard, and no existing behavior is changed for users who never touch the new toggle.
No files require special attention.
Important Files Changed
Sequence Diagram
%%{init: {'theme': 'neutral'}}%% sequenceDiagram participant User participant AppearancePaneView participant SuggestionSettingsModel participant SuggestionSettingsStore participant UserDefaults participant AppStorage as CotabbyApp @AppStorage participant MenuBarExtra User->>AppearancePaneView: Toggle "Show Cotabby in Menu Bar" → false AppearancePaneView->>SuggestionSettingsModel: setMenuBarIconVisible(false) SuggestionSettingsModel->>SuggestionSettingsStore: saveMenuBarIconVisible(false) SuggestionSettingsStore->>UserDefaults: set(false, key: menuBarIconVisible) UserDefaults-->>AppStorage: "KVO notification → isMenuBarIconVisible = false" AppStorage->>MenuBarExtra: isInserted binding getter returns false MenuBarExtra-->>User: Status item removed from menu bar Note over User, MenuBarExtra: Recovery path when icon is hidden User->>User: Relaunches Cotabby from Finder/Spotlight User->>AppDelegate: applicationShouldHandleReopen(_:hasVisibleWindows:) AppDelegate->>SuggestionSettingsModel: "check isMenuBarIconVisible == false" alt "No visible windows (flag = false)" AppDelegate->>AppDelegate: settingsCoordinator.showSettings() AppDelegate-->>User: Settings window appears else "Settings already visible (flag = true)" AppDelegate-->>User: return false (no duplicate window) end%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%% sequenceDiagram participant User participant AppearancePaneView participant SuggestionSettingsModel participant SuggestionSettingsStore participant UserDefaults participant AppStorage as CotabbyApp @AppStorage participant MenuBarExtra User->>AppearancePaneView: Toggle "Show Cotabby in Menu Bar" → false AppearancePaneView->>SuggestionSettingsModel: setMenuBarIconVisible(false) SuggestionSettingsModel->>SuggestionSettingsStore: saveMenuBarIconVisible(false) SuggestionSettingsStore->>UserDefaults: set(false, key: menuBarIconVisible) UserDefaults-->>AppStorage: "KVO notification → isMenuBarIconVisible = false" AppStorage->>MenuBarExtra: isInserted binding getter returns false MenuBarExtra-->>User: Status item removed from menu bar Note over User, MenuBarExtra: Recovery path when icon is hidden User->>User: Relaunches Cotabby from Finder/Spotlight User->>AppDelegate: applicationShouldHandleReopen(_:hasVisibleWindows:) AppDelegate->>SuggestionSettingsModel: "check isMenuBarIconVisible == false" alt "No visible windows (flag = false)" AppDelegate->>AppDelegate: settingsCoordinator.showSettings() AppDelegate-->>User: Settings window appears else "Settings already visible (flag = true)" AppDelegate-->>User: return false (no duplicate window) endComments Outside Diff (1)
Cotabby/UI/Settings/Panes/AppearancePaneView.swift, line 50-57 (link)When
isMenuBarIconVisibleisfalsethe word-count badge has nowhere to render, yet the toggle stays enabled and its value is preserved. A user who hides the icon, notices the toggle is still "on," and tries to turn it off will have no visible effect — which reads as broken. Disabling the toggle (.disabled(!suggestionSettings.isMenuBarIconVisible)) when the icon is hidden would make the dependency explicit and avoid the confusion.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!
Reviews (2): Last reviewed commit: "fix: avoid reopening visible settings wi..." | Re-trigger Greptile