-
Notifications
You must be signed in to change notification settings - Fork 36
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
IOS-8236 Token selector view and buy from action buttons #4161
base: develop
Are you sure you want to change the base?
Conversation
ebbb504
to
eec6d2d
Compare
eec6d2d
to
3f789e9
Compare
|
||
struct BuyTokenSelectorStrings: TokenSelectorLocalizable { | ||
let availableTokensListTitle = Localization.exchangeTokensAvailableTokensHeader | ||
let unavailableTokensListTitle = "Unavailable to purchase" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Попросил скинуть текстовочки, в комите с фиксом по ревью долью
var isNotEmpty: Bool { | ||
return !isEmpty | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Помню на предыдущей работе обсуждали что "оверхэд"
Хз, можно и оставить, а можно и просто !isEmpty
писать
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
сделал из соображений, что более явно читается, чем !isEmpty
Tangem/Modules/Main/ActionButtons/Buy/Coordinator/ActionButtonsBuyCoordinator.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/ActionButtons/Buy/View/ActionButtonsBuyCoordinatorView.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/ActionButtons/Models/ActionButtonsTokenSelectorItem.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/ActionButtons/ViewModel/ActionButtonsViewModel.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/ActionButtons/ViewModel/ActionButtonsViewModel.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/MultiWalletMainContent/MultiWalletMainContentViewModel.swift
Outdated
Show resolved
Hide resolved
Tangem/Modules/Main/MultiWalletMainContent/MultiWalletMainContentViewModel.swift
Outdated
Show resolved
Hide resolved
fe1a39f
to
f8670ed
Compare
|
||
final class ActionButtonsViewModel: ObservableObject { | ||
@Injected(\.exchangeService) private var exchangeService: ExchangeService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Я так понимаю ExpressAvailabilityProvider
потом уже будет?)
@@ -22,6 +22,7 @@ class MainCoordinator: CoordinatorObject { | |||
@Injected(\.safariManager) private var safariManager: SafariManager | |||
@Injected(\.pushNotificationsInteractor) private var pushNotificationsInteractor: PushNotificationsInteractor | |||
@Injected(\.mainBottomSheetUIManager) private var mainBottomSheetUIManager: MainBottomSheetUIManager | |||
@Injected(\.tangemApiService) private var tangemApiService: TangemApiService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
за это точно наругают, тут появляется логика в coordinator, так нельзя )
let openBuy: (URL) -> Void = { url in | ||
self.openBuyCrypto( | ||
at: url, | ||
action: { [weak self] in | ||
self?.actionButtonsBuyCoordinator = nil | ||
} | ||
) | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
И вот это тоже не очень получается, я думаю надо полностью копировать/переносить логику в ActionButtonsBuyCoordinator
У нас же сейчас дублируется логика в TokenDetailsCoordinator
и в MainCoordinator
и в MarketsTokenDetailsCoordinator
Видать надо дублировать и сюда
Можно пробовать их объединить в общую фабрику как нибудь, вообще подход к сборке ViewModel можно чуток поменять на фабрику, но это уже другая история
@@ -32,6 +32,10 @@ final class MultiWalletMainContentViewModel: ObservableObject { | |||
|
|||
private(set) lazy var bottomSheetFooterViewModel = MainBottomSheetFooterViewModel() | |||
|
|||
var actionButtonsViewModel: ActionButtonsViewModel? { | |||
makeActionButtonsViewModel() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
каждый раз новая будет создаваться? И зачем опционал, как будто можно в init все сделать
} | ||
} | ||
} | ||
|
||
private extension ActionButtonViewModel { | ||
convenience init(from dataModel: ActionButtonModel, coordinator: ActionButtonsRoutable) { | ||
convenience init(from dataModel: ActionButtonModel, coordinator: ActionButtonsRoutable, userWalletModel: UserWalletModel) { | ||
let didTapAction: () -> Void = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Тут захватывается координатор, это ок?
Он разве не держит родительские VM, которые в свою очередь держат список action button vms
import Foundation | ||
|
||
final class ActionButtonsBuyCoordinator: CoordinatorObject { | ||
@Injected(\.exchangeService) private var exchangeService: ExchangeService |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Странно что формирование URL не в VM
URL это же в данном случае модель, а не навигация
// Copyright © 2024 Tangem AG. All rights reserved. | ||
// | ||
|
||
struct BuyTokenSelectorStrings: TokenSelectorLocalizable { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А для чего отдельная моделька, а не стринги из Localization инлайн?
@@ -106,6 +110,11 @@ final class MultiWalletMainContentViewModel: ObservableObject { | |||
} | |||
|
|||
isUpdating = true | |||
|
|||
if FeatureProvider.isAvailable(.actionButtons) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Лучше наверное чекать тоггл до создания actionButtonsViewModel, чтобы совсем ее не создавать, если тоггл выкл
import SwiftUI | ||
import Combine | ||
|
||
struct TokenSelectorView< |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
TokenSelector звучит очень дженериково
Ее реально можно использовать везде, где есть выбор токенов?
private extension TokenSelectorView { | ||
@ViewBuilder | ||
func availableSection(title: String, items: [TokenModel]) -> some View { | ||
if !viewModel.searchText.isEmpty || items.isNotEmpty { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: Тогда уже isNotEmpty надо делать на Collection, чтобы для всех было доступно, включая String
let availableTokenItems = availableModels.map { tokenSelectorItemBuilder.map(from: $0, isDisabled: false) } | ||
let unavailableTokenItems = unavailableModels.map { tokenSelectorItemBuilder.map(from: $0, isDisabled: true) } | ||
|
||
Task { @MainActor [weak self] in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
А main тут так как маппинг и сортировка происходит в bg?
Он действительно в bg происходит?
|
||
let unavailableTokenItems = unavailableWalletModels.map { tokenSelectorItemBuilder.map(from: $0, isDisabled: true) } | ||
|
||
Task { @MainActor [weak self] in |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Аналогичный вопрос что и выше
let isContainsName = item.name.lowercased().contains(text.lowercased()) | ||
let isContainsCurrencySymbol = item.currencySymbol.lowercased().contains(text.lowercased()) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: есть caseInsensitiveEquals
экстеншн, он по идее не будет создавать новые стринги. Можно вынести из BSDK в Foundation его и заюзать
.store(in: &cancellables) | ||
} | ||
|
||
func updateView(searchText: String = "") { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Мне кажется еще можно стрипать leading/trailing whitespaces, вроде как стандартная практика
ScreenRecording_11-06-2024.01-30-48_1.mov