159 lines
6.4 KiB
Swift
159 lines
6.4 KiB
Swift
import Foundation
|
|
import AppKit
|
|
import os
|
|
|
|
class ActiveWindowService: ObservableObject {
|
|
static let shared = ActiveWindowService()
|
|
@Published var currentApplication: NSRunningApplication?
|
|
private var enhancementService: AIEnhancementService?
|
|
private let browserURLService = BrowserURLService.shared
|
|
private var whisperState: WhisperState?
|
|
|
|
private let logger = Logger(
|
|
subsystem: "com.prakashjoshipax.VoiceInk",
|
|
category: "browser.detection"
|
|
)
|
|
|
|
private init() {}
|
|
|
|
func configure(with enhancementService: AIEnhancementService) {
|
|
self.enhancementService = enhancementService
|
|
}
|
|
|
|
func configureWhisperState(_ whisperState: WhisperState) {
|
|
self.whisperState = whisperState
|
|
}
|
|
|
|
func applyConfigurationForCurrentApp() async {
|
|
guard PowerModeManager.shared.isPowerModeEnabled else {
|
|
return
|
|
}
|
|
|
|
guard let frontmostApp = NSWorkspace.shared.frontmostApplication,
|
|
let bundleIdentifier = frontmostApp.bundleIdentifier else { return }
|
|
|
|
await MainActor.run {
|
|
currentApplication = frontmostApp
|
|
}
|
|
|
|
if let browserType = BrowserType.allCases.first(where: { $0.bundleIdentifier == bundleIdentifier }) {
|
|
logger.debug("🌐 Detected Browser: \(browserType.displayName)")
|
|
|
|
do {
|
|
logger.debug("📝 Attempting to get URL from \(browserType.displayName)")
|
|
let currentURL = try await browserURLService.getCurrentURL(from: browserType)
|
|
logger.debug("📍 Successfully got URL: \(currentURL)")
|
|
|
|
if let config = PowerModeManager.shared.getConfigurationForURL(currentURL) {
|
|
logger.debug("⚙️ Found URL Configuration: \(config.name) for URL: \(currentURL)")
|
|
await MainActor.run {
|
|
PowerModeManager.shared.setActiveConfiguration(config)
|
|
}
|
|
await applyConfiguration(config)
|
|
return
|
|
} else {
|
|
logger.debug("📝 No URL configuration found for: \(currentURL)")
|
|
}
|
|
} catch {
|
|
logger.error("❌ Failed to get URL from \(browserType.displayName): \(error.localizedDescription)")
|
|
}
|
|
}
|
|
|
|
let config = PowerModeManager.shared.getConfigurationForApp(bundleIdentifier) ?? PowerModeManager.shared.defaultConfig
|
|
|
|
await MainActor.run {
|
|
PowerModeManager.shared.setActiveConfiguration(config)
|
|
}
|
|
|
|
await applyConfiguration(config)
|
|
}
|
|
|
|
/// Applies a specific configuration
|
|
func applyConfiguration(_ config: PowerModeConfig) async {
|
|
guard let enhancementService = enhancementService else { return }
|
|
|
|
// Capture current state before making changes
|
|
let wasScreenCaptureEnabled = await MainActor.run {
|
|
enhancementService.useScreenCaptureContext
|
|
}
|
|
let wasEnhancementEnabled = await MainActor.run {
|
|
enhancementService.isEnhancementEnabled
|
|
}
|
|
|
|
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
|
|
} else {
|
|
if let firstPrompt = enhancementService.allPrompts.first {
|
|
enhancementService.selectedPromptId = firstPrompt.id
|
|
}
|
|
}
|
|
}
|
|
|
|
if config.isAIEnhancementEnabled,
|
|
let aiService = enhancementService.getAIService() {
|
|
|
|
if let providerName = config.selectedAIProvider,
|
|
let provider = AIProvider(rawValue: providerName) {
|
|
aiService.selectedProvider = provider
|
|
|
|
if let model = config.selectedAIModel,
|
|
!model.isEmpty {
|
|
aiService.selectModel(model)
|
|
}
|
|
}
|
|
}
|
|
|
|
if let language = config.selectedLanguage {
|
|
UserDefaults.standard.set(language, forKey: "SelectedLanguage")
|
|
NotificationCenter.default.post(name: .languageDidChange, object: nil)
|
|
}
|
|
}
|
|
|
|
if let whisperState = self.whisperState,
|
|
let modelName = config.selectedTranscriptionModelName,
|
|
let selectedModel = await whisperState.allAvailableModels.first(where: { $0.name == modelName }) {
|
|
|
|
let currentModelName = await MainActor.run { whisperState.currentTranscriptionModel?.name }
|
|
|
|
// Only change the model if it's different from the current one.
|
|
if currentModelName != modelName {
|
|
// Set the new model as default. This works for both local and cloud models.
|
|
await whisperState.setDefaultTranscriptionModel(selectedModel)
|
|
|
|
switch selectedModel.provider {
|
|
case .local:
|
|
await whisperState.cleanupModelResources()
|
|
|
|
if let localModel = await whisperState.availableModels.first(where: { $0.name == selectedModel.name }) {
|
|
do {
|
|
try await whisperState.loadModel(localModel)
|
|
} catch {
|
|
logger.error("❌ Power Mode: Failed to load local model '\(localModel.name)': \(error.localizedDescription)")
|
|
}
|
|
}
|
|
|
|
case .parakeet:
|
|
await whisperState.cleanupModelResources()
|
|
|
|
default:
|
|
await whisperState.cleanupModelResources()
|
|
}
|
|
}
|
|
}
|
|
|
|
// Wait for UI changes and model loading to complete first
|
|
try? await Task.sleep(nanoseconds: 1_500_000_000) // 1.5 seconds
|
|
|
|
// Then check if we should capture
|
|
if config.isAIEnhancementEnabled && config.useScreenCapture {
|
|
await enhancementService.captureScreenContext()
|
|
}
|
|
}
|
|
}
|