{"repo": "baokker/presstalk", "files": {"PressTalk/UI/StatusBarController.swift": {"d1e1ce5efd96f3406076d667d2569c5f04a07f81": {"t": 1785745887.45503, "n": 3147, "h": "55fc3046110b9f9f", "c": "import AppKit\nimport Combine\n\nfinal class StatusBarController {\n private let statusItem: NSStatusItem\n private let state = AppState.shared\n private var cancellables = Set()\n private var countItem: NSMenuItem!\n private var smartItem: NSMenuItem!\n private let onOpenSettings: () -> Void\n\n private let icons: [InputState: String] = [\n .idle: \"●\",\n .recording: \"◉\",\n .transcribing: \"◌\",\n .done: \"✓\",\n ]\n\n init(onOpenSettings: @escaping () -> Void) {\n self.onOpenSettings = onOpenSettings\n statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)\n statusItem.button?.title = icons[.idle]!\n statusItem.button?.font = NSFont.systemFont(ofSize: 14)\n\n buildMenu()\n observeState()\n }\n\n private func buildMenu() {\n let menu = NSMenu()\n\n countItem = NSMenuItem(title: \"今日转录:0 次\", action: nil, keyEquivalent: \"\")\n countItem.isEnabled = false\n menu.addItem(countItem)\n\n menu.addItem(.separator())\n\n smartItem = NSMenuItem(title: \"智能整理(右 Command)\",\n action: #selector(toggleSmart(_:)),\n keyEquivalent: \"\")\n smartItem.target = self\n smartItem.state = state.smartModeEnabled && state.hasDeepSeekConfig ? .on : .off\n menu.addItem(smartItem)\n\n menu.addItem(.separator())\n\n let settingsItem = NSMenuItem(title: \"设置…\",\n action: #selector(openSettings),\n keyEquivalent: \",\")\n settingsItem.target = self\n menu.addItem(settingsItem)\n\n let quitItem = NSMenuItem(title: \"退出\", action: #selector(quit), keyEquivalent: \"q\")\n quitItem.target = self\n menu.addItem(.separator())\n menu.addItem(quitItem)\n\n statusItem.menu = menu\n }\n\n private func observeState() {\n state.$currentState\n .receive(on: DispatchQueue.main)\n .sink { [weak self] newState in\n guard let self else { return }\n self.statusItem.button?.title = self.icons[newState] ?? \"●\"\n }\n .store(in: &cancellables)\n\n state.$transcriptionCount\n .receive(on: DispatchQueue.main)\n .sink { [weak self] count in\n self?.countItem.title = \"今日转录:\\(count) 次\"\n }\n .store(in: &cancellables)\n }\n\n // MARK: - Actions\n\n @objc private func toggleSmart(_ sender: NSMenuItem) {\n if !state.hasDeepSeekConfig {\n let alert = NSAlert()\n alert.messageText = \"未配置 DeepSeek API Key\"\n alert.informativeText = \"请打开「设置」填写 DEEPSEEK_API_KEY。\"\n alert.alertStyle = .informational\n alert.addButton(withTitle: \"确定\")\n alert.runModal()\n return\n }\n state.smartModeEnabled.toggle()\n sender.state = state.smartModeEnabled ? .on : .off\n }\n\n @objc private func openSettings() {\n onOpenSettings()\n }\n\n @objc private func quit() {\n NSApp.terminate(nil)\n }\n}\n"}, "7c98fc84a19a5b0d329864cb406f6ef878b8126b": {"t": 1785757666.3225126, "n": 3147, "h": "55fc3046110b9f9f", "c": "import AppKit\nimport Combine\n\nfinal class StatusBarController {\n private let statusItem: NSStatusItem\n private let state = AppState.shared\n private var cancellables = Set()\n private var countItem: NSMenuItem!\n private var smartItem: NSMenuItem!\n private let onOpenSettings: () -> Void\n\n private let icons: [InputState: String] = [\n .idle: \"●\",\n .recording: \"◉\",\n .transcribing: \"◌\",\n .done: \"✓\",\n ]\n\n init(onOpenSettings: @escaping () -> Void) {\n self.onOpenSettings = onOpenSettings\n statusItem = NSStatusBar.system.statusItem(withLength: NSStatusItem.variableLength)\n statusItem.button?.title = icons[.idle]!\n statusItem.button?.font = NSFont.systemFont(ofSize: 14)\n\n buildMenu()\n observeState()\n }\n\n private func buildMenu() {\n let menu = NSMenu()\n\n countItem = NSMenuItem(title: \"今日转录:0 次\", action: nil, keyEquivalent: \"\")\n countItem.isEnabled = false\n menu.addItem(countItem)\n\n menu.addItem(.separator())\n\n smartItem = NSMenuItem(title: \"智能整理(右 Command)\",\n action: #selector(toggleSmart(_:)),\n keyEquivalent: \"\")\n smartItem.target = self\n smartItem.state = state.smartModeEnabled && state.hasDeepSeekConfig ? .on : .off\n menu.addItem(smartItem)\n\n menu.addItem(.separator())\n\n let settingsItem = NSMenuItem(title: \"设置…\",\n action: #selector(openSettings),\n keyEquivalent: \",\")\n settingsItem.target = self\n menu.addItem(settingsItem)\n\n let quitItem = NSMenuItem(title: \"退出\", action: #selector(quit), keyEquivalent: \"q\")\n quitItem.target = self\n menu.addItem(.separator())\n menu.addItem(quitItem)\n\n statusItem.menu = menu\n }\n\n private func observeState() {\n state.$currentState\n .receive(on: DispatchQueue.main)\n .sink { [weak self] newState in\n guard let self else { return }\n self.statusItem.button?.title = self.icons[newState] ?? \"●\"\n }\n .store(in: &cancellables)\n\n state.$transcriptionCount\n .receive(on: DispatchQueue.main)\n .sink { [weak self] count in\n self?.countItem.title = \"今日转录:\\(count) 次\"\n }\n .store(in: &cancellables)\n }\n\n // MARK: - Actions\n\n @objc private func toggleSmart(_ sender: NSMenuItem) {\n if !state.hasDeepSeekConfig {\n let alert = NSAlert()\n alert.messageText = \"未配置 DeepSeek API Key\"\n alert.informativeText = \"请打开「设置」填写 DEEPSEEK_API_KEY。\"\n alert.alertStyle = .informational\n alert.addButton(withTitle: \"确定\")\n alert.runModal()\n return\n }\n state.smartModeEnabled.toggle()\n sender.state = state.smartModeEnabled ? .on : .off\n }\n\n @objc private func openSettings() {\n onOpenSettings()\n }\n\n @objc private func quit() {\n NSApp.terminate(nil)\n }\n}\n"}}}}