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

[PWN-9213] Fix banner tap processing logic #1463

Merged
merged 2 commits into from
Jul 17, 2023
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 @@ -29,7 +29,7 @@ final class HomeAccountsViewModel: BaseViewModel, ObservableObject {

let navigation: PassthroughSubject<HomeNavigation, Never>
let bannerTapped = PassthroughSubject<Void, Never>()
private let tappedBannerSubject = PassthroughSubject<HomeNavigation, Never>()
private let shouldOpenBankTransfer = PassthroughSubject<Void, Never>()
private let shouldShowErrorSubject = CurrentValueSubject<Bool, Never>(false)

@Published private(set) var balance: String = ""
Expand Down Expand Up @@ -312,56 +312,60 @@ private extension HomeAccountsViewModel {
guard let bannerVisibility = self?.smallBannerVisibility else { return true }
return bannerVisibility.id != $0.value.kycStatus.rawValue || !bannerVisibility.closed
}
.map { [weak self] value -> HomeBannerParameters? in
guard let self else { return nil }

if value.value.isIBANNotReady && !shouldShowErrorSubject.value {
self.shouldShowErrorSubject.send(true)
}

return HomeBannerParameters(
.map { value in
HomeBannerParameters(
status: value.value.kycStatus,
action: { [weak self] in self?.requestCloseBanner(for: value.value) },
action: { [weak self] in self?.bannerTapped.send() },
isLoading: false,
isSmallBanner: true
)
}
.assignWeak(to: \.smallBanner, on: self)
.store(in: &subscriptions)

tappedBannerSubject
shouldOpenBankTransfer
.withLatestFrom(bankTransferService.value.state)
.filter { !$0.isFetching }
.receive(on: RunLoop.main)
.sink{ [weak self] state in
guard let self else { return }
if state.value.isIBANNotReady {
self.smallBanner?.button?.isLoading = true
self.shouldShowErrorSubject.send(false)
Task {
await self.bankTransferService.value.reload()
self.tappedBannerSubject.send(.bankTransfer)
}
self?.shouldShowErrorSubject.send(true)
} else {
self.navigation.send(.bankTransfer)
self?.navigation.send(.bankTransfer)
}
}
.store(in: &subscriptions)

shouldShowErrorSubject
.filter { $0 }
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in self?.notificationService.showToast(title: "❌", text: L10n.somethingWentWrong) }
.receive(on: RunLoop.main)
.sink { [weak self] _ in
self?.notificationService.showToast(title: "❌", text: L10n.somethingWentWrong)
self?.shouldShowErrorSubject.send(false)
}
.store(in: &subscriptions)

bannerTapped
.withLatestFrom(bankTransferService.value.state)
.sink { [weak self] state in self?.requestCloseBanner(for: state.value) }
.filter { !$0.isFetching }
.receive(on: RunLoop.main)
.sink { [weak self] state in
guard let self else { return }
self.requestCloseBanner(for: state.value)

if state.value.isIBANNotReady {
self.smallBanner?.button?.isLoading = true
Task {
await self.bankTransferService.value.reload()
self.shouldOpenBankTransfer.send()
}
} else {
self.shouldOpenBankTransfer.send()
}
}
.store(in: &subscriptions)
}

func requestCloseBanner(for data: UserData) {
tappedBannerSubject.send(.bankTransfer)
switch data.kycStatus {
case .onHold, .pendingReview:
shouldCloseBanner = false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ final class HomeEmptyViewModel: BaseViewModel, ObservableObject {
@Published var popularCoins = [PopularCoin]()
@Published var banner: HomeBannerParameters
let bannerTapped = PassthroughSubject<Void, Never>()
private let tappedBannerSubject = PassthroughSubject<HomeNavigation, Never>()
private let shouldOpenBankTransfer = PassthroughSubject<Void, Never>()
private let shouldShowErrorSubject = CurrentValueSubject<Bool, Never>(false)

// MARK: - Initializer
Expand Down Expand Up @@ -77,52 +77,55 @@ private extension HomeEmptyViewModel {
.filter { !$0.isFetching }
.filter { $0.value.userId != nil && $0.value.mobileVerified }
.receive(on: RunLoop.main)
.compactMap { [weak self] value -> HomeBannerParameters? in
guard let self else { return nil }

if value.value.isIBANNotReady && !shouldShowErrorSubject.value {
self.shouldShowErrorSubject.send(true)
}

return HomeBannerParameters(
.map { value in
HomeBannerParameters(
status: value.value.kycStatus,
action: { [weak self] in
self?.tappedBannerSubject.send(.bankTransfer)
},
action: { [weak self] in self?.bannerTapped.send() },
isLoading: false,
isSmallBanner: false
)
}
.assignWeak(to: \.banner, on: self)
.store(in: &subscriptions)

tappedBannerSubject
shouldOpenBankTransfer
.withLatestFrom(bankTransferService.state)
.filter { !$0.isFetching }
.receive(on: RunLoop.main)
.sink{ [weak self] state in
guard let self else { return }
if state.value.isIBANNotReady {
self.banner.button?.isLoading = true
self.shouldShowErrorSubject.send(false)
Task {
await self.bankTransferService.reload()
self.tappedBannerSubject.send(.bankTransfer)
}
self?.shouldShowErrorSubject.send(true)
} else {
self.navigation.send(.bankTransfer)
self?.navigation.send(.bankTransfer)
}
}
.store(in: &subscriptions)

shouldShowErrorSubject
.filter { $0 }
.receive(on: DispatchQueue.main)
.sink { [weak self] _ in self?.notificationService.showToast(title: "❌", text: L10n.somethingWentWrong) }
.receive(on: RunLoop.main)
.sink { [weak self] _ in
self?.notificationService.showToast(title: "❌", text: L10n.somethingWentWrong)
self?.shouldShowErrorSubject.send(false)
}
.store(in: &subscriptions)

bannerTapped
.sink { [weak self] _ in self?.tappedBannerSubject.send(.bankTransfer) }
.withLatestFrom(bankTransferService.state)
.filter { !$0.isFetching }
.receive(on: RunLoop.main)
.sink { [weak self] state in
guard let self else { return }

if state.value.isIBANNotReady {
self.banner.button?.isLoading = true
Task {
await self.bankTransferService.reload()
self.shouldOpenBankTransfer.send()
}
} else {
self.shouldOpenBankTransfer.send()
}
}
.store(in: &subscriptions)
}
}
Expand Down
42 changes: 23 additions & 19 deletions p2p_wallet/Scenes/Main/Topup/Actions/TopupActionsViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ final class TopupActionsViewModel: BaseViewModel, ObservableObject {
}

private let tappedItemSubject = PassthroughSubject<Action, Never>()
private let shouldCheckBankTransfer = PassthroughSubject<Void, Never>()
private let shouldShowErrorSubject = CurrentValueSubject<Bool, Never>(false)
private var shouldShowBankTransfer: Bool {
// always enabled for mocking
Expand Down Expand Up @@ -80,31 +81,34 @@ final class TopupActionsViewModel: BaseViewModel, ObservableObject {
}

private func bindBankTransfer() {
// Sending tapped event only after BTS is in ready state
Publishers.CombineLatest(
bankTransferService.state,
tappedItemSubject.eraseToAnyPublisher()
).filter { _, action in
action == .transfer
}.sinkAsync { [weak self] state, action in
await MainActor.run {
self?.setTransferLoadingState(isLoading: (state.status != .ready && !state.hasError) || !state.value.isIBANNotReady)
shouldCheckBankTransfer
.withLatestFrom(bankTransferService.state)
.filter({ !$0.isFetching })
.receive(on: RunLoop.main)
.sink { [weak self] state in
self?.setTransferLoadingState(isLoading: false)
// Toggling error
if self?.shouldShowErrorSubject.value == false {
self?.shouldShowErrorSubject.send(state.hasError || state.value.isIBANNotReady)
}
}
}.store(in: &subscriptions)

tappedItemSubject.withLatestFrom(bankTransferService.state).filter({ state in
state.hasError || state.value.isIBANNotReady
}).sinkAsync { [weak self] state in
await MainActor.run {
self?.setTransferLoadingState(isLoading: true)
self?.shouldShowErrorSubject.send(false)
.store(in: &subscriptions)

tappedItemSubject
.filter({ $0 == .transfer })
.withLatestFrom(bankTransferService.state).filter({ state in
state.hasError || state.value.isIBANNotReady
})
.sinkAsync { [weak self] state in
guard let self else { return }
await MainActor.run {
self.setTransferLoadingState(isLoading: true)
self.shouldShowErrorSubject.send(false)
}
await self.bankTransferService.reload()
self.shouldCheckBankTransfer.send(())
}
await self?.bankTransferService.reload()
}.store(in: &subscriptions)
.store(in: &subscriptions)

shouldShowErrorSubject.filter { $0 }.sinkAsync { [weak self] value in
await MainActor.run {
Expand Down
Loading