Skip to content

Commit

Permalink
Add environment picker
Browse files Browse the repository at this point in the history
  • Loading branch information
LaurentTreguier committed Jul 23, 2024
1 parent 136cea3 commit 273e577
Show file tree
Hide file tree
Showing 9 changed files with 215 additions and 26 deletions.
30 changes: 29 additions & 1 deletion Fyreplace.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
4D13AF6B2C48301600845FDB /* openapi-generator-config.yaml in Resources */ = {isa = PBXBuildFile; fileRef = 4D13AF6A2C48301600845FDB /* openapi-generator-config.yaml */; };
4D13AF722C492E7200845FDB /* .gitignore in Resources */ = {isa = PBXBuildFile; fileRef = 4D13AF712C492E7200845FDB /* .gitignore */; };
4D13AF752C492F4500845FDB /* Config.sh in Resources */ = {isa = PBXBuildFile; fileRef = 4D13AF742C492F4500845FDB /* Config.sh */; };
4D13AF7B2C4E8F4200845FDB /* EnvironmentPicker.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13AF7A2C4E8F4200845FDB /* EnvironmentPicker.swift */; };
4D13AF812C4E907200845FDB /* Environment.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D13AF802C4E907200845FDB /* Environment.swift */; };
4D39A4C82BF516B7003FA52E /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 4D39A4C72BF516B7003FA52E /* Localizable.xcstrings */; };
4D4D394A2C086DA2007196D2 /* PublishedScreen.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D4D39492C086DA2007196D2 /* PublishedScreen.swift */; };
4D5251EC2C1097A600018CD2 /* Destination.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D5251EB2C1097A600018CD2 /* Destination.swift */; };
Expand All @@ -40,6 +42,7 @@
4D9B3B452C36F46F00A8F7AD /* NSTextContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9B3B442C36F46F00A8F7AD /* NSTextContentType.swift */; };
4D9B3B472C36F50300A8F7AD /* UITextContentType.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9B3B462C36F50300A8F7AD /* UITextContentType.swift */; };
4D9DC5032C11BF2500BA0507 /* Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4D9DC5022C11BF2500BA0507 /* Config.swift */; };
4DB10B502C4FEBFC00634BF6 /* HelpCommands.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DB10B4F2C4FEBFC00634BF6 /* HelpCommands.swift */; };
4DB2E36D2C416611007F958D /* SubmitButton.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DB2E36C2C416611007F958D /* SubmitButton.swift */; };
4DB2E36F2C418F5C007F958D /* DynamicForm.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DB2E36E2C418F5C007F958D /* DynamicForm.swift */; };
4DB2E3722C419612007F958D /* LoginScreenTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4DB2E3712C419612007F958D /* LoginScreenTests.swift */; };
Expand Down Expand Up @@ -76,6 +79,8 @@
4D13AF712C492E7200845FDB /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
4D13AF732C492E8E00845FDB /* Config.release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.release.xcconfig; sourceTree = "<group>"; };
4D13AF742C492F4500845FDB /* Config.sh */ = {isa = PBXFileReference; lastKnownFileType = text.script.sh; path = Config.sh; sourceTree = "<group>"; };
4D13AF7A2C4E8F4200845FDB /* EnvironmentPicker.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EnvironmentPicker.swift; sourceTree = "<group>"; };
4D13AF802C4E907200845FDB /* Environment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Environment.swift; sourceTree = "<group>"; };
4D39A4C72BF516B7003FA52E /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
4D4D39492C086DA2007196D2 /* PublishedScreen.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PublishedScreen.swift; sourceTree = "<group>"; };
4D5251A22C0A78F800018CD2 /* .gitignore */ = {isa = PBXFileReference; lastKnownFileType = text; path = .gitignore; sourceTree = "<group>"; };
Expand Down Expand Up @@ -114,6 +119,7 @@
4D9B3B442C36F46F00A8F7AD /* NSTextContentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NSTextContentType.swift; sourceTree = "<group>"; };
4D9B3B462C36F50300A8F7AD /* UITextContentType.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UITextContentType.swift; sourceTree = "<group>"; };
4D9DC5022C11BF2500BA0507 /* Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Config.swift; sourceTree = "<group>"; };
4DB10B4F2C4FEBFC00634BF6 /* HelpCommands.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HelpCommands.swift; sourceTree = "<group>"; };
4DB2E36C2C416611007F958D /* SubmitButton.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmitButton.swift; sourceTree = "<group>"; };
4DB2E36E2C418F5C007F958D /* DynamicForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DynamicForm.swift; sourceTree = "<group>"; };
4DB2E3712C419612007F958D /* LoginScreenTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LoginScreenTests.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -156,6 +162,14 @@
/* End PBXFrameworksBuildPhase section */

/* Begin PBXGroup section */
4D13AF7C2C4E904E00845FDB /* Data */ = {
isa = PBXGroup;
children = (
4D13AF802C4E907200845FDB /* Environment.swift */,
);
path = Data;
sourceTree = "<group>";
};
4D39A4C62BF51693003FA52E /* Resources */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -232,7 +246,9 @@
4D39A4C62BF51693003FA52E /* Resources */,
4D54C9322BF2608F001DE071 /* Preview Content */,
4D9B3B432C36E64F00A8F7AD /* Extensions */,
4D13AF7C2C4E904E00845FDB /* Data */,
4D54C95E2BF27C78001DE071 /* Views */,
4DB10B4E2C4FEBCE00634BF6 /* Commands */,
4D54C92B2BF2608A001DE071 /* FyreplaceApp.swift */,
);
path = Fyreplace;
Expand Down Expand Up @@ -309,8 +325,9 @@
isa = PBXGroup;
children = (
4DB2E36E2C418F5C007F958D /* DynamicForm.swift */,
4D9B3B3C2C34B13E00A8F7AD /* LogoHeader.swift */,
4DB2E36C2C416611007F958D /* SubmitButton.swift */,
4D13AF7A2C4E8F4200845FDB /* EnvironmentPicker.swift */,
4D9B3B3C2C34B13E00A8F7AD /* LogoHeader.swift */,
);
path = Forms;
sourceTree = "<group>";
Expand All @@ -325,6 +342,14 @@
path = Extensions;
sourceTree = "<group>";
};
4DB10B4E2C4FEBCE00634BF6 /* Commands */ = {
isa = PBXGroup;
children = (
4DB10B4F2C4FEBFC00634BF6 /* HelpCommands.swift */,
);
path = Commands;
sourceTree = "<group>";
};
4DB2E3702C4195FB007F958D /* Screens */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -530,6 +555,7 @@
files = (
4D9B3B3D2C34B13E00A8F7AD /* LogoHeader.swift in Sources */,
4D54C9712BF4EA15001DE071 /* SettingsScreen.swift in Sources */,
4D13AF7B2C4E8F4200845FDB /* EnvironmentPicker.swift in Sources */,
4D9B3B422C36E23A00A8F7AD /* Array+RawRepresentable.swift in Sources */,
4D4D394A2C086DA2007196D2 /* PublishedScreen.swift in Sources */,
4D5251EC2C1097A600018CD2 /* Destination.swift in Sources */,
Expand All @@ -539,6 +565,7 @@
4D9B3B472C36F50300A8F7AD /* UITextContentType.swift in Sources */,
4D9B3B382C334B3A00A8F7AD /* LoginScreen.swift in Sources */,
4D5251EF2C1098E900018CD2 /* MultiChoiceScreen.swift in Sources */,
4DB10B502C4FEBFC00634BF6 /* HelpCommands.swift in Sources */,
4D9B3B452C36F46F00A8F7AD /* NSTextContentType.swift in Sources */,
4D54C96F2BF4E9DF001DE071 /* DraftsScreen.swift in Sources */,
4DB2E36F2C418F5C007F958D /* DynamicForm.swift in Sources */,
Expand All @@ -548,6 +575,7 @@
4D9B3B3A2C334B6300A8F7AD /* RegisterScreen.swift in Sources */,
4DB2E36D2C416611007F958D /* SubmitButton.swift in Sources */,
4D54C96D2BF4E9BE001DE071 /* ArchiveScreen.swift in Sources */,
4D13AF812C4E907200845FDB /* Environment.swift in Sources */,
4D5251F52C10A9F100018CD2 /* DynamicNavigation.swift in Sources */,
4D9DC5032C11BF2500BA0507 /* Config.swift in Sources */,
4D54C92C2BF2608A001DE071 /* FyreplaceApp.swift in Sources */,
Expand Down
26 changes: 26 additions & 0 deletions Fyreplace/Commands/HelpCommands.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import SwiftUI

struct HelpCommands: Commands {
var body: some Commands {
CommandGroup(replacing: .help) {
HelpCommandsLinks()
}
}
}

private struct HelpCommandsLinks: View {
@Environment(\.config)
private var config

var body: some View {
Link(destination: config.app.info.website) {
Text("App.Help.Website")
}
Link(destination: config.app.info.termsOfService) {
Text("App.Help.TermsOfService")
}
Link(destination: config.app.info.privacyPolicy) {
Text("App.Help.PrivacyPolicy")
}
}
}
50 changes: 36 additions & 14 deletions Fyreplace/Config/Config.swift
Original file line number Diff line number Diff line change
@@ -1,22 +1,22 @@
import Foundation
import SwiftUI

struct Config {
static var `default`: Config {
let data = Bundle.main.infoDictionary!
return Config(
version: .init(
build: data.string("CFBundleVersion")!,
marketing: data.string("CFBundleShortVersionString")!
),
app: .init(data.dictionary("App")!),
sentry: .init(data.dictionary("Sentry")!)
)
}
static var `default` = Config(from: Bundle.main)

let version: Version
let app: App
let sentry: Sentry

init(from bundle: Bundle) {
let data = bundle.infoDictionary!
version = .init(
build: data.string("CFBundleVersion")!,
marketing: data.string("CFBundleShortVersionString")!
)
app = .init(data.dictionary("App")!)
sentry = .init(data.dictionary("Sentry")!)
}

struct Version {
let build: String
let marketing: String
Expand Down Expand Up @@ -54,12 +54,23 @@ struct Config {
struct Api {
let main: URL
let dev: URL
let local: URL
let local: URL?

init(_ data: [String: Any]) {
main = data.url("Main")!
dev = data.url("Dev")!
local = data.url("Local")!
local = data.url("Local")
}

func url(for environment: ServerEnvironment) -> URL? {
switch environment {
case .main:
main
case .dev:
dev
case .local:
local
}
}
}
}
Expand Down Expand Up @@ -87,3 +98,14 @@ private extension [String: Any] {
return self[key] as? [String: Any]
}
}

private struct ConfigEnvironmentKey: EnvironmentKey {
static var defaultValue = Config(from: Bundle.main)
}

extension EnvironmentValues {
var config: Config {
get { self[ConfigEnvironmentKey.self] }
set { self[ConfigEnvironmentKey.self] = newValue }
}
}
33 changes: 33 additions & 0 deletions Fyreplace/Data/Environment.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
import SwiftUI

enum ServerEnvironment: String, CaseIterable, Identifiable {
case main
case dev
case local

var id: String { rawValue }

var description: String {
switch self {
case .main:
.init(localized: "Environment.Main")
case .dev:
.init(localized: "Environment.Dev")
case .local:
.init(localized: "Environment.Local")
}
}

static var `default`: ServerEnvironment {
#if DEBUG
.local
#else
switch Config.default.version.environment {
case "dev":
.dev
default:
.main
}
#endif
}
}
12 changes: 1 addition & 11 deletions Fyreplace/FyreplaceApp.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,17 +24,7 @@ struct FyreplaceApp: App {
.commands {
SidebarCommands()
ToolbarCommands()
CommandGroup(replacing: .help) {
Link(destination: Config.default.app.info.website) {
Text("App.Help.Website")
}
Link(destination: Config.default.app.info.termsOfService) {
Text("App.Help.TermsOfService")
}
Link(destination: Config.default.app.info.privacyPolicy) {
Text("App.Help.PrivacyPolicy")
}
}
HelpCommands()
}
}
}
60 changes: 60 additions & 0 deletions Fyreplace/Resources/Localizable.xcstrings
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,66 @@
}
}
},
"Environment.Default" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "(default)"
}
}
}
},
"Environment.Dev" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Testing server"
}
}
}
},
"Environment.Help" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "If you don't know what this is, pick \"Production server\""
}
}
}
},
"Environment.Local" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Local server"
}
}
}
},
"Environment.Main" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Production server"
}
}
}
},
"Environment.Title" : {
"localizations" : {
"en" : {
"stringUnit" : {
"state" : "translated",
"value" : "Environment"
}
}
}
},
"Login.Header" : {
"localizations" : {
"en" : {
Expand Down
26 changes: 26 additions & 0 deletions Fyreplace/Views/Forms/EnvironmentPicker.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import SwiftUI

struct EnvironmentPicker: View {
let namespace: Namespace.ID

@Environment(\.config)
private var config

@AppStorage("connection.environment")
private var selection = ServerEnvironment.default

var body: some View {
Picker("Environment.Title", selection: $selection) {
ForEach(ServerEnvironment.allCases.filter { config.app.api.url(for: $0) != nil }) { environment in
let suffix = environment == .default
? " " + .init(localized: "Environment.Default")
: ""

Text(verbatim: environment.description + suffix)
.tag(environment)
}
}
.help("Environment.Help")
.matchedGeometryEffect(id: "environment-picker", in: namespace)
}
}
2 changes: 2 additions & 0 deletions Fyreplace/Views/Screens/LoginScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ struct LoginScreen: View {
header: LogoHeader(text: "Login.Header", namespace: namespace),
footer: footer
) {
EnvironmentPicker(namespace: namespace)

TextField("Login.Identifier", text: $identifier, prompt: Text("Login.Identifier.Prompt"))
.autocorrectionDisabled()
.focused($focused)
Expand Down
2 changes: 2 additions & 0 deletions Fyreplace/Views/Screens/RegisterScreen.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ struct RegisterScreen: View {
header: LogoHeader(text: "Register.Header", namespace: namespace),
footer: footer
) {
EnvironmentPicker(namespace: namespace)

TextField("Register.Username", text: $username, prompt: usernamePrompt)
.textContentType(.username)
.autocorrectionDisabled()
Expand Down

0 comments on commit 273e577

Please sign in to comment.