Skip to content

Commit

Permalink
Merge branch 'meta-dev' into meta
Browse files Browse the repository at this point in the history
  • Loading branch information
mrFq1 committed Jan 2, 2025
2 parents b6165f4 + 0df7f0d commit 276dd00
Show file tree
Hide file tree
Showing 11 changed files with 128 additions and 56 deletions.
16 changes: 7 additions & 9 deletions ClashX/Dashboard/Models/DBProviderStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class DBProxyProvider: ObservableObject, Identifiable {
@Published var name: ClashProviderName
@Published var proxies: [DBProxy]
@Published var type: ClashProvider.ProviderType
@Published var vehicleType: ClashProvider.ProviderVehicleType
@Published var vehicleType: ClashProviderVehicleType

@Published var trafficInfo: String
@Published var trafficPercentage: String
Expand Down Expand Up @@ -69,13 +69,9 @@ class DBProxyProvider: ObservableObject, Identifiable {
trafficPercentage = "0.0%"
}

if let updatedAt = provider.updatedAt {
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .abbreviated
self.updatedAt = formatter.localizedString(for: updatedAt, relativeTo: Date())
} else {
self.updatedAt = ""
}
let formatter = RelativeDateTimeFormatter()
formatter.unitsStyle = .abbreviated
self.updatedAt = formatter.localizedString(for: provider.updatedAt, relativeTo: Date())
}

func updateInfo(_ new: DBProxyProvider) {
Expand All @@ -94,7 +90,8 @@ class DBRuleProvider: ObservableObject, Identifiable {
@Published var ruleCount: Int
@Published var behavior: String
@Published var type: String
@Published var updatedAt: Date?
@Published var vehicleType: ClashProviderVehicleType
@Published var updatedAt: Date

init(provider: ClashRuleProvider) {
id = UUID().uuidString
Expand All @@ -103,6 +100,7 @@ class DBRuleProvider: ObservableObject, Identifiable {
ruleCount = provider.ruleCount
behavior = provider.behavior
type = provider.type
vehicleType = provider.vehicleType
updatedAt = provider.updatedAt
}
}
4 changes: 3 additions & 1 deletion ClashX/Dashboard/Models/DBProxyStorage.swift
Original file line number Diff line number Diff line change
Expand Up @@ -34,13 +34,15 @@ class DBProxyGroup: ObservableObject, Identifiable {
}

@Published var proxies: [DBProxy]

@Published var currentProxy: DBProxy?

@Published var hidden: Bool

init(_ group: ClashProxy, resp: ClashProxyResp) {
name = group.name
type = group.type
now = group.now
hidden = group.hidden ?? false

proxies = group.all?.compactMap { name in
resp.proxiesMap[name]
Expand Down
47 changes: 33 additions & 14 deletions ClashX/Dashboard/Views/ContentTabs/Providers/ProvidersView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -37,33 +37,54 @@ struct ProvidersView: View {

var listView: some View {
List {
if providerStorage.proxyProviders.isEmpty,
providerStorage.ruleProviders.isEmpty {
let httpProxyProviders = providerStorage.proxyProviders.filter({ $0.vehicleType == .HTTP })
let inlineProxyProviders = providerStorage.proxyProviders.filter({ $0.vehicleType == .Inline })

let httpRuleProviders = providerStorage.ruleProviders.filter({ $0.vehicleType == .HTTP })
let inlineRuleProviders = providerStorage.ruleProviders.filter({ $0.vehicleType == .Inline })

if httpProxyProviders.isEmpty,
httpRuleProviders.isEmpty,
inlineRuleProviders.isEmpty {
Text("Empty")
.padding()
} else {
Section() {
if !providerStorage.proxyProviders.isEmpty {
if !httpProxyProviders.isEmpty {
ProxyProvidersRowView(providerStorage: providerStorage)
}
if !providerStorage.ruleProviders.isEmpty {
RuleProvidersRowView(providerStorage: providerStorage)
if !httpRuleProviders.isEmpty {
RuleProvidersRowView(providerStorage: providerStorage, vehicleType: .HTTP)
}
if !inlineRuleProviders.isEmpty {
RuleProvidersRowView(providerStorage: providerStorage, vehicleType: .Inline)
}
} header: {
Text("Providers")
}
}

if !providerStorage.proxyProviders.isEmpty {
if httpProxyProviders.count > 0 {
Text("")
Section() {
ForEach(providerStorage.proxyProviders,id: \.id) {
ForEach(httpProxyProviders,id: \.id) {
ProviderRowView(proxyProvider: $0)
}
} header: {
Text("Proxy Provider")
}
}

if inlineProxyProviders.count > 0 {
Text("")
Section() {
ForEach(inlineProxyProviders,id: \.id) {
ProviderRowView(proxyProvider: $0)
}
} header: {
Text("Proxy Provider Inline")
}
}
}
.introspect(.table, on: .macOS(.v12, .v13, .v14, .v15)) {
$0.refusesFirstResponder = true
Expand All @@ -74,18 +95,16 @@ struct ProvidersView: View {

func loadProviders() {
ApiRequest.requestProxyProviderList { resp in
providerStorage.proxyProviders = resp.allProviders.values.filter {
$0.vehicleType == .HTTP
}.sorted {
providerStorage.proxyProviders = resp.allProviders.values.sorted {
$0.name < $1.name
}
.map(DBProxyProvider.init)
}
ApiRequest.requestRuleProviderList { resp in
providerStorage.ruleProviders = resp.allProviders.values.sorted {
$0.name < $1.name
}
.map(DBRuleProvider.init)
providerStorage.ruleProviders = resp.allProviders.values.sorted {
$0.name < $1.name
}
.map(DBRuleProvider.init)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,17 @@ struct ProxyProvidersRowView: View {
@State private var isUpdating = false

var providers: [DBProxyProvider] {
var pp = [DBProxyProvider]()
if searchString.string.isEmpty {
return providerStorage.proxyProviders
pp = providerStorage.proxyProviders
} else {
return providerStorage.proxyProviders.filter {
pp = providerStorage.proxyProviders.filter {
$0.name.lowercased().contains(searchString.string.lowercased())
}
}
return pp.filter {
$0.vehicleType == .HTTP
}
}

var body: some View {
Expand Down Expand Up @@ -52,7 +56,7 @@ struct ProxyProvidersRowView: View {
}

var listView: some View {
ForEach(providers, id: \.id) { provider in
ForEach(providers, id: \.id) { provider in
ProxyProviderInfoView(provider: provider, withUpdateButton: true)
}
}
Expand All @@ -62,7 +66,7 @@ struct ProxyProvidersRowView: View {

ApiRequest.updateAllProviders(for: .proxy) { _ in
ApiRequest.requestProxyProviderList { resp in
providerStorage.proxyProviders = resp.allProviders.values.filter {
providerStorage.proxyProviders = resp.allProviders.values.filter {
$0.vehicleType == .HTTP
}.sorted {
$0.name < $1.name
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,7 @@ struct RuleProviderView: View {

HStack {
Text("\(provider.ruleCount) rules")
if let date = provider.updatedAt {
Text("Updated \(RelativeDateTimeFormatter().localizedString(for: date, relativeTo: Date()))")
}
Text("Updated \(RelativeDateTimeFormatter().localizedString(for: provider.updatedAt, relativeTo: Date()))")
Spacer()
}
.font(.system(size: 12))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,25 +9,30 @@ import SwiftUI
struct RuleProvidersRowView: View {

@ObservedObject var providerStorage: DBProviderStorage
@State var vehicleType: ClashProviderVehicleType

@EnvironmentObject var searchString: ProxiesSearchString

@State private var isUpdating = false

var providers: [DBRuleProvider] {
var pp = [DBRuleProvider]()
if searchString.string.isEmpty {
return providerStorage.ruleProviders
pp = providerStorage.ruleProviders
} else {
return providerStorage.ruleProviders.filter {
pp = providerStorage.ruleProviders.filter {
$0.name.lowercased().contains(searchString.string.lowercased())
}
}
return pp.filter {
$0.vehicleType == vehicleType
}
}
var body: some View {
NavigationLink {
contentView
} label: {
Text("Rule")
Text(vehicleType == .HTTP ? "Rule" : "Rule Inline")
.font(.system(size: 15))
.padding(EdgeInsets(top: 2, leading: 4, bottom: 2, trailing: 4))
}
Expand All @@ -42,13 +47,15 @@ struct RuleProvidersRowView: View {
}
}
} header: {
ProgressButton(
title: "Update All",
title2: "Updating",
iconName: "arrow.clockwise",
inProgress: $isUpdating) {
updateAll()
}
if vehicleType == .HTTP {
ProgressButton(
title: "Update All",
title2: "Updating",
iconName: "arrow.clockwise",
inProgress: $isUpdating) {
updateAll()
}
}
}
.padding()
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ struct ProxiesView: View {

var body: some View {
NavigationView {
List(proxyStorage.groups, id: \.id) { group in
List(proxyStorage.groups.filter({ !$0.hidden }), id: \.id) { group in
ProxyGroupRowView(proxyGroup: group)
}
.introspect(.table, on: .macOS(.v12, .v13, .v14, .v15)) {
Expand Down
4 changes: 4 additions & 0 deletions ClashX/General/Managers/MenuItemFactory.swift
Original file line number Diff line number Diff line change
Expand Up @@ -331,6 +331,10 @@ extension MenuItemFactory {

static func refreshRuleProviderMenuItems(_ ruleProviders: [ClashRuleProvider]) {
let app = AppDelegate.shared

let ruleProviders = ruleProviders.filter {
$0.vehicleType == .HTTP
}
let isEmpty = ruleProviders.count == 0
app.ruleProvidersMenuItem.isEnabled = !isEmpty

Expand Down
39 changes: 31 additions & 8 deletions ClashX/Models/ClashProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -31,22 +31,45 @@ class ClashProvider: Codable {
enum ProviderType: String, Codable {
case Proxy
case String
}

enum ProviderVehicleType: String, Codable {
case HTTP
case File
case Compatible
case Unknown
}

let name: ClashProviderName
let proxies: [ClashProxy]
let type: ProviderType
let vehicleType: ProviderVehicleType
let updatedAt: Date?
let vehicleType: ClashProviderVehicleType
let updatedAt: Date

let subscriptionInfo: ClashProviderSubInfo?


private enum CodingKeys: String, CodingKey {
case name, proxies, type, vehicleType, updatedAt, subscriptionInfo
}

required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(ClashProviderName.self, forKey: .name)
proxies = try container.decode([ClashProxy].self, forKey: .proxies)
type = (try? container.decode(ProviderType.self, forKey: .type)) ?? .Unknown
vehicleType = try container.decode(ClashProviderVehicleType.self, forKey: .vehicleType)
updatedAt = (try? container.decode(Date.self, forKey: .updatedAt)) ?? .init(timeIntervalSince1970: 0)
subscriptionInfo = try? container.decode(ClashProviderSubInfo.self, forKey: .subscriptionInfo)
}
}

enum ClashProviderVehicleType: String, Codable, CaseIterable {
case HTTP
case File
case Compatible
case Inline
case Unknown

init(from decoder: Decoder) throws {
let container = try decoder.singleValueContainer()
let rawString = try container.decode(String.self)
self = ClashProviderVehicleType.allCases.first(where: { $0.rawValue.caseInsensitiveCompare(rawString) == .orderedSame }) ?? .Unknown
}
}

class ClashProviderSubInfo: Codable {
Expand Down
21 changes: 19 additions & 2 deletions ClashX/Models/ClashRuleProvider.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,26 @@ class ClashRuleProviderResp: Codable {
}

class ClashRuleProvider: NSObject, Codable {

@objc let name: ClashProviderName
let ruleCount: Int
@objc let behavior: String
@objc let type: String
let updatedAt: Date?
@objc let type: String
let updatedAt: Date
let vehicleType: ClashProviderVehicleType

private enum CodingKeys: String, CodingKey {
case name, ruleCount, behavior, type, updatedAt, vehicleType
}

required init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
name = try container.decode(ClashProviderName.self, forKey: .name)
ruleCount = try container.decode(Int.self, forKey: .ruleCount)
behavior = try container.decode(String.self, forKey: .behavior)
type = try container.decode(String.self, forKey: .type)
vehicleType = try container.decode(ClashProviderVehicleType.self, forKey: .vehicleType)
updatedAt = (try? container.decode(Date.self, forKey: .updatedAt)) ?? .init(timeIntervalSince1970: 0)
}

}
4 changes: 2 additions & 2 deletions ClashX/zh-Hans.lproj/Main.strings
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"3Da-fL-Mzr.title" = "日志等级";

/* Class = "NSMenuItem"; title = "Proxy providers"; ObjectID = "4Jz-gx-7X9"; */
"4Jz-gx-7X9.title" = "代理 Prividers";
"4Jz-gx-7X9.title" = "代理 Providers";

/* Class = "NSButtonCell"; title = "Add"; ObjectID = "51K-nB-xLS"; */
"51K-nB-xLS.title" = "添加";
Expand Down Expand Up @@ -62,7 +62,7 @@
"C79-J5-30z.headerCell.title" = "链接";

/* Class = "NSMenuItem"; title = "Rule providers"; ObjectID = "cJg-BS-yk2"; */
"cJg-BS-yk2.title" = "规则 Prividers";
"cJg-BS-yk2.title" = "规则 Providers";

/* Class = "NSMenuItem"; title = "Benchmark"; ObjectID = "COu-UX-bww"; */
"COu-UX-bww.title" = "延迟测速";
Expand Down

0 comments on commit 276dd00

Please sign in to comment.