Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 12 additions & 1 deletion Features/Assets/Sources/ViewModels/AssetsFilterViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ public struct AssetsFilterViewModel: Sendable, Equatable {
case .swap(let type):
switch type {
case .pay: [.enabled, .swappable, .hasBalance]
case .receive(let chains, let assetIds):
case .receive(let chains, let assetIds, _):
[
.enabled,
.chainsOrAssets(
Expand All @@ -65,6 +65,17 @@ public struct AssetsFilterViewModel: Sendable, Equatable {
}
}

var preferredChain: Chain? {
switch type {
case .swap(let swapType):
switch swapType {
case .receive(_, _, let chain): chain
case .pay: nil
}
case .send, .receive, .buy, .manage, .priceAlert, .deposit, .withdraw: nil
}
Comment on lines +69 to +76
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The nested switch statement can be simplified by using pattern matching on the associated values of the enum. This will make the code more concise and improve readability by flattening the logic.

        switch type {
        case .swap(.receive(_, _, let chain)):
            return chain
        default:
            return nil
        }

}

var showHasBalanceToggle: Bool {
switch type {
case .send, .receive, .buy, .swap, .priceAlert, .deposit, .withdraw: false
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ public final class SelectAssetViewModel {
self.filterModel = filter
self.searchModel = AssetSearchViewModel(selectType: selectType)

self.assetsQuery = ObservableQuery(AssetsRequest(walletId: wallet.walletId, filters: filter.filters), initialValue: [])
self.assetsQuery = ObservableQuery(AssetsRequest(walletId: wallet.walletId, filters: filter.filters, preferredChain: filter.preferredChain), initialValue: [])
self.recentsQuery = ObservableQuery(
RecentActivityRequest(
walletId: wallet.walletId,
Expand Down
2 changes: 1 addition & 1 deletion Features/Swap/Sources/Scenes/SwapScene.swift
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ extension SwapScene {
private var swapToSectionView: some View {
Section {
SwapTokenView(
model: model.swapTokenModel(type: .receive(chains: [], assetIds: [])),
model: model.swapTokenModel(type: .receive(chains: [], assetIds: [], preferredChain: nil)),
text: $model.toValue,
showLoading: model.isLoading,
disabledTextField: true,
Expand Down
2 changes: 1 addition & 1 deletion Features/Swap/Sources/ViewModels/SwapSceneViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ extension SwapSceneViewModel {
func onSelectAssetReceive() {
guard let fromAsset = fromAsset else { return }
let (chains, assetIds) = swapQuotesProvider.supportedAssets(for: fromAsset.asset.id)
isPresentingInfoSheet = .selectAsset(.receive(chains: chains, assetIds: assetIds))
isPresentingInfoSheet = .selectAsset(.receive(chains: chains, assetIds: assetIds, preferredChain: fromAsset.asset.chain))
}

func onSelectSwapDetails() {
Expand Down
6 changes: 3 additions & 3 deletions Packages/Primitives/Sources/SelectAssetType.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ public extension SelectAssetType {

public enum SelectAssetSwapType: Identifiable, Hashable, Sendable {
case pay
case receive(chains: [Chain], assetIds: [AssetId])
case receive(chains: [Chain], assetIds: [AssetId], preferredChain: Chain?)

public var id: String {
switch self {
case .pay: "pay"
case .receive(let chains, let assetIds): "receive_\(chains)_\(assetIds)"
case .receive(let chains, let assetIds, let preferredChain): "receive_\(chains)_\(assetIds)_\(preferredChain?.rawValue ?? "")"
}
}
}
Expand Down
14 changes: 10 additions & 4 deletions Packages/Store/Sources/Requests/AssetsRequest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,27 @@ public struct AssetsRequest: DatabaseQueryable {
public var walletId: WalletId
public var searchBy: String
public var filters: [AssetsRequestFilter]
public var preferredChain: Chain?

public init(
walletId: WalletId,
searchBy: String = "",
filters: [AssetsRequestFilter] = []
filters: [AssetsRequestFilter] = [],
preferredChain: Chain? = nil
) {
self.walletId = walletId
self.searchBy = searchBy
self.filters = filters
self.preferredChain = preferredChain
}

public func fetch(_ db: Database) throws -> [AssetData] {
let searchBy = searchBy.trim()

let filters = if searchBy.isEmpty {
filters
} else {
filters + [.search(searchBy, hasPriorityAssets: try hasPriorityAssets(db, query: searchBy))]
filters + [.search(searchBy, hasPriorityAssets: try hasPriorityAssets(db, query: searchBy), preferredChain: preferredChain)]
}

if filters.contains(.priceAlerts) {
Expand Down Expand Up @@ -73,12 +76,14 @@ extension AssetsRequest {

static private func applyFilter(request: QueryInterfaceRequest<AssetRecord>, _ filter: AssetsRequestFilter) -> QueryInterfaceRequest<AssetRecord> {
switch filter {
case .search(let query, let hasPriorityAssets):
case .search(let query, let hasPriorityAssets, let preferredChain):
let chainOrder = preferredChain.map { (AssetRecord.Columns.chain == $0.rawValue).desc }
if hasPriorityAssets {
return request.joining(required: AssetRecord.search
.filter(SearchRecord.Columns.query == query)
)
.order(
chainOrder,
TableAlias(name: SearchRecord.databaseTableName)[SearchRecord.Columns.priority].ascNullsLast,
TableAlias(name: AssetRecord.databaseTableName)[AssetRecord.Columns.rank].desc
)
Expand All @@ -90,6 +95,7 @@ extension AssetsRequest {
AssetRecord.Columns.tokenId.like("%%\(query)%%")
)
.order(
chainOrder,
AssetRecord.Columns.rank.desc
)
case .hasBalance:
Expand Down
3 changes: 2 additions & 1 deletion Packages/Store/Sources/Types/AssetsRequestFilter.swift
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
// Copyright (c). Gem Wallet. All rights reserved.

import Foundation
import Primitives

public enum AssetsRequestFilter {
case search(String, hasPriorityAssets: Bool)
case search(String, hasPriorityAssets: Bool, preferredChain: Chain? = nil)
case enabled
case buyable
case swappable
Expand Down
19 changes: 17 additions & 2 deletions Packages/Store/Tests/StoreTests/Requests/AssetsRequestTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,20 @@ struct AssetsRequestTests {
}
}

@Test func testSearchPreferredChain() throws {
let assets: [AssetBasic] = .mock() + [.mock(asset: .mockTronUSDT())]
let db = DB.mockAssets(assets: assets)

try db.dbQueue.read { db in
let result = try AssetsRequest.mock(
filters: [.search("USDT", hasPriorityAssets: false)],
preferredChain: .tron
).fetch(db)

#expect(result.first?.asset == .mockTronUSDT())
}
}
Comment on lines +146 to +158
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

This test is great for covering the hasPriorityAssets: false scenario. To ensure full coverage of the new logic, it would be beneficial to add another test case for when hasPriorityAssets is true. This would verify that the preferredChain ordering correctly interacts with the existing priority-based sorting, especially in cases where they might conflict.


@Test func testOrder() throws {
let db = DB.mockAssets()
let priceStore = PriceStore(db: db)
Expand Down Expand Up @@ -181,8 +195,9 @@ extension AssetsRequest {
static func mock(
walletId: WalletId = .mock(),
searchBy: String = "",
filters: [AssetsRequestFilter] = []
filters: [AssetsRequestFilter] = [],
preferredChain: Chain? = nil
) -> AssetsRequest {
AssetsRequest(walletId: walletId, searchBy: searchBy, filters: filters)
AssetsRequest(walletId: walletId, searchBy: searchBy, filters: filters, preferredChain: preferredChain)
}
}
Loading