From 95c82f001456d4118c54e0b88b01eab73abd882c Mon Sep 17 00:00:00 2001 From: Beingpax Date: Fri, 8 Aug 2025 19:40:35 +0545 Subject: [PATCH] Remove Hober Animation and toggle states; implement always-expanded state for mini-recorder --- .../Views/Recorder/MiniRecorderPanel.swift | 28 ++------ .../Views/Recorder/MiniRecorderView.swift | 53 +++----------- .../Views/Recorder/MiniWindowManager.swift | 72 ------------------- 3 files changed, 15 insertions(+), 138 deletions(-) diff --git a/VoiceInk/Views/Recorder/MiniRecorderPanel.swift b/VoiceInk/Views/Recorder/MiniRecorderPanel.swift index b5e3891..73afcb7 100644 --- a/VoiceInk/Views/Recorder/MiniRecorderPanel.swift +++ b/VoiceInk/Views/Recorder/MiniRecorderPanel.swift @@ -30,14 +30,12 @@ class MiniRecorderPanel: NSPanel { standardWindowButton(.closeButton)?.isHidden = true } - static func calculateWindowMetrics(expanded: Bool = false) -> NSRect { + static func calculateWindowMetrics() -> NSRect { guard let screen = NSScreen.main else { - return NSRect(x: 0, y: 0, width: expanded ? 160 : 70, height: 34) + return NSRect(x: 0, y: 0, width: 160, height: 34) } - let compactWidth: CGFloat = 100 - let expandedWidth: CGFloat = 160 - let width = expanded ? expandedWidth : compactWidth + let width: CGFloat = 160 let height: CGFloat = 34 let padding: CGFloat = 24 @@ -55,29 +53,11 @@ class MiniRecorderPanel: NSPanel { } func show() { - let metrics = MiniRecorderPanel.calculateWindowMetrics(expanded: false) + let metrics = MiniRecorderPanel.calculateWindowMetrics() setFrame(metrics, display: true) orderFrontRegardless() } - func expandWindow(completion: (() -> Void)? = nil) { - let expandedMetrics = MiniRecorderPanel.calculateWindowMetrics(expanded: true) - NSAnimationContext.runAnimationGroup({ context in - context.duration = 0.25 - context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) - animator().setFrame(expandedMetrics, display: true) - }, completionHandler: completion) - } - - func collapseWindow(completion: (() -> Void)? = nil) { - let compactMetrics = MiniRecorderPanel.calculateWindowMetrics(expanded: false) - NSAnimationContext.runAnimationGroup({ context in - context.duration = 0.25 - context.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut) - animator().setFrame(compactMetrics, display: true) - }, completionHandler: completion) - } - func hide(completion: @escaping () -> Void) { completion() } diff --git a/VoiceInk/Views/Recorder/MiniRecorderView.swift b/VoiceInk/Views/Recorder/MiniRecorderView.swift index f788a52..d947fdf 100644 --- a/VoiceInk/Views/Recorder/MiniRecorderView.swift +++ b/VoiceInk/Views/Recorder/MiniRecorderView.swift @@ -8,12 +8,6 @@ struct MiniRecorderView: View { @State private var showPowerModePopover = false @State private var showEnhancementPromptPopover = false - @State private var isHovering = false - - // Computed property to check if any popover is currently showing - private var isAnyPopoverShowing: Bool { - showPowerModePopover || showEnhancementPromptPopover - } private var backgroundView: some View { ZStack { @@ -41,27 +35,21 @@ struct MiniRecorderView: View { private var contentLayout: some View { HStack(spacing: 0) { - if windowManager.isExpanded { - // Left button zone - only exists when expanded - RecorderPromptButton(showPopover: $showEnhancementPromptPopover) - .padding(.leading, 6) - .transition(.scale(scale: 0.5).combined(with: .opacity)) - - Spacer() - } + // Left button zone - always visible + RecorderPromptButton(showPopover: $showEnhancementPromptPopover) + .padding(.leading, 6) - // Fixed visualizer zone - takes full width when compact + Spacer() + + // Fixed visualizer zone statusView .frame(maxWidth: .infinity) - if windowManager.isExpanded { - Spacer() - - // Right button zone - only exists when expanded - RecorderPowerModeButton(showPopover: $showPowerModePopover) - .padding(.trailing, 6) - .transition(.scale(scale: 0.5).combined(with: .opacity)) - } + Spacer() + + // Right button zone - always visible + RecorderPowerModeButton(showPopover: $showPowerModePopover) + .padding(.trailing, 6) } .padding(.vertical, 8) } @@ -83,25 +71,6 @@ struct MiniRecorderView: View { Group { if windowManager.isVisible { recorderCapsule - .onHover { hovering in - isHovering = hovering - if hovering { - windowManager.expand() - } else { - DispatchQueue.main.asyncAfter(deadline: .now() + 0.35) { - // Only collapse if not hovering AND no popover is showing - if !isHovering && !isAnyPopoverShowing { - windowManager.collapse() - } - } - } - } - .onAppear { - // Set up the callback so WindowManager can check popover and hover state - windowManager.shouldPreventCollapse = { - isAnyPopoverShowing || isHovering - } - } } } } diff --git a/VoiceInk/Views/Recorder/MiniWindowManager.swift b/VoiceInk/Views/Recorder/MiniWindowManager.swift index ef05f7c..3817e03 100644 --- a/VoiceInk/Views/Recorder/MiniWindowManager.swift +++ b/VoiceInk/Views/Recorder/MiniWindowManager.swift @@ -3,18 +3,11 @@ import AppKit class MiniWindowManager: ObservableObject { @Published var isVisible = false - @Published var isExpanded = false private var windowController: NSWindowController? private var miniPanel: MiniRecorderPanel? private let whisperState: WhisperState private let recorder: Recorder - // Callback to check if collapse should be prevented (e.g., when popovers are showing) - var shouldPreventCollapse: (() -> Bool)? - - // Debounced timer for auto-collapse - private var debounceTimer: Timer? - init(whisperState: WhisperState, recorder: Recorder) { self.whisperState = whisperState self.recorder = recorder @@ -22,7 +15,6 @@ class MiniWindowManager: ObservableObject { } deinit { - debounceTimer?.invalidate() NotificationCenter.default.removeObserver(self) } @@ -33,50 +25,11 @@ class MiniWindowManager: ObservableObject { name: NSNotification.Name("HideMiniRecorder"), object: nil ) - - NotificationCenter.default.addObserver( - self, - selector: #selector(handleFeedbackNotification), - name: .promptSelectionChanged, - object: nil - ) - - NotificationCenter.default.addObserver( - self, - selector: #selector(handleFeedbackNotification), - name: .powerModeConfigurationApplied, - object: nil - ) - - NotificationCenter.default.addObserver( - self, - selector: #selector(handleFeedbackNotification), - name: .enhancementToggleChanged, - object: nil - ) } @objc private func handleHideNotification() { hide() } - - @objc private func handleFeedbackNotification() { - guard isVisible else { return } - - // Only expand if not already expanded - if !isExpanded { - expand() - } - - // Reset debounce timer - this cancels any existing timer and starts a new one - debounceTimer?.invalidate() - debounceTimer = Timer.scheduledTimer(withTimeInterval: 2.5, repeats: false) { [weak self] _ in - guard let self = self else { return } - if self.isExpanded && !(self.shouldPreventCollapse?() ?? false) { - self.collapse() - } - } - } func show() { if isVisible { return } @@ -87,35 +40,10 @@ class MiniWindowManager: ObservableObject { miniPanel?.show() } - func expand() { - guard isVisible, !isExpanded else { return } - - withAnimation(.easeInOut(duration: 0.25)) { - isExpanded = true - } - - miniPanel?.expandWindow() - } - - func collapse() { - guard isVisible, isExpanded else { return } - - withAnimation(.easeInOut(duration: 0.25)) { - isExpanded = false - } - - miniPanel?.collapseWindow() - } - func hide() { guard isVisible else { return } - // Cancel any pending auto-collapse timer - debounceTimer?.invalidate() - debounceTimer = nil - self.isVisible = false - self.isExpanded = false self.miniPanel?.hide { [weak self] in guard let self = self else { return } self.deinitializeWindow()