Add back always on option

This commit is contained in:
世界
2024-04-06 23:58:59 +08:00
parent db8cbfa865
commit debd0ca1a2
8 changed files with 94 additions and 25 deletions
@@ -12,7 +12,7 @@ public extension Binding {
public extension Binding where Value == Int32 {
func stringBinding(defaultValue: Int32) -> Binding<String> {
return Binding<String> {
Binding<String> {
var intValue = wrappedValue
if intValue == 0 {
intValue = defaultValue
@@ -21,9 +21,9 @@ public struct ProfileShareButton<Label>: View where Label: View {
public var body: some View {
#if os(iOS)
if #available(iOS 17.4, *) {
bodyCompat
} else if #available(iOS 16.0, *) {
if #available(iOS 17.4, *) {
bodyCompat
} else if #available(iOS 16.0, *) {
ShareLink(item: profile, subject: Text(profile.name), preview: SharePreview("Share profile"), label: label)
} else if UIDevice.current.userInterfaceIdiom != .pad {
bodyCompat
@@ -0,0 +1,57 @@
import Foundation
import Library
import SwiftUI
public struct OnDemandRulesView: View {
@State private var isLoading = true
@State private var alwaysOn = false
public init() {}
public var body: some View {
viewBuilder {
if isLoading {
ProgressView().onAppear {
Task.detached {
await loadSettings()
}
}
} else {
FormView {
FormSection {
Toggle("Always On", isOn: $alwaysOn)
.onChangeCompat(of: alwaysOn) { newValue in
Task {
await SharedPreferences.alwaysOn.set(newValue)
}
}
} footer: {
Text("""
Implement always-on via on-demand rules.
This should not be an intended use of the API, so you cannot disable VPN in system settings. To stop the service manually, use the in-app interface or simply delete the VPN profile.
""")
}
FormButton {
Task {
await SharedPreferences.resetOnDemandRules()
isLoading = true
}
} label: {
Label("Reset", systemImage: "eraser.fill")
}
.foregroundColor(.red)
}
}
}
.navigationTitle("On Demand Rules")
#if os(iOS)
.navigationBarTitleDisplayMode(.inline)
#endif
}
private func loadSettings() async {
alwaysOn = await SharedPreferences.alwaysOn.get()
isLoading = false
}
}
@@ -2,10 +2,6 @@ import Library
import SwiftUI
struct PacketTunnelView: View {
#if os(macOS)
public static let windowID = "packet-tunnel"
#endif
@State private var isLoading = true
@State private var ignoreMemoryLimit = false
@@ -12,7 +12,7 @@ public struct SettingView: View {
case app
#endif
case core, packetTunnel, profileOverride, sponsors
case core, packetTunnel, onDemandRules, profileOverride, sponsors
var label: some View {
Label(title, systemImage: iconImage)
@@ -28,6 +28,8 @@ public struct SettingView: View {
return NSLocalizedString("Core", comment: "")
case .packetTunnel:
return NSLocalizedString("Packet Tunnel", comment: "")
case .onDemandRules:
return NSLocalizedString("On Demand Rules", comment: "")
case .profileOverride:
return NSLocalizedString("Profile Override", comment: "")
case .sponsors:
@@ -45,6 +47,8 @@ public struct SettingView: View {
return "shippingbox.fill"
case .packetTunnel:
return "aspectratio.fill"
case .onDemandRules:
return "filemenu.and.selection"
case .profileOverride:
return "square.dashed.inset.filled"
case .sponsors:
@@ -64,6 +68,8 @@ public struct SettingView: View {
CoreView()
case .packetTunnel:
PacketTunnelView()
case .onDemandRules:
OnDemandRulesView()
case .profileOverride:
ProfileOverrideView()
case .sponsors:
@@ -95,7 +101,7 @@ public struct SettingView: View {
#if os(macOS)
Tabs.app.navigationLink
#endif
ForEach([Tabs.core, Tabs.packetTunnel, Tabs.profileOverride]) { it in
ForEach([Tabs.core, Tabs.packetTunnel, Tabs.onDemandRules, Tabs.profileOverride]) { it in
it.navigationLink
}
#if !os(tvOS)