mirror of
https://github.com/yJason/ClashX-Dashboard.git
synced 2026-02-04 10:02:26 +08:00
refactor: DBConnectionSnapShot
This commit is contained in:
@@ -20,12 +20,13 @@
|
|||||||
0172F1352A1FB0B900EE2B6D /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1342A1FB0B900EE2B6D /* ConfigManager.swift */; };
|
0172F1352A1FB0B900EE2B6D /* ConfigManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1342A1FB0B900EE2B6D /* ConfigManager.swift */; };
|
||||||
0172F1372A1FB0CD00EE2B6D /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1362A1FB0CD00EE2B6D /* ApiRequest.swift */; };
|
0172F1372A1FB0CD00EE2B6D /* ApiRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1362A1FB0CD00EE2B6D /* ApiRequest.swift */; };
|
||||||
0172F1392A1FB0E900EE2B6D /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1382A1FB0E900EE2B6D /* Logger.swift */; };
|
0172F1392A1FB0E900EE2B6D /* Logger.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1382A1FB0E900EE2B6D /* Logger.swift */; };
|
||||||
0172F1412A1FB10D00EE2B6D /* ClashConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13B2A1FB10C00EE2B6D /* ClashConnection.swift */; };
|
0172F1412A1FB10D00EE2B6D /* DBConnectionSnapShot.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13B2A1FB10C00EE2B6D /* DBConnectionSnapShot.swift */; };
|
||||||
0172F1422A1FB10D00EE2B6D /* ClashRuleProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13C2A1FB10D00EE2B6D /* ClashRuleProvider.swift */; };
|
0172F1422A1FB10D00EE2B6D /* ClashRuleProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13C2A1FB10D00EE2B6D /* ClashRuleProvider.swift */; };
|
||||||
0172F1432A1FB10D00EE2B6D /* ClashRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */; };
|
0172F1432A1FB10D00EE2B6D /* ClashRule.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */; };
|
||||||
0172F1442A1FB10D00EE2B6D /* ClashConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */; };
|
0172F1442A1FB10D00EE2B6D /* ClashConfig.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */; };
|
||||||
0172F1452A1FB10D00EE2B6D /* ClashProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */; };
|
0172F1452A1FB10D00EE2B6D /* ClashProvider.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */; };
|
||||||
0172F1462A1FB10D00EE2B6D /* ClashProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */; };
|
0172F1462A1FB10D00EE2B6D /* ClashProxy.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */; };
|
||||||
|
0172F1482A1FB90200EE2B6D /* ClashConnection.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0172F1472A1FB90200EE2B6D /* ClashConnection.swift */; };
|
||||||
017753C029EF7FB2006999DB /* APIServerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017753BF29EF7FB1006999DB /* APIServerItem.swift */; };
|
017753C029EF7FB2006999DB /* APIServerItem.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017753BF29EF7FB1006999DB /* APIServerItem.swift */; };
|
||||||
017DCADD29E83BFD00B9622A /* RuleProviderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017DCADC29E83BFD00B9622A /* RuleProviderView.swift */; };
|
017DCADD29E83BFD00B9622A /* RuleProviderView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 017DCADC29E83BFD00B9622A /* RuleProviderView.swift */; };
|
||||||
017F9AAA2A0DFEBD00B81497 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 017F9AA92A0DFEBD00B81497 /* Introspect */; };
|
017F9AAA2A0DFEBD00B81497 /* Introspect in Frameworks */ = {isa = PBXBuildFile; productRef = 017F9AA92A0DFEBD00B81497 /* Introspect */; };
|
||||||
@@ -80,12 +81,13 @@
|
|||||||
0172F1342A1FB0B900EE2B6D /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
|
0172F1342A1FB0B900EE2B6D /* ConfigManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ConfigManager.swift; sourceTree = "<group>"; };
|
||||||
0172F1362A1FB0CD00EE2B6D /* ApiRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
|
0172F1362A1FB0CD00EE2B6D /* ApiRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ApiRequest.swift; sourceTree = "<group>"; };
|
||||||
0172F1382A1FB0E900EE2B6D /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
0172F1382A1FB0E900EE2B6D /* Logger.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Logger.swift; sourceTree = "<group>"; };
|
||||||
0172F13B2A1FB10C00EE2B6D /* ClashConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashConnection.swift; sourceTree = "<group>"; };
|
0172F13B2A1FB10C00EE2B6D /* DBConnectionSnapShot.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DBConnectionSnapShot.swift; sourceTree = "<group>"; };
|
||||||
0172F13C2A1FB10D00EE2B6D /* ClashRuleProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashRuleProvider.swift; sourceTree = "<group>"; };
|
0172F13C2A1FB10D00EE2B6D /* ClashRuleProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashRuleProvider.swift; sourceTree = "<group>"; };
|
||||||
0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashRule.swift; sourceTree = "<group>"; };
|
0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashRule.swift; sourceTree = "<group>"; };
|
||||||
0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashConfig.swift; sourceTree = "<group>"; };
|
0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashConfig.swift; sourceTree = "<group>"; };
|
||||||
0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashProvider.swift; sourceTree = "<group>"; };
|
0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashProvider.swift; sourceTree = "<group>"; };
|
||||||
0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashProxy.swift; sourceTree = "<group>"; };
|
0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashProxy.swift; sourceTree = "<group>"; };
|
||||||
|
0172F1472A1FB90200EE2B6D /* ClashConnection.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ClashConnection.swift; sourceTree = "<group>"; };
|
||||||
017753BF29EF7FB1006999DB /* APIServerItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIServerItem.swift; sourceTree = "<group>"; };
|
017753BF29EF7FB1006999DB /* APIServerItem.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = APIServerItem.swift; sourceTree = "<group>"; };
|
||||||
017DCADC29E83BFD00B9622A /* RuleProviderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleProviderView.swift; sourceTree = "<group>"; };
|
017DCADC29E83BFD00B9622A /* RuleProviderView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RuleProviderView.swift; sourceTree = "<group>"; };
|
||||||
017F9AAB2A0E0B2300B81497 /* ProxyGroupRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyGroupRowView.swift; sourceTree = "<group>"; };
|
017F9AAB2A0E0B2300B81497 /* ProxyGroupRowView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProxyGroupRowView.swift; sourceTree = "<group>"; };
|
||||||
@@ -179,7 +181,7 @@
|
|||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */,
|
0172F13E2A1FB10D00EE2B6D /* ClashConfig.swift */,
|
||||||
0172F13B2A1FB10C00EE2B6D /* ClashConnection.swift */,
|
0172F1472A1FB90200EE2B6D /* ClashConnection.swift */,
|
||||||
0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */,
|
0172F13F2A1FB10D00EE2B6D /* ClashProvider.swift */,
|
||||||
0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */,
|
0172F1402A1FB10D00EE2B6D /* ClashProxy.swift */,
|
||||||
0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */,
|
0172F13D2A1FB10D00EE2B6D /* ClashRule.swift */,
|
||||||
@@ -344,6 +346,7 @@
|
|||||||
children = (
|
children = (
|
||||||
01A3EF032A120103003038B5 /* DBProxyStorage.swift */,
|
01A3EF032A120103003038B5 /* DBProxyStorage.swift */,
|
||||||
01505C492A147B84001ACC4F /* DBProviderStorage.swift */,
|
01505C492A147B84001ACC4F /* DBProviderStorage.swift */,
|
||||||
|
0172F13B2A1FB10C00EE2B6D /* DBConnectionSnapShot.swift */,
|
||||||
);
|
);
|
||||||
path = Models;
|
path = Models;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
@@ -455,7 +458,7 @@
|
|||||||
0192318029DD5E0B00539EDD /* LogsView.swift in Sources */,
|
0192318029DD5E0B00539EDD /* LogsView.swift in Sources */,
|
||||||
0172F1392A1FB0E900EE2B6D /* Logger.swift in Sources */,
|
0172F1392A1FB0E900EE2B6D /* Logger.swift in Sources */,
|
||||||
01505C4E2A14AAEB001ACC4F /* ProviderProxiesView.swift in Sources */,
|
01505C4E2A14AAEB001ACC4F /* ProviderProxiesView.swift in Sources */,
|
||||||
0172F1412A1FB10D00EE2B6D /* ClashConnection.swift in Sources */,
|
0172F1412A1FB10D00EE2B6D /* DBConnectionSnapShot.swift in Sources */,
|
||||||
0192318529DD7DCD00539EDD /* SidebarItemView.swift in Sources */,
|
0192318529DD7DCD00539EDD /* SidebarItemView.swift in Sources */,
|
||||||
0172F1442A1FB10D00EE2B6D /* ClashConfig.swift in Sources */,
|
0172F1442A1FB10D00EE2B6D /* ClashConfig.swift in Sources */,
|
||||||
0172F1452A1FB10D00EE2B6D /* ClashProvider.swift in Sources */,
|
0172F1452A1FB10D00EE2B6D /* ClashProvider.swift in Sources */,
|
||||||
@@ -489,6 +492,7 @@
|
|||||||
015278082A15F9FD00516236 /* ProxyProviderInfoView.swift in Sources */,
|
015278082A15F9FD00516236 /* ProxyProviderInfoView.swift in Sources */,
|
||||||
0192317829DD5DA500539EDD /* ProxiesView.swift in Sources */,
|
0192317829DD5DA500539EDD /* ProxiesView.swift in Sources */,
|
||||||
01F885CF29DFD8DF008241EB /* CollectionsTableView.swift in Sources */,
|
01F885CF29DFD8DF008241EB /* CollectionsTableView.swift in Sources */,
|
||||||
|
0172F1482A1FB90200EE2B6D /* ClashConnection.swift in Sources */,
|
||||||
018AFEA52A1B5F7A0076E66B /* ProgressButton.swift in Sources */,
|
018AFEA52A1B5F7A0076E66B /* ProgressButton.swift in Sources */,
|
||||||
01505C4A2A147B84001ACC4F /* DBProviderStorage.swift in Sources */,
|
01505C4A2A147B84001ACC4F /* DBProviderStorage.swift in Sources */,
|
||||||
0172CB5129E5AE670072DDEF /* SwiftUIViewExtensions.swift in Sources */,
|
0172CB5129E5AE670072DDEF /* SwiftUIViewExtensions.swift in Sources */,
|
||||||
|
|||||||
@@ -284,24 +284,24 @@ class ApiRequest {
|
|||||||
// MARK: - Connections
|
// MARK: - Connections
|
||||||
|
|
||||||
extension ApiRequest {
|
extension ApiRequest {
|
||||||
static func getConnections(completeHandler: @escaping (ClashConnectionSnapShot) -> Void) {
|
static func getConnections(completeHandler: @escaping (DBConnectionSnapShot) -> Void) {
|
||||||
|
|
||||||
let decoder = JSONDecoder()
|
let decoder = JSONDecoder()
|
||||||
decoder.dateDecodingStrategy = .formatted(DateFormatter.js)
|
decoder.dateDecodingStrategy = .formatted(DateFormatter.js)
|
||||||
|
|
||||||
req("/connections").responseDecodable(of: ClashConnectionSnapShot.self, decoder: decoder) { resp in
|
req("/connections").responseDecodable(of: DBConnectionSnapShot.self, decoder: decoder) { resp in
|
||||||
switch resp.result {
|
switch resp.result {
|
||||||
case let .success(snapshot):
|
case let .success(snapshot):
|
||||||
completeHandler(snapshot)
|
completeHandler(snapshot)
|
||||||
case .failure:
|
case .failure:
|
||||||
return
|
return
|
||||||
// assertionFailure()
|
// assertionFailure()
|
||||||
// completeHandler(ClashConnectionSnapShot())
|
// completeHandler(DBConnectionSnapShot())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static func closeConnection(_ conn: ClashConnection) {
|
static func closeConnection(_ conn: ClashConnectionSnapShot.Connection) {
|
||||||
req("/connections/".appending(conn.id), method: .delete).response { _ in }
|
req("/connections/".appending(conn.id), method: .delete).response { _ in }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,104 +7,14 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Cocoa
|
import Cocoa
|
||||||
import DifferenceKit
|
|
||||||
|
|
||||||
struct ClashConnectionSnapShot: Codable {
|
struct ClashConnectionSnapShot: Codable {
|
||||||
let downloadTotal: Int
|
let connections: [Connection]
|
||||||
let uploadTotal: Int
|
|
||||||
let connections: [ClashConnection]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct ClashConnection: Codable, Hashable {
|
extension ClashConnectionSnapShot {
|
||||||
let id: String
|
struct Connection: Codable {
|
||||||
let chains: [String]
|
let id: String
|
||||||
let upload: Int64
|
let chains: [String]
|
||||||
let download: Int64
|
}
|
||||||
let start: Date
|
|
||||||
let rule: String
|
|
||||||
let rulePayload: String
|
|
||||||
|
|
||||||
let metadata: MetaConnectionData
|
|
||||||
}
|
|
||||||
|
|
||||||
struct MetaConnectionData: Codable, Hashable {
|
|
||||||
let uid: Int
|
|
||||||
|
|
||||||
let network: String
|
|
||||||
let type: String
|
|
||||||
let sourceIP: String
|
|
||||||
let destinationIP: String
|
|
||||||
let sourcePort: String
|
|
||||||
let destinationPort: String
|
|
||||||
let inboundIP: String
|
|
||||||
let inboundPort: String
|
|
||||||
let inboundName: String
|
|
||||||
let host: String
|
|
||||||
let dnsMode: String
|
|
||||||
let process: String
|
|
||||||
let processPath: String
|
|
||||||
let specialProxy: String
|
|
||||||
let specialRules: String
|
|
||||||
let remoteDestination: String
|
|
||||||
let sniffHost: String
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
class ClashConnectionObject: NSObject, Differentiable {
|
|
||||||
@objc let id: String
|
|
||||||
@objc let host: String
|
|
||||||
@objc let sniffHost: String
|
|
||||||
@objc let process: String
|
|
||||||
@objc let download: Int64
|
|
||||||
@objc let upload: Int64
|
|
||||||
let downloadString: String
|
|
||||||
let uploadString: String
|
|
||||||
let chains: [String]
|
|
||||||
@objc let chainString: String
|
|
||||||
@objc let ruleString: String
|
|
||||||
@objc let startDate: Date
|
|
||||||
let startString: String
|
|
||||||
@objc let source: String
|
|
||||||
@objc let destinationIP: String?
|
|
||||||
@objc let type: String
|
|
||||||
|
|
||||||
var differenceIdentifier: String {
|
|
||||||
return id
|
|
||||||
}
|
|
||||||
|
|
||||||
func isContentEqual(to source: ClashConnectionObject) -> Bool {
|
|
||||||
download == source.download &&
|
|
||||||
upload == source.upload &&
|
|
||||||
startString == source.startString
|
|
||||||
}
|
|
||||||
|
|
||||||
init(_ conn: ClashConnection) {
|
|
||||||
let byteCountFormatter = ByteCountFormatter()
|
|
||||||
let startFormatter = RelativeDateTimeFormatter()
|
|
||||||
startFormatter.unitsStyle = .short
|
|
||||||
|
|
||||||
let metadata = conn.metadata
|
|
||||||
|
|
||||||
id = conn.id
|
|
||||||
host = "\(metadata.host == "" ? metadata.destinationIP : metadata.host):\(metadata.destinationPort)"
|
|
||||||
sniffHost = metadata.sniffHost == "" ? "-" : metadata.sniffHost
|
|
||||||
process = metadata.process
|
|
||||||
download = conn.download
|
|
||||||
downloadString = byteCountFormatter.string(fromByteCount: conn.download)
|
|
||||||
upload = conn.upload
|
|
||||||
uploadString = byteCountFormatter.string(fromByteCount: conn.upload)
|
|
||||||
chains = conn.chains
|
|
||||||
chainString = conn.chains.reversed().joined(separator: "/")
|
|
||||||
ruleString = conn.rulePayload == "" ? conn.rule : "\(conn.rule) :: \(conn.rulePayload)"
|
|
||||||
startDate = conn.start
|
|
||||||
startString = startFormatter.localizedString(for: conn.start, relativeTo: Date())
|
|
||||||
source = "\(metadata.sourceIP):\(metadata.sourcePort)"
|
|
||||||
destinationIP = [metadata.remoteDestination,
|
|
||||||
metadata.destinationIP,
|
|
||||||
metadata.host].first(where: { $0 != "" })
|
|
||||||
|
|
||||||
type = "\(metadata.type)(\(metadata.network))"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
108
ClashX Dashboard/Models/DBConnectionSnapShot.swift
Normal file
108
ClashX Dashboard/Models/DBConnectionSnapShot.swift
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
//
|
||||||
|
// DBConnectionSnapShot.swift
|
||||||
|
// ClashX Dashboard
|
||||||
|
//
|
||||||
|
//
|
||||||
|
|
||||||
|
import Cocoa
|
||||||
|
import DifferenceKit
|
||||||
|
|
||||||
|
struct DBConnectionSnapShot: Codable {
|
||||||
|
let downloadTotal: Int
|
||||||
|
let uploadTotal: Int
|
||||||
|
let connections: [DBConnection]
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DBConnection: Codable, Hashable {
|
||||||
|
let id: String
|
||||||
|
let chains: [String]
|
||||||
|
let upload: Int64
|
||||||
|
let download: Int64
|
||||||
|
let start: Date
|
||||||
|
let rule: String
|
||||||
|
let rulePayload: String
|
||||||
|
|
||||||
|
let metadata: DBMetaConnectionData
|
||||||
|
}
|
||||||
|
|
||||||
|
struct DBMetaConnectionData: Codable, Hashable {
|
||||||
|
let uid: Int
|
||||||
|
|
||||||
|
let network: String
|
||||||
|
let type: String
|
||||||
|
let sourceIP: String
|
||||||
|
let destinationIP: String
|
||||||
|
let sourcePort: String
|
||||||
|
let destinationPort: String
|
||||||
|
let inboundIP: String
|
||||||
|
let inboundPort: String
|
||||||
|
let inboundName: String
|
||||||
|
let host: String
|
||||||
|
let dnsMode: String
|
||||||
|
let process: String
|
||||||
|
let processPath: String
|
||||||
|
let specialProxy: String
|
||||||
|
let specialRules: String
|
||||||
|
let remoteDestination: String
|
||||||
|
let sniffHost: String
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
class DBConnectionObject: NSObject, Differentiable {
|
||||||
|
@objc let id: String
|
||||||
|
@objc let host: String
|
||||||
|
@objc let sniffHost: String
|
||||||
|
@objc let process: String
|
||||||
|
@objc let download: Int64
|
||||||
|
@objc let upload: Int64
|
||||||
|
let downloadString: String
|
||||||
|
let uploadString: String
|
||||||
|
let chains: [String]
|
||||||
|
@objc let chainString: String
|
||||||
|
@objc let ruleString: String
|
||||||
|
@objc let startDate: Date
|
||||||
|
let startString: String
|
||||||
|
@objc let source: String
|
||||||
|
@objc let destinationIP: String?
|
||||||
|
@objc let type: String
|
||||||
|
|
||||||
|
var differenceIdentifier: String {
|
||||||
|
return id
|
||||||
|
}
|
||||||
|
|
||||||
|
func isContentEqual(to source: DBConnectionObject) -> Bool {
|
||||||
|
download == source.download &&
|
||||||
|
upload == source.upload &&
|
||||||
|
startString == source.startString
|
||||||
|
}
|
||||||
|
|
||||||
|
init(_ conn: DBConnection) {
|
||||||
|
let byteCountFormatter = ByteCountFormatter()
|
||||||
|
let startFormatter = RelativeDateTimeFormatter()
|
||||||
|
startFormatter.unitsStyle = .short
|
||||||
|
|
||||||
|
let metadata = conn.metadata
|
||||||
|
|
||||||
|
id = conn.id
|
||||||
|
host = "\(metadata.host == "" ? metadata.destinationIP : metadata.host):\(metadata.destinationPort)"
|
||||||
|
sniffHost = metadata.sniffHost == "" ? "-" : metadata.sniffHost
|
||||||
|
process = metadata.process
|
||||||
|
download = conn.download
|
||||||
|
downloadString = byteCountFormatter.string(fromByteCount: conn.download)
|
||||||
|
upload = conn.upload
|
||||||
|
uploadString = byteCountFormatter.string(fromByteCount: conn.upload)
|
||||||
|
chains = conn.chains
|
||||||
|
chainString = conn.chains.reversed().joined(separator: "/")
|
||||||
|
ruleString = conn.rulePayload == "" ? conn.rule : "\(conn.rule) :: \(conn.rulePayload)"
|
||||||
|
startDate = conn.start
|
||||||
|
startString = startFormatter.localizedString(for: conn.start, relativeTo: Date())
|
||||||
|
source = "\(metadata.sourceIP):\(metadata.sourcePort)"
|
||||||
|
destinationIP = [metadata.remoteDestination,
|
||||||
|
metadata.destinationIP,
|
||||||
|
metadata.host].first(where: { $0 != "" })
|
||||||
|
|
||||||
|
type = "\(metadata.type)(\(metadata.network))"
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
@@ -148,5 +148,5 @@ class ClashLogStorage: ObservableObject {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class ClashConnsStorage: ObservableObject {
|
class ClashConnsStorage: ObservableObject {
|
||||||
@Published var conns = [ClashConnection]()
|
@Published var conns = [DBConnection]()
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -72,27 +72,27 @@ struct CollectionsTableView<Item: Hashable>: NSViewRepresentable {
|
|||||||
|
|
||||||
switch $0 {
|
switch $0 {
|
||||||
case .host:
|
case .host:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.host, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.host, ascending: true)
|
||||||
case .sniffHost:
|
case .sniffHost:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.sniffHost, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.sniffHost, ascending: true)
|
||||||
case .process:
|
case .process:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.process, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.process, ascending: true)
|
||||||
case .dl:
|
case .dl:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.download, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.download, ascending: true)
|
||||||
case .ul:
|
case .ul:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.upload, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.upload, ascending: true)
|
||||||
case .chain:
|
case .chain:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.chainString, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.chainString, ascending: true)
|
||||||
case .rule:
|
case .rule:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.ruleString, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.ruleString, ascending: true)
|
||||||
case .time:
|
case .time:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.startDate, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.startDate, ascending: true)
|
||||||
case .source:
|
case .source:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.source, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.source, ascending: true)
|
||||||
case .destinationIP:
|
case .destinationIP:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.destinationIP, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.destinationIP, ascending: true)
|
||||||
case .type:
|
case .type:
|
||||||
sort = .init(keyPath: \ClashConnectionObject.type, ascending: true)
|
sort = .init(keyPath: \DBConnectionObject.type, ascending: true)
|
||||||
default:
|
default:
|
||||||
sort = nil
|
sort = nil
|
||||||
}
|
}
|
||||||
@@ -114,11 +114,11 @@ struct CollectionsTableView<Item: Hashable>: NSViewRepresentable {
|
|||||||
func updateNSView(_ nsView: NSScrollView, context: Context) {
|
func updateNSView(_ nsView: NSScrollView, context: Context) {
|
||||||
context.coordinator.parent = self
|
context.coordinator.parent = self
|
||||||
guard let tableView = nsView.documentView as? NSTableView,
|
guard let tableView = nsView.documentView as? NSTableView,
|
||||||
let data = data as? [ClashConnection] else {
|
let data = data as? [DBConnection] else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let target = updateSorts(data.map(ClashConnectionObject.init), tableView: tableView)
|
let target = updateSorts(data.map(DBConnectionObject.init), tableView: tableView)
|
||||||
|
|
||||||
let source = context.coordinator.conns
|
let source = context.coordinator.conns
|
||||||
let changeset = StagedChangeset(source: source, target: target)
|
let changeset = StagedChangeset(source: source, target: target)
|
||||||
@@ -129,12 +129,12 @@ struct CollectionsTableView<Item: Hashable>: NSViewRepresentable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateSorts(_ objects: [ClashConnectionObject],
|
func updateSorts(_ objects: [DBConnectionObject],
|
||||||
tableView: NSTableView) -> [ClashConnectionObject] {
|
tableView: NSTableView) -> [DBConnectionObject] {
|
||||||
var re = objects
|
var re = objects
|
||||||
|
|
||||||
var sortDescriptors = tableView.sortDescriptors
|
var sortDescriptors = tableView.sortDescriptors
|
||||||
sortDescriptors.append(.init(keyPath: \ClashConnectionObject.id, ascending: true))
|
sortDescriptors.append(.init(keyPath: \DBConnectionObject.id, ascending: true))
|
||||||
re = re.sorted(descriptors: sortDescriptors)
|
re = re.sorted(descriptors: sortDescriptors)
|
||||||
|
|
||||||
let filterKeys = [
|
let filterKeys = [
|
||||||
@@ -161,7 +161,7 @@ struct CollectionsTableView<Item: Hashable>: NSViewRepresentable {
|
|||||||
|
|
||||||
var parent: CollectionsTableView
|
var parent: CollectionsTableView
|
||||||
|
|
||||||
var conns = [ClashConnectionObject]()
|
var conns = [DBConnectionObject]()
|
||||||
|
|
||||||
init(parent: CollectionsTableView) {
|
init(parent: CollectionsTableView) {
|
||||||
self.parent = parent
|
self.parent = parent
|
||||||
|
|||||||
Reference in New Issue
Block a user