-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MOB-1924 - Added activity tab (#463)
* Updated confirm send transaction pull up * Fixed wallet icons tint color on receiver selection screen * Fixed copy for max token pull up * Added activity view to tab * Created wallet transactions service and API to get transactions * Removed test code * Refactoring * Updated transactions response structure. * Moved cache transactions logic to separate service. Created tests for transactions service * Refactoring. Added wallet txs service to app context. Created functions to create mock txs related objects * Updated tx timestamp property * Created structure for WalletTransactionDisplayInfo * Load txs in view model * Setup home activity stack * Created simple ui for transactions * Fixed icon for external wallet in select receiver screen * Open Tx details on tap Updated UI for nft Txs. Added PTR * Pass force refresh flag to request
- Loading branch information
1 parent
b6a5a33
commit 2500d43
Showing
38 changed files
with
1,400 additions
and
26 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
122 changes: 122 additions & 0 deletions
122
unstoppable-ios-app/domains-manager-ios.xcodeproj/project.pbxproj
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
66 changes: 66 additions & 0 deletions
66
unstoppable-ios-app/domains-manager-ios/Entities/Mock/MockEntitiesFabric+Txs.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
// | ||
// MockEntitiesFabric+Txs.swift | ||
// domains-manager-ios | ||
// | ||
// Created by Oleg Kuplin on 27.03.2024. | ||
// | ||
|
||
import Foundation | ||
|
||
// MARK: - WalletTxs | ||
extension MockEntitiesFabric { | ||
enum WalletTxs { | ||
@MainActor | ||
static func createViewModel() -> HomeActivityViewModel { | ||
createViewModelUsing(Home.createHomeTabRouter()) | ||
} | ||
|
||
@MainActor | ||
static func createViewModelUsing(_ router: HomeTabRouter) -> HomeActivityViewModel { | ||
HomeActivityViewModel(router: router) | ||
} | ||
|
||
static func createMockTxsResponses(canLoadMore: Bool = false, | ||
amount: Int = 20) -> [WalletTransactionsPerChainResponse] { | ||
[createMockTxsResponse(chain: "ETH", | ||
canLoadMore: canLoadMore, | ||
amount: amount), | ||
createMockTxsResponse(chain: "MATIC", | ||
canLoadMore: canLoadMore, | ||
amount: amount), | ||
createMockTxsResponse(chain: "BASE", | ||
canLoadMore: canLoadMore, | ||
amount: amount)] | ||
} | ||
|
||
static func createMockTxsResponse(chain: String, | ||
canLoadMore: Bool = false, | ||
amount: Int = 20) -> WalletTransactionsPerChainResponse { | ||
WalletTransactionsPerChainResponse(chain: chain, | ||
cursor: canLoadMore ? UUID().uuidString : nil, | ||
txs: createMockEmptyTxs(range: 1...amount)) | ||
} | ||
|
||
|
||
static func createMockEmptyTxs(range: ClosedRange<Int> = 1...3) -> [SerializedWalletTransaction] { | ||
range.map { createMockEmptyTx(id: "\($0)", dateOffset: TimeInterval($0)) } | ||
} | ||
|
||
static func createMockEmptyTx(id: String = "1", | ||
dateOffset: TimeInterval = 0) -> SerializedWalletTransaction { | ||
SerializedWalletTransaction(hash: id, | ||
block: "", | ||
timestamp: Date().addingTimeInterval(dateOffset), | ||
success: true, | ||
value: 1, | ||
gas: 1, | ||
method: "", | ||
link: "", | ||
imageUrl: "", | ||
symbol: "", | ||
type: "", | ||
from: .init(address: "1", label: nil, link: ""), | ||
to: .init(address: "2", label: nil, link: "")) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
34 changes: 34 additions & 0 deletions
34
unstoppable-ios-app/domains-manager-ios/Modules/Home/Activity/HomeActivity.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
// | ||
// HomeActivity.swift | ||
// domains-manager-ios | ||
// | ||
// Created by Oleg Kuplin on 27.03.2024. | ||
// | ||
|
||
import Foundation | ||
|
||
// Namespace | ||
enum HomeActivity { } | ||
|
||
// MARK: - Open methods | ||
extension HomeActivity { | ||
struct GroupedTransactions: Hashable { | ||
let date: Date | ||
let txs: [WalletTransactionDisplayInfo] | ||
|
||
init(date: Date, txs: [WalletTransactionDisplayInfo]) { | ||
self.date = date | ||
self.txs = txs.sorted { $0.time > $1.time } | ||
} | ||
|
||
static func buildGroupsFrom(txs: [WalletTransactionDisplayInfo]) -> [GroupedTransactions] { | ||
txs.reduce(into: [Date: [WalletTransactionDisplayInfo]]()) { result, tx in | ||
let date = tx.time.dayStart | ||
result[date, default: []].append(tx) | ||
} | ||
.map { GroupedTransactions(date: $0.key, txs: $0.value) } | ||
.sorted { $0.date > $1.date } | ||
} | ||
|
||
} | ||
} |
26 changes: 26 additions & 0 deletions
26
...ios-app/domains-manager-ios/Modules/Home/Activity/HomeActivityNavigationDestination.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// | ||
// HomeActivityNavigationDestination.swift | ||
// domains-manager-ios | ||
// | ||
// Created by Oleg Kuplin on 27.03.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
enum HomeActivityNavigationDestination: Hashable { | ||
|
||
} | ||
|
||
struct HomeActivityLinkNavigationDestination { | ||
|
||
@ViewBuilder | ||
static func viewFor(navigationDestination: HomeActivityNavigationDestination, | ||
tabRouter: HomeTabRouter) -> some View { | ||
switch navigationDestination { | ||
default: | ||
EmptyView() | ||
} | ||
} | ||
|
||
} | ||
|
53 changes: 53 additions & 0 deletions
53
...s-app/domains-manager-ios/Modules/Home/Activity/HomeActivityTransactionsSectionView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
// | ||
// HomeActivityTransactionsSectionView.swift | ||
// domains-manager-ios | ||
// | ||
// Created by Oleg Kuplin on 27.03.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct HomeActivityTransactionsSectionView: View { | ||
|
||
@EnvironmentObject var viewModel: HomeActivityViewModel | ||
let groupedTxs: HomeActivity.GroupedTransactions | ||
|
||
var body: some View { | ||
Section { | ||
ForEach(groupedTxs.txs) { tx in | ||
clickableTxRowView(tx) | ||
.onAppear { | ||
viewModel.willDisplayTransaction(tx) | ||
} | ||
} | ||
} header: { | ||
HStack { | ||
Text(DateFormattingService.shared.formatICloudBackUpDate(groupedTxs.date)) | ||
.font(.currentFont(size: 14, weight: .semibold)) | ||
.foregroundStyle(Color.foregroundSecondary) | ||
Spacer() | ||
} | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Private methods | ||
private extension HomeActivityTransactionsSectionView { | ||
@ViewBuilder | ||
func clickableTxRowView(_ tx: WalletTransactionDisplayInfo) -> some View { | ||
Button { | ||
UDVibration.buttonTap.vibrate() | ||
if let url = tx.link { | ||
openLink(.direct(url: url)) | ||
} | ||
} label: { | ||
WalletTransactionDisplayInfoListItemView(transaction: tx) | ||
} | ||
.buttonStyle(.plain) | ||
.allowsHitTesting(tx.link != nil) | ||
} | ||
} | ||
|
||
#Preview { | ||
HomeActivityTransactionsSectionView(groupedTxs: HomeActivity.GroupedTransactions(date: Date(), txs: [])) | ||
} |
113 changes: 113 additions & 0 deletions
113
unstoppable-ios-app/domains-manager-ios/Modules/Home/Activity/HomeActivityView.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
// | ||
// ActivityView.swift | ||
// domains-manager-ios | ||
// | ||
// Created by Oleg Kuplin on 27.03.2024. | ||
// | ||
|
||
import SwiftUI | ||
|
||
struct HomeActivityView: View, ViewAnalyticsLogger { | ||
|
||
@EnvironmentObject var tabRouter: HomeTabRouter | ||
@State private var navigationState: NavigationStateManager? | ||
@StateObject var viewModel: HomeActivityViewModel | ||
|
||
var isOtherScreenPushed: Bool { !tabRouter.activityTabNavPath.isEmpty } | ||
var analyticsName: Analytics.ViewName { .homeActivity } | ||
|
||
var body: some View { | ||
NavigationViewWithCustomTitle(content: { | ||
contentList() | ||
.animation(.default, value: UUID()) | ||
.background(Color.backgroundDefault) | ||
.navigationTitle("") | ||
.navigationBarTitleDisplayMode(.inline) | ||
.environmentObject(viewModel) | ||
.passViewAnalyticsDetails(logger: self) | ||
.displayError($viewModel.error) | ||
.background(Color.backgroundMuted2) | ||
.refreshable { | ||
logAnalytic(event: .didPullToRefresh) | ||
await viewModel.didPullToRefresh() | ||
} | ||
.onReceive(keyboardPublisher) { value in | ||
viewModel.isKeyboardActive = value | ||
if !value { | ||
UDVibration.buttonTap.vibrate() | ||
} | ||
} | ||
.onChange(of: tabRouter.activityTabNavPath) { path in | ||
withAnimation { | ||
tabRouter.isTabBarVisible = !isOtherScreenPushed | ||
if path.isEmpty { | ||
setupTitle() | ||
} else { | ||
setTitleVisibility() | ||
} | ||
} | ||
} | ||
.navigationDestination(for: HomeActivityNavigationDestination.self) { destination in | ||
HomeActivityLinkNavigationDestination.viewFor(navigationDestination: destination, | ||
tabRouter: tabRouter) | ||
.environmentObject(navigationState!) | ||
.environmentObject(viewModel) | ||
} | ||
.toolbar(content: { | ||
// To keep nav bar background visible when scrolling | ||
ToolbarItem(placement: .topBarLeading) { | ||
Color.clear | ||
} | ||
}) | ||
}, navigationStateProvider: { state in | ||
self.navigationState = state | ||
}, path: $tabRouter.activityTabNavPath) | ||
.onAppear(perform: onAppear) | ||
} | ||
} | ||
|
||
// MARK: - Private methods | ||
private extension HomeActivityView { | ||
func onAppear() { | ||
setupTitle() | ||
} | ||
|
||
func setupTitle() { | ||
navigationState?.setCustomTitle(customTitle: { HomeProfileSelectorNavTitleView() }, | ||
id: UUID().uuidString) | ||
setTitleVisibility() | ||
} | ||
|
||
func setTitleVisibility() { | ||
withAnimation { | ||
navigationState?.isTitleVisible = !isOtherScreenPushed | ||
} | ||
} | ||
} | ||
|
||
// MARK: - Views | ||
private extension HomeActivityView { | ||
@ViewBuilder | ||
func contentList() -> some View { | ||
List { | ||
txsList() | ||
} | ||
.listStyle(.plain) | ||
} | ||
|
||
@ViewBuilder | ||
func txsList() -> some View { | ||
ForEach(viewModel.groupedTxs, id: \.self) { groupedTx in | ||
HomeActivityTransactionsSectionView(groupedTxs: groupedTx) | ||
} | ||
} | ||
} | ||
|
||
#Preview { | ||
let router = MockEntitiesFabric.Home.createHomeTabRouter() | ||
let viewModel = MockEntitiesFabric.WalletTxs.createViewModelUsing(router) | ||
|
||
return HomeActivityView(viewModel: viewModel) | ||
.environmentObject(router) | ||
|
||
} |
Oops, something went wrong.