220 lines
8.3 KiB
Swift
220 lines
8.3 KiB
Swift
import Foundation
|
|
import AppKit
|
|
|
|
struct ApplicationState: Codable {
|
|
var isEnhancementEnabled: Bool
|
|
var useScreenCaptureContext: Bool
|
|
var selectedPromptId: String?
|
|
var selectedAIProvider: String?
|
|
var selectedAIModel: String?
|
|
var selectedLanguage: String?
|
|
var transcriptionModelName: String?
|
|
}
|
|
|
|
struct PowerModeSession: Codable {
|
|
let id: UUID
|
|
let startTime: Date
|
|
var originalState: ApplicationState
|
|
}
|
|
|
|
@MainActor
|
|
class PowerModeSessionManager {
|
|
static let shared = PowerModeSessionManager()
|
|
private let sessionKey = "powerModeActiveSession.v1"
|
|
private var isApplyingPowerModeConfig = false
|
|
|
|
private var whisperState: WhisperState?
|
|
private var enhancementService: AIEnhancementService?
|
|
|
|
private init() {
|
|
recoverSession()
|
|
}
|
|
|
|
func configure(whisperState: WhisperState, enhancementService: AIEnhancementService) {
|
|
self.whisperState = whisperState
|
|
self.enhancementService = enhancementService
|
|
}
|
|
|
|
func beginSession(with config: PowerModeConfig) async {
|
|
guard let whisperState = whisperState, let enhancementService = enhancementService else {
|
|
print("SessionManager not configured.")
|
|
return
|
|
}
|
|
|
|
let originalState = ApplicationState(
|
|
isEnhancementEnabled: enhancementService.isEnhancementEnabled,
|
|
useScreenCaptureContext: enhancementService.useScreenCaptureContext,
|
|
selectedPromptId: enhancementService.selectedPromptId?.uuidString,
|
|
selectedAIProvider: enhancementService.getAIService()?.selectedProvider.rawValue,
|
|
selectedAIModel: enhancementService.getAIService()?.currentModel,
|
|
selectedLanguage: UserDefaults.standard.string(forKey: "SelectedLanguage"),
|
|
transcriptionModelName: whisperState.currentTranscriptionModel?.name
|
|
)
|
|
|
|
let newSession = PowerModeSession(
|
|
id: UUID(),
|
|
startTime: Date(),
|
|
originalState: originalState
|
|
)
|
|
saveSession(newSession)
|
|
|
|
NotificationCenter.default.addObserver(self, selector: #selector(updateSessionSnapshot), name: .AppSettingsDidChange, object: nil)
|
|
|
|
isApplyingPowerModeConfig = true
|
|
await applyConfiguration(config)
|
|
isApplyingPowerModeConfig = false
|
|
}
|
|
|
|
func endSession() async {
|
|
guard let session = loadSession() else { return }
|
|
|
|
isApplyingPowerModeConfig = true
|
|
await restoreState(session.originalState)
|
|
isApplyingPowerModeConfig = false
|
|
|
|
NotificationCenter.default.removeObserver(self, name: .AppSettingsDidChange, object: nil)
|
|
|
|
clearSession()
|
|
}
|
|
|
|
@objc func updateSessionSnapshot() {
|
|
guard !isApplyingPowerModeConfig else { return }
|
|
|
|
guard var session = loadSession(), let whisperState = whisperState, let enhancementService = enhancementService else { return }
|
|
|
|
let updatedState = ApplicationState(
|
|
isEnhancementEnabled: enhancementService.isEnhancementEnabled,
|
|
useScreenCaptureContext: enhancementService.useScreenCaptureContext,
|
|
selectedPromptId: enhancementService.selectedPromptId?.uuidString,
|
|
selectedAIProvider: enhancementService.getAIService()?.selectedProvider.rawValue,
|
|
selectedAIModel: enhancementService.getAIService()?.currentModel,
|
|
selectedLanguage: UserDefaults.standard.string(forKey: "SelectedLanguage"),
|
|
transcriptionModelName: whisperState.currentTranscriptionModel?.name
|
|
)
|
|
|
|
session.originalState = updatedState
|
|
saveSession(session)
|
|
}
|
|
|
|
private func applyConfiguration(_ config: PowerModeConfig) async {
|
|
guard let enhancementService = enhancementService else { return }
|
|
|
|
await MainActor.run {
|
|
enhancementService.isEnhancementEnabled = config.isAIEnhancementEnabled
|
|
enhancementService.useScreenCaptureContext = config.useScreenCapture
|
|
|
|
if config.isAIEnhancementEnabled {
|
|
if let promptId = config.selectedPrompt, let uuid = UUID(uuidString: promptId) {
|
|
enhancementService.selectedPromptId = uuid
|
|
}
|
|
|
|
if let aiService = enhancementService.getAIService() {
|
|
if let providerName = config.selectedAIProvider, let provider = AIProvider(rawValue: providerName) {
|
|
aiService.selectedProvider = provider
|
|
}
|
|
if let model = config.selectedAIModel {
|
|
aiService.selectModel(model)
|
|
}
|
|
}
|
|
}
|
|
|
|
if let language = config.selectedLanguage {
|
|
UserDefaults.standard.set(language, forKey: "SelectedLanguage")
|
|
NotificationCenter.default.post(name: .languageDidChange, object: nil)
|
|
}
|
|
}
|
|
|
|
if let whisperState = whisperState,
|
|
let modelName = config.selectedTranscriptionModelName,
|
|
let selectedModel = await whisperState.allAvailableModels.first(where: { $0.name == modelName }),
|
|
whisperState.currentTranscriptionModel?.name != modelName {
|
|
await handleModelChange(to: selectedModel)
|
|
}
|
|
}
|
|
|
|
private func restoreState(_ state: ApplicationState) async {
|
|
guard let enhancementService = enhancementService else { return }
|
|
|
|
await MainActor.run {
|
|
enhancementService.isEnhancementEnabled = state.isEnhancementEnabled
|
|
enhancementService.useScreenCaptureContext = state.useScreenCaptureContext
|
|
enhancementService.selectedPromptId = state.selectedPromptId.flatMap(UUID.init)
|
|
|
|
if let aiService = enhancementService.getAIService() {
|
|
if let providerName = state.selectedAIProvider, let provider = AIProvider(rawValue: providerName) {
|
|
aiService.selectedProvider = provider
|
|
}
|
|
if let model = state.selectedAIModel {
|
|
aiService.selectModel(model)
|
|
}
|
|
}
|
|
|
|
if let language = state.selectedLanguage {
|
|
UserDefaults.standard.set(language, forKey: "SelectedLanguage")
|
|
NotificationCenter.default.post(name: .languageDidChange, object: nil)
|
|
}
|
|
}
|
|
|
|
if let whisperState = whisperState,
|
|
let modelName = state.transcriptionModelName,
|
|
let selectedModel = await whisperState.allAvailableModels.first(where: { $0.name == modelName }),
|
|
whisperState.currentTranscriptionModel?.name != modelName {
|
|
await handleModelChange(to: selectedModel)
|
|
}
|
|
}
|
|
|
|
private func handleModelChange(to newModel: any TranscriptionModel) async {
|
|
guard let whisperState = whisperState else { return }
|
|
|
|
await whisperState.setDefaultTranscriptionModel(newModel)
|
|
|
|
switch newModel.provider {
|
|
case .local:
|
|
await whisperState.cleanupModelResources()
|
|
if let localModel = await whisperState.availableModels.first(where: { $0.name == newModel.name }) {
|
|
do {
|
|
try await whisperState.loadModel(localModel)
|
|
} catch {
|
|
print("Power Mode: Failed to load local model '\(localModel.name)': \(error)")
|
|
}
|
|
}
|
|
case .parakeet:
|
|
await whisperState.cleanupModelResources()
|
|
|
|
default:
|
|
await whisperState.cleanupModelResources()
|
|
}
|
|
}
|
|
|
|
private func recoverSession() {
|
|
guard let session = loadSession() else { return }
|
|
print("Recovering abandoned Power Mode session.")
|
|
Task {
|
|
await endSession()
|
|
}
|
|
}
|
|
|
|
private func saveSession(_ session: PowerModeSession) {
|
|
do {
|
|
let data = try JSONEncoder().encode(session)
|
|
UserDefaults.standard.set(data, forKey: sessionKey)
|
|
} catch {
|
|
print("Error saving Power Mode session: \(error)")
|
|
}
|
|
}
|
|
|
|
private func loadSession() -> PowerModeSession? {
|
|
guard let data = UserDefaults.standard.data(forKey: sessionKey) else { return nil }
|
|
do {
|
|
return try JSONDecoder().decode(PowerModeSession.self, from: data)
|
|
} catch {
|
|
print("Error loading Power Mode session: \(error)")
|
|
return nil
|
|
}
|
|
}
|
|
|
|
private func clearSession() {
|
|
UserDefaults.standard.removeObject(forKey: sessionKey)
|
|
}
|
|
}
|