From 390e063f20755e51b2bc7c0d754df771d126966d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E4=B8=96=E7=95=8C?= Date: Wed, 20 Sep 2023 21:17:05 +0800 Subject: [PATCH] Fix preview --- .../Views/Dashboard/ActiveDashboardView.swift | 104 ++++++++++-------- .../Views/Dashboard/ExtensionStatusView.swift | 10 +- .../Views/Dashboard/OverviewView.swift | 5 +- .../Views/Groups/GroupListView.swift | 3 +- ApplicationLibrary/Views/Log/LogView.swift | 31 +++++- ApplicationLibrary/Views/NavigationPage.swift | 3 +- .../Views/Setting/SettingView.swift | 27 +++-- Library/Database/SharedPreferences.swift | 5 +- Library/Network/ExtensionProfile.swift | 12 +- Library/Shared/FilePath.swift | 2 +- MacLibrary/MainView.swift | 8 ++ SFI/MainView.swift | 8 ++ sing-box.xcodeproj/project.pbxproj | 12 +- 13 files changed, 150 insertions(+), 80 deletions(-) diff --git a/ApplicationLibrary/Views/Dashboard/ActiveDashboardView.swift b/ApplicationLibrary/Views/Dashboard/ActiveDashboardView.swift index e3897d5..94d4071 100644 --- a/ApplicationLibrary/Views/Dashboard/ActiveDashboardView.swift +++ b/ApplicationLibrary/Views/Dashboard/ActiveDashboardView.swift @@ -24,60 +24,68 @@ public struct ActiveDashboardView: View { } } } else { - VStack { - #if os(iOS) || os(tvOS) - if ApplicationLibrary.inPreview || profile.status.isConnectedStrict { - Picker("Page", selection: $selection) { - ForEach(DashboardPage.allCases) { page in - page.label + if ApplicationLibrary.inPreview { + body1 + } else { + body1 + .onChangeCompat(of: profile.status) { newStatus in + if newStatus == .connected { + Task.detached { + await doReloadSystemProxy() } } - .pickerStyle(.segmented) - #if os(iOS) - .padding([.leading, .trailing]) - .navigationBarTitleDisplayMode(.inline) - #endif - TabView(selection: $selection) { - ForEach(DashboardPage.allCases) { page in - page.contentView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) - .tag(page) - } - } - .tabViewStyle(.page(indexDisplayMode: .always)) - } else { - OverviewView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) } - #elseif os(macOS) - OverviewView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) - #endif } - #if os(iOS) || os(tvOS) - .onChangeCompat(of: scenePhase) { newValue in - if newValue == .active { - Task.detached { - await doReload() - } - } - } - .onChangeCompat(of: parentSelection.wrappedValue) { newValue in - if newValue == .dashboard { - Task.detached { - await doReload() - } - } - } - #endif - .onChangeCompat(of: profile.status) { newStatus in - if newStatus == .connected { - Task.detached { - await doReloadSystemProxy() - } - } - } - .alertBinding($alert) } } + private var body1: some View { + VStack { + #if os(iOS) || os(tvOS) + if ApplicationLibrary.inPreview || profile.status.isConnectedStrict { + Picker("Page", selection: $selection) { + ForEach(DashboardPage.allCases) { page in + page.label + } + } + .pickerStyle(.segmented) + #if os(iOS) + .padding([.leading, .trailing]) + .navigationBarTitleDisplayMode(.inline) + #endif + TabView(selection: $selection) { + ForEach(DashboardPage.allCases) { page in + page.contentView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) + .tag(page) + } + } + .tabViewStyle(.page(indexDisplayMode: .always)) + } else { + OverviewView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) + } + #elseif os(macOS) + OverviewView($profileList, $selectedProfileID, $systemProxyAvailable, $systemProxyEnabled) + #endif + } + #if os(iOS) || os(tvOS) + .onChangeCompat(of: scenePhase) { newValue in + if newValue == .active { + Task.detached { + await doReload() + } + } + } + .onChangeCompat(of: parentSelection.wrappedValue) { newValue in + if newValue == .dashboard { + Task.detached { + await doReload() + } + } + } + #endif + .alertBinding($alert) + } + private func doReload() { defer { isLoading = false @@ -87,6 +95,8 @@ public struct ActiveDashboardView: View { Profile(id: 0, name: "profile local", type: .local, path: ""), Profile(id: 1, name: "profile remote", type: .remote, path: "", lastUpdated: Date(timeIntervalSince1970: 0)), ] + systemProxyAvailable = true + systemProxyEnabled = true selectedProfileID = 0 } else { do { diff --git a/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift b/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift index 26a07ed..e3ef6e7 100644 --- a/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift +++ b/ApplicationLibrary/Views/Dashboard/ExtensionStatusView.swift @@ -27,7 +27,7 @@ public struct ExtensionStatusView: View { LazyVGrid(columns: Array(repeating: GridItem(.flexible()), count: columnCount), alignment: .leading) { if ApplicationLibrary.inPreview { StatusItem("Status") { - StatusLine("Memory", "6.4 MiB") + StatusLine("Memory", "6.4 MB") StatusLine("Goroutines", "89") } StatusItem("Connections") { @@ -36,15 +36,15 @@ public struct ExtensionStatusView: View { } StatusItem("Traffic") { StatusLine("Uplink", "38 B/s") - StatusLine("Downlink", "249 MiB/s") + StatusLine("Downlink", "249 MB/s") } StatusItem("TrafficTotal") { - StatusLine("Uplink", "52 MiB") - StatusLine("Downlink", "5.6 GiB") + StatusLine("Uplink", "52 MB") + StatusLine("Downlink", "5.6 GB") } } else if let message = commandClient.status { StatusItem("Status") { - StatusLine("Memory", LibboxFormatBytes(message.memory)) + StatusLine("Memory", LibboxFormatMemoryBytes(message.memory)) StatusLine("Goroutines", "\(message.goroutines)") } StatusItem("Connections") { diff --git a/ApplicationLibrary/Views/Dashboard/OverviewView.swift b/ApplicationLibrary/Views/Dashboard/OverviewView.swift index 1729095..ef7b0ca 100644 --- a/ApplicationLibrary/Views/Dashboard/OverviewView.swift +++ b/ApplicationLibrary/Views/Dashboard/OverviewView.swift @@ -35,7 +35,7 @@ public struct OverviewView: View { FormView { #if os(iOS) || os(tvOS) StartStopButton() - if profile.status.isConnectedStrict, systemProxyAvailable { + if ApplicationLibrary.inPreview || profile.status.isConnectedStrict, systemProxyAvailable { Toggle("HTTP Proxy", isOn: $systemProxyEnabled) .onChangeCompat(of: systemProxyEnabled) { newValue in Task.detached { @@ -52,7 +52,7 @@ public struct OverviewView: View { .pickerStyle(.inline) } #elseif os(macOS) - if profile.status.isConnectedStrict, systemProxyAvailable { + if ApplicationLibrary.inPreview || profile.status.isConnectedStrict, systemProxyAvailable { Toggle("HTTP Proxy", isOn: $systemProxyEnabled) .onChangeCompat(of: systemProxyEnabled) { newValue in Task.detached { @@ -72,7 +72,6 @@ public struct OverviewView: View { } } } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .alertBinding($alert) .onChangeCompat(of: selectedProfileID) { reasserting = true diff --git a/ApplicationLibrary/Views/Groups/GroupListView.swift b/ApplicationLibrary/Views/Groups/GroupListView.swift index 9a46d64..6fbb432 100644 --- a/ApplicationLibrary/Views/Groups/GroupListView.swift +++ b/ApplicationLibrary/Views/Groups/GroupListView.swift @@ -25,7 +25,6 @@ public struct GroupListView: View { Text("Empty groups") } } - .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) .onAppear { connect() } @@ -54,7 +53,7 @@ public struct GroupListView: View { OutboundGroupItem(tag: "server2", type: "WireGuard", urlTestTime: .now, urlTestDelay: 34), OutboundGroupItem(tag: "auto", type: "URLTest", urlTestTime: .now, urlTestDelay: 100), ]), - OutboundGroup(tag: "group2", type: "urltest", selected: "client", selectable: true, isExpand: true, items: + OutboundGroup(tag: "group2", type: "urltest", selected: "client", selectable: true, isExpand: false, items: (0 ..< 234).map { index in OutboundGroupItem(tag: "client\(index)", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: UInt16(100 + index * 10)) }), diff --git a/ApplicationLibrary/Views/Log/LogView.swift b/ApplicationLibrary/Views/Log/LogView.swift index 5bc0e0a..afe0601 100644 --- a/ApplicationLibrary/Views/Log/LogView.swift +++ b/ApplicationLibrary/Views/Log/LogView.swift @@ -10,7 +10,34 @@ public struct LogView: View { public init() {} public var body: some View { - if environments.logClient.logList.isEmpty { + if ApplicationLibrary.inPreview { + let logList = [ + "(packet-tunnel) log server started", + "INFO[0000] router: loaded geoip database: 250 codes", + "INFO[0000] router: loaded geosite database: 1400 codes", + "INFO[0000] router: updated default interface en0, index 11", + "inbound/tun[0]: started at utun3", + "sing-box started (1.666s)", + ] + ScrollView { + VStack(alignment: .leading, spacing: 0) { + ForEach(Array(logList.enumerated()), id: \.offset) { it in + Text(it.element) + .font(logFont) + #if os(tvOS) + .focusable() + #endif + Spacer(minLength: 8) + } + } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .topLeading) + .padding() + } + #if os(tvOS) + .focusEffectDisabled() + .focusSection() + #endif + } else if environments.logClient.logList.isEmpty { VStack { if environments.logClient.isConnected { Text("Empty logs") @@ -19,7 +46,7 @@ public struct LogView: View { environments.connectLog() } } - }.frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) + } } else { ScrollViewReader { reader in ScrollView { diff --git a/ApplicationLibrary/Views/NavigationPage.swift b/ApplicationLibrary/Views/NavigationPage.swift index 8ee0f5f..062c7b0 100644 --- a/ApplicationLibrary/Views/NavigationPage.swift +++ b/ApplicationLibrary/Views/NavigationPage.swift @@ -76,8 +76,9 @@ public extension NavigationPage { SettingView() } } + .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .center) #if os(iOS) - .background(Color(uiColor: .systemGroupedBackground)) + .background(Color(uiColor: .systemGroupedBackground)) #endif } diff --git a/ApplicationLibrary/Views/Setting/SettingView.swift b/ApplicationLibrary/Views/Setting/SettingView.swift index e06c2c6..0507b3c 100644 --- a/ApplicationLibrary/Views/Setting/SettingView.swift +++ b/ApplicationLibrary/Views/Setting/SettingView.swift @@ -22,7 +22,11 @@ public struct SettingView: View { @State private var alwaysOn = false @State private var disableMemoryLimit = false - @State private var includeAllNetworks = false + + #if !os(tvOS) + @State private var includeAllNetworks = false + #endif + @State private var version = "" @State private var dataSize = "" @State private var taiwanFlagAvailable = false @@ -81,12 +85,14 @@ public struct SettingView: View { SharedPreferences.disableMemoryLimit = newValue } } - Toggle("Include All Networks", isOn: $includeAllNetworks) - .onChangeCompat(of: includeAllNetworks) { newValue in - Task.detached { - SharedPreferences.includeAllNetworks = newValue + #if !os(tvOS) + Toggle("Include All Networks", isOn: $includeAllNetworks) + .onChangeCompat(of: includeAllNetworks) { newValue in + Task.detached { + SharedPreferences.includeAllNetworks = newValue + } } - } + #endif #if os(macOS) if Variant.useSystemExtension { HStack { @@ -172,13 +178,16 @@ public struct SettingView: View { #endif alwaysOn = SharedPreferences.alwaysOn disableMemoryLimit = SharedPreferences.disableMemoryLimit - includeAllNetworks = SharedPreferences.includeAllNetworks - version = LibboxVersion() + #if !os(tvOS) + includeAllNetworks = SharedPreferences.includeAllNetworks + #endif if ApplicationLibrary.inPreview { - dataSize = LibboxFormatBytes(1024 * 1024 * 10) + version = "" + dataSize = LibboxFormatBytes(1000 * 1000 * 10) taiwanFlagAvailable = true isLoading = false } else { + version = LibboxVersion() dataSize = "Loading..." taiwanFlagAvailable = !DeviceCensorship.isChinaDevice() isLoading = false diff --git a/Library/Database/SharedPreferences.swift b/Library/Database/SharedPreferences.swift index 91b7f13..8d812b3 100644 --- a/Library/Database/SharedPreferences.swift +++ b/Library/Database/SharedPreferences.swift @@ -9,7 +9,10 @@ public enum SharedPreferences { private static let disableMemoryLimitByDefault = false #endif @Preference("disable_memory_limit", defaultValue: disableMemoryLimitByDefault) public static var disableMemoryLimit - @Preference("include_all_networks", defaultValue: false) public static var includeAllNetworks + + #if !os(tvOS) + @Preference("include_all_networks", defaultValue: false) public static var includeAllNetworks + #endif @Preference("max_log_lines", defaultValue: 300) public static var maxLogLines @Preference("always_on", defaultValue: false) public static var alwaysOn diff --git a/Library/Network/ExtensionProfile.swift b/Library/Network/ExtensionProfile.swift index f149662..edd452a 100644 --- a/Library/Network/ExtensionProfile.swift +++ b/Library/Network/ExtensionProfile.swift @@ -58,9 +58,15 @@ public class ExtensionProfile: ObservableObject { manager.isOnDemandEnabled = true setOnDemandRules() } - if let protocolConfiguration = manager.protocolConfiguration { - protocolConfiguration.includeAllNetworks = SharedPreferences.includeAllNetworks - } + #if !os(tvOS) + if let protocolConfiguration = manager.protocolConfiguration { + let includeAllNetworks = SharedPreferences.includeAllNetworks + protocolConfiguration.includeAllNetworks = includeAllNetworks + if #available(iOS 16.4, macOS 13.3, *) { + protocolConfiguration.excludeCellularServices = !includeAllNetworks + } + } + #endif try await manager.saveToPreferences() #if os(macOS) if Variant.useSystemExtension { diff --git a/Library/Shared/FilePath.swift b/Library/Shared/FilePath.swift index bfccef5..e2e6df3 100644 --- a/Library/Shared/FilePath.swift +++ b/Library/Shared/FilePath.swift @@ -46,7 +46,7 @@ public extension FilePath { #endif - static var iCloudDirectory: URL! = FileManager.default.url(forUbiquityContainerIdentifier: nil)!.appendingPathComponent("Documents", isDirectory: true) + static var iCloudDirectory = FileManager.default.url(forUbiquityContainerIdentifier: nil)?.appendingPathComponent("Documents", isDirectory: true) ?? URL(string: "stub")! } public extension URL { diff --git a/MacLibrary/MainView.swift b/MacLibrary/MainView.swift index add19b6..297d258 100644 --- a/MacLibrary/MainView.swift +++ b/MacLibrary/MainView.swift @@ -14,6 +14,14 @@ public struct MainView: View { public init() {} public var body: some View { + if ApplicationLibrary.inPreview { + body1.frame(width: 1280, height: 750, alignment: .topLeading) + } else { + body1 + } + } + + private var body1: some View { NavigationSplitView { SidebarView() } detail: { diff --git a/SFI/MainView.swift b/SFI/MainView.swift index f4daa2b..b854a86 100644 --- a/SFI/MainView.swift +++ b/SFI/MainView.swift @@ -13,6 +13,14 @@ struct MainView: View { @State private var alert: Alert? var body: some View { + if ApplicationLibrary.inPreview { + body1.preferredColorScheme(.dark) + } else { + body1 + } + } + + var body1: some View { TabView(selection: $selection) { ForEach(NavigationPage.allCases, id: \.self) { page in NavigationStackCompat { diff --git a/sing-box.xcodeproj/project.pbxproj b/sing-box.xcodeproj/project.pbxproj index 75e4594..deac908 100644 --- a/sing-box.xcodeproj/project.pbxproj +++ b/sing-box.xcodeproj/project.pbxproj @@ -2293,7 +2293,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = Z56Z6NYZN2; ENABLE_HARDENED_RUNTIME = YES; @@ -2331,7 +2331,7 @@ CODE_SIGN_IDENTITY = "Apple Development"; CODE_SIGN_STYLE = Automatic; COMBINE_HIDPI_IMAGES = YES; - CURRENT_PROJECT_VERSION = 54; + CURRENT_PROJECT_VERSION = 55; DEAD_CODE_STRIPPING = YES; DEVELOPMENT_TEAM = Z56Z6NYZN2; ENABLE_HARDENED_RUNTIME = YES; @@ -2489,7 +2489,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.5.0-beta.11; + MARKETING_VERSION = 1.5.0-rc.1; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system; PRODUCT_NAME = "$(inherited)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2525,7 +2525,7 @@ "@executable_path/../../../../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.5.0-beta.11; + MARKETING_VERSION = 1.5.0-rc.1; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system; PRODUCT_NAME = "$(inherited)"; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2565,7 +2565,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.5.0-beta.11; + MARKETING_VERSION = 1.5.0-rc.1; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent; PRODUCT_NAME = SFM; PROVISIONING_PROFILE_SPECIFIER = ""; @@ -2604,7 +2604,7 @@ "@executable_path/../Frameworks", ); MACOSX_DEPLOYMENT_TARGET = 13.0; - MARKETING_VERSION = 1.5.0-beta.11; + MARKETING_VERSION = 1.5.0-rc.1; PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent; PRODUCT_NAME = SFM; PROVISIONING_PROFILE_SPECIFIER = "";