Minor improvements

This commit is contained in:
世界
2023-08-14 09:40:21 +08:00
parent 736bbc81e9
commit 1ac5df7f72
6 changed files with 86 additions and 63 deletions
@@ -18,11 +18,7 @@ public struct GroupListView: View {
ScrollView {
VStack {
ForEach(groups, id: \.hashValue) { it in
GroupView(it, Binding(get: {
groupExpand[it.tag] ?? it.selectable
}, set: { newValue in
groupExpand[it.tag] = newValue
}))
GroupView(it)
}
}.padding()
}
@@ -44,12 +40,12 @@ public struct GroupListView: View {
private func doReload() {
if ApplicationLibrary.inPreview {
groups = [
OutboundGroup(tag: "my_group", type: "selector", selected: "server", selectable: true, items: [
OutboundGroup(tag: "my_group", type: "selector", selected: "server", selectable: true, isExpand: true, items: [
OutboundGroupItem(tag: "server", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: 12),
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, items:
OutboundGroup(tag: "group2", type: "urltest", selected: "client", selectable: true, isExpand: true, items:
(0 ..< 234).map { index in
OutboundGroupItem(tag: "client\(index)", type: "Shadowsocks", urlTestTime: .now, urlTestDelay: UInt16(100 + index * 10))
}),
@@ -105,7 +101,7 @@ public struct GroupListView: View {
let goItem = itemIterator.next()!
items.append(OutboundGroupItem(tag: goItem.tag, type: goItem.type, urlTestTime: Date(timeIntervalSince1970: Double(goItem.urlTestTime)), urlTestDelay: UInt16(goItem.urlTestDelay)))
}
groups.append(OutboundGroup(tag: goGroup.tag, type: goGroup.type, selected: goGroup.selected, selectable: goGroup.selectable, items: items))
groups.append(OutboundGroup(tag: goGroup.tag, type: goGroup.type, selected: goGroup.selected, selectable: goGroup.selectable, isExpand: goGroup.isExpand(), items: items))
}
self.groups = groups
isLoading = false
@@ -3,13 +3,12 @@ import Library
import SwiftUI
public struct GroupView: View {
@Binding private var expland: Bool
@State private var group: OutboundGroup
@State private var geometryWidth: CGFloat = 300
@State private var alert: Alert?
public init(_ group: OutboundGroup, _ expland: Binding<Bool>) {
self.group = group
_expland = expland
public init(_ group: OutboundGroup) {
_group = State(initialValue: group)
}
private var title: some View {
@@ -25,9 +24,12 @@ public struct GroupView: View {
.background(Color.gray.opacity(0.5))
.cornerRadius(4)
Button {
expland = !expland
group.isExpand = !group.isExpand
Task.detached {
setGroupExpand()
}
} label: {
if expland {
if group.isExpand {
Image(systemName: "arrow.down.to.line")
} else {
Image(systemName: "arrow.up.to.line")
@@ -46,12 +48,14 @@ public struct GroupView: View {
#if os(macOS) || os(tvOS)
.buttonStyle(.plain)
#endif
}.padding([.top, .bottom], 8)
}
.alertBinding($alert)
.padding([.top, .bottom], 8)
}
public var body: some View {
Section {
if expland {
if group.isExpand {
LazyVGrid(columns: Array(repeating: GridItem(.flexible()),
count: explandColumnCount()))
{
@@ -123,7 +127,19 @@ public struct GroupView: View {
}
private func doURLTest() {
try? LibboxNewStandaloneCommandClient()!.urlTest(group.tag)
do {
try LibboxNewStandaloneCommandClient()!.urlTest(group.tag)
} catch {
alert = Alert(error)
}
}
private func setGroupExpand() {
do {
try LibboxNewStandaloneCommandClient()!.setGroupExpand(group.tag, isExpand: group.isExpand)
} catch {
alert = Alert(error)
}
}
}
@@ -7,6 +7,7 @@ public struct OutboundGroup: Codable {
let type: String
var selected: String
let selectable: Bool
var isExpand: Bool
let items: [OutboundGroupItem]
var hashValue: Int {
@@ -53,7 +53,7 @@ public struct ProfileView: View {
}
}
FormView {
#if os(iOS) || os(tvOS)
#if os(iOS)
NavigationLink {
NewProfileView {
Task.detached {
@@ -64,17 +64,27 @@ public struct ProfileView: View {
Text("New Profile").foregroundColor(.accentColor)
}
.disabled(editMode.isEditing)
#endif
#if os(tvOS)
if ApplicationLibrary.inPreview || devicePickerSupports(.applicationService(name: "sing-box"), parameters: { .applicationService }) {
#elseif os(tvOS)
Section {
NavigationLink {
ImportProfileView {
NewProfileView {
Task.detached {
doReload()
}
}
} label: {
Text("Import Profile").foregroundColor(.accentColor)
Text("New Profile").foregroundColor(.accentColor)
}
if ApplicationLibrary.inPreview || devicePickerSupports(.applicationService(name: "sing-box"), parameters: { .applicationService }) {
NavigationLink {
ImportProfileView {
Task.detached {
doReload()
}
}
} label: {
Text("Import Profile").foregroundColor(.accentColor)
}
}
}
#endif
@@ -8,6 +8,7 @@ public struct ServiceLogView: View {
public static let windowID = "service-log"
#endif
@Environment(\.dismiss) private var dismiss
@State private var isLoading = true
@State private var content = ""
@State private var fileExporterPresented = false
@@ -28,7 +29,9 @@ public struct ServiceLogView: View {
Text("Empty content")
} else {
ScrollView {
Text(content).font(logFont)
Text(content)
.font(logFont)
.frame(maxWidth: .infinity, alignment: .topLeading)
}
.padding()
}
@@ -36,10 +39,16 @@ public struct ServiceLogView: View {
}
#if !os(tvOS)
.toolbar {
Button("Export") {
fileExporterPresented = true
if !content.isEmpty {
Button("Export") {
fileExporterPresented = true
}
Button("Delete", role: .destructive) {
Task.detached {
deleteContent()
}
}
}
.disabled(content.isEmpty)
}
#endif
#if !os(tvOS)
@@ -52,11 +61,8 @@ public struct ServiceLogView: View {
)
#endif
.navigationTitle("Service Log")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
#if os(tvOS)
.focusable()
.focusable()
#endif
}
@@ -67,11 +73,21 @@ public struct ServiceLogView: View {
if content.isEmpty {
do {
content = try String(contentsOf: FilePath.cacheDirectory.appendingPathComponent("stderr.log.old"))
} catch {}
} catch {
}
}
isLoading = false
}
private func deleteContent() {
try? FileManager.default.removeItem(at: FilePath.cacheDirectory.appendingPathComponent("stderr.log"))
try? FileManager.default.removeItem(at: FilePath.cacheDirectory.appendingPathComponent("stderr.log.old"))
DispatchQueue.main.async {
dismiss()
}
}
#if !os(tvOS)
private struct LogDocument: FileDocument {
static var readableContentTypes = [UTType.text]
+15 -31
View File
@@ -1316,12 +1316,12 @@
3AEC20F22A459AB400A63465 /* SFI */,
3AEC21082A459B1900A63465 /* SFM */,
3AEECC032A6DF9CA006A0E0C /* SFM.System */,
3AEECBF02A6DF40A006A0E0C /* SystemExtension */,
3AC03B952A72BF3300B7946F /* SFT */,
3AEC211C2A459B4700A63465 /* Library */,
3A4EAD0F2A4FEAE6005435B3 /* ApplicationLibrary */,
3AEECC2E2A6DFDAD006A0E0C /* MacLibrary */,
3A096F852A4ED3DE00D4A2ED /* Extension */,
3AEECBF02A6DF40A006A0E0C /* SystemExtension */,
3A77016C2A4E6B34008F031F /* IntentsExtension */,
3AE171982A8128DD00393060 /* TVExtension */,
);
@@ -1704,7 +1704,6 @@
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1744,7 +1743,6 @@
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1868,7 +1866,6 @@
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.intents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1908,7 +1905,6 @@
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.intents;
PRODUCT_NAME = "$(TARGET_NAME)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -1948,8 +1944,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3.7;
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
SDKROOT = appletvos;
@@ -1983,8 +1978,7 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3.7;
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = 1.4.0;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
SDKROOT = appletvos;
@@ -2015,7 +2009,6 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2048,7 +2041,6 @@
"@executable_path/../../Frameworks",
);
MARKETING_VERSION = 1.0;
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.extension;
PRODUCT_NAME = "$(TARGET_NAME)";
SDKROOT = iphoneos;
@@ -2220,9 +2212,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3.7;
MARKETING_VERSION = 1.4.0;
OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2261,9 +2252,8 @@
"$(inherited)",
"@executable_path/Frameworks",
);
MARKETING_VERSION = 1.3.7;
MARKETING_VERSION = 1.4.0;
OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2301,9 +2291,8 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.7;
MARKETING_VERSION = 1.4.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2340,9 +2329,8 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.7;
MARKETING_VERSION = 1.4.0;
OTHER_CODE_SIGN_FLAGS = "";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa;
PRODUCT_NAME = "sing-box";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2390,7 +2378,6 @@
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.library;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2445,7 +2432,6 @@
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu17 gnu++20";
OTHER_CODE_SIGN_FLAGS = "--deep";
OTHER_LDFLAGS = "-ld_classic";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.library;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2469,6 +2455,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES;
@@ -2484,8 +2471,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.4;
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = "1.4.0-beta.5";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system;
PRODUCT_NAME = "$(inherited)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2505,6 +2491,7 @@
CODE_SIGN_IDENTITY = "Apple Development";
"CODE_SIGN_IDENTITY[sdk=macosx*]" = "Developer ID Application";
CODE_SIGN_STYLE = Manual;
CURRENT_PROJECT_VERSION = 1;
DEVELOPMENT_TEAM = "";
"DEVELOPMENT_TEAM[sdk=macosx*]" = Z56Z6NYZN2;
ENABLE_HARDENED_RUNTIME = YES;
@@ -2520,8 +2507,7 @@
"@executable_path/../../../../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = 1.3.4;
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = "1.4.0-beta.5";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.system;
PRODUCT_NAME = "$(inherited)";
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2561,8 +2547,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "1.4.0-beta.1";
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = "1.4.0-beta.5";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent;
PRODUCT_NAME = SFM;
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2601,8 +2586,7 @@
"@executable_path/../Frameworks",
);
MACOSX_DEPLOYMENT_TARGET = 13.0;
MARKETING_VERSION = "1.4.0-beta.1";
OTHER_LDFLAGS = "-ld_classic";
MARKETING_VERSION = "1.4.0-beta.5";
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.independent;
PRODUCT_NAME = SFM;
PROVISIONING_PROFILE_SPECIFIER = "";
@@ -2642,7 +2626,7 @@
MARKETING_VERSION = 1.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = org.sagernet.sfa.macapp;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.macapp;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;
@@ -2682,7 +2666,7 @@
MARKETING_VERSION = 1.0;
MODULE_VERIFIER_SUPPORTED_LANGUAGES = "objective-c objective-c++";
MODULE_VERIFIER_SUPPORTED_LANGUAGE_STANDARDS = "gnu11 gnu++20";
PRODUCT_BUNDLE_IDENTIFIER = org.sagernet.sfa.macapp;
PRODUCT_BUNDLE_IDENTIFIER = io.nekohasekai.sfa.macapp;
PRODUCT_NAME = "$(TARGET_NAME:c99extidentifier)";
PROVISIONING_PROFILE_SPECIFIER = "";
SDKROOT = macosx;