87 lines
2.8 KiB
Swift
87 lines
2.8 KiB
Swift
import ComposableArchitecture
|
|
import SwiftUI
|
|
import Models
|
|
import UserMetadataProvider
|
|
|
|
@Reducer
|
|
public struct TransactionList {
|
|
public enum Constants {
|
|
public static let homePageTransactionsCount = 5
|
|
}
|
|
|
|
@ObservableState
|
|
public struct State: Equatable {
|
|
public var CancelId = UUID()
|
|
|
|
public var isInvalidated = true
|
|
public var latestTransactionId = ""
|
|
@Shared(.inMemory(.selectedWalletAccount)) public var selectedWalletAccount: WalletAccount? = nil
|
|
@Shared(.inMemory(.transactions)) public var transactions: IdentifiedArrayOf<TransactionState> = []
|
|
public var transactionListHomePage: IdentifiedArrayOf<TransactionState> = []
|
|
|
|
public init() { }
|
|
}
|
|
|
|
public enum Action: Equatable {
|
|
case onAppear
|
|
case transactionsUpdated
|
|
case transactionTapped(String)
|
|
}
|
|
|
|
@Dependency(\.userMetadataProvider) var userMetadataProvider
|
|
|
|
public init() {}
|
|
|
|
public var body: some Reducer<State, Action> {
|
|
Reduce { state, action in
|
|
switch action {
|
|
case .onAppear:
|
|
return .publisher {
|
|
state.$transactions.publisher
|
|
.map { _ in
|
|
TransactionList.Action.transactionsUpdated
|
|
}
|
|
}
|
|
.cancellable(id: state.CancelId, cancelInFlight: true)
|
|
|
|
case .transactionsUpdated:
|
|
state.isInvalidated = false
|
|
state.transactionListHomePage = IdentifiedArrayOf(uniqueElements: state.transactions.prefix(Constants.homePageTransactionsCount))
|
|
state.latestTransactionId = state.transactionListHomePage.last?.id ?? ""
|
|
return .none
|
|
|
|
case .transactionTapped(let txId):
|
|
if let index = state.transactions.index(id: txId) {
|
|
if TransactionList.isUnread(state.transactions[index]) {
|
|
userMetadataProvider.readTx(txId)
|
|
if let account = state.selectedWalletAccount?.account {
|
|
try? userMetadataProvider.store(account)
|
|
}
|
|
}
|
|
}
|
|
return .none
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public extension TransactionList {
|
|
static func isUnread(_ transaction: TransactionState) -> Bool {
|
|
guard !transaction.isSentTransaction else {
|
|
return false
|
|
}
|
|
|
|
guard !transaction.isShieldingTransaction else {
|
|
return false
|
|
}
|
|
|
|
guard transaction.memoCount > 0 else {
|
|
return false
|
|
}
|
|
|
|
@Dependency(\.userMetadataProvider) var userMetadataProvider
|
|
|
|
return !userMetadataProvider.isRead(transaction.id, transaction.timestamp)
|
|
}
|
|
}
|