Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

MOB-2155 - All done after domains purchased #630

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -1041,6 +1041,10 @@
C6631BB62C69EA600045186D /* PurchaseDomainsSearchFiltersView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BB42C69EA600045186D /* PurchaseDomainsSearchFiltersView.swift */; };
C6631BB82C69EDB50045186D /* TLDCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BB72C69EDB50045186D /* TLDCategory.swift */; };
C6631BB92C69EDB50045186D /* TLDCategory.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BB72C69EDB50045186D /* TLDCategory.swift */; };
C6631BC42C6A45FC0045186D /* UDConfettiViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BC32C6A45FC0045186D /* UDConfettiViewModifier.swift */; };
C6631BC52C6A45FC0045186D /* UDConfettiViewModifier.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BC32C6A45FC0045186D /* UDConfettiViewModifier.swift */; };
C6631BC82C6A46F70045186D /* PurchaseDomainsCompletedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BC72C6A46F70045186D /* PurchaseDomainsCompletedView.swift */; };
C6631BC92C6A46F70045186D /* PurchaseDomainsCompletedView.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6631BC72C6A46F70045186D /* PurchaseDomainsCompletedView.swift */; };
C663538B294319B400EF1DC7 /* ScrollViewOffsetListener.swift in Sources */ = {isa = PBXBuildFile; fileRef = C663538A294319B400EF1DC7 /* ScrollViewOffsetListener.swift */; };
C6637A6A2810074D0000AE56 /* SecurityWindow.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6637A692810074D0000AE56 /* SecurityWindow.swift */; };
C6637A7128100D3A0000AE56 /* LaunchViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = C6637A6F28100D3A0000AE56 /* LaunchViewController.swift */; };
Expand Down Expand Up @@ -3461,6 +3465,8 @@
C6631BB12C69DFAC0045186D /* RecentDomainsToPurchaseSearchStorageProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RecentDomainsToPurchaseSearchStorageProtocol.swift; sourceTree = "<group>"; };
C6631BB42C69EA600045186D /* PurchaseDomainsSearchFiltersView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseDomainsSearchFiltersView.swift; sourceTree = "<group>"; };
C6631BB72C69EDB50045186D /* TLDCategory.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TLDCategory.swift; sourceTree = "<group>"; };
C6631BC32C6A45FC0045186D /* UDConfettiViewModifier.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UDConfettiViewModifier.swift; sourceTree = "<group>"; };
C6631BC72C6A46F70045186D /* PurchaseDomainsCompletedView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PurchaseDomainsCompletedView.swift; sourceTree = "<group>"; };
C663538A294319B400EF1DC7 /* ScrollViewOffsetListener.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScrollViewOffsetListener.swift; sourceTree = "<group>"; };
C6637A692810074D0000AE56 /* SecurityWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityWindow.swift; sourceTree = "<group>"; };
C6637A6F28100D3A0000AE56 /* LaunchViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LaunchViewController.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -6294,6 +6300,14 @@
path = AlreadyHaveWallet;
sourceTree = "<group>";
};
C6631BC62C6A46E00045186D /* Purchased */ = {
isa = PBXGroup;
children = (
C6631BC72C6A46F70045186D /* PurchaseDomainsCompletedView.swift */,
);
path = Purchased;
sourceTree = "<group>";
};
C6637A6E28100D180000AE56 /* LaunchViewController */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -7297,6 +7311,7 @@
C617FDB22B5919CC00B93433 /* OnAppearanceChange.swift */,
C6102FC22B6A12010098AF75 /* OnButtonTapModifier.swift */,
C6289A462AAB06F9002C2DEC /* SquareFrame.swift */,
C6631BC32C6A45FC0045186D /* UDConfettiViewModifier.swift */,
C6DDF2582B147F5E006D1F0B /* UDSubtitleText.swift */,
C6DDF2572B147F5D006D1F0B /* UDTitleText.swift */,
C69F99172A9F1264004B1958 /* UnstoppableListRowInset.swift */,
Expand Down Expand Up @@ -8273,8 +8288,9 @@
C6489AC82C5D09F9004AE320 /* PurchaseDomainsRootView.swift */,
C602041B2C622851000B5553 /* PurchaseDomainsTitleViewModifier.swift */,
C602041E2C625315000B5553 /* PurchaseDomainsTitleView.swift */,
C655CA9F2B16E82700FDA063 /* Checkout */,
C655CA9E2B16E81700FDA063 /* Search */,
C655CA9F2B16E82700FDA063 /* Checkout */,
C6631BC62C6A46E00045186D /* Purchased */,
);
path = PurchaseDomains;
sourceTree = "<group>";
Expand Down Expand Up @@ -9251,6 +9267,7 @@
C692C36A282EADA400C31393 /* SelectAppearanceThemePullUpView.swift in Sources */,
C6ECBF7A28D2C86F00E94309 /* ReverseResolutionTransactionInProgressViewPresenter.swift in Sources */,
C6952A292BC4E9F700F4B475 /* MPCWalletsServiceProtocol.swift in Sources */,
C6631BC82C6A46F70045186D /* PurchaseDomainsCompletedView.swift in Sources */,
C645131128095BA400413C51 /* ExistingUsersTutorialViewController.swift in Sources */,
C6D6E4F72817E045008C66BB /* OnboardingConfirmWordsPresenter.swift in Sources */,
C62900F82BAAC922008B35A2 /* UDNumberButtonView.swift in Sources */,
Expand Down Expand Up @@ -9382,6 +9399,7 @@
C62C8DC928DAF8E500967D0A /* PaymentTransactionGasOnlyCostView.swift in Sources */,
296BB61F2A309DD90068EEEC /* Encrypting.swift in Sources */,
C6F4332F2BB15641000C5E46 /* DomainsTLDGroup.swift in Sources */,
C6631BC42C6A45FC0045186D /* UDConfettiViewModifier.swift in Sources */,
C630C72F2BD779A500AC1662 /* RestoreWalletType.swift in Sources */,
C68F157C2BD76A650049BFA2 /* MPCWalletActivationError.swift in Sources */,
C6526DED29D2E12000D6F2EB /* ParkedDomainsFoundInAppViewPresenter.swift in Sources */,
Expand Down Expand Up @@ -10588,6 +10606,7 @@
C6D646322B1DC43100D724AC /* SecondaryButton.swift in Sources */,
C6D6473C2B1ED9EF00D724AC /* PaymentTransactionCostView.swift in Sources */,
C6D6461D2B1DC1F900D724AC /* PreviewStripePaymentHelper.swift in Sources */,
C6631BC52C6A45FC0045186D /* UDConfettiViewModifier.swift in Sources */,
C6A231F62BEB22230037E093 /* TextAttributesModifier.swift in Sources */,
C640F37D2C08643B009EB0F9 /* PurchaseMPCWalletAlreadyHaveWalletInAppView.swift in Sources */,
C6C8F81B2B217CC000A9834D /* BaseCreateWalletPresenter.swift in Sources */,
Expand Down Expand Up @@ -11214,6 +11233,7 @@
C6DEA16B2BD8D2AB00838215 /* ActivateMPCWalletFlowNavigationDestination.swift in Sources */,
C6D646EF2B1ED5B200D724AC /* AddWalletViewController.swift in Sources */,
C6534AAE2BBFBA10008EEBB5 /* HomeExploreNavigationDestination.swift in Sources */,
C6631BC92C6A46F70045186D /* PurchaseDomainsCompletedView.swift in Sources */,
C6C8F82E2B217DE300A9834D /* ExternalWalletMake.swift in Sources */,
C61807D02B19A4040032E543 /* AnalyticsServiceEnvironment.swift in Sources */,
C6C8F87E2B21827700A9834D /* LoginWithEmailViewController.swift in Sources */,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,21 @@ extension MockEntitiesFabric {
metadata: nil,
isTaken: false,
isAbleToPurchase: true),
DomainToPurchase(name: "oleg2.x",
price: 10000,
metadata: nil,
isTaken: false,
isAbleToPurchase: true),
DomainToPurchase(name: "oleg3.x",
price: 10000,
metadata: nil,
isTaken: false,
isAbleToPurchase: true),
DomainToPurchase(name: "oleg4.x",
price: 10000,
metadata: nil,
isTaken: false,
isAbleToPurchase: true),
DomainToPurchase(name: "oleg.com",
price: 10000,
metadata: nil,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,8 @@ extension String {
static let checkoutFromWebPullUpTitle = "CHECKOUT_FROM_WEB_PULL_UP_TITLE"
static let checkoutFromWebPullUpSubtitle = "CHECKOUT_FROM_WEB_PULL_UP_SUBTITLE"
static let endings = "ENDINGS"
static let suggestions = "SUGGESTIONS"
static let domainsPurchasedSummaryMessage = "DOMAINS_PURCHASED_SUMMARY_MESSAGE"

// Home
static let homeWalletTokensComeTitle = "HOME_WALLET_TOKENS_COME_TITLE"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -739,7 +739,11 @@ private extension PurchaseDomainsCheckoutView {
try? await walletsDataService.refreshDataForWallet(selectedWallet)
}

viewModel.handleAction(.didPurchaseDomains)
let purchasedData = PurchaseDomains.PurchasedDomainsData(domains: domains,
totalSum: formatCartPrice(totalPrice),
wallet: selectedWallet)

viewModel.handleAction(.didPurchaseDomains(purchasedData))
} catch {
logAnalytic(event: .didFailToPurchaseDomains, parameters: [.value : String(cartStatus.totalPrice),
.count: String(1),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ extension PurchaseDomains {
case didSelectDomains(_ domains: [DomainToPurchase])
case didFillProfileForDomain(_ domain: DomainToPurchase, profileChanges: DomainProfilePendingChanges)
case didRemoveAllDomainsFromTheCart
case didPurchaseDomains
case didPurchaseDomains(_ purchasedDomainsData: PurchasedDomainsData)
case goToDomains
}
}
Expand All @@ -27,6 +27,12 @@ extension PurchaseDomains {
let wallets: [WalletEntity]
}

struct PurchasedDomainsData: Hashable {
let domains: [DomainToPurchase]
let totalSum: String
let wallet: WalletEntity
}

enum EmptyStateMode {
case start
case noResults
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ extension PurchaseDomains {
enum NavigationDestination: Hashable {
case root(HomeTabRouter)
case checkout(_ checkoutData: CheckoutData, viewModel: PurchaseDomainsViewModel)
case purchased(PurchaseDomainsViewModel)
case purchased(_ purchasedDomainsData: PurchasedDomainsData, viewModel: PurchaseDomainsViewModel)

var isWithCustomTitle: Bool {
if case .purchased = self {
Expand Down Expand Up @@ -70,10 +70,9 @@ extension PurchaseDomains {
wallets: checkoutData.wallets,
profileChanges: checkoutData.profileChanges ?? .init(domainName: checkoutData.domains[0].name))
.environmentObject(viewModel)
case .purchased(let viewModel):
PurchaseDomainsHappyEndViewControllerWrapper(viewModel: viewModel)
.ignoresSafeArea()
.navigationBarBackButtonHidden(true)
case .purchased(let purchasedDomainsData, let viewModel):
PurchaseDomainsCompletedView(purchasedDomainsData: purchasedDomainsData)
.environmentObject(viewModel)
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,8 @@ final class PurchaseDomainsViewModel: ObservableObject {
localCart.clearCart()
router.walletViewNavPath.removeLast()
appContext.toastMessageService.showToast(.cartCleared, isSticky: false)
case .didPurchaseDomains:
pushTo(.purchased(self))
case .didPurchaseDomains(let purchasedDomainsData):
pushTo(.purchased(purchasedDomainsData, viewModel: self))
case .goToDomains:
router.didPurchaseDomains()
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
//
// PurchaseDomainsCompletedView.swift
// domains-manager-ios
//
// Created by Oleg Kuplin on 12.08.2024.
//

import SwiftUI

struct PurchaseDomainsCompletedView: View {

@EnvironmentObject var viewModel: PurchaseDomainsViewModel

let purchasedDomainsData: PurchaseDomains.PurchasedDomainsData
@State private var offset: CGPoint = .zero
@State private var confettiCounter = 0

var body: some View {
VStack(spacing: 0) {
OffsetObservingScrollView(offset: $offset) {
headerView()
purchasedDomainsList()
}

doneButtonView()
}
.navigationBarBackButtonHidden(true)
.navigationTitle(navTitle)
.navigationBarTitleDisplayMode(.inline)
.background(Color.backgroundDefault)
.toolbar {
// To keep showing top bar when scrolling
ToolbarItem(placement: .topBarTrailing) {
Color.clear
}
}
.udConfetti(counter: $confettiCounter)
.onAppear {
confettiCounter += 1
}
}

}

// MARK: - Private methods
private extension PurchaseDomainsCompletedView {
var navTitle: String {
if offset.y > 144 {
return String.Constants.youAreAllDoneTitle.localized()
}
return ""
}

@ViewBuilder
func headerView() -> some View {
LazyVStack(spacing: 24) {
Image.checkCircle
.resizable()
.squareFrame(56)
.foregroundStyle(Color.foregroundAccent)
LazyVStack(spacing: 16) {
Text(String.Constants.youAreAllDoneTitle.localized())
.textAttributes(color: .foregroundDefault,
fontSize: 32,
fontWeight: .bold)
.onDisappear {
print("title disappeared")
}
orderInfoView()
}
}
.padding(.top, 32)
.padding(.horizontal, 16)
}

@ViewBuilder
func orderInfoView() -> some View {
AttributedText(attributesList: .init(text: String.Constants.domainsPurchasedSummaryMessage.localized(orderTotal, mintWalletDescription),
font: .currentFont(withSize: 16, weight: .regular),
textColor: .foregroundSecondary,
alignment: .center),
updatedAttributesList: [.init(text: mintWalletName ?? walletAddress,
font: .currentFont(withSize: 16, weight: .medium),
textColor: .foregroundDefault)])
}

var wallet: WalletEntity {
purchasedDomainsData.wallet
}

var orderTotal: String {
purchasedDomainsData.totalSum
}

var walletAddress: String {
wallet.address.walletAddressTruncated
}

var mintWalletDescription: String {
if let mintWalletName {
return "\(mintWalletName) (\(walletAddress))"
}
return walletAddress
}

var mintWalletName: String? {
if wallet.displayInfo.isNameSet {
return wallet.displayInfo.name
}
return nil
}

@ViewBuilder
func purchasedDomainsList() -> some View {
UDCollectionSectionBackgroundView {
LazyVStack(alignment: .center, spacing: 4) {
ForEach(purchasedDomainsData.domains) { domain in
domainRowView(domain)
}
}
}
.padding(.top, 32)
.padding(.horizontal, 16)
}

@ViewBuilder
func domainRowView(_ domain: DomainToPurchase) -> some View {
HStack(spacing: 16) {
domain.tldCategory.icon
.resizable()
.squareFrame(24)
.foregroundStyle(Color.foregroundSecondary)

Text(domain.name)
.textAttributes(color: .foregroundDefault,
fontSize: 16,
fontWeight: .medium)
.lineLimit(1)
Spacer()
}
.frame(height: 64)
.padding(.horizontal, 16)
}

@ViewBuilder
func doneButtonView() -> some View {
UDButtonView(text: String.Constants.goToDomains.localized(),
style: .large(.raisedPrimary)) {
viewModel.handleAction(.goToDomains)
}
.padding(.horizontal, 16)
.background(Color.backgroundDefault)
.background(
Color.backgroundDefault
.shadow(color: Color.backgroundDefault,
radius: 8,
y: -8)
.mask(Rectangle().padding(.top, -20))
)
}
}

#Preview {
let router = MockEntitiesFabric.Home.createHomeTabRouter()
let viewModel = PurchaseDomainsViewModel(router: router)
let domains = MockEntitiesFabric.Domains.mockDomainsToPurchase()
let sum = formatCartPrice(domains.reduce(0, { $0 + $1.price }))
let wallet = MockEntitiesFabric.Wallet.mockEntities().randomElement()!

return NavigationStack {
PurchaseDomainsCompletedView(purchasedDomainsData: .init(domains: domains,
totalSum: sum,
wallet: wallet))
.environmentObject(router)
.environmentObject(viewModel)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,13 @@ private extension MockFirebaseInteractionsService {
}

func loadUserCryptoWallets() async throws -> [Ecom.UDUserAccountCryptWallet] {
let wallets = appContext.udWalletsService.getUserWallets()
return wallets.map { Ecom.UDUserAccountCryptWallet(id: 1, address: $0.address, type: "") }
// [.init(id: 1605, address: "0xc4a748796805dfa42cafe0901ec182936584cc6e"),
// .init(id: 1606, address: "0x8ed92xjd2793yenx837g3847d3n4dx9h")]
let wallets = MockEntitiesFabric.Wallet.mockEntities()
var cryptoWallets: [Ecom.UDUserAccountCryptWallet] = []
for (i, wallet) in wallets.enumerated() {
let cryptoWallet = Ecom.UDUserAccountCryptWallet(id: i, address: wallet.address, type: "")
cryptoWallets.append(cryptoWallet)
}
return cryptoWallets
}

func updateCart() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1002,6 +1002,7 @@
"CHECKOUT_FROM_WEB_PULL_UP_SUBTITLE" = "For purchases above $10,000 at once, checkout is only possible using crypto. However, the app currently doesn’t support crypto checkout.";
"ENDINGS" = "Endings";
"SUGGESTIONS" = "Suggestions";
"DOMAINS_PURCHASED_SUMMARY_MESSAGE" = "Order total: %@\n\nMinting started, this can take up to 5 minutes.\nWill be minted to: %@";

// Home
"HOME_WALLET_TOKENS_COME_TITLE" = "No more tokens here yet";
Expand Down
Loading