Minor fixes
This commit is contained in:
@@ -7,20 +7,18 @@
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
public struct ImportProfileView: View {
|
public struct ImportProfileView: View {
|
||||||
|
@EnvironmentObject private var environments: ExtensionEnvironments
|
||||||
@Environment(\.dismiss) private var dismiss
|
@Environment(\.dismiss) private var dismiss
|
||||||
|
|
||||||
@State private var isLoading = false
|
@State private var isLoading = false
|
||||||
@State private var selected = false
|
@State private var selected = false
|
||||||
@State private var alert: Alert?
|
@State private var alert: Alert?
|
||||||
@State private var connection: NWSocket?
|
@State private var connection: NWConnection?
|
||||||
|
@State private var socket: NWSocket?
|
||||||
@State private var profiles: [LibboxProfilePreview]?
|
@State private var profiles: [LibboxProfilePreview]?
|
||||||
@State private var isImporting = false
|
@State private var isImporting = false
|
||||||
private let callback: () async -> Void
|
|
||||||
|
|
||||||
public init(callback: @escaping () async -> Void) {
|
|
||||||
self.callback = callback
|
|
||||||
}
|
|
||||||
|
|
||||||
|
public init() {}
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
VStack(alignment: .center) {
|
VStack(alignment: .center) {
|
||||||
if !selected {
|
if !selected {
|
||||||
@@ -73,17 +71,23 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func reset() {
|
private func reset() {
|
||||||
selected = false
|
|
||||||
profiles = nil
|
|
||||||
if let connection {
|
if let connection {
|
||||||
|
connection.stateUpdateHandler = nil
|
||||||
connection.cancel()
|
connection.cancel()
|
||||||
self.connection = nil
|
self.connection = nil
|
||||||
}
|
}
|
||||||
|
if let socket {
|
||||||
|
socket.cancel()
|
||||||
|
self.socket = nil
|
||||||
|
}
|
||||||
|
selected = false
|
||||||
|
profiles = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
private func handleEndpoint(_ endpoint: NWEndpoint) async {
|
private func handleEndpoint(_ endpoint: NWEndpoint) async {
|
||||||
let connection = NWConnection(to: endpoint, using: NWParameters.applicationService)
|
let connection = NWConnection(to: endpoint, using: NWParameters.applicationService)
|
||||||
self.connection = NWSocket(connection)
|
self.connection = connection
|
||||||
|
socket = NWSocket(connection)
|
||||||
connection.stateUpdateHandler = { state in
|
connection.stateUpdateHandler = { state in
|
||||||
switch state {
|
switch state {
|
||||||
case let .failed(error):
|
case let .failed(error):
|
||||||
@@ -104,13 +108,13 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
private nonisolated func loopMessages() async throws {
|
private nonisolated func loopMessages() async throws {
|
||||||
guard let connection = await connection else {
|
guard let socket = await socket else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
var message: Data
|
var message: Data
|
||||||
while true {
|
while true {
|
||||||
do {
|
do {
|
||||||
message = try connection.read()
|
message = try socket.read()
|
||||||
} catch {
|
} catch {
|
||||||
throw NSError(domain: "read from connection: \(error.localizedDescription)", code: 0)
|
throw NSError(domain: "read from connection: \(error.localizedDescription)", code: 0)
|
||||||
}
|
}
|
||||||
@@ -147,6 +151,7 @@
|
|||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
try await importProfile(content!)
|
try await importProfile(content!)
|
||||||
|
return
|
||||||
default:
|
default:
|
||||||
throw NSError(domain: "unknown message type \(message[0])", code: 0)
|
throw NSError(domain: "unknown message type \(message[0])", code: 0)
|
||||||
}
|
}
|
||||||
@@ -157,10 +162,14 @@
|
|||||||
guard let connection else {
|
guard let connection else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
guard let socket else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
connection.stateUpdateHandler = nil
|
||||||
let request = LibboxProfileContentRequest()
|
let request = LibboxProfileContentRequest()
|
||||||
request.profileID = profileID
|
request.profileID = profileID
|
||||||
do {
|
do {
|
||||||
try connection.write(request.encode())
|
try socket.write(request.encode())
|
||||||
isImporting = true
|
isImporting = true
|
||||||
} catch {
|
} catch {
|
||||||
alert = Alert(error)
|
alert = Alert(error)
|
||||||
@@ -191,8 +200,8 @@
|
|||||||
}
|
}
|
||||||
try await ProfileManager.create(Profile(name: content.name, type: type, path: profileConfig.relativePath, remoteURL: content.remotePath, autoUpdate: content.autoUpdate, lastUpdated: lastUpdated))
|
try await ProfileManager.create(Profile(name: content.name, type: type, path: profileConfig.relativePath, remoteURL: content.remotePath, autoUpdate: content.autoUpdate, lastUpdated: lastUpdated))
|
||||||
await reset()
|
await reset()
|
||||||
await callback()
|
|
||||||
await MainActor.run {
|
await MainActor.run {
|
||||||
|
environments.profileUpdate.send()
|
||||||
dismiss()
|
dismiss()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,9 +66,7 @@ public struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
if ApplicationLibrary.inPreview || devicePickerSupports(.applicationService(name: "sing-box"), parameters: { .applicationService }) {
|
if ApplicationLibrary.inPreview || devicePickerSupports(.applicationService(name: "sing-box"), parameters: { .applicationService }) {
|
||||||
FormNavigationLink {
|
FormNavigationLink {
|
||||||
ImportProfileView {
|
ImportProfileView()
|
||||||
await doReload()
|
|
||||||
}
|
|
||||||
} label: {
|
} label: {
|
||||||
Text("Import Profile").foregroundColor(.accentColor)
|
Text("Import Profile").foregroundColor(.accentColor)
|
||||||
}
|
}
|
||||||
@@ -188,15 +186,15 @@ public struct ProfileView: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private func doReload() async {
|
private func doReload() async {
|
||||||
|
defer {
|
||||||
|
isLoading = false
|
||||||
|
}
|
||||||
if ApplicationLibrary.inPreview {
|
if ApplicationLibrary.inPreview {
|
||||||
profileList = [
|
profileList = [
|
||||||
ProfilePreview(Profile(id: 0, name: "profile local", type: .local, path: "")),
|
ProfilePreview(Profile(id: 0, name: "profile local", type: .local, path: "")),
|
||||||
ProfilePreview(Profile(id: 1, name: "profile remote", type: .remote, path: "", lastUpdated: Date(timeIntervalSince1970: 0))),
|
ProfilePreview(Profile(id: 1, name: "profile remote", type: .remote, path: "", lastUpdated: Date(timeIntervalSince1970: 0))),
|
||||||
]
|
]
|
||||||
} else {
|
} else {
|
||||||
defer {
|
|
||||||
isLoading = false
|
|
||||||
}
|
|
||||||
do {
|
do {
|
||||||
profileList = try await ProfileManager.list().map { ProfilePreview($0) }
|
profileList = try await ProfileManager.list().map { ProfilePreview($0) }
|
||||||
} catch {
|
} catch {
|
||||||
|
|||||||
@@ -132,10 +132,18 @@ public struct SettingView: View {
|
|||||||
Text("Loading...")
|
Text("Loading...")
|
||||||
.onAppear {
|
.onAppear {
|
||||||
Task.detached {
|
Task.detached {
|
||||||
taiwanFlagAvailable = !DeviceCensorship.isChinaDevice()
|
let available: Bool
|
||||||
|
if ApplicationLibrary.inPreview {
|
||||||
|
available = true
|
||||||
|
} else {
|
||||||
|
available = !DeviceCensorship.isChinaDevice()
|
||||||
|
}
|
||||||
|
await MainActor.run {
|
||||||
|
taiwanFlagAvailable = available
|
||||||
isLoading = false
|
isLoading = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
Text(taiwanFlagAvailable.description)
|
Text(taiwanFlagAvailable.description)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,15 +14,8 @@ public struct MainView: View {
|
|||||||
@State private var alert: Alert?
|
@State private var alert: Alert?
|
||||||
|
|
||||||
public init() {}
|
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 {
|
public var body: some View {
|
||||||
NavigationSplitView {
|
NavigationSplitView {
|
||||||
SidebarView()
|
SidebarView()
|
||||||
.navigationSplitViewColumnWidth(150)
|
.navigationSplitViewColumnWidth(150)
|
||||||
@@ -31,9 +24,9 @@ public struct MainView: View {
|
|||||||
selection.contentView
|
selection.contentView
|
||||||
.navigationTitle(selection.title)
|
.navigationTitle(selection.title)
|
||||||
}
|
}
|
||||||
.navigationSplitViewColumnWidth(600)
|
.navigationSplitViewColumnWidth(650)
|
||||||
}
|
}
|
||||||
.frame(minHeight: 470)
|
.frame(minHeight: 500)
|
||||||
.onAppear {
|
.onAppear {
|
||||||
environments.postReload()
|
environments.postReload()
|
||||||
#if !DEBUG
|
#if !DEBUG
|
||||||
|
|||||||
@@ -9,14 +9,16 @@ public struct SidebarView: View {
|
|||||||
public init() {}
|
public init() {}
|
||||||
public var body: some View {
|
public var body: some View {
|
||||||
VStack {
|
VStack {
|
||||||
if environments.extensionProfileLoading {
|
if ApplicationLibrary.inPreview {
|
||||||
|
SidebarViewPreview()
|
||||||
|
} else if environments.extensionProfileLoading {
|
||||||
ProgressView()
|
ProgressView()
|
||||||
} else if let profile = environments.extensionProfile {
|
} else if let profile = environments.extensionProfile {
|
||||||
SidebarView0().environmentObject(profile)
|
SidebarView0().environmentObject(profile)
|
||||||
} else {
|
} else {
|
||||||
SidebarView1()
|
SidebarView1()
|
||||||
}
|
}
|
||||||
}.frame(minWidth: 150)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct SidebarView0: View {
|
struct SidebarView0: View {
|
||||||
@@ -69,4 +71,26 @@ public struct SidebarView: View {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct SidebarViewPreview: View {
|
||||||
|
@Environment(\.selection) private var selection
|
||||||
|
var body: some View {
|
||||||
|
VStack {
|
||||||
|
List(selection: selection) {
|
||||||
|
Section(NavigationPage.dashboard.title) {
|
||||||
|
Label("Overview", systemImage: "text.and.command.macwindow")
|
||||||
|
.tint(.textColor)
|
||||||
|
.tag(NavigationPage.dashboard)
|
||||||
|
NavigationPage.groups.label.tag(NavigationPage.groups)
|
||||||
|
}
|
||||||
|
Divider()
|
||||||
|
ForEach(NavigationPage.macosDefaultPages, id: \.self) { it in
|
||||||
|
it.label
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.listStyle(.sidebar)
|
||||||
|
.scrollDisabled(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
|
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
||||||
|
<plist version="1.0">
|
||||||
|
<dict>
|
||||||
|
<key>destination</key>
|
||||||
|
<string>export</string>
|
||||||
|
<key>method</key>
|
||||||
|
<string>developer-id</string>
|
||||||
|
<key>provisioningProfiles</key>
|
||||||
|
<dict>
|
||||||
|
<key>io.nekohasekai.sfavt.standalone</key>
|
||||||
|
<string>XC io nekohasekai sfavt standalone</string>
|
||||||
|
<key>io.nekohasekai.sfavt.system</key>
|
||||||
|
<string>XC io nekohasekai sfavt system</string>
|
||||||
|
</dict>
|
||||||
|
</dict>
|
||||||
|
</plist>
|
||||||
@@ -24,6 +24,7 @@
|
|||||||
3A27D9002A89BE230031EBCC /* CommandClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27D8FF2A89BE230031EBCC /* CommandClient.swift */; };
|
3A27D9002A89BE230031EBCC /* CommandClient.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27D8FF2A89BE230031EBCC /* CommandClient.swift */; };
|
||||||
3A27D9022A89C6870031EBCC /* ExtensionEnvironments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27D9012A89C6870031EBCC /* ExtensionEnvironments.swift */; };
|
3A27D9022A89C6870031EBCC /* ExtensionEnvironments.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A27D9012A89C6870031EBCC /* ExtensionEnvironments.swift */; };
|
||||||
3A2EAEED2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */; };
|
3A2EAEED2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */; };
|
||||||
|
3A2F29EB2C998A5D007E024C /* Export.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3A2F29EA2C998A5D007E024C /* Export.plist */; };
|
||||||
3A3AA7FC2A4EFDAE002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
|
3A3AA7FC2A4EFDAE002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
|
||||||
3A3AA7FF2A4EFDB3002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
|
3A3AA7FF2A4EFDB3002F78AB /* Library.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AEC211D2A459B4700A63465 /* Library.framework */; };
|
||||||
3A3AB2A72B70C146001815AE /* CoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3AB2A62B70C146001815AE /* CoreView.swift */; };
|
3A3AB2A72B70C146001815AE /* CoreView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 3A3AB2A62B70C146001815AE /* CoreView.swift */; };
|
||||||
@@ -454,6 +455,7 @@
|
|||||||
3A27D8FF2A89BE230031EBCC /* CommandClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandClient.swift; sourceTree = "<group>"; };
|
3A27D8FF2A89BE230031EBCC /* CommandClient.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandClient.swift; sourceTree = "<group>"; };
|
||||||
3A27D9012A89C6870031EBCC /* ExtensionEnvironments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionEnvironments.swift; sourceTree = "<group>"; };
|
3A27D9012A89C6870031EBCC /* ExtensionEnvironments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ExtensionEnvironments.swift; sourceTree = "<group>"; };
|
||||||
3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndependentApplicationDelegate.swift; sourceTree = "<group>"; };
|
3A2EAEEC2A6F4CBB00D00DE3 /* IndependentApplicationDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = IndependentApplicationDelegate.swift; sourceTree = "<group>"; };
|
||||||
|
3A2F29EA2C998A5D007E024C /* Export.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Export.plist; sourceTree = "<group>"; };
|
||||||
3A3AB2A62B70C146001815AE /* CoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreView.swift; sourceTree = "<group>"; };
|
3A3AB2A62B70C146001815AE /* CoreView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CoreView.swift; sourceTree = "<group>"; };
|
||||||
3A3AB2A82B70C5F1001815AE /* RequestReviewButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestReviewButton.swift; sourceTree = "<group>"; };
|
3A3AB2A82B70C5F1001815AE /* RequestReviewButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RequestReviewButton.swift; sourceTree = "<group>"; };
|
||||||
3A3DEBE12A4FFA1A00373BF4 /* ExtensionFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExtensionFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/ExtensionFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
3A3DEBE12A4FFA1A00373BF4 /* ExtensionFoundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = ExtensionFoundation.framework; path = Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS17.0.sdk/System/Library/Frameworks/ExtensionFoundation.framework; sourceTree = DEVELOPER_DIR; };
|
||||||
@@ -966,6 +968,7 @@
|
|||||||
3AEECC052A6DF9CA006A0E0C /* SFM.System */ = {
|
3AEECC052A6DF9CA006A0E0C /* SFM.System */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
3A2F29EA2C998A5D007E024C /* Export.plist */,
|
||||||
3AEECC062A6DF9CA006A0E0C /* Application.swift */,
|
3AEECC062A6DF9CA006A0E0C /* Application.swift */,
|
||||||
3AEECC502A6E0074006A0E0C /* SFM.entitlements */,
|
3AEECC502A6E0074006A0E0C /* SFM.entitlements */,
|
||||||
3A2223532A6E1B6700C50B23 /* Info.plist */,
|
3A2223532A6E1B6700C50B23 /* Info.plist */,
|
||||||
@@ -1438,6 +1441,7 @@
|
|||||||
3AABFD472A9CCC58005A24A4 /* Upload.plist in Resources */,
|
3AABFD472A9CCC58005A24A4 /* Upload.plist in Resources */,
|
||||||
3A6CA5A82A713B340027933B /* AppIcon.icns in Resources */,
|
3A6CA5A82A713B340027933B /* AppIcon.icns in Resources */,
|
||||||
3AEC8A4F2A6E5E18003702E1 /* Assets.xcassets in Resources */,
|
3AEC8A4F2A6E5E18003702E1 /* Assets.xcassets in Resources */,
|
||||||
|
3A2F29EB2C998A5D007E024C /* Export.plist in Resources */,
|
||||||
3AEECC0B2A6DF9CA006A0E0C /* Assets.xcassets in Resources */,
|
3AEECC0B2A6DF9CA006A0E0C /* Assets.xcassets in Resources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
|
|||||||
Reference in New Issue
Block a user