// // ClientOnlyManager.swift // ClashX Pro // // Created by 称一称 on 2020/6/16. // Copyright © 2020 west2online. All rights reserved. // import Cocoa class RemoteControl: Codable { let name: String let url: String let secret: String let uuid: String init(name: String, url: String, secret: String) { self.name = name self.url = url self.secret = secret uuid = UUID().uuidString } } class RemoteControlManager { enum Recorder { @UserDefault("selectedRemoteControlConfigID", defaultValue: "") static var selected: String } static let shared = RemoteControlManager() static var configs: [RemoteControl] = loadConfig() { didSet { if let encoded = try? JSONEncoder().encode(configs) { UserDefaults.standard.set(encoded, forKey: "kRemoteControls") } updateMenuItems() } } static var selectConfig: RemoteControl? { didSet { Recorder.selected = selectConfig?.uuid ?? "" } } private static var menuSeparator: NSMenuItem? static func loadConfig() -> [RemoteControl] { if let savedConfigs = UserDefaults.standard.object(forKey: "kRemoteControls") as? Data { if let loadedConfig = try? JSONDecoder().decode([RemoteControl].self, from: savedConfigs) { return loadedConfig } else { assertionFailure() return [] } } return [] } static func setupMenuItem(separator: NSMenuItem) { menuSeparator = separator updateMenuItems() updateDropDownMenuItems() DispatchQueue.main.asyncAfter(deadline: .now() + 3) { RemoteControlManager.recoverSelection() } } static private func recoverSelection() { if Recorder.selected != "" { if let config = configs.first(where: { $0.uuid == Recorder.selected }) { selectConfig = config updateRemoteControl() updateMenuItems() } else { Recorder.selected = "" } } } static func updateMenuItems() { guard let separator = menuSeparator, let menu = separator.menu else { return } let idx = menu.index(of: separator) for _ in 0.. ExternalControlMenuItem { return ExternalControlMenuItem(title: "None") } }