Merge pull request #1307 from LukasKorba/1305-Upgrade-TransactionListReducer-to-the-latest-TCA

[#1305] Upgrade TransactionListReducer to the latest TCA
This commit is contained in:
Lukas Korba 2024-06-21 10:29:16 +02:00 committed by GitHub
commit 1375c75267
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 329 additions and 324 deletions

View File

@ -25,7 +25,7 @@ public struct Home {
public var scanState: Scan.State
public var syncProgressState: SyncProgress.State
public var walletConfig: WalletConfig
public var transactionListState: TransactionListReducer.State
public var transactionListState: TransactionList.State
public var walletBalancesState: WalletBalances.State
public init(
@ -33,7 +33,7 @@ public struct Home {
migratingDatabase: Bool = true,
scanState: Scan.State,
syncProgressState: SyncProgress.State,
transactionListState: TransactionListReducer.State,
transactionListState: TransactionList.State,
walletBalancesState: WalletBalances.State,
walletConfig: WalletConfig
) {
@ -60,7 +60,7 @@ public struct Home {
case syncFailed(ZcashError)
case syncProgress(SyncProgress.Action)
case updateTransactionList([TransactionState])
case transactionList(TransactionListReducer.Action)
case transactionList(TransactionList.Action)
case walletBalances(WalletBalances.Action)
}
@ -73,7 +73,7 @@ public struct Home {
public var body: some Reducer<State, Action> {
Scope(state: \.transactionListState, action: /Action.transactionList) {
TransactionListReducer()
TransactionList()
}
Scope(state: \.syncProgressState, action: /Action.syncProgress) {

View File

@ -13,13 +13,13 @@ public struct SandboxReducer: Reducer {
case recoveryPhraseDisplay
case scan
}
public var transactionListState: TransactionListReducer.State
public var transactionListState: TransactionList.State
public var destination: Destination?
}
public enum Action: Equatable {
case updateDestination(SandboxReducer.State.Destination?)
case transactionList(TransactionListReducer.Action)
case transactionList(TransactionList.Action)
case reset
}
@ -32,7 +32,7 @@ public struct SandboxReducer: Reducer {
return .none
case let .transactionList(transactionListAction):
return TransactionListReducer()
return TransactionList()
.reduce(into: &state.transactionListState, action: transactionListAction)
.map(SandboxReducer.Action.transactionList)
@ -45,7 +45,7 @@ public struct SandboxReducer: Reducer {
// MARK: - Store
extension SandboxStore {
func historyStore() -> TransactionListStore {
func historyStore() -> StoreOf<TransactionList> {
self.scope(
state: \.transactionListState,
action: SandboxReducer.Action.transactionList

View File

@ -9,19 +9,18 @@ import SDKSynchronizer
import ReadTransactionsStorage
import ZcashSDKEnvironment
public typealias TransactionListStore = Store<TransactionListReducer.State, TransactionListReducer.Action>
public typealias TransactionListViewStore = ViewStore<TransactionListReducer.State, TransactionListReducer.Action>
public struct TransactionListReducer: Reducer {
@Reducer
public struct TransactionList {
private let CancelStateId = UUID()
private let CancelEventId = UUID()
@ObservableState
public struct State: Equatable {
public var latestMinedHeight: BlockHeight?
public var requiredTransactionConfirmations = 0
public var latestTransactionList: [TransactionState] = []
public var transactionList: IdentifiedArrayOf<TransactionState>
public var latestTranassctionId = ""
public var latestTransactionId = ""
public init(
latestMinedHeight: BlockHeight? = nil,
@ -68,7 +67,7 @@ public struct TransactionListReducer: Reducer {
.publisher {
sdkSynchronizer.stateStream()
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.map { TransactionListReducer.Action.synchronizerStateChanged($0.syncStatus) }
.map { TransactionList.Action.synchronizerStateChanged($0.syncStatus) }
}
.cancellable(id: CancelStateId, cancelInFlight: true),
.publisher {
@ -76,7 +75,7 @@ public struct TransactionListReducer: Reducer {
.throttle(for: .seconds(0.2), scheduler: mainQueue, latest: true)
.compactMap {
if case SynchronizerEvent.foundTransactions = $0 {
return TransactionListReducer.Action.foundTransactions
return TransactionList.Action.foundTransactions
}
return nil
}
@ -156,7 +155,7 @@ public struct TransactionListReducer: Reducer {
}
state.transactionList = IdentifiedArrayOf(uniqueElements: sortedTransactionList)
state.latestTranassctionId = state.transactionList.first?.id ?? ""
state.latestTransactionId = state.transactionList.first?.id ?? ""
return .none
@ -247,59 +246,3 @@ public struct TransactionListReducer: Reducer {
}
}
}
// MARK: ViewStore
extension TransactionListViewStore {
func isLatestTransaction(id: String) -> Bool {
state.latestTranassctionId == id
}
}
// MARK: Placeholders
extension TransactionListReducer.State {
public static var placeholder: Self {
.init(transactionList: .mocked)
}
public static var initial: Self {
.init(transactionList: [])
}
}
extension TransactionListStore {
public static var placeholder: Store<TransactionListReducer.State, TransactionListReducer.Action> {
Store(
initialState: .placeholder
) {
TransactionListReducer()
.dependency(\.zcashSDKEnvironment, .testnet)
}
}
}
extension IdentifiedArrayOf where Element == TransactionState {
public static var placeholder: IdentifiedArrayOf<TransactionState> {
.init(
uniqueElements: (0..<30).map {
TransactionState(
fee: Zatoshi(10),
id: String($0),
status: .paid,
timestamp: 1234567,
zecAmount: Zatoshi(25)
)
}
)
}
public static var mocked: IdentifiedArrayOf<TransactionState> {
.init(
uniqueElements: [
TransactionState.mockedSent,
TransactionState.mockedReceived
]
)
}
}

View File

@ -2,20 +2,22 @@ import SwiftUI
import ComposableArchitecture
import Generated
import UIComponents
import Models
import ZcashLightClientKit
public struct TransactionListView: View {
let store: TransactionListStore
let store: StoreOf<TransactionList>
let tokenName: String
public init(store: TransactionListStore, tokenName: String) {
public init(store: StoreOf<TransactionList>, tokenName: String) {
self.store = store
self.tokenName = tokenName
}
public var body: some View {
WithViewStore(store, observe: { $0 }) { viewStore in
WithPerceptionTracking {
List {
if viewStore.transactionList.isEmpty {
if store.transactionList.isEmpty {
Text(L10n.TransactionList.noTransactions)
.font(.custom(FontFamily.Inter.bold.name, size: 13))
.frame(maxWidth: .infinity)
@ -24,24 +26,26 @@ public struct TransactionListView: View {
.listRowSeparator(.hidden)
.padding(.top, 30)
} else {
ForEach(viewStore.transactionList) { transaction in
TransactionRowView(
viewStore: viewStore,
transaction: transaction,
tokenName: tokenName,
isLatestTransaction: viewStore.isLatestTransaction(id: transaction.id)
)
.listRowInsets(EdgeInsets())
ForEach(store.transactionList) { transaction in
WithPerceptionTracking {
TransactionRowView(
store: store,
transaction: transaction,
tokenName: tokenName,
isLatestTransaction: store.latestTransactionId == transaction.id
)
.listRowInsets(EdgeInsets())
}
}
.listRowBackground(Asset.Colors.shade97.color)
.listRowSeparator(.hidden)
}
}
.disabled(viewStore.transactionList.isEmpty)
.disabled(store.transactionList.isEmpty)
.background(Asset.Colors.shade97.color)
.listStyle(.plain)
.onAppear { viewStore.send(.onAppear) }
.onDisappear(perform: { viewStore.send(.onDisappear) })
.onAppear { store.send(.onAppear) }
.onDisappear(perform: { store.send(.onDisappear) })
}
}
}
@ -54,3 +58,51 @@ public struct TransactionListView: View {
.preferredColorScheme(.light)
}
}
// MARK: Placeholders
extension TransactionList.State {
public static var placeholder: Self {
.init(transactionList: .mocked)
}
public static var initial: Self {
.init(transactionList: [])
}
}
extension StoreOf<TransactionList> {
public static var placeholder: Store<TransactionList.State, TransactionList.Action> {
Store(
initialState: .placeholder
) {
TransactionList()
.dependency(\.zcashSDKEnvironment, .testnet)
}
}
}
extension IdentifiedArrayOf where Element == TransactionState {
public static var placeholder: IdentifiedArrayOf<TransactionState> {
.init(
uniqueElements: (0..<30).map {
TransactionState(
fee: Zatoshi(10),
id: String($0),
status: .paid,
timestamp: 1234567,
zecAmount: Zatoshi(25)
)
}
)
}
public static var mocked: IdentifiedArrayOf<TransactionState> {
.init(
uniqueElements: [
TransactionState.mockedSent,
TransactionState.mockedReceived
]
)
}
}

View File

@ -11,70 +11,72 @@ import ComposableArchitecture
import Generated
struct MessageView: View {
let viewStore: TransactionListViewStore
let store: StoreOf<TransactionList>
let messages: [String]?
let isSpending: Bool
let isFailed: Bool
public init(
viewStore: TransactionListViewStore,
store: StoreOf<TransactionList>,
messages: [String]?,
isSpending: Bool,
isFailed: Bool = false
) {
self.viewStore = viewStore
self.store = store
self.messages = messages
self.isSpending = isSpending
self.isFailed = isFailed
}
var body: some View {
if let memoTexts = messages {
VStack(alignment: .leading, spacing: 0) {
Text(memoTexts.count == 1
? L10n.TransactionList.messageTitle
: L10n.TransactionList.messageTitlePlural
)
.font(.custom(FontFamily.Inter.medium.name, size: 13))
.padding(.bottom, 8)
ForEach(0..<memoTexts.count, id: \.self) { index in
VStack(alignment: .leading, spacing: 0) {
Color.clear.frame(height: 0)
Text(memoTexts[index])
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(
isFailed ?
Asset.Colors.error.color
: Asset.Colors.primary.color
)
.conditionalStrikethrough(isFailed)
.padding()
}
.messageShape(
filled: !isSpending
? Asset.Colors.messageBcgReceived.color
: nil,
border: isSpending
? Asset.Colors.primary.color
: nil,
orientation: !isSpending
? .right
: .left
WithPerceptionTracking {
if let memoTexts = messages {
VStack(alignment: .leading, spacing: 0) {
Text(memoTexts.count == 1
? L10n.TransactionList.messageTitle
: L10n.TransactionList.messageTitlePlural
)
.font(.custom(FontFamily.Inter.medium.name, size: 13))
.padding(.bottom, 8)
TapToCopyTransactionDataView(viewStore: viewStore, data: memoTexts[index].redacted)
ForEach(0..<memoTexts.count, id: \.self) { index in
VStack(alignment: .leading, spacing: 0) {
Color.clear.frame(height: 0)
Text(memoTexts[index])
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(
isFailed ?
Asset.Colors.error.color
: Asset.Colors.primary.color
)
.conditionalStrikethrough(isFailed)
.padding()
}
.messageShape(
filled: !isSpending
? Asset.Colors.messageBcgReceived.color
: nil,
border: isSpending
? Asset.Colors.primary.color
: nil,
orientation: !isSpending
? .right
: .left
)
TapToCopyTransactionDataView(store: store, data: memoTexts[index].redacted)
}
.padding(.bottom, 20)
}
.padding(.bottom, 20)
.padding(.bottom, 7)
.padding(.vertical, 10)
} else {
Text(L10n.TransactionList.noMessageIncluded)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
}
.padding(.bottom, 7)
.padding(.vertical, 10)
} else {
Text(L10n.TransactionList.noMessageIncluded)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
}
}
}
@ -82,14 +84,14 @@ struct MessageView: View {
#Preview {
VStack(alignment: .leading) {
MessageView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
messages: ["Test"],
isSpending: true
)
.padding(.bottom, 50)
MessageView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
messages: ["Test"],
isSpending: true,
isFailed: true
@ -97,13 +99,13 @@ struct MessageView: View {
.padding(.bottom, 50)
MessageView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
messages: ["Test"],
isSpending: false
)
MessageView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
messages: nil,
isSpending: false
)

View File

@ -11,37 +11,39 @@ import Generated
import Utils
struct TapToCopyTransactionDataView: View {
let viewStore: TransactionListViewStore
let store: StoreOf<TransactionList>
let data: RedactableString
public init(viewStore: TransactionListViewStore, data: RedactableString) {
self.viewStore = viewStore
public init(store: StoreOf<TransactionList>, data: RedactableString) {
self.store = store
self.data = data
}
var body: some View {
Button {
viewStore.send(.copyToPastboard(data))
} label: {
HStack {
Asset.Assets.copy.image
.renderingMode(.template)
.resizable()
.frame(width: 11, height: 11)
.foregroundColor(Asset.Colors.primary.color)
Text(L10n.General.tapToCopy)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
WithPerceptionTracking {
Button {
store.send(.copyToPastboard(data))
} label: {
HStack {
Asset.Assets.copy.image
.renderingMode(.template)
.resizable()
.frame(width: 11, height: 11)
.foregroundColor(Asset.Colors.primary.color)
Text(L10n.General.tapToCopy)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
}
}
.buttonStyle(.borderless)
}
.buttonStyle(.borderless)
}
}
#Preview {
TapToCopyTransactionDataView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
data: "something to copy".redacted
)
}

View File

@ -12,66 +12,68 @@ import Models
import UIComponents
struct TransactionHeaderView: View {
let viewStore: TransactionListViewStore
let store: StoreOf<TransactionList>
let transaction: TransactionState
let isLatestTransaction: Bool
init(
viewStore: TransactionListViewStore,
store: StoreOf<TransactionList>,
transaction: TransactionState,
isLatestTransaction: Bool = false
) {
self.viewStore = viewStore
self.store = store
self.transaction = transaction
self.isLatestTransaction = isLatestTransaction
}
var body: some View {
VStack(spacing: 0) {
Divider()
.padding(.horizontal, 30)
.padding(.bottom, 30)
.opacity(isLatestTransaction ? 0.0 : 1.0)
HStack {
VStack(alignment: .leading, spacing: 5) {
HStack(spacing: 0) {
iconImage()
titleText()
addressArea()
Spacer(minLength: 60)
balanceView()
}
.padding(.trailing, 30)
if transaction.zAddress != nil && transaction.isAddressExpanded {
HStack {
Text(transaction.address)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
Spacer(minLength: 100)
WithPerceptionTracking {
VStack(spacing: 0) {
Divider()
.padding(.horizontal, 30)
.padding(.bottom, 30)
.opacity(isLatestTransaction ? 0.0 : 1.0)
HStack {
VStack(alignment: .leading, spacing: 5) {
HStack(spacing: 0) {
iconImage()
titleText()
addressArea()
Spacer(minLength: 60)
balanceView()
}
.padding(.horizontal, 60)
.padding(.bottom, 5)
.padding(.trailing, 30)
TapToCopyTransactionDataView(viewStore: viewStore, data: transaction.address.redacted)
if transaction.zAddress != nil && transaction.isAddressExpanded {
HStack {
Text(transaction.address)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
Spacer(minLength: 100)
}
.padding(.horizontal, 60)
.padding(.bottom, 5)
TapToCopyTransactionDataView(store: store, data: transaction.address.redacted)
.padding(.horizontal, 60)
.padding(.bottom, 20)
}
Text("\(transaction.dateString ?? "")")
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
.padding(.horizontal, 60)
.padding(.bottom, 20)
}
Text("\(transaction.dateString ?? "")")
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
.padding(.horizontal, 60)
}
}
.padding(.bottom, 30)
}
.padding(.bottom, 30)
}
@ViewBuilder private func iconImage() -> some View {
@ -105,7 +107,7 @@ struct TransactionHeaderView: View {
.foregroundColor(Asset.Colors.primary.color)
} else if !transaction.isAddressExpanded {
Button {
viewStore.send(.transactionAddressExpandRequested(transaction.id))
store.send(.transactionAddressExpandRequested(transaction.id))
} label: {
Text(transaction.address)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
@ -165,37 +167,37 @@ extension TransactionHeaderView {
#Preview {
VStack(spacing: 0) {
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedFailed
)
.listRowSeparator(.hidden)
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedFailedReceive
)
.listRowSeparator(.hidden)
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedSent
)
.listRowSeparator(.hidden)
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedReceived
)
.listRowSeparator(.hidden)
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedSending
)
.listRowSeparator(.hidden)
TransactionHeaderView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedReceiving
)
.listRowSeparator(.hidden)

View File

@ -11,53 +11,55 @@ import Generated
import Models
struct TransactionIdView: View {
let viewStore: TransactionListViewStore
let store: StoreOf<TransactionList>
let transaction: TransactionState
public init(viewStore: TransactionListViewStore, transaction: TransactionState) {
self.viewStore = viewStore
public init(store: StoreOf<TransactionList>, transaction: TransactionState) {
self.store = store
self.transaction = transaction
}
var body: some View {
VStack(alignment: .leading, spacing: 0) {
if !transaction.isIdExpanded {
HStack {
Text(L10n.TransactionList.transactionId)
Button {
viewStore.send(.transactionIdExpandRequested(transaction.id))
} label: {
Text(transaction.id)
.lineLimit(1)
.truncationMode(.middle)
WithPerceptionTracking {
VStack(alignment: .leading, spacing: 0) {
if !transaction.isIdExpanded {
HStack {
Text(L10n.TransactionList.transactionId)
Button {
store.send(.transactionIdExpandRequested(transaction.id))
} label: {
Text(transaction.id)
.lineLimit(1)
.truncationMode(.middle)
}
Spacer(minLength: 50)
}
.padding(.vertical, 20)
}
if transaction.isIdExpanded {
Text(L10n.TransactionList.transactionId)
.padding(.top, 20)
.padding(.bottom, 4)
Spacer(minLength: 50)
HStack {
Text(transaction.id)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
Spacer(minLength: 100)
}
.padding(.bottom, 10)
TapToCopyTransactionDataView(store: store, data: transaction.id.redacted)
.padding(.bottom, 20)
}
.padding(.vertical, 20)
}
if transaction.isIdExpanded {
Text(L10n.TransactionList.transactionId)
.padding(.top, 20)
.padding(.bottom, 4)
HStack {
Text(transaction.id)
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.primary.color)
Spacer(minLength: 100)
}
.padding(.bottom, 10)
TapToCopyTransactionDataView(viewStore: viewStore, data: transaction.id.redacted)
.padding(.bottom, 20)
}
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
}
.font(.custom(FontFamily.Inter.regular.name, size: 13))
.foregroundColor(Asset.Colors.shade47.color)
}
}
@ -66,7 +68,7 @@ struct TransactionIdView: View {
transaction.isIdExpanded = true
return TransactionIdView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: transaction
)
}

View File

@ -13,71 +13,73 @@ import Generated
import UIComponents
public struct TransactionRowView: View {
let viewStore: TransactionListViewStore
let store: StoreOf<TransactionList>
let transaction: TransactionState
let tokenName: String
let isLatestTransaction: Bool
public init(
viewStore: TransactionListViewStore,
store: StoreOf<TransactionList>,
transaction: TransactionState,
tokenName: String,
isLatestTransaction: Bool = false
) {
self.viewStore = viewStore
self.store = store
self.transaction = transaction
self.tokenName = tokenName
self.isLatestTransaction = isLatestTransaction
}
public var body: some View {
Button {
viewStore.send(.transactionExpandRequested(transaction.id), animation: .default)
} label: {
if transaction.isExpanded {
TransactionHeaderView(
viewStore: viewStore,
transaction: transaction,
isLatestTransaction: isLatestTransaction
)
} else {
TransactionHeaderView(
viewStore: viewStore,
transaction: transaction,
isLatestTransaction: isLatestTransaction
)
}
}
if transaction.isExpanded {
Group {
if !transaction.isTransparentRecipient {
MessageView(
viewStore: viewStore,
messages: transaction.textMemos,
isSpending: transaction.isSpending,
isFailed: transaction.status == .failed
WithPerceptionTracking {
Button {
store.send(.transactionExpandRequested(transaction.id), animation: .default)
} label: {
if transaction.isExpanded {
TransactionHeaderView(
store: store,
transaction: transaction,
isLatestTransaction: isLatestTransaction
)
} else {
TransactionHeaderView(
store: store,
transaction: transaction,
isLatestTransaction: isLatestTransaction
)
}
TransactionIdView(
viewStore: viewStore,
transaction: transaction
)
if transaction.isSpending {
TransactionFeeView(fee: transaction.fee ?? .zero)
.padding(.vertical, 10)
}
Button {
viewStore.send(.transactionCollapseRequested(transaction.id), animation: .default)
} label: {
CollapseTransactionView()
.padding(.vertical, 20)
}
}
.padding(.horizontal, 60)
if transaction.isExpanded {
Group {
if !transaction.isTransparentRecipient {
MessageView(
store: store,
messages: transaction.textMemos,
isSpending: transaction.isSpending,
isFailed: transaction.status == .failed
)
}
TransactionIdView(
store: store,
transaction: transaction
)
if transaction.isSpending {
TransactionFeeView(fee: transaction.fee ?? .zero)
.padding(.vertical, 10)
}
Button {
store.send(.transactionCollapseRequested(transaction.id), animation: .default)
} label: {
CollapseTransactionView()
.padding(.vertical, 20)
}
}
.padding(.horizontal, 60)
}
}
}
}
@ -85,7 +87,7 @@ public struct TransactionRowView: View {
#Preview {
List {
TransactionRowView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedFailed,
tokenName: "ZEC"
)
@ -93,7 +95,7 @@ public struct TransactionRowView: View {
.listRowInsets(EdgeInsets())
TransactionRowView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedReceived,
tokenName: "ZEC"
)
@ -101,7 +103,7 @@ public struct TransactionRowView: View {
.listRowInsets(EdgeInsets())
TransactionRowView(
viewStore: ViewStore(.placeholder, observe: { $0 }),
store: .placeholder,
transaction: .mockedSent,
tokenName: "ZEC"
)

View File

@ -15,10 +15,10 @@ import Home
class TransactionListSnapshotTests: XCTestCase {
func testFullTransactionListSnapshot() throws {
let store = TransactionListStore(
let store = StoreOf<TransactionList>(
initialState: .placeholder
) {
TransactionListReducer()
TransactionList()
.dependency(\.sdkSynchronizer, .mock)
.dependency(\.mainQueue, .immediate)
}

View File

@ -17,11 +17,11 @@ import TransactionList
class TransactionListTests: XCTestCase {
func testSynchronizerSubscription() async throws {
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: []
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.sdkSynchronizer = .mocked()
@ -76,11 +76,11 @@ class TransactionListTests: XCTestCase {
let identifiedTransactionList = IdentifiedArrayOf(uniqueElements: transactionList)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: identifiedTransactionList
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.mainQueue = .immediate
@ -104,7 +104,7 @@ class TransactionListTests: XCTestCase {
state.transactionList = receivedTransactionList
state.latestTransactionList = transactionList
state.latestTranassctionId = "aa11"
state.latestTransactionId = "aa11"
}
await store.finish()
@ -143,12 +143,12 @@ class TransactionListTests: XCTestCase {
let identifiedTransactionList = IdentifiedArrayOf(uniqueElements: transactionList)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
latestTransactionList: transactionList,
transactionList: identifiedTransactionList
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.mainQueue = .immediate
@ -168,11 +168,11 @@ class TransactionListTests: XCTestCase {
let testPasteboard = PasteboardClient.testPasteboard
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: []
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.pasteboard = testPasteboard
@ -210,11 +210,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -243,11 +243,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -277,11 +277,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -312,11 +312,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -346,11 +346,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -380,11 +380,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -414,11 +414,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -448,11 +448,11 @@ class TransactionListTests: XCTestCase {
)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: [transaction]
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.readTransactionsStorage = .noOp
@ -488,11 +488,11 @@ class TransactionListTests: XCTestCase {
let identifiedTransactionList = IdentifiedArrayOf(uniqueElements: transactionList)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: identifiedTransactionList
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.mainQueue = .immediate
@ -509,7 +509,7 @@ class TransactionListTests: XCTestCase {
await store.receive(.updateTransactionList(transactionList)) { state in
state.transactionList = IdentifiedArrayOf(uniqueElements: transactionList)
state.latestTransactionList = transactionList
state.latestTranassctionId = id
state.latestTransactionId = id
XCTAssertTrue(state.transactionList[0].isUnread)
}
@ -541,11 +541,11 @@ class TransactionListTests: XCTestCase {
let identifiedTransactionList = IdentifiedArrayOf(uniqueElements: transactionList)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: identifiedTransactionList
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.mainQueue = .immediate
@ -563,7 +563,7 @@ class TransactionListTests: XCTestCase {
await store.receive(.updateTransactionList(transactionList)) { state in
state.transactionList = IdentifiedArrayOf(uniqueElements: transactionList)
state.latestTransactionList = transactionList
state.latestTranassctionId = id
state.latestTransactionId = id
state.transactionList[0].isMarkedAsRead = true
XCTAssertFalse(state.transactionList[0].isUnread)
@ -596,11 +596,11 @@ class TransactionListTests: XCTestCase {
let identifiedTransactionList = IdentifiedArrayOf(uniqueElements: transactionList)
let store = TestStore(
initialState: TransactionListReducer.State(
initialState: TransactionList.State(
transactionList: identifiedTransactionList
)
) {
TransactionListReducer()
TransactionList()
}
store.dependencies.mainQueue = .immediate
@ -618,7 +618,7 @@ class TransactionListTests: XCTestCase {
await store.receive(.updateTransactionList(transactionList)) { state in
state.transactionList = IdentifiedArrayOf(uniqueElements: transactionList)
state.latestTransactionList = transactionList
state.latestTranassctionId = id
state.latestTransactionId = id
state.transactionList[0].isMarkedAsRead = true
XCTAssertFalse(state.transactionList[0].isUnread)