Confirm quit on macOS (#634)

To do so, must prevent window from closing.

Fixes #223
This commit is contained in:
Davide 2024-09-28 17:58:48 +02:00 committed by GitHub
parent 5deb8ec763
commit 28a2017da2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 339 additions and 272 deletions

View File

@ -33,8 +33,50 @@ final class AppDelegate: NSObject, UIApplicationDelegate {
#else #else
import AppKit import AppKit
import AppUI
import CommonLibrary
import SwiftUI
final class AppDelegate: NSObject, NSApplicationDelegate { final class AppDelegate: NSObject, NSApplicationDelegate {
@AppStorage(AppPreference.confirmsQuit.key)
private var confirmsQuit = true
func applicationDidFinishLaunching(_ notification: Notification) {
NSApp.windows[0].styleMask.remove(.closable)
}
func applicationShouldTerminate(_ sender: NSApplication) -> NSApplication.TerminateReply {
if confirmsQuit {
return quitConfirmationAlert()
}
return .terminateNow
}
}
@MainActor
private extension AppDelegate {
func quitConfirmationAlert() -> NSApplication.TerminateReply {
let alert = NSAlert()
alert.alertStyle = .warning
alert.messageText = Strings.Alerts.ConfirmQuit.title(Constants.shared.identifiers.displayName)
alert.informativeText = Strings.Alerts.ConfirmQuit.message
alert.addButton(withTitle: Strings.Global.ok)
alert.addButton(withTitle: Strings.Global.cancel)
alert.addButton(withTitle: Strings.Global.doNotAskAgain)
switch alert.runModal() {
case .alertSecondButtonReturn:
return .terminateCancel
case .alertThirdButtonReturn:
confirmsQuit = false
default:
break
}
return .terminateNow
}
} }
#endif #endif

View File

@ -54,10 +54,10 @@ struct PassepartoutApp: App {
Window(appName, id: appName, content: content) Window(appName, id: appName, content: content)
.defaultSize(width: 600.0, height: 400.0) .defaultSize(width: 600.0, height: 400.0)
// Settings { Settings {
// SettingsView() SettingsView()
// .frame(minWidth: 300, minHeight: 100) .frame(minWidth: 300, minHeight: 100)
// } }
#endif #endif
} }
} }

View File

@ -9,549 +9,557 @@ import Foundation
// swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length // swiftlint:disable explicit_type_interface function_parameter_count identifier_name line_length
// swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces // swiftlint:disable nesting type_body_length type_name vertical_whitespace_opening_braces
internal enum Strings { public enum Strings {
internal enum Alerts { public enum Alerts {
internal enum Iap { public enum ConfirmQuit {
internal enum Restricted { /// The VPN, if enabled, will still run in the background. Do you want to quit?
public static let message = Strings.tr("Localizable", "alerts.confirm_quit.message", fallback: "The VPN, if enabled, will still run in the background. Do you want to quit?")
/// Quit %@
public static func title(_ p1: Any) -> String {
return Strings.tr("Localizable", "alerts.confirm_quit.title", String(describing: p1), fallback: "Quit %@")
}
}
public enum Iap {
public enum Restricted {
/// The requested feature is unavailable in this build. /// The requested feature is unavailable in this build.
internal static let message = Strings.tr("Localizable", "alerts.iap.restricted.message", fallback: "The requested feature is unavailable in this build.") public static let message = Strings.tr("Localizable", "alerts.iap.restricted.message", fallback: "The requested feature is unavailable in this build.")
/// Restricted /// Restricted
internal static let title = Strings.tr("Localizable", "alerts.iap.restricted.title", fallback: "Restricted") public static let title = Strings.tr("Localizable", "alerts.iap.restricted.title", fallback: "Restricted")
} }
} }
} }
internal enum Entities { public enum Entities {
internal enum ConnectionStatus { public enum ConnectionStatus {
/// Connected /// Connected
internal static let connected = Strings.tr("Localizable", "entities.connection_status.connected", fallback: "Connected") public static let connected = Strings.tr("Localizable", "entities.connection_status.connected", fallback: "Connected")
/// Connecting /// Connecting
internal static let connecting = Strings.tr("Localizable", "entities.connection_status.connecting", fallback: "Connecting") public static let connecting = Strings.tr("Localizable", "entities.connection_status.connecting", fallback: "Connecting")
/// Disconnected /// Disconnected
internal static let disconnected = Strings.tr("Localizable", "entities.connection_status.disconnected", fallback: "Disconnected") public static let disconnected = Strings.tr("Localizable", "entities.connection_status.disconnected", fallback: "Disconnected")
/// Disconnecting /// Disconnecting
internal static let disconnecting = Strings.tr("Localizable", "entities.connection_status.disconnecting", fallback: "Disconnecting") public static let disconnecting = Strings.tr("Localizable", "entities.connection_status.disconnecting", fallback: "Disconnecting")
} }
internal enum Dns { public enum Dns {
/// Search domains /// Search domains
internal static let searchDomains = Strings.tr("Localizable", "entities.dns.search_domains", fallback: "Search domains") public static let searchDomains = Strings.tr("Localizable", "entities.dns.search_domains", fallback: "Search domains")
/// Servers /// Servers
internal static let servers = Strings.tr("Localizable", "entities.dns.servers", fallback: "Servers") public static let servers = Strings.tr("Localizable", "entities.dns.servers", fallback: "Servers")
} }
internal enum DnsProtocol { public enum DnsProtocol {
/// Cleartext /// Cleartext
internal static let cleartext = Strings.tr("Localizable", "entities.dns_protocol.cleartext", fallback: "Cleartext") public static let cleartext = Strings.tr("Localizable", "entities.dns_protocol.cleartext", fallback: "Cleartext")
/// Over HTTPS /// Over HTTPS
internal static let https = Strings.tr("Localizable", "entities.dns_protocol.https", fallback: "Over HTTPS") public static let https = Strings.tr("Localizable", "entities.dns_protocol.https", fallback: "Over HTTPS")
/// Over TLS /// Over TLS
internal static let tls = Strings.tr("Localizable", "entities.dns_protocol.tls", fallback: "Over TLS") public static let tls = Strings.tr("Localizable", "entities.dns_protocol.tls", fallback: "Over TLS")
} }
internal enum HttpProxy { public enum HttpProxy {
/// Bypass domains /// Bypass domains
internal static let bypassDomains = Strings.tr("Localizable", "entities.http_proxy.bypass_domains", fallback: "Bypass domains") public static let bypassDomains = Strings.tr("Localizable", "entities.http_proxy.bypass_domains", fallback: "Bypass domains")
} }
internal enum OnDemand { public enum OnDemand {
internal enum Policy { public enum Policy {
/// All networks /// All networks
internal static let any = Strings.tr("Localizable", "entities.on_demand.policy.any", fallback: "All networks") public static let any = Strings.tr("Localizable", "entities.on_demand.policy.any", fallback: "All networks")
/// Excluding /// Excluding
internal static let excluding = Strings.tr("Localizable", "entities.on_demand.policy.excluding", fallback: "Excluding") public static let excluding = Strings.tr("Localizable", "entities.on_demand.policy.excluding", fallback: "Excluding")
/// Including /// Including
internal static let including = Strings.tr("Localizable", "entities.on_demand.policy.including", fallback: "Including") public static let including = Strings.tr("Localizable", "entities.on_demand.policy.including", fallback: "Including")
} }
} }
internal enum Openvpn { public enum Openvpn {
internal enum CompressionAlgorithm { public enum CompressionAlgorithm {
/// Unsupported /// Unsupported
internal static let other = Strings.tr("Localizable", "entities.openvpn.compression_algorithm.other", fallback: "Unsupported") public static let other = Strings.tr("Localizable", "entities.openvpn.compression_algorithm.other", fallback: "Unsupported")
} }
internal enum OtpMethod { public enum OtpMethod {
/// Append /// Append
internal static let append = Strings.tr("Localizable", "entities.openvpn.otp_method.append", fallback: "Append") public static let append = Strings.tr("Localizable", "entities.openvpn.otp_method.append", fallback: "Append")
/// Encode /// Encode
internal static let encode = Strings.tr("Localizable", "entities.openvpn.otp_method.encode", fallback: "Encode") public static let encode = Strings.tr("Localizable", "entities.openvpn.otp_method.encode", fallback: "Encode")
/// None /// None
internal static let `none` = Strings.tr("Localizable", "entities.openvpn.otp_method.none", fallback: "None") public static let `none` = Strings.tr("Localizable", "entities.openvpn.otp_method.none", fallback: "None")
} }
} }
internal enum Profile { public enum Profile {
internal enum Name { public enum Name {
/// New profile /// New profile
internal static let new = Strings.tr("Localizable", "entities.profile.name.new", fallback: "New profile") public static let new = Strings.tr("Localizable", "entities.profile.name.new", fallback: "New profile")
} }
} }
internal enum TunnelStatus { public enum TunnelStatus {
/// Activating /// Activating
internal static let activating = Strings.tr("Localizable", "entities.tunnel_status.activating", fallback: "Activating") public static let activating = Strings.tr("Localizable", "entities.tunnel_status.activating", fallback: "Activating")
/// Active /// Active
internal static let active = Strings.tr("Localizable", "entities.tunnel_status.active", fallback: "Active") public static let active = Strings.tr("Localizable", "entities.tunnel_status.active", fallback: "Active")
/// Deactivating /// Deactivating
internal static let deactivating = Strings.tr("Localizable", "entities.tunnel_status.deactivating", fallback: "Deactivating") public static let deactivating = Strings.tr("Localizable", "entities.tunnel_status.deactivating", fallback: "Deactivating")
/// Inactive /// Inactive
internal static let inactive = Strings.tr("Localizable", "entities.tunnel_status.inactive", fallback: "Inactive") public static let inactive = Strings.tr("Localizable", "entities.tunnel_status.inactive", fallback: "Inactive")
} }
} }
internal enum Errors { public enum Errors {
internal enum App { public enum App {
/// Unable to complete operation. /// Unable to complete operation.
internal static let `default` = Strings.tr("Localizable", "errors.app.default", fallback: "Unable to complete operation.") public static let `default` = Strings.tr("Localizable", "errors.app.default", fallback: "Unable to complete operation.")
/// Profile name is empty. /// Profile name is empty.
internal static let emptyProfileName = Strings.tr("Localizable", "errors.app.empty_profile_name", fallback: "Profile name is empty.") public static let emptyProfileName = Strings.tr("Localizable", "errors.app.empty_profile_name", fallback: "Profile name is empty.")
/// IP module can only be enabled together with a connection. /// IP module can only be enabled together with a connection.
internal static let ipModuleRequiresConnection = Strings.tr("Localizable", "errors.app.ip_module_requires_connection", fallback: "IP module can only be enabled together with a connection.") public static let ipModuleRequiresConnection = Strings.tr("Localizable", "errors.app.ip_module_requires_connection", fallback: "IP module can only be enabled together with a connection.")
/// Module %@ is malformed. %@ /// Module %@ is malformed. %@
internal static func malformedModule(_ p1: Any, _ p2: Any) -> String { public static func malformedModule(_ p1: Any, _ p2: Any) -> String {
return Strings.tr("Localizable", "errors.app.malformed_module", String(describing: p1), String(describing: p2), fallback: "Module %@ is malformed. %@") return Strings.tr("Localizable", "errors.app.malformed_module", String(describing: p1), String(describing: p2), fallback: "Module %@ is malformed. %@")
} }
/// Only one connection module can be active at a time. /// Only one connection module can be active at a time.
internal static let multipleConnectionModules = Strings.tr("Localizable", "errors.app.multiple_connection_modules", fallback: "Only one connection module can be active at a time.") public static let multipleConnectionModules = Strings.tr("Localizable", "errors.app.multiple_connection_modules", fallback: "Only one connection module can be active at a time.")
internal enum Passepartout { public enum Passepartout {
/// Unable to complete operation (code=%@). /// Unable to complete operation (code=%@).
internal static func `default`(_ p1: Any) -> String { public static func `default`(_ p1: Any) -> String {
return Strings.tr("Localizable", "errors.app.passepartout.default", String(describing: p1), fallback: "Unable to complete operation (code=%@).") return Strings.tr("Localizable", "errors.app.passepartout.default", String(describing: p1), fallback: "Unable to complete operation (code=%@).")
} }
/// Invalid fields (%@). /// Invalid fields (%@).
internal static func invalidFields(_ p1: Any) -> String { public static func invalidFields(_ p1: Any) -> String {
return Strings.tr("Localizable", "errors.app.passepartout.invalid_fields", String(describing: p1), fallback: "Invalid fields (%@).") return Strings.tr("Localizable", "errors.app.passepartout.invalid_fields", String(describing: p1), fallback: "Invalid fields (%@).")
} }
/// Unable to parse file. /// Unable to parse file.
internal static let parsing = Strings.tr("Localizable", "errors.app.passepartout.parsing", fallback: "Unable to parse file.") public static let parsing = Strings.tr("Localizable", "errors.app.passepartout.parsing", fallback: "Unable to parse file.")
} }
} }
internal enum Tunnel { public enum Tunnel {
/// Auth failed /// Auth failed
internal static let auth = Strings.tr("Localizable", "errors.tunnel.auth", fallback: "Auth failed") public static let auth = Strings.tr("Localizable", "errors.tunnel.auth", fallback: "Auth failed")
/// Compression unsupported /// Compression unsupported
internal static let compression = Strings.tr("Localizable", "errors.tunnel.compression", fallback: "Compression unsupported") public static let compression = Strings.tr("Localizable", "errors.tunnel.compression", fallback: "Compression unsupported")
/// DNS failed /// DNS failed
internal static let dns = Strings.tr("Localizable", "errors.tunnel.dns", fallback: "DNS failed") public static let dns = Strings.tr("Localizable", "errors.tunnel.dns", fallback: "DNS failed")
/// Encryption failed /// Encryption failed
internal static let encryption = Strings.tr("Localizable", "errors.tunnel.encryption", fallback: "Encryption failed") public static let encryption = Strings.tr("Localizable", "errors.tunnel.encryption", fallback: "Encryption failed")
/// Failed /// Failed
internal static let generic = Strings.tr("Localizable", "errors.tunnel.generic", fallback: "Failed") public static let generic = Strings.tr("Localizable", "errors.tunnel.generic", fallback: "Failed")
/// Missing routing /// Missing routing
internal static let routing = Strings.tr("Localizable", "errors.tunnel.routing", fallback: "Missing routing") public static let routing = Strings.tr("Localizable", "errors.tunnel.routing", fallback: "Missing routing")
/// Server shutdown /// Server shutdown
internal static let shutdown = Strings.tr("Localizable", "errors.tunnel.shutdown", fallback: "Server shutdown") public static let shutdown = Strings.tr("Localizable", "errors.tunnel.shutdown", fallback: "Server shutdown")
/// Timeout /// Timeout
internal static let timeout = Strings.tr("Localizable", "errors.tunnel.timeout", fallback: "Timeout") public static let timeout = Strings.tr("Localizable", "errors.tunnel.timeout", fallback: "Timeout")
/// TLS failed /// TLS failed
internal static let tls = Strings.tr("Localizable", "errors.tunnel.tls", fallback: "TLS failed") public static let tls = Strings.tr("Localizable", "errors.tunnel.tls", fallback: "TLS failed")
} }
} }
internal enum Global { public enum Global {
/// About /// About
internal static let about = Strings.tr("Localizable", "global.about", fallback: "About") public static let about = Strings.tr("Localizable", "global.about", fallback: "About")
/// Account /// Account
internal static let account = Strings.tr("Localizable", "global.account", fallback: "Account") public static let account = Strings.tr("Localizable", "global.account", fallback: "Account")
/// Address /// Address
internal static let address = Strings.tr("Localizable", "global.address", fallback: "Address") public static let address = Strings.tr("Localizable", "global.address", fallback: "Address")
/// Addresses /// Addresses
internal static let addresses = Strings.tr("Localizable", "global.addresses", fallback: "Addresses") public static let addresses = Strings.tr("Localizable", "global.addresses", fallback: "Addresses")
/// Any /// Any
internal static let any = Strings.tr("Localizable", "global.any", fallback: "Any") public static let any = Strings.tr("Localizable", "global.any", fallback: "Any")
/// Cancel /// Cancel
internal static let cancel = Strings.tr("Localizable", "global.cancel", fallback: "Cancel") public static let cancel = Strings.tr("Localizable", "global.cancel", fallback: "Cancel")
/// Certificate /// Certificate
internal static let certificate = Strings.tr("Localizable", "global.certificate", fallback: "Certificate") public static let certificate = Strings.tr("Localizable", "global.certificate", fallback: "Certificate")
/// Compression /// Compression
internal static let compression = Strings.tr("Localizable", "global.compression", fallback: "Compression") public static let compression = Strings.tr("Localizable", "global.compression", fallback: "Compression")
/// Connect /// Connect
internal static let connect = Strings.tr("Localizable", "global.connect", fallback: "Connect") public static let connect = Strings.tr("Localizable", "global.connect", fallback: "Connect")
/// Connection /// Connection
internal static let connection = Strings.tr("Localizable", "global.connection", fallback: "Connection") public static let connection = Strings.tr("Localizable", "global.connection", fallback: "Connection")
/// Default /// Default
internal static let `default` = Strings.tr("Localizable", "global.default", fallback: "Default") public static let `default` = Strings.tr("Localizable", "global.default", fallback: "Default")
/// Destination /// Destination
internal static let destination = Strings.tr("Localizable", "global.destination", fallback: "Destination") public static let destination = Strings.tr("Localizable", "global.destination", fallback: "Destination")
/// Disable /// Disable
internal static let disable = Strings.tr("Localizable", "global.disable", fallback: "Disable") public static let disable = Strings.tr("Localizable", "global.disable", fallback: "Disable")
/// Disabled /// Disabled
internal static let disabled = Strings.tr("Localizable", "global.disabled", fallback: "Disabled") public static let disabled = Strings.tr("Localizable", "global.disabled", fallback: "Disabled")
/// Disconnect /// Disconnect
internal static let disconnect = Strings.tr("Localizable", "global.disconnect", fallback: "Disconnect") public static let disconnect = Strings.tr("Localizable", "global.disconnect", fallback: "Disconnect")
/// Don't ask again
public static let doNotAskAgain = Strings.tr("Localizable", "global.do_not_ask_again", fallback: "Don't ask again")
/// Domain /// Domain
internal static let domain = Strings.tr("Localizable", "global.domain", fallback: "Domain") public static let domain = Strings.tr("Localizable", "global.domain", fallback: "Domain")
/// Done /// Done
internal static let done = Strings.tr("Localizable", "global.done", fallback: "Done") public static let done = Strings.tr("Localizable", "global.done", fallback: "Done")
/// Duplicate /// Duplicate
internal static let duplicate = Strings.tr("Localizable", "global.duplicate", fallback: "Duplicate") public static let duplicate = Strings.tr("Localizable", "global.duplicate", fallback: "Duplicate")
/// Edit /// Edit
internal static let edit = Strings.tr("Localizable", "global.edit", fallback: "Edit") public static let edit = Strings.tr("Localizable", "global.edit", fallback: "Edit")
/// Empty /// Empty
internal static let empty = Strings.tr("Localizable", "global.empty", fallback: "Empty") public static let empty = Strings.tr("Localizable", "global.empty", fallback: "Empty")
/// Enable /// Enable
internal static let enable = Strings.tr("Localizable", "global.enable", fallback: "Enable") public static let enable = Strings.tr("Localizable", "global.enable", fallback: "Enable")
/// Enabled /// Enabled
internal static let enabled = Strings.tr("Localizable", "global.enabled", fallback: "Enabled") public static let enabled = Strings.tr("Localizable", "global.enabled", fallback: "Enabled")
/// Endpoint /// Endpoint
internal static let endpoint = Strings.tr("Localizable", "global.endpoint", fallback: "Endpoint") public static let endpoint = Strings.tr("Localizable", "global.endpoint", fallback: "Endpoint")
/// Folder /// Folder
internal static let folder = Strings.tr("Localizable", "global.folder", fallback: "Folder") public static let folder = Strings.tr("Localizable", "global.folder", fallback: "Folder")
/// Gateway /// Gateway
internal static let gateway = Strings.tr("Localizable", "global.gateway", fallback: "Gateway") public static let gateway = Strings.tr("Localizable", "global.gateway", fallback: "Gateway")
/// General /// General
internal static let general = Strings.tr("Localizable", "global.general", fallback: "General") public static let general = Strings.tr("Localizable", "global.general", fallback: "General")
/// Hostname /// Hostname
internal static let hostname = Strings.tr("Localizable", "global.hostname", fallback: "Hostname") public static let hostname = Strings.tr("Localizable", "global.hostname", fallback: "Hostname")
/// Interface /// Interface
internal static let interface = Strings.tr("Localizable", "global.interface", fallback: "Interface") public static let interface = Strings.tr("Localizable", "global.interface", fallback: "Interface")
/// Keep-alive /// Keep-alive
internal static let keepAlive = Strings.tr("Localizable", "global.keep_alive", fallback: "Keep-alive") public static let keepAlive = Strings.tr("Localizable", "global.keep_alive", fallback: "Keep-alive")
/// Key /// Key
internal static let key = Strings.tr("Localizable", "global.key", fallback: "Key") public static let key = Strings.tr("Localizable", "global.key", fallback: "Key")
/// Method /// Method
internal static let method = Strings.tr("Localizable", "global.method", fallback: "Method") public static let method = Strings.tr("Localizable", "global.method", fallback: "Method")
/// Modules /// Modules
internal static let modules = Strings.tr("Localizable", "global.modules", fallback: "Modules") public static let modules = Strings.tr("Localizable", "global.modules", fallback: "Modules")
/// %d seconds /// %d seconds
internal static func nSeconds(_ p1: Int) -> String { public static func nSeconds(_ p1: Int) -> String {
return Strings.tr("Localizable", "global.n_seconds", p1, fallback: "%d seconds") return Strings.tr("Localizable", "global.n_seconds", p1, fallback: "%d seconds")
} }
/// Name /// Name
internal static let name = Strings.tr("Localizable", "global.name", fallback: "Name") public static let name = Strings.tr("Localizable", "global.name", fallback: "Name")
/// Networks /// Networks
internal static let networks = Strings.tr("Localizable", "global.networks", fallback: "Networks") public static let networks = Strings.tr("Localizable", "global.networks", fallback: "Networks")
/// No content /// No content
internal static let noContent = Strings.tr("Localizable", "global.no_content", fallback: "No content") public static let noContent = Strings.tr("Localizable", "global.no_content", fallback: "No content")
/// No selection /// No selection
internal static let noSelection = Strings.tr("Localizable", "global.no_selection", fallback: "No selection") public static let noSelection = Strings.tr("Localizable", "global.no_selection", fallback: "No selection")
/// None /// None
internal static let `none` = Strings.tr("Localizable", "global.none", fallback: "None") public static let `none` = Strings.tr("Localizable", "global.none", fallback: "None")
/// OK /// OK
internal static let ok = Strings.tr("Localizable", "global.ok", fallback: "OK") public static let ok = Strings.tr("Localizable", "global.ok", fallback: "OK")
/// On demand /// On demand
internal static let onDemand = Strings.tr("Localizable", "global.on_demand", fallback: "On demand") public static let onDemand = Strings.tr("Localizable", "global.on_demand", fallback: "On demand")
/// Other /// Other
internal static let other = Strings.tr("Localizable", "global.other", fallback: "Other") public static let other = Strings.tr("Localizable", "global.other", fallback: "Other")
/// Password /// Password
internal static let password = Strings.tr("Localizable", "global.password", fallback: "Password") public static let password = Strings.tr("Localizable", "global.password", fallback: "Password")
/// Port /// Port
internal static let port = Strings.tr("Localizable", "global.port", fallback: "Port") public static let port = Strings.tr("Localizable", "global.port", fallback: "Port")
/// Private key /// Private key
internal static let privateKey = Strings.tr("Localizable", "global.private_key", fallback: "Private key") public static let privateKey = Strings.tr("Localizable", "global.private_key", fallback: "Private key")
/// Protocol /// Protocol
internal static let `protocol` = Strings.tr("Localizable", "global.protocol", fallback: "Protocol") public static let `protocol` = Strings.tr("Localizable", "global.protocol", fallback: "Protocol")
/// Public key /// Public key
internal static let publicKey = Strings.tr("Localizable", "global.public_key", fallback: "Public key") public static let publicKey = Strings.tr("Localizable", "global.public_key", fallback: "Public key")
/// Delete /// Delete
internal static let remove = Strings.tr("Localizable", "global.remove", fallback: "Delete") public static let remove = Strings.tr("Localizable", "global.remove", fallback: "Delete")
/// Restart /// Restart
internal static let restart = Strings.tr("Localizable", "global.restart", fallback: "Restart") public static let restart = Strings.tr("Localizable", "global.restart", fallback: "Restart")
/// Route /// Route
internal static let route = Strings.tr("Localizable", "global.route", fallback: "Route") public static let route = Strings.tr("Localizable", "global.route", fallback: "Route")
/// Routes /// Routes
internal static let routes = Strings.tr("Localizable", "global.routes", fallback: "Routes") public static let routes = Strings.tr("Localizable", "global.routes", fallback: "Routes")
/// Save /// Save
internal static let save = Strings.tr("Localizable", "global.save", fallback: "Save") public static let save = Strings.tr("Localizable", "global.save", fallback: "Save")
/// Server /// Server
internal static let server = Strings.tr("Localizable", "global.server", fallback: "Server") public static let server = Strings.tr("Localizable", "global.server", fallback: "Server")
/// Servers /// Servers
internal static let servers = Strings.tr("Localizable", "global.servers", fallback: "Servers") public static let servers = Strings.tr("Localizable", "global.servers", fallback: "Servers")
/// Settings /// Settings
internal static let settings = Strings.tr("Localizable", "global.settings", fallback: "Settings") public static let settings = Strings.tr("Localizable", "global.settings", fallback: "Settings")
/// Status /// Status
internal static let status = Strings.tr("Localizable", "global.status", fallback: "Status") public static let status = Strings.tr("Localizable", "global.status", fallback: "Status")
/// Storage /// Storage
internal static let storage = Strings.tr("Localizable", "global.storage", fallback: "Storage") public static let storage = Strings.tr("Localizable", "global.storage", fallback: "Storage")
/// Subnet /// Subnet
internal static let subnet = Strings.tr("Localizable", "global.subnet", fallback: "Subnet") public static let subnet = Strings.tr("Localizable", "global.subnet", fallback: "Subnet")
/// Uninstall /// Uninstall
internal static let uninstall = Strings.tr("Localizable", "global.uninstall", fallback: "Uninstall") public static let uninstall = Strings.tr("Localizable", "global.uninstall", fallback: "Uninstall")
/// Unknown /// Unknown
internal static let unknown = Strings.tr("Localizable", "global.unknown", fallback: "Unknown") public static let unknown = Strings.tr("Localizable", "global.unknown", fallback: "Unknown")
/// Username /// Username
internal static let username = Strings.tr("Localizable", "global.username", fallback: "Username") public static let username = Strings.tr("Localizable", "global.username", fallback: "Username")
/// Version /// Version
internal static let version = Strings.tr("Localizable", "global.version", fallback: "Version") public static let version = Strings.tr("Localizable", "global.version", fallback: "Version")
} }
internal enum Modules { public enum Modules {
internal enum Dns { public enum Dns {
internal enum SearchDomains { public enum SearchDomains {
/// Add domain /// Add domain
internal static let add = Strings.tr("Localizable", "modules.dns.search_domains.add", fallback: "Add domain") public static let add = Strings.tr("Localizable", "modules.dns.search_domains.add", fallback: "Add domain")
} }
internal enum Servers { public enum Servers {
/// Add address /// Add address
internal static let add = Strings.tr("Localizable", "modules.dns.servers.add", fallback: "Add address") public static let add = Strings.tr("Localizable", "modules.dns.servers.add", fallback: "Add address")
} }
} }
internal enum HttpProxy { public enum HttpProxy {
internal enum BypassDomains { public enum BypassDomains {
/// Add bypass domain /// Add bypass domain
internal static let add = Strings.tr("Localizable", "modules.http_proxy.bypass_domains.add", fallback: "Add bypass domain") public static let add = Strings.tr("Localizable", "modules.http_proxy.bypass_domains.add", fallback: "Add bypass domain")
} }
} }
internal enum Ip { public enum Ip {
internal enum Routes { public enum Routes {
/// Add %@ /// Add %@
internal static func addFamily(_ p1: Any) -> String { public static func addFamily(_ p1: Any) -> String {
return Strings.tr("Localizable", "modules.ip.routes.add_family", String(describing: p1), fallback: "Add %@") return Strings.tr("Localizable", "modules.ip.routes.add_family", String(describing: p1), fallback: "Add %@")
} }
/// Exclude route /// Exclude route
internal static let exclude = Strings.tr("Localizable", "modules.ip.routes.exclude", fallback: "Exclude route") public static let exclude = Strings.tr("Localizable", "modules.ip.routes.exclude", fallback: "Exclude route")
/// Excluded routes /// Excluded routes
internal static let excluded = Strings.tr("Localizable", "modules.ip.routes.excluded", fallback: "Excluded routes") public static let excluded = Strings.tr("Localizable", "modules.ip.routes.excluded", fallback: "Excluded routes")
/// Include route /// Include route
internal static let include = Strings.tr("Localizable", "modules.ip.routes.include", fallback: "Include route") public static let include = Strings.tr("Localizable", "modules.ip.routes.include", fallback: "Include route")
/// Included routes /// Included routes
internal static let included = Strings.tr("Localizable", "modules.ip.routes.included", fallback: "Included routes") public static let included = Strings.tr("Localizable", "modules.ip.routes.included", fallback: "Included routes")
} }
} }
internal enum OnDemand { public enum OnDemand {
/// Ethernet /// Ethernet
internal static let ethernet = Strings.tr("Localizable", "modules.on_demand.ethernet", fallback: "Ethernet") public static let ethernet = Strings.tr("Localizable", "modules.on_demand.ethernet", fallback: "Ethernet")
/// Mobile /// Mobile
internal static let mobile = Strings.tr("Localizable", "modules.on_demand.mobile", fallback: "Mobile") public static let mobile = Strings.tr("Localizable", "modules.on_demand.mobile", fallback: "Mobile")
/// Policy /// Policy
internal static let policy = Strings.tr("Localizable", "modules.on_demand.policy", fallback: "Policy") public static let policy = Strings.tr("Localizable", "modules.on_demand.policy", fallback: "Policy")
internal enum Policy { public enum Policy {
/// Activate the VPN %@. /// Activate the VPN %@.
internal static func footer(_ p1: Any) -> String { public static func footer(_ p1: Any) -> String {
return Strings.tr("Localizable", "modules.on_demand.policy.footer", String(describing: p1), fallback: "Activate the VPN %@.") return Strings.tr("Localizable", "modules.on_demand.policy.footer", String(describing: p1), fallback: "Activate the VPN %@.")
} }
internal enum Footer { public enum Footer {
/// in any network /// in any network
internal static let any = Strings.tr("Localizable", "modules.on_demand.policy.footer.any", fallback: "in any network") public static let any = Strings.tr("Localizable", "modules.on_demand.policy.footer.any", fallback: "in any network")
/// except in the networks below /// except in the networks below
internal static let excluding = Strings.tr("Localizable", "modules.on_demand.policy.footer.excluding", fallback: "except in the networks below") public static let excluding = Strings.tr("Localizable", "modules.on_demand.policy.footer.excluding", fallback: "except in the networks below")
/// only in the networks below /// only in the networks below
internal static let including = Strings.tr("Localizable", "modules.on_demand.policy.footer.including", fallback: "only in the networks below") public static let including = Strings.tr("Localizable", "modules.on_demand.policy.footer.including", fallback: "only in the networks below")
} }
} }
internal enum Ssid { public enum Ssid {
/// Add SSID /// Add SSID
internal static let add = Strings.tr("Localizable", "modules.on_demand.ssid.add", fallback: "Add SSID") public static let add = Strings.tr("Localizable", "modules.on_demand.ssid.add", fallback: "Add SSID")
} }
} }
internal enum Openvpn { public enum Openvpn {
/// Cipher /// Cipher
internal static let cipher = Strings.tr("Localizable", "modules.openvpn.cipher", fallback: "Cipher") public static let cipher = Strings.tr("Localizable", "modules.openvpn.cipher", fallback: "Cipher")
/// Communication /// Communication
internal static let communication = Strings.tr("Localizable", "modules.openvpn.communication", fallback: "Communication") public static let communication = Strings.tr("Localizable", "modules.openvpn.communication", fallback: "Communication")
/// Compression /// Compression
internal static let compression = Strings.tr("Localizable", "modules.openvpn.compression", fallback: "Compression") public static let compression = Strings.tr("Localizable", "modules.openvpn.compression", fallback: "Compression")
/// Algorithm /// Algorithm
internal static let compressionAlgorithm = Strings.tr("Localizable", "modules.openvpn.compression_algorithm", fallback: "Algorithm") public static let compressionAlgorithm = Strings.tr("Localizable", "modules.openvpn.compression_algorithm", fallback: "Algorithm")
/// Framing /// Framing
internal static let compressionFraming = Strings.tr("Localizable", "modules.openvpn.compression_framing", fallback: "Framing") public static let compressionFraming = Strings.tr("Localizable", "modules.openvpn.compression_framing", fallback: "Framing")
/// Credentials /// Credentials
internal static let credentials = Strings.tr("Localizable", "modules.openvpn.credentials", fallback: "Credentials") public static let credentials = Strings.tr("Localizable", "modules.openvpn.credentials", fallback: "Credentials")
/// Digest /// Digest
internal static let digest = Strings.tr("Localizable", "modules.openvpn.digest", fallback: "Digest") public static let digest = Strings.tr("Localizable", "modules.openvpn.digest", fallback: "Digest")
/// Extended verification /// Extended verification
internal static let eku = Strings.tr("Localizable", "modules.openvpn.eku", fallback: "Extended verification") public static let eku = Strings.tr("Localizable", "modules.openvpn.eku", fallback: "Extended verification")
/// Pull /// Pull
internal static let pull = Strings.tr("Localizable", "modules.openvpn.pull", fallback: "Pull") public static let pull = Strings.tr("Localizable", "modules.openvpn.pull", fallback: "Pull")
/// Randomize endpoint /// Randomize endpoint
internal static let randomizeEndpoint = Strings.tr("Localizable", "modules.openvpn.randomize_endpoint", fallback: "Randomize endpoint") public static let randomizeEndpoint = Strings.tr("Localizable", "modules.openvpn.randomize_endpoint", fallback: "Randomize endpoint")
/// Randomize hostname /// Randomize hostname
internal static let randomizeHostname = Strings.tr("Localizable", "modules.openvpn.randomize_hostname", fallback: "Randomize hostname") public static let randomizeHostname = Strings.tr("Localizable", "modules.openvpn.randomize_hostname", fallback: "Randomize hostname")
/// Redirect gateway /// Redirect gateway
internal static let redirectGateway = Strings.tr("Localizable", "modules.openvpn.redirect_gateway", fallback: "Redirect gateway") public static let redirectGateway = Strings.tr("Localizable", "modules.openvpn.redirect_gateway", fallback: "Redirect gateway")
/// Remotes /// Remotes
internal static let remotes = Strings.tr("Localizable", "modules.openvpn.remotes", fallback: "Remotes") public static let remotes = Strings.tr("Localizable", "modules.openvpn.remotes", fallback: "Remotes")
/// Renegotiation /// Renegotiation
internal static let renegotiation = Strings.tr("Localizable", "modules.openvpn.renegotiation", fallback: "Renegotiation") public static let renegotiation = Strings.tr("Localizable", "modules.openvpn.renegotiation", fallback: "Renegotiation")
/// Wrapping /// Wrapping
internal static let tlsWrap = Strings.tr("Localizable", "modules.openvpn.tls_wrap", fallback: "Wrapping") public static let tlsWrap = Strings.tr("Localizable", "modules.openvpn.tls_wrap", fallback: "Wrapping")
internal enum Credentials { public enum Credentials {
/// Interactive /// Interactive
internal static let interactive = Strings.tr("Localizable", "modules.openvpn.credentials.interactive", fallback: "Interactive") public static let interactive = Strings.tr("Localizable", "modules.openvpn.credentials.interactive", fallback: "Interactive")
internal enum Interactive { public enum Interactive {
/// On-demand will be disabled. /// On-demand will be disabled.
internal static let footer = Strings.tr("Localizable", "modules.openvpn.credentials.interactive.footer", fallback: "On-demand will be disabled.") public static let footer = Strings.tr("Localizable", "modules.openvpn.credentials.interactive.footer", fallback: "On-demand will be disabled.")
} }
internal enum OtpMethod { public enum OtpMethod {
internal enum Approach { public enum Approach {
/// The OTP will be appended to the password. /// The OTP will be appended to the password.
internal static let append = Strings.tr("Localizable", "modules.openvpn.credentials.otp_method.approach.append", fallback: "The OTP will be appended to the password.") public static let append = Strings.tr("Localizable", "modules.openvpn.credentials.otp_method.approach.append", fallback: "The OTP will be appended to the password.")
/// The OTP will be encoded in Base64 with the password. /// The OTP will be encoded in Base64 with the password.
internal static let encode = Strings.tr("Localizable", "modules.openvpn.credentials.otp_method.approach.encode", fallback: "The OTP will be encoded in Base64 with the password.") public static let encode = Strings.tr("Localizable", "modules.openvpn.credentials.otp_method.approach.encode", fallback: "The OTP will be encoded in Base64 with the password.")
} }
} }
} }
} }
internal enum Wireguard { public enum Wireguard {
/// Allowed IPs /// Allowed IPs
internal static let allowedIps = Strings.tr("Localizable", "modules.wireguard.allowed_ips", fallback: "Allowed IPs") public static let allowedIps = Strings.tr("Localizable", "modules.wireguard.allowed_ips", fallback: "Allowed IPs")
/// Interface /// Interface
internal static let interface = Strings.tr("Localizable", "modules.wireguard.interface", fallback: "Interface") public static let interface = Strings.tr("Localizable", "modules.wireguard.interface", fallback: "Interface")
/// Peer #%d /// Peer #%d
internal static func peer(_ p1: Int) -> String { public static func peer(_ p1: Int) -> String {
return Strings.tr("Localizable", "modules.wireguard.peer", p1, fallback: "Peer #%d") return Strings.tr("Localizable", "modules.wireguard.peer", p1, fallback: "Peer #%d")
} }
/// Pre-shared key /// Pre-shared key
internal static let presharedKey = Strings.tr("Localizable", "modules.wireguard.preshared_key", fallback: "Pre-shared key") public static let presharedKey = Strings.tr("Localizable", "modules.wireguard.preshared_key", fallback: "Pre-shared key")
} }
} }
internal enum Placeholders { public enum Placeholders {
/// secret /// secret
internal static let secret = Strings.tr("Localizable", "placeholders.secret", fallback: "secret") public static let secret = Strings.tr("Localizable", "placeholders.secret", fallback: "secret")
/// username /// username
internal static let username = Strings.tr("Localizable", "placeholders.username", fallback: "username") public static let username = Strings.tr("Localizable", "placeholders.username", fallback: "username")
internal enum OnDemand { public enum OnDemand {
/// My SSID /// My SSID
internal static let ssid = Strings.tr("Localizable", "placeholders.on_demand.ssid", fallback: "My SSID") public static let ssid = Strings.tr("Localizable", "placeholders.on_demand.ssid", fallback: "My SSID")
} }
internal enum Profile { public enum Profile {
/// My profile /// My profile
internal static let name = Strings.tr("Localizable", "placeholders.profile.name", fallback: "My profile") public static let name = Strings.tr("Localizable", "placeholders.profile.name", fallback: "My profile")
} }
} }
internal enum Views { public enum Views {
internal enum About { public enum About {
/// About /// About
internal static let title = Strings.tr("Localizable", "views.about.title", fallback: "About") public static let title = Strings.tr("Localizable", "views.about.title", fallback: "About")
internal enum Credits { public enum Credits {
/// Licenses /// Licenses
internal static let licenses = Strings.tr("Localizable", "views.about.credits.licenses", fallback: "Licenses") public static let licenses = Strings.tr("Localizable", "views.about.credits.licenses", fallback: "Licenses")
/// Notices /// Notices
internal static let notices = Strings.tr("Localizable", "views.about.credits.notices", fallback: "Notices") public static let notices = Strings.tr("Localizable", "views.about.credits.notices", fallback: "Notices")
/// Credits /// Credits
internal static let title = Strings.tr("Localizable", "views.about.credits.title", fallback: "Credits") public static let title = Strings.tr("Localizable", "views.about.credits.title", fallback: "Credits")
/// Translations /// Translations
internal static let translations = Strings.tr("Localizable", "views.about.credits.translations", fallback: "Translations") public static let translations = Strings.tr("Localizable", "views.about.credits.translations", fallback: "Translations")
} }
internal enum Links { public enum Links {
/// Links /// Links
internal static let title = Strings.tr("Localizable", "views.about.links.title", fallback: "Links") public static let title = Strings.tr("Localizable", "views.about.links.title", fallback: "Links")
internal enum Rows { public enum Rows {
/// Disclaimer /// Disclaimer
internal static let disclaimer = Strings.tr("Localizable", "views.about.links.rows.disclaimer", fallback: "Disclaimer") public static let disclaimer = Strings.tr("Localizable", "views.about.links.rows.disclaimer", fallback: "Disclaimer")
/// Home page /// Home page
internal static let homePage = Strings.tr("Localizable", "views.about.links.rows.home_page", fallback: "Home page") public static let homePage = Strings.tr("Localizable", "views.about.links.rows.home_page", fallback: "Home page")
/// Join community /// Join community
internal static let joinCommunity = Strings.tr("Localizable", "views.about.links.rows.join_community", fallback: "Join community") public static let joinCommunity = Strings.tr("Localizable", "views.about.links.rows.join_community", fallback: "Join community")
/// Privacy policy /// Privacy policy
internal static let privacyPolicy = Strings.tr("Localizable", "views.about.links.rows.privacy_policy", fallback: "Privacy policy") public static let privacyPolicy = Strings.tr("Localizable", "views.about.links.rows.privacy_policy", fallback: "Privacy policy")
/// Write a review /// Write a review
internal static let writeReview = Strings.tr("Localizable", "views.about.links.rows.write_review", fallback: "Write a review") public static let writeReview = Strings.tr("Localizable", "views.about.links.rows.write_review", fallback: "Write a review")
} }
internal enum Sections { public enum Sections {
/// Support /// Support
internal static let support = Strings.tr("Localizable", "views.about.links.sections.support", fallback: "Support") public static let support = Strings.tr("Localizable", "views.about.links.sections.support", fallback: "Support")
/// Web /// Web
internal static let web = Strings.tr("Localizable", "views.about.links.sections.web", fallback: "Web") public static let web = Strings.tr("Localizable", "views.about.links.sections.web", fallback: "Web")
} }
} }
internal enum Sections { public enum Sections {
/// Resources /// Resources
internal static let resources = Strings.tr("Localizable", "views.about.sections.resources", fallback: "Resources") public static let resources = Strings.tr("Localizable", "views.about.sections.resources", fallback: "Resources")
} }
} }
internal enum Diagnostics { public enum Diagnostics {
/// Diagnostics /// Diagnostics
internal static let title = Strings.tr("Localizable", "views.diagnostics.title", fallback: "Diagnostics") public static let title = Strings.tr("Localizable", "views.diagnostics.title", fallback: "Diagnostics")
internal enum Alerts { public enum Alerts {
internal enum ReportIssue { public enum ReportIssue {
/// The device is not configured to send e-mails. /// The device is not configured to send e-mails.
internal static let email = Strings.tr("Localizable", "views.diagnostics.alerts.report_issue.email", fallback: "The device is not configured to send e-mails.") public static let email = Strings.tr("Localizable", "views.diagnostics.alerts.report_issue.email", fallback: "The device is not configured to send e-mails.")
} }
} }
internal enum Openvpn { public enum Openvpn {
internal enum Rows { public enum Rows {
/// Server configuration /// Server configuration
internal static let serverConfiguration = Strings.tr("Localizable", "views.diagnostics.openvpn.rows.server_configuration", fallback: "Server configuration") public static let serverConfiguration = Strings.tr("Localizable", "views.diagnostics.openvpn.rows.server_configuration", fallback: "Server configuration")
} }
} }
internal enum ReportIssue { public enum ReportIssue {
/// Report issue /// Report issue
internal static let title = Strings.tr("Localizable", "views.diagnostics.report_issue.title", fallback: "Report issue") public static let title = Strings.tr("Localizable", "views.diagnostics.report_issue.title", fallback: "Report issue")
} }
internal enum Rows { public enum Rows {
/// App /// App
internal static let app = Strings.tr("Localizable", "views.diagnostics.rows.app", fallback: "App") public static let app = Strings.tr("Localizable", "views.diagnostics.rows.app", fallback: "App")
/// Include private data /// Include private data
internal static let includePrivateData = Strings.tr("Localizable", "views.diagnostics.rows.include_private_data", fallback: "Include private data") public static let includePrivateData = Strings.tr("Localizable", "views.diagnostics.rows.include_private_data", fallback: "Include private data")
/// Delete all logs /// Delete all logs
internal static let removeTunnelLogs = Strings.tr("Localizable", "views.diagnostics.rows.remove_tunnel_logs", fallback: "Delete all logs") public static let removeTunnelLogs = Strings.tr("Localizable", "views.diagnostics.rows.remove_tunnel_logs", fallback: "Delete all logs")
/// Tunnel /// Tunnel
internal static let tunnel = Strings.tr("Localizable", "views.diagnostics.rows.tunnel", fallback: "Tunnel") public static let tunnel = Strings.tr("Localizable", "views.diagnostics.rows.tunnel", fallback: "Tunnel")
} }
internal enum Sections { public enum Sections {
/// Live log /// Live log
internal static let live = Strings.tr("Localizable", "views.diagnostics.sections.live", fallback: "Live log") public static let live = Strings.tr("Localizable", "views.diagnostics.sections.live", fallback: "Live log")
/// Tunnel logs /// Tunnel logs
internal static let tunnel = Strings.tr("Localizable", "views.diagnostics.sections.tunnel", fallback: "Tunnel logs") public static let tunnel = Strings.tr("Localizable", "views.diagnostics.sections.tunnel", fallback: "Tunnel logs")
} }
} }
internal enum Donate { public enum Donate {
/// Make a donation /// Make a donation
internal static let title = Strings.tr("Localizable", "views.donate.title", fallback: "Make a donation") public static let title = Strings.tr("Localizable", "views.donate.title", fallback: "Make a donation")
} }
internal enum Profile { public enum Profile {
internal enum ModuleList { public enum ModuleList {
internal enum Section { public enum Section {
/// Drag modules to rearrange them, as their order determines priority. /// Drag modules to rearrange them, as their order determines priority.
internal static let footer = Strings.tr("Localizable", "views.profile.module_list.section.footer", fallback: "Drag modules to rearrange them, as their order determines priority.") public static let footer = Strings.tr("Localizable", "views.profile.module_list.section.footer", fallback: "Drag modules to rearrange them, as their order determines priority.")
} }
} }
internal enum Rows { public enum Rows {
/// Add module /// Add module
internal static let addModule = Strings.tr("Localizable", "views.profile.rows.add_module", fallback: "Add module") public static let addModule = Strings.tr("Localizable", "views.profile.rows.add_module", fallback: "Add module")
} }
} }
internal enum Profiles { public enum Profiles {
internal enum Alerts { public enum Alerts {
internal enum Import { public enum Import {
internal enum Passphrase { public enum Passphrase {
/// Enter passphrase for '%@'. /// Enter passphrase for '%@'.
internal static func message(_ p1: Any) -> String { public static func message(_ p1: Any) -> String {
return Strings.tr("Localizable", "views.profiles.alerts.import.passphrase.message", String(describing: p1), fallback: "Enter passphrase for '%@'.") return Strings.tr("Localizable", "views.profiles.alerts.import.passphrase.message", String(describing: p1), fallback: "Enter passphrase for '%@'.")
} }
/// Decrypt /// Decrypt
internal static let ok = Strings.tr("Localizable", "views.profiles.alerts.import.passphrase.ok", fallback: "Decrypt") public static let ok = Strings.tr("Localizable", "views.profiles.alerts.import.passphrase.ok", fallback: "Decrypt")
} }
} }
} }
internal enum Errors { public enum Errors {
/// Unable to duplicate profile '%@'. /// Unable to duplicate profile '%@'.
internal static func duplicate(_ p1: Any) -> String { public static func duplicate(_ p1: Any) -> String {
return Strings.tr("Localizable", "views.profiles.errors.duplicate", String(describing: p1), fallback: "Unable to duplicate profile '%@'.") return Strings.tr("Localizable", "views.profiles.errors.duplicate", String(describing: p1), fallback: "Unable to duplicate profile '%@'.")
} }
/// Unable to import profiles. /// Unable to import profiles.
internal static let `import` = Strings.tr("Localizable", "views.profiles.errors.import", fallback: "Unable to import profiles.") public static let `import` = Strings.tr("Localizable", "views.profiles.errors.import", fallback: "Unable to import profiles.")
/// Unable to execute tunnel operation. /// Unable to execute tunnel operation.
internal static let tunnel = Strings.tr("Localizable", "views.profiles.errors.tunnel", fallback: "Unable to execute tunnel operation.") public static let tunnel = Strings.tr("Localizable", "views.profiles.errors.tunnel", fallback: "Unable to execute tunnel operation.")
} }
internal enum Folders { public enum Folders {
/// Installed profile /// Installed profile
internal static let activeProfile = Strings.tr("Localizable", "views.profiles.folders.active_profile", fallback: "Installed profile") public static let activeProfile = Strings.tr("Localizable", "views.profiles.folders.active_profile", fallback: "Installed profile")
/// Add profile /// Add profile
internal static let addProfile = Strings.tr("Localizable", "views.profiles.folders.add_profile", fallback: "Add profile") public static let addProfile = Strings.tr("Localizable", "views.profiles.folders.add_profile", fallback: "Add profile")
/// My profiles /// My profiles
internal static let `default` = Strings.tr("Localizable", "views.profiles.folders.default", fallback: "My profiles") public static let `default` = Strings.tr("Localizable", "views.profiles.folders.default", fallback: "My profiles")
/// No profiles /// No profiles
internal static let noProfiles = Strings.tr("Localizable", "views.profiles.folders.no_profiles", fallback: "No profiles") public static let noProfiles = Strings.tr("Localizable", "views.profiles.folders.no_profiles", fallback: "No profiles")
} }
internal enum Rows { public enum Rows {
/// %d modules /// %d modules
internal static func modules(_ p1: Int) -> String { public static func modules(_ p1: Int) -> String {
return Strings.tr("Localizable", "views.profiles.rows.modules", p1, fallback: "%d modules") return Strings.tr("Localizable", "views.profiles.rows.modules", p1, fallback: "%d modules")
} }
/// Select a profile /// Select a profile
internal static let notInstalled = Strings.tr("Localizable", "views.profiles.rows.not_installed", fallback: "Select a profile") public static let notInstalled = Strings.tr("Localizable", "views.profiles.rows.not_installed", fallback: "Select a profile")
} }
internal enum Toolbar { public enum Toolbar {
/// Import profile /// Import profile
internal static let importProfile = Strings.tr("Localizable", "views.profiles.toolbar.import_profile", fallback: "Import profile") public static let importProfile = Strings.tr("Localizable", "views.profiles.toolbar.import_profile", fallback: "Import profile")
/// New profile /// New profile
internal static let newProfile = Strings.tr("Localizable", "views.profiles.toolbar.new_profile", fallback: "New profile") public static let newProfile = Strings.tr("Localizable", "views.profiles.toolbar.new_profile", fallback: "New profile")
} }
} }
internal enum Settings { public enum Settings {
internal enum Rows { public enum Rows {
/// Confirm quit
public static let confirmQuit = Strings.tr("Localizable", "views.settings.rows.confirm_quit", fallback: "Confirm quit")
/// Lock in background /// Lock in background
internal static let lockInBackground = Strings.tr("Localizable", "views.settings.rows.lock_in_background", fallback: "Lock in background") public static let lockInBackground = Strings.tr("Localizable", "views.settings.rows.lock_in_background", fallback: "Lock in background")
internal enum LockInBackground { public enum LockInBackground {
/// Passepartout is locked /// Passepartout is locked
internal static let message = Strings.tr("Localizable", "views.settings.rows.lock_in_background.message", fallback: "Passepartout is locked") public static let message = Strings.tr("Localizable", "views.settings.rows.lock_in_background.message", fallback: "Passepartout is locked")
} }
} }
internal enum Sections {
/// Lock
internal static let lock = Strings.tr("Localizable", "views.settings.sections.lock", fallback: "Lock")
}
} }
} }
} }

View File

@ -17,6 +17,7 @@
"global.disconnect" = "Disconnect"; "global.disconnect" = "Disconnect";
"global.domain" = "Domain"; "global.domain" = "Domain";
"global.done" = "Done"; "global.done" = "Done";
"global.do_not_ask_again" = "Don't ask again";
"global.duplicate" = "Duplicate"; "global.duplicate" = "Duplicate";
"global.edit" = "Edit"; "global.edit" = "Edit";
"global.empty" = "Empty"; "global.empty" = "Empty";
@ -120,7 +121,7 @@
"views.profile.rows.add_module" = "Add module"; "views.profile.rows.add_module" = "Add module";
"views.profile.module_list.section.footer" = "Drag modules to rearrange them, as their order determines priority."; "views.profile.module_list.section.footer" = "Drag modules to rearrange them, as their order determines priority.";
"views.settings.sections.lock" = "Lock"; "views.settings.rows.confirm_quit" = "Confirm quit";
"views.settings.rows.lock_in_background" = "Lock in background"; "views.settings.rows.lock_in_background" = "Lock in background";
"views.settings.rows.lock_in_background.message" = "Passepartout is locked"; "views.settings.rows.lock_in_background.message" = "Passepartout is locked";
@ -207,6 +208,9 @@
"alerts.iap.restricted.title" = "Restricted"; "alerts.iap.restricted.title" = "Restricted";
"alerts.iap.restricted.message" = "The requested feature is unavailable in this build."; "alerts.iap.restricted.message" = "The requested feature is unavailable in this build.";
"alerts.confirm_quit.title" = "Quit %@";
"alerts.confirm_quit.message" = "The VPN, if enabled, will still run in the background. Do you want to quit?";
// MARK: - Errors // MARK: - Errors
"errors.app.empty_profile_name" = "Profile name is empty."; "errors.app.empty_profile_name" = "Profile name is empty.";

View File

@ -28,6 +28,9 @@ import SwiftUI
public struct SettingsView: View { public struct SettingsView: View {
@AppStorage(AppPreference.confirmsQuit.key)
private var confirmsQuit = true
@AppStorage(AppPreference.locksInBackground.key) @AppStorage(AppPreference.locksInBackground.key)
private var locksInBackground = false private var locksInBackground = false
@ -40,9 +43,12 @@ public struct SettingsView: View {
public var body: some View { public var body: some View {
Form { Form {
Section { Section {
#if os(macOS)
confirmsQuitToggle
#endif
#if os(iOS)
lockInBackgroundToggle lockInBackgroundToggle
} header: { #endif
Text(Strings.Views.Settings.Sections.lock)
} }
} }
.themeForm() .themeForm()
@ -55,6 +61,10 @@ public struct SettingsView: View {
} }
private extension SettingsView { private extension SettingsView {
var confirmsQuitToggle: some View {
Toggle(Strings.Views.Settings.Rows.confirmQuit, isOn: $confirmsQuit)
}
var lockInBackgroundToggle: some View { var lockInBackgroundToggle: some View {
Toggle(Strings.Views.Settings.Rows.lockInBackground, isOn: $locksInBackground) Toggle(Strings.Views.Settings.Rows.lockInBackground, isOn: $locksInBackground)
} }

View File

@ -26,6 +26,8 @@
import Foundation import Foundation
public enum AppPreference: String { public enum AppPreference: String {
case confirmsQuit
case locksInBackground case locksInBackground
case logsPrivateData case logsPrivateData

View File

@ -7,3 +7,4 @@ strings:
params: params:
bundle: Bundle.main bundle: Bundle.main
enumName: Strings enumName: Strings
publicAccess: true