diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 2fb3d3c..8e46226 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -23,7 +23,7 @@ jobs: uses: robinraju/release-downloader@v1.10 with: repository: 'MetaCubeX/mihomo' - tag: "v1.18.10" + tag: "v1.19.0" fileName: ".*darwin.*64-v.*.gz" # releaseId: "62870807" diff --git a/ClashX.xcodeproj/project.pbxproj b/ClashX.xcodeproj/project.pbxproj index 388e55f..362eaf5 100644 --- a/ClashX.xcodeproj/project.pbxproj +++ b/ClashX.xcodeproj/project.pbxproj @@ -443,8 +443,8 @@ 01BCDAC72C9ECD010028FA94 /* Config */ = { isa = PBXGroup; children = ( - 01BCDAC52C9ECD010028FA94 /* ConfigItemView.swift */, 01BCDAC62C9ECD010028FA94 /* ConfigView.swift */, + 01BCDAC52C9ECD010028FA94 /* ConfigItemView.swift */, ); path = Config; sourceTree = ""; @@ -452,9 +452,9 @@ 01BCDACB2C9ECD010028FA94 /* Connections */ = { isa = PBXGroup; children = ( - 01BCDAC82C9ECD010028FA94 /* Connections.swift */, - 01BCDAC92C9ECD010028FA94 /* ConnectionsTableView.swift */, 01BCDACA2C9ECD010028FA94 /* ConnectionsView.swift */, + 01BCDAC92C9ECD010028FA94 /* ConnectionsTableView.swift */, + 01BCDAC82C9ECD010028FA94 /* Connections.swift */, ); path = Connections; sourceTree = ""; @@ -462,8 +462,8 @@ 01BCDACE2C9ECD010028FA94 /* Logs */ = { isa = PBXGroup; children = ( - 01BCDACC2C9ECD010028FA94 /* LogsTableView.swift */, 01BCDACD2C9ECD010028FA94 /* LogsView.swift */, + 01BCDACC2C9ECD010028FA94 /* LogsTableView.swift */, ); path = Logs; sourceTree = ""; @@ -471,8 +471,8 @@ 01BCDAD22C9ECD010028FA94 /* Overview */ = { isa = PBXGroup; children = ( - 01BCDACF2C9ECD010028FA94 /* OverviewTopItemView.swift */, 01BCDAD02C9ECD010028FA94 /* OverviewView.swift */, + 01BCDACF2C9ECD010028FA94 /* OverviewTopItemView.swift */, 01BCDAD12C9ECD010028FA94 /* TrafficGraphView.swift */, ); path = Overview; @@ -481,8 +481,8 @@ 01BCDADA2C9ECD010028FA94 /* Providers */ = { isa = PBXGroup; children = ( - 01BCDAD42C9ECD010028FA94 /* ProviderRowView.swift */, 01BCDAD52C9ECD010028FA94 /* ProvidersView.swift */, + 01BCDAD42C9ECD010028FA94 /* ProviderRowView.swift */, 01BCDAD62C9ECD010028FA94 /* ProxyProviderInfoView.swift */, 01BCDAD72C9ECD010028FA94 /* ProxyProvidersRowView.swift */, 01BCDAD82C9ECD010028FA94 /* RuleProvidersRowView.swift */, @@ -506,8 +506,8 @@ 01BCDAE22C9ECD010028FA94 /* Rules */ = { isa = PBXGroup; children = ( - 01BCDAE02C9ECD010028FA94 /* RuleItemView.swift */, 01BCDAE12C9ECD010028FA94 /* RulesView.swift */, + 01BCDAE02C9ECD010028FA94 /* RuleItemView.swift */, ); path = Rules; sourceTree = ""; @@ -515,13 +515,13 @@ 01BCDAE32C9ECD010028FA94 /* ContentTabs */ = { isa = PBXGroup; children = ( - 01BCDAC72C9ECD010028FA94 /* Config */, - 01BCDACB2C9ECD010028FA94 /* Connections */, - 01BCDACE2C9ECD010028FA94 /* Logs */, 01BCDAD22C9ECD010028FA94 /* Overview */, - 01BCDADA2C9ECD010028FA94 /* Providers */, 01BCDADF2C9ECD010028FA94 /* Proxies */, + 01BCDADA2C9ECD010028FA94 /* Providers */, 01BCDAE22C9ECD010028FA94 /* Rules */, + 01BCDACB2C9ECD010028FA94 /* Connections */, + 01BCDAC72C9ECD010028FA94 /* Config */, + 01BCDACE2C9ECD010028FA94 /* Logs */, 01BCDAD32C9ECD010028FA94 /* ProviderProxiesView.swift */, ); path = ContentTabs; diff --git a/ClashX/Dashboard/DashboardViewContoller.swift b/ClashX/Dashboard/DashboardViewContoller.swift index d82cc88..de5cdcf 100644 --- a/ClashX/Dashboard/DashboardViewContoller.swift +++ b/ClashX/Dashboard/DashboardViewContoller.swift @@ -72,6 +72,13 @@ class DashboardViewContoller: NSViewController { .info, .debug ] + + enum LogFilter: String, CaseIterable { + case all = "All" + case rule = "Rule" + case dns = "DNS" + case others = "Others" + } private var sidebarItemObserver: NSObjectProtocol? private var searchStringObserver: NSObjectProtocol? @@ -109,6 +116,7 @@ class DashboardViewContoller: NSViewController { items.append(.stopConnsItem) items.append(.searchItem) case .logs: + items.append(.logFilterItem) items.append(.logLevelItem) items.append(.searchItem) } @@ -187,6 +195,7 @@ extension NSToolbarItem.Identifier { static let hideNamesItem = NSToolbarItem.Identifier("HideNamesItem") static let stopConnsItem = NSToolbarItem.Identifier("StopConnsItem") static let logLevelItem = NSToolbarItem.Identifier("LogLevelItem") + static let logFilterItem = NSToolbarItem.Identifier("logFilterItem") static let searchItem = NSToolbarItem.Identifier("SearchItem") } @@ -224,6 +233,14 @@ extension DashboardViewContoller: NSSearchFieldDelegate { NotificationCenter.default.post(name: .logLevelChanged, object: nil, userInfo: ["level": level]) } + + @objc func setLogFilter(_ sender: NSToolbarItemGroup) { + guard sender.selectedIndex < LogFilter.allCases.count, sender.selectedIndex >= 0 else { return } + let filter = LogFilter.allCases[sender.selectedIndex] + + NotificationCenter.default.post(name: .logFilterChanged, object: nil, userInfo: ["filter": filter]) + } + } extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { @@ -254,7 +271,23 @@ extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { group.controlRepresentation = .collapsed group.selectedIndex = levels.firstIndex(of: ConfigManager.selectLoggingApiLevel) ?? 0 + group.label = "Log Level" + return group + case .logFilterItem: + let titles = LogFilter.allCases.map { + $0.rawValue + } + + let group = NSToolbarItemGroup(itemIdentifier: .logFilterItem, titles: titles, selectionMode: .selectOne, labels: titles, target: nil, action: #selector(setLogFilter(_:))) + + group.selectionMode = .selectOne + group.controlRepresentation = .collapsed + group.selectedIndex = 0 + + group.label = "Log Filter" + + return group case .hideNamesItem: let item = NSToolbarItem(itemIdentifier: .hideNamesItem) item.target = self @@ -262,6 +295,9 @@ extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { item.isBordered = true item.tag = 0 item.image = NSImage(systemSymbolName: "wand.and.stars", accessibilityDescription: nil) + + item.label = "Hide Names" + return item case .stopConnsItem: let item = NSToolbarItem(itemIdentifier: .stopConnsItem) @@ -269,6 +305,9 @@ extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { item.action = #selector(stopConns(_:)) item.isBordered = true item.image = NSImage(systemSymbolName: "stop.circle.fill", accessibilityDescription: nil) + + item.label = "Stop All" + return item default: break @@ -284,6 +323,7 @@ extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { .stopConnsItem, .hideNamesItem, .logLevelItem, + .logFilterItem, .searchItem ] } @@ -294,6 +334,7 @@ extension DashboardViewContoller: NSToolbarDelegate, NSToolbarItemValidation { .stopConnsItem, .hideNamesItem, .logLevelItem, + .logFilterItem, .searchItem ] } diff --git a/ClashX/Dashboard/Extensions/NotificationNames.swift b/ClashX/Dashboard/Extensions/NotificationNames.swift index 5347b33..e710198 100644 --- a/ClashX/Dashboard/Extensions/NotificationNames.swift +++ b/ClashX/Dashboard/Extensions/NotificationNames.swift @@ -14,4 +14,5 @@ extension NSNotification.Name { static let stopConns = NSNotification.Name("StopConns") static let hideNames = NSNotification.Name("HideNames") static let logLevelChanged = NSNotification.Name("LogLevelChanged") + static let logFilterChanged = NSNotification.Name("LogFilterChanged") } diff --git a/ClashX/Dashboard/Models/DBProxyStorage.swift b/ClashX/Dashboard/Models/DBProxyStorage.swift index bac75ce..76637d9 100644 --- a/ClashX/Dashboard/Models/DBProxyStorage.swift +++ b/ClashX/Dashboard/Models/DBProxyStorage.swift @@ -103,7 +103,7 @@ class DBProxy: ObservableObject { switch delay { case 0: - return .gray + return .red case ..<200 where !httpsTest: return .green case ..<800 where httpsTest: @@ -118,3 +118,19 @@ class DBProxy: ObservableObject { } } + +extension String { + var hiddenID: String { + guard UUID(uuidString: self) != nil else { return "" } + let components = split(separator: "-").map(String.init) + guard components.count == 5 else { return "" } + + let re = components[0].prefix(2) + + components[1].prefix(1) + + components[2].prefix(1) + + components[3].prefix(1) + + components[4].suffix(3) + + return String(re) + } +} diff --git a/ClashX/Dashboard/Views/ContentTabs/Config/ConfigItemView.swift b/ClashX/Dashboard/Views/ContentTabs/Config/ConfigItemView.swift index 393db16..c91fb73 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Config/ConfigItemView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Config/ConfigItemView.swift @@ -22,7 +22,7 @@ struct ConfigItemView: View { HStack(content: content) } .padding(EdgeInsets(top: 10, leading: 13, bottom: 10, trailing: 13)) - .background(Color(compatible: .textBackgroundColor)) + .background(Color("SwiftUI Colors/ContentBackgroundColor")) .cornerRadius(10) } } diff --git a/ClashX/Dashboard/Views/ContentTabs/Config/ConfigView.swift b/ClashX/Dashboard/Views/ContentTabs/Config/ConfigView.swift index 2b8860c..c424b06 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Config/ConfigView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Config/ConfigView.swift @@ -46,6 +46,7 @@ struct ConfigView: View { content2 .padding() } + .background(Color("SwiftUI Colors/WindowBackgroundColor")) .disabled(!configInited) .onAppear { configInited = false diff --git a/ClashX/Dashboard/Views/ContentTabs/Logs/LogsTableView.swift b/ClashX/Dashboard/Views/ContentTabs/Logs/LogsTableView.swift index 3f346dd..a10ad74 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Logs/LogsTableView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Logs/LogsTableView.swift @@ -17,6 +17,7 @@ struct LogsTableView: NSViewRepresentable { var data: [Item] var filterString: String + var logFilter: DashboardViewContoller.LogFilter class NonRespondingScrollView: NSScrollView { override var acceptsFirstResponder: Bool { false } @@ -84,6 +85,29 @@ struct LogsTableView: NSViewRepresentable { "log", ] + switch logFilter { + case .all: + break + case .rule: + re = re.filter { + $0.log.starts(with: "[Rule") + || $0.log.starts(with: "[TCP") + || $0.log.starts(with: "[UDP") + } + case .dns: + re = re.filter { + $0.log.starts(with: "[DNS") + } + case .others: + re = re.filter { + !$0.log.starts(with: "[DNS") + && !$0.log.starts(with: "[Rule") + && !$0.log.starts(with: "[TCP") + && !$0.log.starts(with: "[UDP") + } + } + + re = re.filtered(filterString, for: filterKeys) return re diff --git a/ClashX/Dashboard/Views/ContentTabs/Logs/LogsView.swift b/ClashX/Dashboard/Views/ContentTabs/Logs/LogsView.swift index d27d9c6..f11b3f4 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Logs/LogsView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Logs/LogsView.swift @@ -11,11 +11,17 @@ struct LogsView: View { @EnvironmentObject var logStorage: ClashLogStorage @State var searchString: String = "" + @State var logFilter = DashboardViewContoller.LogFilter.all + @State var logLevel = ConfigManager.selectLoggingApiLevel var body: some View { Group { - LogsTableView(data: logStorage.logs.reversed(), filterString: searchString) + LogsTableView( + data: logStorage.logs.reversed(), + filterString: searchString, + logFilter: logFilter + ) } .onAppear { guard let s = ToolbarStore.shared.searchStrings["logs"] else { return } @@ -33,6 +39,10 @@ struct LogsView: View { guard let level = $0.userInfo?["level"] as? ClashLogLevel else { return } logLevelChanged(level) } + .onReceive(NotificationCenter.default.publisher(for: .logFilterChanged)) { + guard let level = $0.userInfo?["filter"] as? DashboardViewContoller.LogFilter else { return } + logFilterChanged(level) + } } func logLevelChanged(_ level: ClashLogLevel) { @@ -40,6 +50,10 @@ struct LogsView: View { ConfigManager.selectLoggingApiLevel = level ApiRequest.shared.resetLogStreamApi() } + + func logFilterChanged(_ filter: DashboardViewContoller.LogFilter) { + logFilter = filter + } } struct LogsView_Previews: PreviewProvider { diff --git a/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewTopItemView.swift b/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewTopItemView.swift index 9ff7711..095ee96 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewTopItemView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewTopItemView.swift @@ -24,7 +24,7 @@ struct OverviewTopItemView: View { } .frame(width: 125) .padding(EdgeInsets(top: 10, leading: 13, bottom: 10, trailing: 13)) - .background(Color(compatible: .textBackgroundColor)) + .background(Color("SwiftUI Colors/ContentBackgroundColor")) .cornerRadius(10) } } diff --git a/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewView.swift b/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewView.swift index 7abae94..a0efaf5 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Overview/OverviewView.swift @@ -72,6 +72,7 @@ struct OverviewView: View { self.version = $0?.version ?? "" } } + .background(Color("SwiftUI Colors/WindowBackgroundColor")) } func updateColumnCount(_ width: Double) { diff --git a/ClashX/Dashboard/Views/ContentTabs/Providers/ProviderRowView.swift b/ClashX/Dashboard/Views/ContentTabs/Providers/ProviderRowView.swift index 1fe907c..30fb6f8 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Providers/ProviderRowView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Providers/ProviderRowView.swift @@ -23,7 +23,7 @@ struct ProviderRowView: View { VStack(spacing: 2) { HStack(alignment: .center) { Text(hideProxyNames.hide - ? String(proxyProvider.id.prefix(8)) + ? String(proxyProvider.id.hiddenID) : proxyProvider.name) .font(.system(size: 15)) Spacer() diff --git a/ClashX/Dashboard/Views/ContentTabs/Providers/ProvidersView.swift b/ClashX/Dashboard/Views/ContentTabs/Providers/ProvidersView.swift index 113481d..fecf57a 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Providers/ProvidersView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Providers/ProvidersView.swift @@ -15,11 +15,11 @@ struct ProvidersView: View { @StateObject private var hideProxyNames = HideProxyNames() var body: some View { - NavigationView { listView EmptyView() } + .background(Color("SwiftUI Colors/WindowBackgroundColor")) .onReceive(NotificationCenter.default.publisher(for: .toolbarSearchString)) { guard let string = $0.userInfo?["String"] as? String else { return } searchString.string = string diff --git a/ClashX/Dashboard/Views/ContentTabs/Providers/ProxyProviderInfoView.swift b/ClashX/Dashboard/Views/ContentTabs/Providers/ProxyProviderInfoView.swift index 003061d..465de7e 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Providers/ProxyProviderInfoView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Providers/ProxyProviderInfoView.swift @@ -36,7 +36,7 @@ struct ProxyProviderInfoView: View { var header: some View { HStack() { Text(hideProxyNames.hide - ? String(provider.id.prefix(8)) + ? String(provider.id.hiddenID) : provider.name) .font(.system(size: 17)) Text(provider.vehicleType.rawValue) diff --git a/ClashX/Dashboard/Views/ContentTabs/Providers/RuleProviderView.swift b/ClashX/Dashboard/Views/ContentTabs/Providers/RuleProviderView.swift index 1e40902..b009b0f 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Providers/RuleProviderView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Providers/RuleProviderView.swift @@ -15,7 +15,7 @@ struct RuleProviderView: View { VStack(alignment: .leading) { HStack { Text(provider.name) - .font(.title) + .font(.title2) .fontWeight(.medium) Text(provider.type) Text(provider.behavior) diff --git a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxiesView.swift b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxiesView.swift index 4fd986a..bcc6587 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxiesView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxiesView.swift @@ -33,6 +33,7 @@ struct ProxiesView: View { .listStyle(.plain) EmptyView() } + .background(Color("SwiftUI Colors/WindowBackgroundColor")) .onReceive(NotificationCenter.default.publisher(for: .toolbarSearchString)) { guard let string = $0.userInfo?["String"] as? String else { return } searchString.string = string diff --git a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupRowView.swift b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupRowView.swift index f7895d7..5527b95 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupRowView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupRowView.swift @@ -24,7 +24,7 @@ struct ProxyGroupRowView: View { VStack(spacing: 2) { HStack(alignment: .center) { Text(hideProxyNames.hide - ? String(proxyGroup.id.prefix(8)) + ? String(proxyGroup.id.hiddenID) : proxyGroup.name) .font(.system(size: 15)) Spacer() @@ -40,7 +40,7 @@ struct ProxyGroupRowView: View { Spacer() if let proxy = proxyGroup.currentProxy { Text(hideProxyNames.hide - ? String(proxy.id.prefix(8)) + ? String(proxy.id.hiddenID) : proxy.name) } } @@ -50,4 +50,3 @@ struct ProxyGroupRowView: View { .padding(EdgeInsets(top: 3, leading: 4, bottom: 3, trailing: 4)) } } - diff --git a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupView.swift b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupView.swift index d52f6ad..47a55c8 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyGroupView.swift @@ -73,7 +73,7 @@ struct ProxyGroupView: View { var proxyInfoView: some View { HStack() { Text(hideProxyNames.hide - ? String(proxyGroup.id.prefix(8)) + ? String(proxyGroup.id.hiddenID) : proxyGroup.name) .font(.system(size: 17)) Text(proxyGroup.type.rawValue) diff --git a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyNodeView.swift b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyNodeView.swift index b734388..02289cc 100644 --- a/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyNodeView.swift +++ b/ClashX/Dashboard/Views/ContentTabs/Proxies/ProxyNodeView.swift @@ -29,7 +29,7 @@ struct ProxyNodeView: View { VStack { HStack(alignment: .center) { Text(hideProxyNames.hide - ? String(proxy.id.prefix(8)) + ? String(proxy.id.hiddenID) : proxy.name) .truncationMode(.tail) .lineLimit(1) @@ -62,7 +62,7 @@ struct ProxyNodeView: View { guard selectable else { return } mouseOver = $0 } - .frame(height: 36) + .frame(height: 34) .padding(12) .overlay( RoundedRectangle(cornerRadius: 6) @@ -78,7 +78,7 @@ struct ProxyNodeView: View { .padding(1) ) - .background(now == proxy.name ? Color.accentColor.opacity(0.7) : Color(compatible: .textBackgroundColor)) + .background(now == proxy.name ? Color.accentColor.opacity(0.7) : Color("SwiftUI Colors/ContentBackgroundColor")) } } diff --git a/ClashX/Images.xcassets/SwiftUI Colors/ContentBackgroundColor.colorset/Contents.json b/ClashX/Images.xcassets/SwiftUI Colors/ContentBackgroundColor.colorset/Contents.json new file mode 100644 index 0000000..7a2b853 --- /dev/null +++ b/ClashX/Images.xcassets/SwiftUI Colors/ContentBackgroundColor.colorset/Contents.json @@ -0,0 +1,28 @@ +{ + "colors" : [ + { + "color" : { + "platform" : "osx", + "reference" : "alternatingContentBackgroundColor" + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "platform" : "osx", + "reference" : "alternatingContentBackgroundColor" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ClashX/Images.xcassets/SwiftUI Colors/Contents.json b/ClashX/Images.xcassets/SwiftUI Colors/Contents.json new file mode 100644 index 0000000..6e96565 --- /dev/null +++ b/ClashX/Images.xcassets/SwiftUI Colors/Contents.json @@ -0,0 +1,9 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + }, + "properties" : { + "provides-namespace" : true + } +} diff --git a/ClashX/Images.xcassets/SwiftUI Colors/WindowBackgroundColor.colorset/Contents.json b/ClashX/Images.xcassets/SwiftUI Colors/WindowBackgroundColor.colorset/Contents.json new file mode 100644 index 0000000..6cb3fca --- /dev/null +++ b/ClashX/Images.xcassets/SwiftUI Colors/WindowBackgroundColor.colorset/Contents.json @@ -0,0 +1,28 @@ +{ + "colors" : [ + { + "color" : { + "platform" : "osx", + "reference" : "textBackgroundColor" + }, + "idiom" : "universal" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "color" : { + "platform" : "osx", + "reference" : "textBackgroundColor" + }, + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/ClashX/Models/ClashProxy.swift b/ClashX/Models/ClashProxy.swift index 57e2bff..7c500e6 100644 --- a/ClashX/Models/ClashProxy.swift +++ b/ClashX/Models/ClashProxy.swift @@ -31,6 +31,7 @@ enum ClashProxyType: String, Codable, CaseIterable { case tuic = "Tuic" case hysteria2 = "Hysteria2" case ssh = "SSH" + case mieru = "mieru" case pass = "Pass"