Mark pause media feature as experimental
This commit is contained in:
parent
99e95bedf5
commit
4601c4c67b
@ -3,8 +3,6 @@ import Combine
|
||||
import Foundation
|
||||
import SwiftUI
|
||||
import MediaRemoteAdapter
|
||||
|
||||
/// Pauses media when recording starts, resumes when recording stops
|
||||
class PlaybackController: ObservableObject {
|
||||
static let shared = PlaybackController()
|
||||
private var mediaController: MediaRemoteAdapter.MediaController
|
||||
@ -12,6 +10,7 @@ class PlaybackController: ObservableObject {
|
||||
private var isMediaPlaying = false
|
||||
private var lastKnownTrackInfo: TrackInfo?
|
||||
private var originalMediaAppBundleId: String?
|
||||
|
||||
|
||||
@Published var isPauseMediaEnabled: Bool = UserDefaults.standard.bool(forKey: "isPauseMediaEnabled") {
|
||||
didSet {
|
||||
@ -23,7 +22,7 @@ class PlaybackController: ObservableObject {
|
||||
mediaController = MediaRemoteAdapter.MediaController()
|
||||
|
||||
if !UserDefaults.standard.contains(key: "isPauseMediaEnabled") {
|
||||
UserDefaults.standard.set(true, forKey: "isPauseMediaEnabled")
|
||||
UserDefaults.standard.set(false, forKey: "isPauseMediaEnabled")
|
||||
}
|
||||
|
||||
mediaController.startListening()
|
||||
@ -40,29 +39,47 @@ class PlaybackController: ObservableObject {
|
||||
}
|
||||
|
||||
func pauseMedia() async {
|
||||
guard isPauseMediaEnabled else { return }
|
||||
|
||||
if isMediaPlaying {
|
||||
wasPlayingWhenRecordingStarted = true
|
||||
originalMediaAppBundleId = lastKnownTrackInfo?.payload.bundleIdentifier
|
||||
mediaController.pause()
|
||||
} else {
|
||||
wasPlayingWhenRecordingStarted = false
|
||||
originalMediaAppBundleId = nil
|
||||
wasPlayingWhenRecordingStarted = false
|
||||
originalMediaAppBundleId = nil
|
||||
|
||||
guard isPauseMediaEnabled,
|
||||
isMediaPlaying,
|
||||
lastKnownTrackInfo?.payload.isPlaying == true,
|
||||
let bundleId = lastKnownTrackInfo?.payload.bundleIdentifier else {
|
||||
return
|
||||
}
|
||||
|
||||
wasPlayingWhenRecordingStarted = true
|
||||
originalMediaAppBundleId = bundleId
|
||||
mediaController.pause()
|
||||
}
|
||||
|
||||
func resumeMedia() async {
|
||||
guard isPauseMediaEnabled, wasPlayingWhenRecordingStarted else { return }
|
||||
|
||||
if let bundleId = originalMediaAppBundleId, isAppStillRunning(bundleId: bundleId) {
|
||||
mediaController.play()
|
||||
defer {
|
||||
wasPlayingWhenRecordingStarted = false
|
||||
originalMediaAppBundleId = nil
|
||||
}
|
||||
|
||||
originalMediaAppBundleId = nil
|
||||
guard isPauseMediaEnabled,
|
||||
wasPlayingWhenRecordingStarted,
|
||||
let bundleId = originalMediaAppBundleId else {
|
||||
return
|
||||
}
|
||||
|
||||
guard isAppStillRunning(bundleId: bundleId) else {
|
||||
return
|
||||
}
|
||||
|
||||
guard let currentTrackInfo = lastKnownTrackInfo,
|
||||
let currentBundleId = currentTrackInfo.payload.bundleIdentifier,
|
||||
currentBundleId == bundleId,
|
||||
currentTrackInfo.payload.isPlaying == false else {
|
||||
return
|
||||
}
|
||||
|
||||
mediaController.play()
|
||||
}
|
||||
|
||||
/// Checks if an app with the given bundle identifier is currently running
|
||||
private func isAppStillRunning(bundleId: String) -> Bool {
|
||||
let runningApps = NSWorkspace.shared.runningApplications
|
||||
return runningApps.contains { $0.bundleIdentifier == bundleId }
|
||||
|
||||
@ -152,8 +152,8 @@ class Recorder: ObservableObject {
|
||||
audioMeter = AudioMeter(averagePower: 0, peakPower: 0)
|
||||
|
||||
Task {
|
||||
// Complete system audio operations first
|
||||
await mediaController.unmuteSystemAudio()
|
||||
try? await Task.sleep(nanoseconds: 100_000_000)
|
||||
await playbackController.resumeMedia()
|
||||
}
|
||||
deviceManager.isRecordingActive = false
|
||||
|
||||
@ -3,7 +3,6 @@ import Cocoa
|
||||
import KeyboardShortcuts
|
||||
import LaunchAtLogin
|
||||
import AVFoundation
|
||||
// Additional imports for Settings components
|
||||
|
||||
struct SettingsView: View {
|
||||
@EnvironmentObject private var updaterViewModel: UpdaterViewModel
|
||||
@ -23,7 +22,6 @@ struct SettingsView: View {
|
||||
var body: some View {
|
||||
ScrollView {
|
||||
VStack(spacing: 24) {
|
||||
// Hotkey Selection Section
|
||||
SettingsSection(
|
||||
icon: "command.circle",
|
||||
title: "VoiceInk Shortcut",
|
||||
@ -36,7 +34,6 @@ struct SettingsView: View {
|
||||
shortcutName: .toggleMiniRecorder
|
||||
)
|
||||
|
||||
// Hotkey 2 Configuration (Conditional)
|
||||
if hotkeyManager.selectedHotkey2 != .none {
|
||||
Divider()
|
||||
hotkeyView(
|
||||
@ -50,7 +47,6 @@ struct SettingsView: View {
|
||||
)
|
||||
}
|
||||
|
||||
// "Add another hotkey" button
|
||||
if hotkeyManager.selectedHotkey1 != .none && hotkeyManager.selectedHotkey2 == .none {
|
||||
HStack {
|
||||
Spacer()
|
||||
@ -71,7 +67,6 @@ struct SettingsView: View {
|
||||
|
||||
Divider()
|
||||
|
||||
// Cancel Recording Override Toggle
|
||||
Toggle(isOn: $isCustomCancelEnabled) {
|
||||
Text("Override default double-tap Escape cancellation")
|
||||
}
|
||||
@ -82,7 +77,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Show shortcut recorder only when override is enabled
|
||||
if isCustomCancelEnabled {
|
||||
HStack(spacing: 12) {
|
||||
Text("Custom Cancel Shortcut")
|
||||
@ -123,7 +117,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Recording Feedback Section
|
||||
SettingsSection(
|
||||
icon: "speaker.wave.2.bubble.left.fill",
|
||||
title: "Recording Feedback",
|
||||
@ -145,16 +138,15 @@ struct SettingsView: View {
|
||||
.help("Automatically mute system audio when recording starts and restore when recording stops")
|
||||
|
||||
Toggle(isOn: $playbackController.isPauseMediaEnabled) {
|
||||
Text("Pause media during recording")
|
||||
Text("Pause media during recording (Experimental)")
|
||||
}
|
||||
.toggleStyle(.switch)
|
||||
.help("Automatically pause active media playback when recording starts and resume when recording stops")
|
||||
.help("Automatically pause active media playback when recording starts and resume when recording stops. This feature is experimental and may occasionally cause unexpected behavior.")
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
// Recorder Preference Section
|
||||
SettingsSection(
|
||||
icon: "rectangle.on.rectangle",
|
||||
title: "Recorder Style",
|
||||
@ -173,7 +165,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Paste Method Section
|
||||
SettingsSection(
|
||||
icon: "doc.on.clipboard",
|
||||
title: "Paste Method",
|
||||
@ -191,7 +182,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// App Appearance Section
|
||||
SettingsSection(
|
||||
icon: "dock.rectangle",
|
||||
title: "App Appearance",
|
||||
@ -206,7 +196,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Data & Privacy Section
|
||||
SettingsSection(
|
||||
icon: "lock.shield",
|
||||
title: "Data & Privacy",
|
||||
@ -215,7 +204,6 @@ struct SettingsView: View {
|
||||
AudioCleanupSettingsView()
|
||||
}
|
||||
|
||||
// Startup Section
|
||||
SettingsSection(
|
||||
icon: "power",
|
||||
title: "Startup",
|
||||
@ -230,7 +218,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Updates Section
|
||||
SettingsSection(
|
||||
icon: "arrow.triangle.2.circlepath",
|
||||
title: "Updates",
|
||||
@ -249,7 +236,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Reset Onboarding Section
|
||||
SettingsSection(
|
||||
icon: "arrow.counterclockwise",
|
||||
title: "Reset Onboarding",
|
||||
@ -267,7 +253,6 @@ struct SettingsView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// Data Management Section
|
||||
SettingsSection(
|
||||
icon: "arrow.up.arrow.down.circle",
|
||||
title: "Data Management",
|
||||
@ -320,7 +305,6 @@ struct SettingsView: View {
|
||||
}
|
||||
.background(Color(NSColor.controlBackgroundColor))
|
||||
.onAppear {
|
||||
// Initialize custom cancel shortcut state from stored preferences
|
||||
isCustomCancelEnabled = KeyboardShortcuts.getShortcut(for: .cancelRecorder) != nil
|
||||
}
|
||||
.alert("Reset Onboarding", isPresented: $showResetOnboardingAlert) {
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user