damus

nostr ios client
git clone git://jb55.com/damus
Log | Files | Refs | README | LICENSE

commit dd240899cfea37f5aeabac3571cd62696b61e642
parent 992b0f2eba52e8376be29288437d4038932c3581
Author: Daniel D’Aquino <daniel@daquino.me>
Date:   Tue, 30 Jan 2024 07:41:38 +0000

purple: improve environment handling

This commit improves the handling of different Purple environments:

- 3 environments were added (test, staging, production) to fulfill all
  testing needs

- Damus website constants were also added (This will become important
  for the next few commits)

- Toggle settings were replaced with a picker, where the user can select
  one of the 3 environments (test, staging, production)

- Damus purple page and website address links can now be obtained
  directly from the DamusPurple struct, which improves flexibility and
  reduces complexity for code that consumes these constants.

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>

Diffstat:
Mdamus.xcodeproj/project.pbxproj | 6++++++
Mdamus/Models/Purple/DamusPurple.swift | 28+++++++---------------------
Adamus/Models/Purple/DamusPurpleEnvironment.swift | 69+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mdamus/Models/UserSettingsStore.swift | 4++--
Mdamus/Util/Constants.swift | 14++++++++++++--
Mdamus/Views/Purple/DamusPurpleView.swift | 2+-
Mdamus/Views/Settings/DeveloperSettingsView.swift | 10+++++++---
7 files changed, 104 insertions(+), 29 deletions(-)

diff --git a/damus.xcodeproj/project.pbxproj b/damus.xcodeproj/project.pbxproj @@ -439,6 +439,8 @@ D2277EEA2A089BD5006C3807 /* Router.swift in Sources */ = {isa = PBXBuildFile; fileRef = D2277EE92A089BD5006C3807 /* Router.swift */; }; D70A3B172B02DCE5008BD568 /* NotificationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A3B162B02DCE5008BD568 /* NotificationFormatter.swift */; }; D71DC1EC2A9129C3006E207C /* PostViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D71DC1EB2A9129C3006E207C /* PostViewTests.swift */; }; + D72341192B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72341182B6864F200E1E135 /* DamusPurpleEnvironment.swift */; }; + D723411A2B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72341182B6864F200E1E135 /* DamusPurpleEnvironment.swift */; }; D723C38E2AB8D83400065664 /* ContentFilters.swift in Sources */ = {isa = PBXBuildFile; fileRef = D723C38D2AB8D83400065664 /* ContentFilters.swift */; }; D72A2D022AD9C136002AFF62 /* EventViewTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2CFF2AD9B66B002AFF62 /* EventViewTests.swift */; }; D72A2D052AD9C1B5002AFF62 /* MockDamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2D042AD9C1B5002AFF62 /* MockDamusState.swift */; }; @@ -1331,6 +1333,7 @@ D2277EE92A089BD5006C3807 /* Router.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Router.swift; sourceTree = "<group>"; }; D70A3B162B02DCE5008BD568 /* NotificationFormatter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationFormatter.swift; sourceTree = "<group>"; }; D71DC1EB2A9129C3006E207C /* PostViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PostViewTests.swift; sourceTree = "<group>"; }; + D72341182B6864F200E1E135 /* DamusPurpleEnvironment.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleEnvironment.swift; sourceTree = "<group>"; }; D723C38D2AB8D83400065664 /* ContentFilters.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentFilters.swift; sourceTree = "<group>"; }; D72A2CFF2AD9B66B002AFF62 /* EventViewTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = EventViewTests.swift; sourceTree = "<group>"; }; D72A2D042AD9C1B5002AFF62 /* MockDamusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockDamusState.swift; sourceTree = "<group>"; }; @@ -2634,6 +2637,7 @@ D74F43092B23F0BE00425B75 /* DamusPurple.swift */, D74F430B2B23FB9B00425B75 /* StoreObserver.swift */, D7ADD3DD2B53854300F104C4 /* DamusPurpleURL.swift */, + D72341182B6864F200E1E135 /* DamusPurpleEnvironment.swift */, ); path = Purple; sourceTree = "<group>"; @@ -3213,6 +3217,7 @@ 5C0707D12A1ECB38004E7B51 /* DamusLogoGradient.swift in Sources */, 4CDD1AE02A6B305F001CD4DF /* NdbTagElem.swift in Sources */, 4C5F9114283D694D0052CD1C /* FollowTarget.swift in Sources */, + D72341192B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */, 4CF0ABD629817F5B00D66079 /* ReportView.swift in Sources */, 4C1A9A2729DDE31900516EAC /* TranslationSettingsView.swift in Sources */, BA3759942ABCCEBA0018D73B /* CameraService.swift in Sources */, @@ -3474,6 +3479,7 @@ D7CE1B322B0BE6C3002EDAD4 /* NdbTxn.swift in Sources */, D7CE1B372B0BE719002EDAD4 /* Verifier.swift in Sources */, D74AAFC82B155C9D006CF0F4 /* InsertSort.swift in Sources */, + D723411A2B6864F200E1E135 /* DamusPurpleEnvironment.swift in Sources */, D7EDED292B1182060018B19C /* AttachMediaUtility.swift in Sources */, D798D21A2B0856CC00234419 /* Mentions.swift in Sources */, D7CE1B212B0BE1CB002EDAD4 /* wasm.c in Sources */, diff --git a/damus/Models/Purple/DamusPurple.swift b/damus/Models/Purple/DamusPurple.swift @@ -23,8 +23,8 @@ class DamusPurple: StoreObserverDelegate { return await self.profile_purple_badge_info(pubkey: pubkey)?.active } - var environment: ServerEnvironment { - self.settings.purple_api_staging ? .staging : .production + var environment: DamusPurpleEnvironment { + return self.settings.purple_enviroment } func profile_purple_badge_info(pubkey: Pubkey) async -> UserBadgeInfo? { @@ -57,7 +57,7 @@ class DamusPurple: StoreObserverDelegate { } func get_account_data(pubkey: Pubkey) async -> Data? { - let url = environment.get_base_url().appendingPathComponent("accounts/\(pubkey.hex())") + let url = environment.api_base_url().appendingPathComponent("accounts/\(pubkey.hex())") var request = URLRequest(url: url) request.httpMethod = "GET" @@ -72,7 +72,7 @@ class DamusPurple: StoreObserverDelegate { } func create_account(pubkey: Pubkey) async throws { - let url = environment.get_base_url().appendingPathComponent("accounts") + let url = environment.api_base_url().appendingPathComponent("accounts") Log.info("Creating account with Damus Purple server", for: .damus_purple) @@ -110,7 +110,7 @@ class DamusPurple: StoreObserverDelegate { do { let receiptData = try Data(contentsOf: appStoreReceiptURL, options: .alwaysMapped) - let url = environment.get_base_url().appendingPathComponent("accounts/\(keypair.pubkey.hex())/app-store-receipt") + let url = environment.api_base_url().appendingPathComponent("accounts/\(keypair.pubkey.hex())/app-store-receipt") Log.info("Sending in-app purchase receipt to Damus Purple server", for: .damus_purple) @@ -139,7 +139,7 @@ class DamusPurple: StoreObserverDelegate { } func translate(text: String, source source_language: String, target target_language: String) async throws -> String { - var url = environment.get_base_url() + var url = environment.api_base_url() url.append(path: "/translate") url.append(queryItems: [ .init(name: "source", value: source_language), @@ -169,7 +169,7 @@ class DamusPurple: StoreObserverDelegate { } func verify_npub_for_checkout(checkout_id: String) async throws { - var url = environment.get_base_url() + var url = environment.api_base_url() url.append(path: "/ln-checkout/\(checkout_id)/verify") let (data, response) = try await make_nip98_authenticated_request( @@ -219,20 +219,6 @@ extension DamusPurple { // MARK: Helper structures extension DamusPurple { - enum ServerEnvironment { - case staging - case production - - func get_base_url() -> URL { - switch self { - case .staging: - Constants.PURPLE_API_TEST_BASE_URL - case .production: - Constants.PURPLE_API_PRODUCTION_BASE_URL - } - } - } - enum PurpleError: Error { case translation_error(status_code: Int, response: Data) case translation_no_response diff --git a/damus/Models/Purple/DamusPurpleEnvironment.swift b/damus/Models/Purple/DamusPurpleEnvironment.swift @@ -0,0 +1,69 @@ +// +// DamusPurpleEnvironment.swift +// damus +// +// Created by Daniel D’Aquino on 2024-01-29. +// + +import Foundation + +enum DamusPurpleEnvironment: String, CaseIterable, Codable, Identifiable, StringCodable, Equatable { + case local_test + case staging + case production + + func text_description() -> String { + switch self { + case .local_test: + return NSLocalizedString("Test (localhost)", comment: "Label indicating a localhost test environment for Damus Purple functionality (Developer feature)") + case .staging: + return NSLocalizedString("Staging", comment: "Label indicating a staging test environment for Damus Purple functionality (Developer feature)") + case .production: + return NSLocalizedString("Production", comment: "Label indicating the production environment for Damus Purple") + } + } + + func api_base_url() -> URL { + switch self { + case .local_test: + Constants.PURPLE_API_LOCAL_TEST_BASE_URL + case .staging: + Constants.PURPLE_API_STAGING_BASE_URL + case .production: + Constants.PURPLE_API_PRODUCTION_BASE_URL + } + } + + func purple_landing_page_url() -> URL { + switch self { + case .local_test: + Constants.PURPLE_LANDING_PAGE_LOCAL_TEST_URL + case .staging: + Constants.PURPLE_LANDING_PAGE_STAGING_URL + case .production: + Constants.PURPLE_LANDING_PAGE_PRODUCTION_URL + } + } + + func damus_website_url() -> URL { + switch self { + case .local_test: + Constants.DAMUS_WEBSITE_LOCAL_TEST_URL + case .staging: + Constants.DAMUS_WEBSITE_STAGING_URL + case .production: + Constants.DAMUS_WEBSITE_PRODUCTION_URL + } + } + + init?(from string: String) { + guard let initialized = Self.init(rawValue: string) else { return nil } + self = initialized + } + + func to_string() -> String { + return self.rawValue + } + + var id: String { self.rawValue } +} diff --git a/damus/Models/UserSettingsStore.swift b/damus/Models/UserSettingsStore.swift @@ -205,8 +205,8 @@ class UserSettingsStore: ObservableObject { @Setting(key: "enable_experimental_purple_api", default_value: false) var enable_experimental_purple_api: Bool - @Setting(key: "purple_api_staging", default_value: false) - var purple_api_staging: Bool + @StringSetting(key: "purple_environment", default_value: .production) + var purple_enviroment: DamusPurpleEnvironment @Setting(key: "emoji_reactions", default_value: default_emoji_reactions) var emoji_reactions: [String] diff --git a/damus/Util/Constants.swift b/damus/Util/Constants.swift @@ -14,8 +14,18 @@ class Constants { static let DEVICE_TOKEN_RECEIVER_TEST_URL: URL = URL(string: "http://localhost:8000/user-info")! static let MAIN_APP_BUNDLE_IDENTIFIER: String = "com.jb55.damus2" static let NOTIFICATION_EXTENSION_BUNDLE_IDENTIFIER: String = "com.jb55.damus2.DamusNotificationService" + + // MARK: Purple + // API + static let PURPLE_API_LOCAL_TEST_BASE_URL: URL = URL(string: "http://localhost:8989")! + static let PURPLE_API_STAGING_BASE_URL: URL = URL(string: "https://api-staging.damus.io")! static let PURPLE_API_PRODUCTION_BASE_URL: URL = URL(string: "https://api.damus.io")! - static let PURPLE_API_TEST_BASE_URL: URL = URL(string: "https://api-staging.damus.io")! - static let PURPLE_LANDING_PAGE_TEST_URL: URL = URL(string: "https://staging.damus.io/purple")! + // Purple landing page + static let PURPLE_LANDING_PAGE_LOCAL_TEST_URL: URL = URL(string: "http://localhost:3000")! + static let PURPLE_LANDING_PAGE_STAGING_URL: URL = URL(string: "https://staging.damus.io/purple")! static let PURPLE_LANDING_PAGE_PRODUCTION_URL: URL = URL(string: "https://damus.io/purple")! + // Website + static let DAMUS_WEBSITE_LOCAL_TEST_URL: URL = URL(string: "http://localhost:3000")! + static let DAMUS_WEBSITE_STAGING_URL: URL = URL(string: "https://staging.damus.io")! + static let DAMUS_WEBSITE_PRODUCTION_URL: URL = URL(string: "https://damus.io")! } diff --git a/damus/Views/Purple/DamusPurpleView.swift b/damus/Views/Purple/DamusPurpleView.swift @@ -412,7 +412,7 @@ struct DamusPurpleView: View { Spacer() Link( NSLocalizedString("Learn more", comment: "Label for a link to the Damus Purple landing page"), - destination: damus_state.settings.purple_api_staging ? Constants.PURPLE_LANDING_PAGE_TEST_URL : Constants.PURPLE_LANDING_PAGE_PRODUCTION_URL + destination: damus_state.purple.environment.purple_landing_page_url() ) .foregroundColor(DamusColors.pink) .padding() diff --git a/damus/Views/Settings/DeveloperSettingsView.swift b/damus/Views/Settings/DeveloperSettingsView.swift @@ -27,9 +27,13 @@ struct DeveloperSettingsView: View { Toggle("Enable experimental Purple API support", isOn: $settings.enable_experimental_purple_api) .toggleStyle(.switch) - - Toggle("Purple API staging mode", isOn: $settings.purple_api_staging) - .toggleStyle(.switch) + + Picker(NSLocalizedString("Damus Purple environment", comment: "Prompt selection of the Damus purple environment (Developer feature to switch between real/production mode to test modes)."), selection: $settings.purple_enviroment) { + ForEach(DamusPurpleEnvironment.allCases, id: \.self) { purple_environment in + Text(purple_environment.text_description()) + .tag(purple_environment.rawValue) + } + } } } }