From 8bcc73fc92f404bd82c900ee238ff9b956554e8a Mon Sep 17 00:00:00 2001 From: nookery Date: Tue, 26 Dec 2023 16:34:22 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=88=97=E8=A1=A8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TravelMode.xcodeproj/project.pbxproj | 4 ++ TravelMode/Bootstrap/RootView.swift | 1 + TravelMode/View/AppLine.swift | 62 +++++++++++++++++++++++++++ TravelMode/View/AppList.swift | 37 +++------------- TravelMode/View/ContentView.swift | 4 +- TravelMode/View/Toolbar.swift | 22 +++++----- TravelMode/ViewModel/AppManager.swift | 2 +- 7 files changed, 89 insertions(+), 43 deletions(-) create mode 100644 TravelMode/View/AppLine.swift diff --git a/TravelMode.xcodeproj/project.pbxproj b/TravelMode.xcodeproj/project.pbxproj index a292de2..93a05c6 100644 --- a/TravelMode.xcodeproj/project.pbxproj +++ b/TravelMode.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + 0B19F0C52B3AB6AB002D8FAC /* AppLine.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B19F0C42B3AB6AB002D8FAC /* AppLine.swift */; }; 0B1C33FC2B39C1E7004A5E36 /* SmartApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B1C33FB2B39C1E7004A5E36 /* SmartApp.swift */; }; 0B1C33FE2B39C2AA004A5E36 /* Toolbar.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B1C33FD2B39C2AA004A5E36 /* Toolbar.swift */; }; 0B1D14982B3A63A3005A3D65 /* BackgroundView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0B1D14972B3A63A3005A3D65 /* BackgroundView.swift */; }; @@ -63,6 +64,7 @@ /* End PBXCopyFilesBuildPhase section */ /* Begin PBXFileReference section */ + 0B19F0C42B3AB6AB002D8FAC /* AppLine.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AppLine.swift; sourceTree = ""; }; 0B1C33FB2B39C1E7004A5E36 /* SmartApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SmartApp.swift; sourceTree = ""; }; 0B1C33FD2B39C2AA004A5E36 /* Toolbar.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Toolbar.swift; sourceTree = ""; }; 0B1D14972B3A63A3005A3D65 /* BackgroundView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = BackgroundView.swift; sourceTree = ""; }; @@ -184,6 +186,7 @@ children = ( 0B5B1CA92B385BF30002421E /* ContentView.swift */, 0B3399372B39277B005CC627 /* EventList.swift */, + 0B19F0C42B3AB6AB002D8FAC /* AppLine.swift */, 0B40CE412B39646100DC6771 /* AppList.swift */, 0B1C33FD2B39C2AA004A5E36 /* Toolbar.swift */, 0B1D14A32B3A9ED0005A3D65 /* DatabaseView.swift */, @@ -382,6 +385,7 @@ files = ( 0B33993A2B392B20005CC627 /* FilterStatus.swift in Sources */, 0B1C33FC2B39C1E7004A5E36 /* SmartApp.swift in Sources */, + 0B19F0C52B3AB6AB002D8FAC /* AppLine.swift in Sources */, 0B33992D2B3911F1005CC627 /* FirewallEvent.swift in Sources */, 0B408A2C2B395A77000E77DB /* NEFilterFlowExt.swift in Sources */, C4B1415C227BBC0200B26560 /* IPCConnection.swift in Sources */, diff --git a/TravelMode/Bootstrap/RootView.swift b/TravelMode/Bootstrap/RootView.swift index 44c0779..57dc6c1 100644 --- a/TravelMode/Bootstrap/RootView.swift +++ b/TravelMode/Bootstrap/RootView.swift @@ -14,6 +14,7 @@ struct RootView: View where Content: View { .environmentObject(Channel()) .environmentObject(EventManager()) .modelContainer(DBConfig.container) + .frame(minWidth: 500, minHeight: 200) } } diff --git a/TravelMode/View/AppLine.swift b/TravelMode/View/AppLine.swift new file mode 100644 index 0000000..cf71e6e --- /dev/null +++ b/TravelMode/View/AppLine.swift @@ -0,0 +1,62 @@ +import SwiftUI + +struct AppLine: View { + var app: SmartApp + + @State private var hovering: Bool = false + + private var background: some View { + ZStack { + if hovering { + BackgroundView.type1.opacity(0.4) + } else { + if !AppSetting.shouldAllow(app.id) { + Color.red.opacity(0.1) + } + } + } + } + + var body: some View { + HStack { + app.icon.frame(width: 40, height: 40) + + VStack(alignment: .leading) { + Text(app.name) + HStack(alignment: .top) { + Text("\(app.events.count)").font(.callout) + Text(app.id) + } + } + + Spacer() + + if hovering { + if AppSetting.shouldAllow(app.id) { + Button("禁止") { + AppSetting.setDeny(app.id) + } + } else { + Button("允许") { + AppSetting.setAllow(app.id) + } + } + } + } + .padding(.vertical, 5) + .padding(.horizontal, 10) + .background(background) + .scaleEffect(hovering ? 1 : 1) + .onHover(perform: { hovering in + self.hovering = hovering + }) + .frame(height: 50) + .frame(maxWidth: .infinity, maxHeight: .infinity) + } +} + +#Preview { + RootView { + ContentView() + } +} diff --git a/TravelMode/View/AppList.swift b/TravelMode/View/AppList.swift index 3691041..08bedc2 100644 --- a/TravelMode/View/AppList.swift +++ b/TravelMode/View/AppList.swift @@ -13,40 +13,17 @@ struct AppList: View { } var body: some View { - VStack { - Table(appsVisible, columns: { - TableColumn("名称") { smartApp in - HStack { - smartApp.icon.frame(width: 33) - smartApp.nameView - } - } - TableColumn("ID", value: \.id) - TableColumn("事件") { app in - Text("\(app.events.count)") - } - TableColumn("操作") { i in - if AppSetting.shouldAllow(i.id) { - HStack { - Image("dot_green").scaleEffect(0.5) - Button("禁止") { - AppSetting.setDeny(i.id) - } - } - } else { - HStack { - Image("dot_red").scaleEffect(0.5) - Button("允许") { - AppSetting.setAllow(i.id) - } - } - } + ScrollView { + VStack(spacing: 0) { + ForEach(appsVisible) { app in + AppLine(app: app) + Divider() } - }) + } } + .background(Color.white.opacity(0.95)) .onAppear { apps = SmartApp.appList - onNewEvent() } } diff --git a/TravelMode/View/ContentView.swift b/TravelMode/View/ContentView.swift index 84e4de7..0248f55 100644 --- a/TravelMode/View/ContentView.swift +++ b/TravelMode/View/ContentView.swift @@ -5,7 +5,7 @@ struct ContentView: View { @EnvironmentObject private var channel: Channel var body: some View { - VStack { + VStack(spacing: 0) { VSplitView { AppList() if app.logVisible { @@ -13,7 +13,7 @@ struct ContentView: View { } } } - .background(BackgroundView.forest) + .background(BackgroundView.type2A) .onAppear { channel.viewWillAppear() EventManager().onFilterStatusChanged({ diff --git a/TravelMode/View/Toolbar.swift b/TravelMode/View/Toolbar.swift index 6cc5a36..de618e1 100644 --- a/TravelMode/View/Toolbar.swift +++ b/TravelMode/View/Toolbar.swift @@ -6,15 +6,15 @@ struct Toolbar: View { var body: some View { HStack { - Button("数据库") { - app.databaseVisible.toggle() - } - .popover(isPresented: $app.databaseVisible, arrowEdge: .bottom) { - DatabaseView() - .frame(width: 500, height: 500) - .background(BackgroundView.type1) - .cornerRadius(10) - } +// Button("数据库") { +// app.databaseVisible.toggle() +// } +// .popover(isPresented: $app.databaseVisible, arrowEdge: .bottom) { +// DatabaseView() +// .frame(width: 500, height: 500) +// .background(BackgroundView.type1) +// .cornerRadius(10) +// } if app.logVisible { Button("隐藏日志") { @@ -51,5 +51,7 @@ struct Toolbar: View { } #Preview { - Toolbar() + RootView { + ContentView() + } } diff --git a/TravelMode/ViewModel/AppManager.swift b/TravelMode/ViewModel/AppManager.swift index 768e690..119f229 100644 --- a/TravelMode/ViewModel/AppManager.swift +++ b/TravelMode/ViewModel/AppManager.swift @@ -5,7 +5,7 @@ class AppManager: ObservableObject { @Published var status: FilterStatus = .indeterminate @Published var events: [FirewallEvent] = [] @Published var logVisible: Bool = false - @Published var databaseVisible: Bool = false + @Published var dbVisible: Bool = false func appendEvent(_ e: FirewallEvent) { self.events.append(e)