Skip to content

refactor: cleanup & rename after adding the floating panel - #22

Merged
kurama merged 13 commits into
mainfrom
cleanup-refactor
Jul 28, 2026
Merged

refactor: cleanup & rename after adding the floating panel#22
kurama merged 13 commits into
mainfrom
cleanup-refactor

Conversation

@kurama

@kurama kurama commented Jul 28, 2026

Copy link
Copy Markdown
Owner

Follow-up housekeeping now that the panel supports both the notch and floating layouts. Six focused commits, each self-contained.

Changes

  1. Remove unused WaveformView — dead code; only WingWaveformView is used.
  2. Centralize notch dimensions — the width (644) and body height (88) were hard-coded in both the view and the window; moved to PanelPosition (notchWidth / notchBodyHeight).
  3. Fix multi-screen notch heightnotchHeight was captured once at window construction (NSScreen.main) and never updated, so moving the panel to a display with a different notch (or none) left the header mis-sized. It now lives on the view model and is refreshed on every open.
  4. Merge mic/camera wing views — the two near-identical views became one wingView(icon:label:isActive:showWaveform:) helper.
  5. Share focus-duration formatting — the same minutes→label logic lived in both PanelView and SettingsView; extracted to Int.focusDurationLabel.
  6. Rename Notch*Panel*NotchPanelView/Window/ViewModel handle both modes now, so the Notch prefix was misleading. Renamed the types and their files (NotchPanelShape keeps its name — it is genuinely notch-specific).

Validation

All files pass swiftc -typecheck (macOS 14 target). No behavioral change intended beyond fix #3.

kurama added 13 commits July 28, 2026 20:15
WaveformView was defined but never referenced; only WingWaveformView
is used (in the mic indicator).
The notch layout's width (644) and body height (88) were hard-coded in
both NotchPanelView and NotchPanelWindow. Moved them to PanelPosition
alongside floatingWidth so the canonical size lives in one place.
notchHeight was captured once at window construction (from NSScreen.main)
and never updated, so moving the panel to a display with a different notch
(or none) left the header sized for the original screen. It now lives on
the view model and is refreshed in positionAtNotch on every open, so the
notch layout matches whichever display the panel lands on.
micWingView and cameraWingView were near-identical; collapsed them into
a single wingView(icon:label:isActive:showWaveform:) helper. The waveform
stays mic-only via the showWaveform flag.
The same minutes-to-label formatting lived in both NotchPanelView
(defaultFocusLabel) and SettingsView (durationLabel). Extracted it to
Int.focusDurationLabel so both read from one implementation.
…h modes

NotchPanelView/Window/ViewModel handle both the notch and floating layouts,
so the Notch prefix described only one of the two modes and misled readers.
Renamed the types (and their files) to PanelView/PanelWindow/PanelViewModel,
plus the notchPanel properties to panel. NotchPanelShape keeps its name — it
is genuinely specific to the notch outline.
The floating panel had a fixed 280pt width, so when both Disable and
Focus were shown the row overflowed and the non-fixedSize Disable pill
was truncated to "Di...". The panel now sizes to its content (at least
floatingWidth) and the pills keep their intrinsic width, so no button is
ever clipped regardless of which actions are visible.
The 580x340 size was hard-coded in both SettingsView's frame and
SettingsWindowController's setContentSize, which had to stay in sync by
hand. Exposed it as SettingsView.windowSize and referenced it from both.
The quick-pick durations (5/15/30/60) and their labels were spelled out
twice: once as hard-coded buttons in the panel's Focus menu and again as
durationPill calls in settings. Introduced FocusPreset.all as the single
source and drove both with a ForEach, so adding or renaming a preset is a
one-line change.
The accent blue and the near-black window background were each written
out as raw literals in several files (Color and NSColor forms both).
Collected them into Colors.swift as muteBlue/muteBackground on both types,
so the palette lives in one place. No visual change.
onMonitoringChange fired on every observable change (mic, camera, trigger
mode, focus), not just monitoring enable/disable, so the name misled. Renamed
it onStateRefresh. It always fires after onStateChange, so the VM refresh that
onStateChange also did was redundant — removed it, leaving a single refresh
path.
The refreshState() + onStateRefresh?() pair was repeated in setMicActive,
setCameraActive, endFocus and the triggerMode setter. Collapsed it into a
stateDidChange() helper. startFocus and the monitoring toggle keep their own
notify calls since they drive the active state differently.
show() positioned against NSScreen.main, which for an .accessory app with
no key window is unreliable and can resolve to the wrong display. On a
multi-monitor setup that meant the notch panel could anchor to an external
(notch-less) screen, or the floating panel could be clamped to the wrong
one. It now resolves the screen from the status item's frame (the display
the user actually clicked), falling back to NSScreen.main then any screen.
@kurama
kurama merged commit 8b431f0 into main Jul 28, 2026
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.

Sync Slack status when camera is active

1 participant