1
0
mirror of git://jb55.com/damus synced 2024-09-30 00:40:45 +00:00

purple: add support for LN checkout flow

This commit adds support for the LN checkout flow, and the Purple
landing page:

1. It adds a "learn more" button on the Damus Purple view, where the
   user can learn more
2. It adds new `damus:purple` urls to enable the LN checkout flow

Signed-off-by: Daniel D’Aquino <daniel@daquino.me>
Reviewed-by: William Casarin <jb55@jb55.com>
Signed-off-by: William Casarin <jb55@jb55.com>
This commit is contained in:
Daniel D’Aquino 2024-01-14 21:55:04 +00:00 committed by William Casarin
parent 75a9b4df7f
commit 534969e616
8 changed files with 243 additions and 35 deletions

View File

@ -445,9 +445,6 @@
D72A2D072AD9C1FB002AFF62 /* MockProfiles.swift in Sources */ = {isa = PBXBuildFile; fileRef = D72A2D062AD9C1FB002AFF62 /* MockProfiles.swift */; };
D7315A2A2ACDF3B70036E30A /* DamusCacheManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315A292ACDF3B70036E30A /* DamusCacheManager.swift */; };
D7315A2C2ACDF4DA0036E30A /* DamusCacheManagerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7315A2B2ACDF4DA0036E30A /* DamusCacheManagerTests.swift */; };
D74F430A2B23F0BE00425B75 /* DamusPurple.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74F43092B23F0BE00425B75 /* DamusPurple.swift */; };
D74F430C2B23FB9B00425B75 /* StoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74F430B2B23FB9B00425B75 /* StoreObserver.swift */; };
D76556D62B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */; };
D74AAFC22B153395006CF0F4 /* HeadlessDamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74AAFC12B153395006CF0F4 /* HeadlessDamusState.swift */; };
D74AAFC32B153395006CF0F4 /* HeadlessDamusState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74AAFC12B153395006CF0F4 /* HeadlessDamusState.swift */; };
D74AAFC52B1538DF006CF0F4 /* NotificationExtensionState.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74AAFC42B1538DE006CF0F4 /* NotificationExtensionState.swift */; };
@ -463,6 +460,9 @@
D74AAFD22B155E78006CF0F4 /* WalletConnect.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4C7D09612A098D0E00943473 /* WalletConnect.swift */; };
D74AAFD42B155ECB006CF0F4 /* Zaps+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74AAFD32B155ECB006CF0F4 /* Zaps+.swift */; };
D74AAFD62B155F0C006CF0F4 /* WalletConnect+.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74AAFD52B155F0C006CF0F4 /* WalletConnect+.swift */; };
D74F430A2B23F0BE00425B75 /* DamusPurple.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74F43092B23F0BE00425B75 /* DamusPurple.swift */; };
D74F430C2B23FB9B00425B75 /* StoreObserver.swift in Sources */ = {isa = PBXBuildFile; fileRef = D74F430B2B23FB9B00425B75 /* StoreObserver.swift */; };
D76556D62B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */; };
D76874F32AE3632B00FB0F68 /* ProfileZapLinkView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D76874F22AE3632B00FB0F68 /* ProfileZapLinkView.swift */; };
D77BFA0B2AE3051200621634 /* ProfileActionSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D77BFA0A2AE3051200621634 /* ProfileActionSheetView.swift */; };
D783A63F2AD4E53D00658DDA /* SuggestedHashtagsView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D783A63E2AD4E53D00658DDA /* SuggestedHashtagsView.swift */; };
@ -491,6 +491,9 @@
D79C4C1B2AFEB061003A41B4 /* DamusNotificationService.appex in Embed Foundation Extensions */ = {isa = PBXBuildFile; fileRef = D79C4C142AFEB061003A41B4 /* DamusNotificationService.appex */; settings = {ATTRIBUTES = (RemoveHeadersOnCopy, ); }; };
D7A343EE2AD0D77C00CED48B /* InlineSnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = D7A343ED2AD0D77C00CED48B /* InlineSnapshotTesting */; };
D7A343F02AD0D77C00CED48B /* SnapshotTesting in Frameworks */ = {isa = PBXBuildFile; productRef = D7A343EF2AD0D77C00CED48B /* SnapshotTesting */; };
D7ADD3DE2B53854300F104C4 /* DamusPurpleURL.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7ADD3DD2B53854300F104C4 /* DamusPurpleURL.swift */; };
D7ADD3E02B538D4200F104C4 /* DamusPurpleURLSheetView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7ADD3DF2B538D4200F104C4 /* DamusPurpleURLSheetView.swift */; };
D7ADD3E22B538E3500F104C4 /* DamusPurpleVerifyNpubView.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7ADD3E12B538E3500F104C4 /* DamusPurpleVerifyNpubView.swift */; };
D7C6787E2B2D34CC00BCEAFB /* NIP98AuthenticatedRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = D7C6787D2B2D34CC00BCEAFB /* NIP98AuthenticatedRequest.swift */; };
D7CB5D3B2B112FBB00AD4105 /* NotificationFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D70A3B162B02DCE5008BD568 /* NotificationFormatter.swift */; };
D7CB5D3C2B1130C600AD4105 /* LocalNotification.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4CDA128B29EB19C40006FA5A /* LocalNotification.swift */; };
@ -1333,15 +1336,15 @@
D72A2D062AD9C1FB002AFF62 /* MockProfiles.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MockProfiles.swift; sourceTree = "<group>"; };
D7315A292ACDF3B70036E30A /* DamusCacheManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusCacheManager.swift; sourceTree = "<group>"; };
D7315A2B2ACDF4DA0036E30A /* DamusCacheManagerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusCacheManagerTests.swift; sourceTree = "<group>"; };
D74F43092B23F0BE00425B75 /* DamusPurple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurple.swift; sourceTree = "<group>"; };
D74F430B2B23FB9B00425B75 /* StoreObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreObserver.swift; sourceTree = "<group>"; };
D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleWelcomeView.swift; sourceTree = "<group>"; };
D74AAFC12B153395006CF0F4 /* HeadlessDamusState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = HeadlessDamusState.swift; sourceTree = "<group>"; };
D74AAFC42B1538DE006CF0F4 /* NotificationExtensionState.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationExtensionState.swift; sourceTree = "<group>"; };
D74AAFCB2B155D07006CF0F4 /* MakeZapRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = MakeZapRequest.swift; sourceTree = "<group>"; };
D74AAFCE2B155D8C006CF0F4 /* ZapDataModel.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ZapDataModel.swift; sourceTree = "<group>"; };
D74AAFD32B155ECB006CF0F4 /* Zaps+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Zaps+.swift"; sourceTree = "<group>"; };
D74AAFD52B155F0C006CF0F4 /* WalletConnect+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "WalletConnect+.swift"; sourceTree = "<group>"; };
D74F43092B23F0BE00425B75 /* DamusPurple.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurple.swift; sourceTree = "<group>"; };
D74F430B2B23FB9B00425B75 /* StoreObserver.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StoreObserver.swift; sourceTree = "<group>"; };
D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleWelcomeView.swift; sourceTree = "<group>"; };
D76874F22AE3632B00FB0F68 /* ProfileZapLinkView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileZapLinkView.swift; sourceTree = "<group>"; };
D77BFA0A2AE3051200621634 /* ProfileActionSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ProfileActionSheetView.swift; sourceTree = "<group>"; };
D783A63E2AD4E53D00658DDA /* SuggestedHashtagsView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SuggestedHashtagsView.swift; sourceTree = "<group>"; };
@ -1355,6 +1358,9 @@
D79C4C162AFEB061003A41B4 /* NotificationService.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationService.swift; sourceTree = "<group>"; };
D79C4C182AFEB061003A41B4 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
D79C4C1C2AFEB061003A41B4 /* DamusNotificationService.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = DamusNotificationService.entitlements; sourceTree = "<group>"; };
D7ADD3DD2B53854300F104C4 /* DamusPurpleURL.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleURL.swift; sourceTree = "<group>"; };
D7ADD3DF2B538D4200F104C4 /* DamusPurpleURLSheetView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleURLSheetView.swift; sourceTree = "<group>"; };
D7ADD3E12B538E3500F104C4 /* DamusPurpleVerifyNpubView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DamusPurpleVerifyNpubView.swift; sourceTree = "<group>"; };
D7C6787D2B2D34CC00BCEAFB /* NIP98AuthenticatedRequest.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NIP98AuthenticatedRequest.swift; sourceTree = "<group>"; };
D7CB5D3D2B116DAD00AD4105 /* NotificationsManager.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NotificationsManager.swift; sourceTree = "<group>"; };
D7CB5D442B116FE800AD4105 /* Contacts+.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Contacts+.swift"; sourceTree = "<group>"; };
@ -2562,6 +2568,8 @@
children = (
4CFF8F5829C9FD1E008DB934 /* DamusPurpleView.swift */,
D76556D52B1E6C08001B0CCC /* DamusPurpleWelcomeView.swift */,
D7ADD3DF2B538D4200F104C4 /* DamusPurpleURLSheetView.swift */,
D7ADD3E12B538E3500F104C4 /* DamusPurpleVerifyNpubView.swift */,
);
path = Purple;
sourceTree = "<group>";
@ -2622,6 +2630,7 @@
children = (
D74F43092B23F0BE00425B75 /* DamusPurple.swift */,
D74F430B2B23FB9B00425B75 /* StoreObserver.swift */,
D7ADD3DD2B53854300F104C4 /* DamusPurpleURL.swift */,
);
path = Purple;
sourceTree = "<group>";
@ -2912,6 +2921,7 @@
4CEF958D2A9CE650000F901B /* verifier.c in Sources */,
4C32B9342A9AD01A00DC3548 /* NdbProfile.swift in Sources */,
4C32B9332A99845B00DC3548 /* Ndb.swift in Sources */,
D7ADD3E22B538E3500F104C4 /* DamusPurpleVerifyNpubView.swift in Sources */,
4C4793082A993E8900489948 /* refmap.c in Sources */,
4C4793072A993E6200489948 /* emitter.c in Sources */,
4C4793062A993E5300489948 /* json_parser.c in Sources */,
@ -3045,6 +3055,7 @@
D74F430C2B23FB9B00425B75 /* StoreObserver.swift in Sources */,
4C363A9A28283854006E126D /* Reply.swift in Sources */,
BA693074295D649800ADDB87 /* UserSettingsStore.swift in Sources */,
D7ADD3E02B538D4200F104C4 /* DamusPurpleURLSheetView.swift in Sources */,
4CFF8F6729CC9E3A008DB934 /* ImageView.swift in Sources */,
4CA927632A290EB10098A105 /* EventTop.swift in Sources */,
4C90BD18283A9EE5008EE7EF /* LoginView.swift in Sources */,
@ -3327,6 +3338,7 @@
D7CB5D4E2B11728000AD4105 /* NewEventsBits.swift in Sources */,
4CC7AAFA297F64AC00430951 /* EventMenu.swift in Sources */,
B57B4C622B312BD700A232C0 /* ReconnectRelaysNotify.swift in Sources */,
D7ADD3DE2B53854300F104C4 /* DamusPurpleURL.swift in Sources */,
E4FA1C032A24BB7F00482697 /* SearchSettingsView.swift in Sources */,
4C75EFBB2804A34C0006080F /* ProofOfWork.swift in Sources */,
4C3AC7A52836987600E1F516 /* MainTabView.swift in Sources */,

View File

@ -28,6 +28,7 @@ enum Sheets: Identifiable {
case filter
case user_status
case onboardingSuggestions
case purple(DamusPurpleURL)
static func zap(target: ZapTarget, lnurl: String) -> Sheets {
return .zap(ZapSheet(target: target, lnurl: lnurl))
@ -48,6 +49,7 @@ enum Sheets: Identifiable {
case .select_wallet: return "select-wallet"
case .filter: return "filter"
case .onboardingSuggestions: return "onboarding-suggestions"
case .purple(let purple_url): return "purple" + purple_url.url_string()
}
}
}
@ -330,6 +332,8 @@ struct ContentView: View {
.presentationDragIndicator(.visible)
case .onboardingSuggestions:
OnboardingSuggestionsView(model: SuggestedUsersViewModel(damus_state: damus_state!))
case .purple(let purple_url):
DamusPurpleURLSheetView(damus_state: damus_state!, purple_url: purple_url)
}
}
.onOpenURL { url in
@ -344,6 +348,7 @@ struct ContentView: View {
case .event(let ev): self.open_event(ev: ev)
case .wallet_connect(let nwc): self.open_wallet(nwc: nwc)
case .script(let data): self.open_script(data)
case .purple(let purple_url): self.active_sheet = .purple(purple_url)
}
}
}
@ -1043,9 +1048,15 @@ enum OpenResult {
case event(NostrEvent)
case wallet_connect(WalletConnectURL)
case script([UInt8])
case purple(DamusPurpleURL)
}
func on_open_url(state: DamusState, url: URL, result: @escaping (OpenResult?) -> Void) {
if let purple_url = DamusPurpleURL.from_url(url: url) {
result(.purple(purple_url))
return
}
if let nwc = WalletConnectURL(str: url.absoluteString) {
result(.wallet_connect(nwc))
return

View File

@ -156,6 +156,30 @@ class DamusPurple: StoreObserverDelegate {
throw PurpleError.translation_no_response
}
}
func verify_npub_for_checkout(checkout_id: String) async throws {
var url = environment.get_base_url()
url.append(path: "/ln-checkout/\(checkout_id)/verify")
let (data, response) = try await make_nip98_authenticated_request(
method: .put,
url: url,
payload: nil,
payload_type: nil,
auth_keypair: self.keypair
)
if let httpResponse = response as? HTTPURLResponse {
switch httpResponse.statusCode {
case 200:
Log.info("Verified npub for checkout id `%s` with Damus Purple server", for: .damus_purple, checkout_id)
default:
Log.error("Error in verifying npub with Damus Purple. HTTP status code: %d; Response: %s; Checkout id: ", for: .damus_purple, httpResponse.statusCode, String(data: data, encoding: .utf8) ?? "Unknown", checkout_id)
throw PurpleError.checkout_npub_verification_error
}
}
}
}
// MARK: API types
@ -189,6 +213,7 @@ extension DamusPurple {
enum PurpleError: Error {
case translation_error(status_code: Int, response: Data)
case translation_no_response
case checkout_npub_verification_error
}
struct TranslationResult: Codable {

View File

@ -0,0 +1,43 @@
//
// DamusPurpleURL.swift
// damus
//
// Created by Daniel Nogueira on 2024-01-13.
//
import Foundation
enum DamusPurpleURL {
case verify_npub(checkout_id: String)
case welcome(checkout_id: String)
case landing
static func from_url(url: URL) -> DamusPurpleURL? {
guard let components = URLComponents(url: url, resolvingAgainstBaseURL: false) else { return nil }
guard components.scheme == "damus" else { return nil }
switch components.path {
case "purple:verify":
guard let checkout_id: String = components.queryItems?.first(where: { $0.name == "id" })?.value else { return nil }
return .verify_npub(checkout_id: checkout_id)
case "purple:welcome":
guard let checkout_id: String = components.queryItems?.first(where: { $0.name == "id" })?.value else { return nil }
return .welcome(checkout_id: checkout_id)
case "purple:landing":
return .landing
default:
return nil
}
}
func url_string() -> String {
switch self {
case .verify_npub(let id):
return "damus:purple:verify?id=\(id)"
case .welcome(let id):
return "damus:purple:welcome?id=\(id)"
case .landing:
return "damus:purple:landing"
}
}
}

View File

@ -16,4 +16,6 @@ class Constants {
static let NOTIFICATION_EXTENSION_BUNDLE_IDENTIFIER: String = "com.jb55.damus2.DamusNotificationService"
static let PURPLE_API_PRODUCTION_BASE_URL: URL = URL(string: "https://purple.damus.io")!
static let PURPLE_API_TEST_BASE_URL: URL = URL(string: "http://127.0.0.1:8989")!
static let PURPLE_LANDING_PAGE_TEST_URL: URL = URL(string: "http://localhost:3000/purple")!
static let PURPLE_LANDING_PAGE_PRODUCTION_URL: URL = URL(string: "https://damus.io/purple")!
}

View File

@ -0,0 +1,34 @@
//
// DamusPurpleURLSheetView.swift
// damus
//
// Created by Daniel DAquino on 2024-01-13.
//
import Foundation
import SwiftUI
struct DamusPurpleURLSheetView: View {
@Environment(\.dismiss) var dismiss
let damus_state: DamusState
let purple_url: DamusPurpleURL
var body: some View {
switch self.purple_url {
case .verify_npub(let checkout_id):
DamusPurpleVerifyNpubView(damus_state: damus_state, checkout_id: checkout_id)
case .welcome(_):
DamusPurpleWelcomeView()
case .landing:
DamusPurpleView(damus_state: damus_state)
}
}
}
struct DamusPurpleURLSheetView_Previews: PreviewProvider {
static var previews: some View {
DamusPurpleURLSheetView(damus_state: test_damus_state, purple_url: .verify_npub(checkout_id: "123"))
}
}

View File

@ -0,0 +1,64 @@
//
// DamusPurpleVerifyNpubView.swift
// damus
//
// Created by Daniel DAquino on 2024-01-13.
//
import SwiftUI
struct DamusPurpleVerifyNpubView: View {
let damus_state: DamusState
let checkout_id: String
@State var verified: Bool = false
var body: some View {
ZStack {
Rectangle()
.background(Color.black)
VStack {
DamusPurpleLogoView()
VStack(alignment: .center, spacing: 30) {
Subtitle(NSLocalizedString("To continue your Purple subscription checkout, please verify your npub by clicking on the button below", comment: "Instruction on how to verify npub during Damus Purple checkout"))
.multilineTextAlignment(.center)
if !verified {
Button(action: {
Task {
try await damus_state.purple.verify_npub_for_checkout(checkout_id: checkout_id)
verified = true
}
}, label: {
HStack {
Spacer()
Text(NSLocalizedString("Verify my npub", comment: "Button label to verify the user's npub for the purpose of Purple subscription checkout"))
Spacer()
}
})
.padding(.horizontal, 30)
.buttonStyle(GradientButtonStyle())
}
else {
Text(NSLocalizedString("Verified! Please head back to the checkout page to continue", comment: "Instructions after the user has verified their npub for Damus Purple purchase checkout"))
.multilineTextAlignment(.center)
.foregroundColor(.green)
}
}
.padding([.trailing, .leading], 30)
.padding(.bottom, 20)
}
}
}
func Subtitle(_ txt: String) -> some View {
Text(txt)
.foregroundColor(.white.opacity(0.65))
}
}
#Preview {
DamusPurpleVerifyNpubView(damus_state: test_damus_state, checkout_id: "123")
}

View File

@ -345,35 +345,7 @@ struct DamusPurpleView: View {
var MainContent: some View {
VStack {
HStack(spacing: 20) {
Image("damus-dark-logo")
.resizable()
.frame(width: 60, height: 60)
.clipShape(RoundedRectangle(cornerRadius: 15.0))
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(LinearGradient(
colors: [DamusColors.lighterPink.opacity(0.8), .white.opacity(0), DamusColors.deepPurple.opacity(0.6)],
startPoint: .topLeading,
endPoint: .bottomTrailing), lineWidth: 1)
)
.shadow(radius: 5)
VStack(alignment: .leading) {
Text(NSLocalizedString("Purple", comment: "Subscription service name"))
.font(.system(size: 60.0).weight(.bold))
.foregroundStyle(
LinearGradient(
colors: [DamusColors.lighterPink, DamusColors.deepPurple],
startPoint: .bottomLeading,
endPoint: .topTrailing
)
)
.foregroundColor(.white)
.tracking(-2)
}
}
.padding(.bottom, 30)
DamusPurpleLogoView()
VStack(alignment: .leading, spacing: 30) {
Subtitle(NSLocalizedString("Help us stay independent in our mission for Freedom tech with our Purple subscription, and look cool doing it!", comment: "Damus purple subscription pitch"))
@ -426,6 +398,17 @@ struct DamusPurpleView: View {
}
}
HStack {
Spacer()
Link(
NSLocalizedString("Learn more", comment: "Label for a link to the Damus Purple landing page"),
destination: damus_state.settings.purple_api_local_test_mode ? Constants.PURPLE_LANDING_PAGE_TEST_URL : Constants.PURPLE_LANDING_PAGE_PRODUCTION_URL
)
.foregroundColor(DamusColors.pink)
.padding()
Spacer()
}
}
.padding([.trailing, .leading], 30)
.padding(.bottom, 20)
@ -441,6 +424,40 @@ struct DamusPurpleView: View {
}
}
struct DamusPurpleLogoView: View {
var body: some View {
HStack(spacing: 20) {
Image("damus-dark-logo")
.resizable()
.frame(width: 60, height: 60)
.clipShape(RoundedRectangle(cornerRadius: 15.0))
.overlay(
RoundedRectangle(cornerRadius: 15)
.stroke(LinearGradient(
colors: [DamusColors.lighterPink.opacity(0.8), .white.opacity(0), DamusColors.deepPurple.opacity(0.6)],
startPoint: .topLeading,
endPoint: .bottomTrailing), lineWidth: 1)
)
.shadow(radius: 5)
VStack(alignment: .leading) {
Text(NSLocalizedString("Purple", comment: "Subscription service name"))
.font(.system(size: 60.0).weight(.bold))
.foregroundStyle(
LinearGradient(
colors: [DamusColors.lighterPink, DamusColors.deepPurple],
startPoint: .bottomLeading,
endPoint: .topTrailing
)
)
.foregroundColor(.white)
.tracking(-2)
}
}
.padding(.bottom, 30)
}
}
struct DamusPurpleView_Previews: PreviewProvider {
static var previews: some View {
/*