Skip to content

Commit 9bcf084

Browse files
authored
Merge pull request #785 from Adamant-im/carousel_update
Optimize the carousel updating. Instead of updating the whole carousel update only inner cells.
2 parents dd85b6f + 1d01a65 commit 9bcf084

File tree

7 files changed

+131
-131
lines changed

7 files changed

+131
-131
lines changed

Adamant.xcodeproj/project.pbxproj

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
557AC306287B10D8004699D7 /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 557AC305287B10D8004699D7 /* SnapKit */; };
1919
55D1D84F287B78F200F94A4E /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 55D1D84E287B78F200F94A4E /* SnapKit */; };
2020
55D1D851287B78FC00F94A4E /* SnapKit in Frameworks */ = {isa = PBXBuildFile; productRef = 55D1D850287B78FC00F94A4E /* SnapKit */; };
21-
6403F5DB2272389800D58779 /* BuildFile in Sources */ = {isa = PBXBuildFile; };
21+
6403F5DB2272389800D58779 /* (null) in Sources */ = {isa = PBXBuildFile; };
2222
6FB686162D3AAE8800CAB6DD /* AdamantWalletsKit in Frameworks */ = {isa = PBXBuildFile; productRef = 6FB686152D3AAE8800CAB6DD /* AdamantWalletsKit */; };
2323
9342F6C22A6A35E300A9B39F /* CommonKit in Frameworks */ = {isa = PBXBuildFile; productRef = 9342F6C12A6A35E300A9B39F /* CommonKit */; };
2424
937751A52A68B3320054BD65 /* CommonKit in Frameworks */ = {isa = PBXBuildFile; productRef = 937751A42A68B3320054BD65 /* CommonKit */; };
@@ -31,7 +31,7 @@
3131
A5241B70262DEDE1009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B6F262DEDE1009FA43E /* Clibsodium */; };
3232
A5241B77262DEDEF009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B76262DEDEF009FA43E /* Clibsodium */; };
3333
A5241B7E262DEDFE009FA43E /* Clibsodium in Frameworks */ = {isa = PBXBuildFile; productRef = A5241B7D262DEDFE009FA43E /* Clibsodium */; };
34-
A530B0D82842110D003F0210 /* BuildFile in Frameworks */ = {isa = PBXBuildFile; };
34+
A530B0D82842110D003F0210 /* (null) in Frameworks */ = {isa = PBXBuildFile; };
3535
A544F0D4262C9878001F1A6D /* Eureka in Frameworks */ = {isa = PBXBuildFile; productRef = A544F0D3262C9878001F1A6D /* Eureka */; };
3636
A57282CA262C94CD00C96FA8 /* DateToolsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A57282C9262C94CD00C96FA8 /* DateToolsSwift */; };
3737
A57282D1262C94DA00C96FA8 /* DateToolsSwift in Frameworks */ = {isa = PBXBuildFile; productRef = A57282D0262C94DA00C96FA8 /* DateToolsSwift */; };
@@ -249,8 +249,6 @@
249249
};
250250
D3A860F82DA1C1980007B599 /* NotificationsShared */ = {
251251
isa = PBXFileSystemSynchronizedRootGroup;
252-
exceptions = (
253-
);
254252
path = NotificationsShared;
255253
sourceTree = "<group>";
256254
};
@@ -317,7 +315,7 @@
317315
A5DBBABD262C7221004AC028 /* Clibsodium in Frameworks */,
318316
6FB686162D3AAE8800CAB6DD /* AdamantWalletsKit in Frameworks */,
319317
938F7D582955C1DA001915CA /* MessageKit in Frameworks */,
320-
A530B0D82842110D003F0210 /* BuildFile in Frameworks */,
318+
A530B0D82842110D003F0210 /* (null) in Frameworks */,
321319
4177E5E12A52DA7100C089FE /* AdvancedContextMenuKit in Frameworks */,
322320
A5D87BA3262CA01D00DC28F0 /* ProcedureKit in Frameworks */,
323321
A5C99E0E262C9E3A00F7B1B7 /* Reachability in Frameworks */,
@@ -669,12 +667,12 @@
669667
A57282C8262C94CD00C96FA8 /* XCRemoteSwiftPackageReference "DateTools" */,
670668
A544F0D2262C9878001F1A6D /* XCRemoteSwiftPackageReference "Eureka" */,
671669
A5F0A049262C9CA90009672A /* XCRemoteSwiftPackageReference "Swinject" */,
672-
A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */,
670+
A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */,
673671
A5D87BA1262CA01D00DC28F0 /* XCRemoteSwiftPackageReference "ProcedureKit" */,
674672
A5AC8DFD262E0B030053A7E2 /* XCRemoteSwiftPackageReference "SipHash" */,
675673
3A8875ED27BBF38D00436195 /* XCRemoteSwiftPackageReference "Parchment" */,
676674
557AC304287B10D8004699D7 /* XCRemoteSwiftPackageReference "SnapKit" */,
677-
416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */,
675+
416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */,
678676
938F7D562955C1DA001915CA /* XCRemoteSwiftPackageReference "MessageKit" */,
679677
4184F16F2A33044E00D7B8B9 /* XCRemoteSwiftPackageReference "firebase-ios-sdk" */,
680678
3AC76E3B2AB09118008042C4 /* XCRemoteSwiftPackageReference "Elegant-Emoji-Picker" */,
@@ -824,7 +822,7 @@
824822
isa = PBXSourcesBuildPhase;
825823
buildActionMask = 2147483647;
826824
files = (
827-
6403F5DB2272389800D58779 /* BuildFile in Sources */,
825+
6403F5DB2272389800D58779 /* (null) in Sources */,
828826
);
829827
runOnlyForDeploymentPostprocessing = 0;
830828
};
@@ -1367,7 +1365,7 @@
13671365
kind = branch;
13681366
};
13691367
};
1370-
416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */ = {
1368+
416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */ = {
13711369
isa = XCRemoteSwiftPackageReference;
13721370
repositoryURL = "https://github.com/socketio/socket.io-client-swift";
13731371
requirement = {
@@ -1447,7 +1445,7 @@
14471445
minimumVersion = 1.2.2;
14481446
};
14491447
};
1450-
A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */ = {
1448+
A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */ = {
14511449
isa = XCRemoteSwiftPackageReference;
14521450
repositoryURL = "https://github.com/ashleymills/Reachability.swift";
14531451
requirement = {
@@ -1526,7 +1524,7 @@
15261524
};
15271525
416F5EA3290162EB00EF0400 /* SocketIO */ = {
15281526
isa = XCSwiftPackageProductDependency;
1529-
package = 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket.io-client-swift" */;
1527+
package = 416F5EA2290162EB00EF0400 /* XCRemoteSwiftPackageReference "socket" */;
15301528
productName = SocketIO;
15311529
};
15321530
4177E5E02A52DA7100C089FE /* AdvancedContextMenuKit */ = {
@@ -1644,7 +1642,7 @@
16441642
};
16451643
A5C99E0D262C9E3A00F7B1B7 /* Reachability */ = {
16461644
isa = XCSwiftPackageProductDependency;
1647-
package = A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability.swift" */;
1645+
package = A5C99E0C262C9E3A00F7B1B7 /* XCRemoteSwiftPackageReference "Reachability" */;
16481646
productName = Reachability;
16491647
};
16501648
A5D87BA2262CA01D00DC28F0 /* ProcedureKit */ = {

Adamant/Modules/Account/AccountViewController/AccountViewController.swift

Lines changed: 20 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -90,13 +90,10 @@ final class AccountViewController: FormViewController {
9090
}()
9191

9292
private var walletViewControllers: [WalletViewController] = []
93-
94-
private var currentWalletCoinID: String = ""
95-
private var currentSelectedWalletItem: WalletCollectionViewCell.Model? {
96-
viewModel.state.wallets.first { wallet in
97-
wallet.coinID == currentWalletCoinID
98-
}
99-
}
93+
94+
private lazy var currentSelectedWallet: AccountWalletCellState? = {
95+
viewModel.state.wallets.first(where: { $0.model.index == 0 })
96+
}()
10097

10198
private var initiated = false
10299

@@ -186,14 +183,13 @@ final class AccountViewController: FormViewController {
186183
setupWalletsVC()
187184

188185
pagingViewController = PagingViewController()
189-
pagingViewController.register(UINib(nibName: "WalletCollectionViewCell", bundle: nil), for: WalletCollectionViewCell.Model.self)
186+
pagingViewController.register(UINib(nibName: "WalletCollectionViewCell", bundle: nil), for: AccountWalletCellState.self)
190187
pagingViewController.menuItemSize = .fixed(width: 110, height: 110)
191188
pagingViewController.indicatorColor = UIColor.adamant.primary
192189
pagingViewController.indicatorOptions = .visible(height: 2, zIndex: Int.max, spacing: UIEdgeInsets.zero, insets: UIEdgeInsets.zero)
193190
pagingViewController.dataSource = self
194191
pagingViewController.delegate = self
195-
selectCurrentWallet()
196-
192+
197193
accountHeaderView.walletViewContainer.addSubview(pagingViewController.view)
198194
pagingViewController.view.snp.makeConstraints {
199195
$0.directionalEdges.equalToSuperview()
@@ -204,17 +200,7 @@ final class AccountViewController: FormViewController {
204200
updatePagingItemHeight()
205201

206202
pagingViewController.borderColor = UIColor.clear
207-
208-
viewModel.$state
209-
.removeDuplicates()
210-
.debounce(for: .nanoseconds(500_000_000), scheduler: DispatchQueue.main)
211-
.receive(on: DispatchQueue.main)
212-
.sink { [weak self] _ in
213-
guard let self = self else { return }
214-
self.pagingViewController.reloadMenu()
215-
}
216-
.store(in: &notificationsSet)
217-
203+
218204
// MARK: Rows&Sections
219205

220206
// MARK: Application
@@ -872,8 +858,6 @@ final class AccountViewController: FormViewController {
872858
let collectionView = self.pagingViewController.collectionView
873859
collectionView.reloadData()
874860
self.tableView.reloadData()
875-
876-
selectCurrentWallet()
877861
}
878862
.store(in: &notificationsSet)
879863
}
@@ -978,35 +962,27 @@ final class AccountViewController: FormViewController {
978962
}
979963

980964
@objc private func handleRefresh(_ refreshControl: UIRefreshControl) {
981-
let unavailableNodes: Set<NodeGroup> = Set(
982-
NodeGroup.allCases.filter {
983-
!(apiServiceCompose.get($0)?.hasSupportedNode ?? true)
984-
}
985-
)
986-
965+
guard let currencyNetwork = currentSelectedWallet?.model.currencyNetwork else { return }
966+
967+
let unavailableNodes: Set<NodeGroup> = Set(NodeGroup.allCases.filter {
968+
!(apiServiceCompose.get($0)?.hasSupportedNode ?? true)
969+
})
970+
987971
if unavailableNodes.contains(where: {
988-
$0.name == currentSelectedWalletItem?.currencyNetwork
972+
$0.name == currencyNetwork
989973
}) {
990974
dialogService.showWarning(
991975
withMessage: ApiServiceError.noEndpointsAvailable(
992-
nodeGroupName: currentSelectedWalletItem?.currencyNetwork ?? ""
976+
nodeGroupName: currencyNetwork
993977
).localizedDescription
994978
)
995979
}
996-
980+
997981
Task { @MainActor in
998982
accountService.update()
999983
refreshControl.endRefreshing()
1000984
}
1001985
}
1002-
1003-
private func selectCurrentWallet() {
1004-
if let index = viewModel.state.wallets.firstIndex(where: { $0.coinID == currentWalletCoinID }) {
1005-
pagingViewController.select(index: index, animated: false)
1006-
} else if let firstWalletID = viewModel.state.wallets.first?.coinID {
1007-
currentWalletCoinID = firstWalletID
1008-
}
1009-
}
1010986
}
1011987

1012988
// MARK: - AccountHeaderViewDelegate
@@ -1081,7 +1057,7 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr
10811057
MainActor.assertIsolated()
10821058

10831059
return DispatchQueue.onMainThreadSyncSafe {
1084-
return viewModel.state.wallets[safe: index] ?? WalletCollectionViewCell.Model.default
1060+
return viewModel.state.wallets[safe: index] ?? AccountWalletCellState.default
10851061
}
10861062
}
10871063

@@ -1110,10 +1086,9 @@ extension AccountViewController: PagingViewControllerDataSource, PagingViewContr
11101086
didSelectItem pagingItem: PagingItem
11111087
) {
11121088
Task { @MainActor in
1113-
currentWalletCoinID =
1114-
viewModel.state.wallets.first(where: { wallet in
1115-
wallet.index == pagingItem.identifier
1116-
})?.coinID ?? ""
1089+
currentSelectedWallet = viewModel.state.wallets.first(where: { wallet in
1090+
wallet.model.index == pagingItem.identifier
1091+
})
11171092
}
11181093
}
11191094

Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsState.swift

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,41 @@
66
// Copyright © 2025 Adamant. All rights reserved.
77
//
88

9-
struct AccountWalletsState: Equatable {
10-
var wallets: [WalletCollectionViewCell.Model]
9+
import CommonKit
10+
import Parchment
1111

12+
struct AccountWalletsState {
13+
var wallets: [AccountWalletCellState]
14+
1215
static let `default` = Self(wallets: [])
1316
}
17+
18+
struct AccountWalletCellState {
19+
@ObservableValue var model: WalletCollectionViewCellModel
20+
21+
init(model: WalletCollectionViewCellModel) {
22+
self.model = model
23+
}
24+
25+
static let `default` = Self(model: .default)
26+
}
27+
28+
extension AccountWalletCellState: Equatable {
29+
static func == (lhs: AccountWalletCellState, rhs: AccountWalletCellState) -> Bool {
30+
lhs.model == rhs.model
31+
}
32+
}
33+
34+
extension AccountWalletCellState: PagingItem{
35+
var identifier: Int { model.index }
36+
37+
func isBefore(item: PagingItem) -> Bool {
38+
guard let other = item as? Self else { return false }
39+
return self.model.index < other.model.index
40+
}
41+
42+
func isEqual(to item: PagingItem) -> Bool {
43+
guard let other = item as? Self else { return false }
44+
return self == other
45+
}
46+
}

Adamant/Modules/Account/AccountViewController/AccountWallets/AccountWalletsViewModel.swift

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,8 @@ import Foundation
1212

1313
@MainActor
1414
final class AccountWalletsViewModel {
15-
@ObservableValue var state: AccountWalletsState = .default
16-
15+
var state: AccountWalletsState = .default
16+
1717
private let walletsStoreService: WalletStoreServiceProviderProtocol
1818
private var subscriptions = Set<AnyCancellable>()
1919

@@ -43,25 +43,29 @@ extension AccountWalletsViewModel {
4343

4444
fileprivate func updateInfo(for wallet: WalletService) {
4545
let coreService = wallet.core
46-
if let index = state.wallets.firstIndex(where: { $0.coinID == coreService.tokenUniqueID }) {
47-
state.wallets[index].balance = coreService.wallet?.balance ?? 0
48-
state.wallets[index].isBalanceInitialized = coreService.wallet?.isBalanceInitialized ?? false
49-
state.wallets[index].notificationBadgeCount = coreService.wallet?.notifications ?? 0
46+
let tokenID = coreService.tokenUniqueID
47+
if let index = state.wallets.firstIndex(where: { $0.model.coinID == tokenID }) {
48+
let cellState = state.wallets[index]
49+
var currentModel = cellState.model
50+
currentModel.balance = coreService.wallet?.balance ?? 0
51+
currentModel.isBalanceInitialized = coreService.wallet?.isBalanceInitialized ?? false
52+
currentModel.notificationBadgeCount = coreService.wallet?.notifications ?? 0
53+
cellState.model = currentModel
54+
state.wallets[index] = cellState
5055
} else {
5156
let network = type(of: coreService).tokenNetworkSymbol
52-
53-
let model = WalletCollectionViewCell.Model(
57+
let newModel = WalletCollectionViewCellModel(
5458
index: state.wallets.count,
55-
coinID: coreService.tokenUniqueID,
59+
coinID: tokenID,
5660
currencySymbol: coreService.tokenSymbol,
5761
currencyImage: coreService.tokenLogo,
5862
currencyNetwork: network,
5963
isBalanceInitialized: coreService.wallet?.isBalanceInitialized ?? false,
6064
balance: coreService.wallet?.balance ?? 0,
6165
notificationBadgeCount: coreService.wallet?.notifications ?? 0
6266
)
63-
64-
state.wallets.append(model)
67+
let cellState = AccountWalletCellState(model: newModel)
68+
state.wallets.append(cellState)
6569
}
6670
}
6771
}

0 commit comments

Comments
 (0)