diff --git a/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj b/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj index 073fea228a..3e89e35f92 100644 --- a/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj +++ b/UnstoppableWallet/UnstoppableWallet.xcodeproj/project.pbxproj @@ -13243,7 +13243,7 @@ repositoryURL = "https://github.com/horizontalsystems/MarketKit.Swift"; requirement = { kind = exactVersion; - version = 3.0.9; + version = 3.0.10; }; }; D3604E7D28F03C1D0066C366 /* XCRemoteSwiftPackageReference "Chart" */ = { diff --git a/UnstoppableWallet/UnstoppableWallet/Core/Managers/PriceChangeModeManager.swift b/UnstoppableWallet/UnstoppableWallet/Core/Managers/PriceChangeModeManager.swift index a5dbf40316..c5aba5f95a 100644 --- a/UnstoppableWallet/UnstoppableWallet/Core/Managers/PriceChangeModeManager.swift +++ b/UnstoppableWallet/UnstoppableWallet/Core/Managers/PriceChangeModeManager.swift @@ -1,5 +1,6 @@ import Combine import HsExtensions +import MarketKit class PriceChangeModeManager { private let keyPriceChangeMode = "price-change-mode" @@ -12,6 +13,13 @@ class PriceChangeModeManager { } } + var day1Period: HsTimePeriod { + switch priceChangeMode { + case .hour24: .hour24 + case .day1: .day1 + } + } + init(userDefaultsStorage: UserDefaultsStorage) { self.userDefaultsStorage = userDefaultsStorage @@ -21,4 +29,12 @@ class PriceChangeModeManager { priceChangeMode = .hour24 } } + + func convert(period: HsTimePeriod) -> HsTimePeriod { + guard [HsTimePeriod.day1, .hour24].contains(period) else { + return period + } + + return day1Period + } } diff --git a/UnstoppableWallet/UnstoppableWallet/Extensions/StatExtensions.swift b/UnstoppableWallet/UnstoppableWallet/Extensions/StatExtensions.swift index 3bd522e14f..7a317780c6 100644 --- a/UnstoppableWallet/UnstoppableWallet/Extensions/StatExtensions.swift +++ b/UnstoppableWallet/UnstoppableWallet/Extensions/StatExtensions.swift @@ -3,6 +3,7 @@ import MarketKit extension HsTimePeriod { var statPeriod: StatPeriod { switch self { + case .hour24: return .hour24 case .day1: return .day1 case .week1: return .week1 case .week2: return .week2 diff --git a/UnstoppableWallet/UnstoppableWallet/Models/PriceChangeMode.swift b/UnstoppableWallet/UnstoppableWallet/Models/PriceChangeMode.swift index d067ad1f1f..04655e535b 100644 --- a/UnstoppableWallet/UnstoppableWallet/Models/PriceChangeMode.swift +++ b/UnstoppableWallet/UnstoppableWallet/Models/PriceChangeMode.swift @@ -1,13 +1,13 @@ enum PriceChangeMode: String, CaseIterable, Codable { case hour24 = "hour_24" - case midnightUtc = "midnight_utc" + case day1 = "day_1" } extension PriceChangeMode { var statName: String { switch self { case .hour24: return "hour_24" - case .midnightUtc: return "midnight_utc" + case .day1: return "day_1" } } } diff --git a/UnstoppableWallet/UnstoppableWallet/Models/Stats.swift b/UnstoppableWallet/UnstoppableWallet/Models/Stats.swift index 01e080cd8e..c8e8c03595 100644 --- a/UnstoppableWallet/UnstoppableWallet/Models/Stats.swift +++ b/UnstoppableWallet/UnstoppableWallet/Models/Stats.swift @@ -439,6 +439,7 @@ enum StatSortType: String { } enum StatPeriod: String { + case hour24 = "24h" case day1 = "1d" case week1 = "1w" case week2 = "2w" diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChart/CoinChartService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChart/CoinChartService.swift index 9e95269369..eb2955ed1c 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChart/CoinChartService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChart/CoinChartService.swift @@ -75,7 +75,7 @@ class CoinChartService { self.indicatorRepository = indicatorRepository self.coinUid = coinUid - periodType = .byCustomPoints(.day1, indicatorRepository.extendedPointCount) + periodType = .byCustomPoints(App.shared.priceChangeModeManager.day1Period, indicatorRepository.extendedPointCount) indicatorRepository.updatedPublisher .sink { [weak self] in self?.fetchWithUpdatedIndicators() @@ -122,7 +122,8 @@ class CoinChartService { let item = Item( coinUid: coinUid, rate: coinPrice.value, - rateDiff24h: coinPrice.diff, + rateDiff24h: coinPrice.diff24h, + rateDiff1d: coinPrice.diff1d, timestamp: coinPrice.timestamp, chartPointsItem: chartPointsItem, indicators: indicatorRepository.indicators, @@ -223,6 +224,7 @@ extension CoinChartService { let coinUid: String let rate: Decimal let rateDiff24h: Decimal? + let rateDiff1d: Decimal? let timestamp: TimeInterval let chartPointsItem: ChartPointsItem let indicators: [ChartIndicator] diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChartFactory.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChartFactory.swift index a7745fb3c0..225ddfb1a8 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChartFactory.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinChartFactory.swift @@ -22,21 +22,30 @@ class CoinChartFactory { points.append(point) lastPoint = point - // for daily chart we need change oldest visible point to 24h back timestamp-same point - if periodType.in([.day1]), let rateDiff24 = item.rateDiff24h { + var pointToPrepend: ChartPoint? + + if periodType.in([.hour24]), let rateDiff24 = item.rateDiff24h { + // for 24h chart we need change oldest visible point to 24h back timestamp-same point let timestamp = item.timestamp - 24 * 60 * 60 let value = 100 * item.rate / (100 + rateDiff24) - let point = ChartPoint(timestamp: timestamp, value: value) + pointToPrepend = ChartPoint(timestamp: timestamp, value: value) + } else if periodType.in([.day1]), let rateDiff1d = item.rateDiff1d { + // for 1day chart we need change oldest visible point to 24h back timestamp-same point + let value = 100 * item.rate / (100 + rateDiff1d) + + pointToPrepend = ChartPoint(timestamp: TimeInterval.midnightUTC(), value: value) + } - if let index = points.firstIndex(where: { $0.timestamp > timestamp }) { - points.insert(point, at: index) + if let pointToPrepend { + if let index = points.firstIndex(where: { $0.timestamp > pointToPrepend.timestamp }) { + points.insert(pointToPrepend, at: index) if index > 0 { points.remove(at: index - 1) } } - firstPoint = point + firstPoint = pointToPrepend } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinOverview/CoinOverviewViewItemFactory.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinOverview/CoinOverviewViewItemFactory.swift index 03198dd18f..cf95a77e0a 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinOverview/CoinOverviewViewItemFactory.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Coin/CoinOverview/CoinOverviewViewItemFactory.swift @@ -12,7 +12,8 @@ class CoinOverviewViewItemFactory { private func roiTitle(timePeriod: HsTimePeriod) -> String { switch timePeriod { - case .day1: return "coin_overview.roi.hour24".localized + case .hour24: return "coin_overview.roi.hour24".localized + case .day1: return "coin_overview.roi.day1".localized case .week1: return "coin_overview.roi.day7".localized case .week2: return "coin_overview.roi.day14".localized case .month1: return "coin_overview.roi.day30".localized diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Market/AdvancedSearch/MarketAdvancedSearchViewModel.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Market/AdvancedSearch/MarketAdvancedSearchViewModel.swift index 12acd9a981..826810565a 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Market/AdvancedSearch/MarketAdvancedSearchViewModel.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Market/AdvancedSearch/MarketAdvancedSearchViewModel.swift @@ -28,6 +28,8 @@ class MarketAdvancedSearchViewModel: ObservableObject { private let marketKit = App.shared.marketKit private let currencyManager = App.shared.currencyManager + private let priceChangeModeManager = App.shared.priceChangeModeManager + private var cancellables = Set() private var tasks = Set() private var internalState: State = .loading { @@ -102,7 +104,7 @@ class MarketAdvancedSearchViewModel: ObservableObject { } } - @Published var priceChangePeriod: HsTimePeriod = .day1 { + @Published var priceChangePeriod: HsTimePeriod { didSet { syncState() } @@ -152,6 +154,16 @@ class MarketAdvancedSearchViewModel: ObservableObject { allBlockchains = [] } + priceChangePeriod = priceChangeModeManager.day1Period + + priceChangeModeManager.$priceChangeMode + .sink { [weak self] _ in + if let strongSelf = self { + strongSelf.priceChangePeriod = strongSelf.priceChangeModeManager.day1Period + } + } + .store(in: &cancellables) + syncMarketInfos() } @@ -179,7 +191,7 @@ class MarketAdvancedSearchViewModel: ObservableObject { || !blockchains.isEmpty || signal != nil || priceChange != .none - || priceChangePeriod != .day1 + || priceChangePeriod != priceChangeModeManager.day1Period || outperformedBtc != false || outperformedEth != false || outperformedBnb != false @@ -307,7 +319,7 @@ extension MarketAdvancedSearchViewModel { } var priceChangePeriods: [HsTimePeriod] { - [.day1, .week1, .week2, .month1, .month6, .year1] + [priceChangeModeManager.day1Period, .week1, .week2, .month1, .month6, .year1] } func syncMarketInfos() { @@ -343,7 +355,7 @@ extension MarketAdvancedSearchViewModel { blockchains = Set() signal = nil priceChange = .none - priceChangePeriod = .day1 + priceChangePeriod = priceChangeModeManager.day1Period outperformedBtc = false outperformedEth = false outperformedBnb = false diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Market/Coins/MarketCoinsViewModel.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Market/Coins/MarketCoinsViewModel.swift index 520a96e3f7..d0a055916e 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Market/Coins/MarketCoinsViewModel.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Market/Coins/MarketCoinsViewModel.swift @@ -7,6 +7,8 @@ class MarketCoinsViewModel: ObservableObject { private let marketKit = App.shared.marketKit private let currencyManager = App.shared.currencyManager private let appManager = App.shared.appManager + private let priceChangeModeManager = App.shared.priceChangeModeManager + private var cancellables = Set() private var tasks = Set() @@ -32,13 +34,27 @@ class MarketCoinsViewModel: ObservableObject { } } - var timePeriod: HsTimePeriod = .day1 { + var timePeriod: HsTimePeriod { didSet { stat(page: .markets, section: .coins, event: .switchPeriod(period: timePeriod.statPeriod)) syncState() } } + init() { + timePeriod = priceChangeModeManager.day1Period + + priceChangeModeManager.$priceChangeMode + .sink { [weak self] _ in + self?.syncPeriod() + } + .store(in: &cancellables) + } + + private func syncPeriod() { + timePeriod = priceChangeModeManager.convert(period: timePeriod) + } + private func syncMarketInfos() { tasks = Set() @@ -94,7 +110,7 @@ extension MarketCoinsViewModel { } var timePeriods: [HsTimePeriod] { - [.day1, .week1, .month1, .month3] + [priceChangeModeManager.day1Period, .week1, .month1, .month3] } func load() { diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Market/MarketModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Market/MarketModule.swift index 8bbd522792..5772a64a83 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Market/MarketModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Market/MarketModule.swift @@ -78,7 +78,8 @@ enum MarketModule { extension MarketKit.MarketInfo { func priceChangeValue(timePeriod: HsTimePeriod) -> Decimal? { switch timePeriod { - case .day1: return priceChange24h + case .day1: return priceChange1d + case .hour24: return priceChange24h case .week1: return priceChange7d case .week2: return priceChange14d case .month1: return priceChange30d @@ -91,7 +92,7 @@ extension MarketKit.MarketInfo { func priceChangeValue(timePeriod: WatchlistTimePeriod) -> Decimal? { switch timePeriod { - case .day1: return priceChange24h + case .day1: return priceChange1d case .week1: return priceChange7d case .month1: return priceChange30d case .month3: return priceChange90d @@ -189,17 +190,11 @@ extension [MarketKit.TopPlatform] { extension HsTimePeriod { var title: String { - switch self { - case .day1: return "market.time_period.24h".localized - default: return "market.time_period.\(rawValue)".localized - } + "market.time_period.\(rawValue)".localized } var shortTitle: String { - switch self { - case .day1: return "market.time_period.24h.short".localized - default: return "market.time_period.\(rawValue).short".localized - } + "market.time_period.\(rawValue).short".localized } init?(_ periodType: HsPeriodType) { @@ -212,17 +207,11 @@ extension HsTimePeriod { extension WatchlistTimePeriod { var title: String { - switch self { - case .day1: return "market.time_period.24h".localized - default: return "market.time_period.\(rawValue)".localized - } + "market.time_period.\(rawValue)".localized } var shortTitle: String { - switch self { - case .day1: return "market.time_period.24h.short".localized - default: return "market.time_period.\(rawValue).short".localized - } + "market.time_period.\(rawValue).short".localized } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftModule.swift index 749687d5b0..2aabf8b0e5 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftModule.swift @@ -5,6 +5,7 @@ enum NftModule { static func viewController() -> UIViewController? { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftService.swift index 10de187e54..93a3b9ee15 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Nft/NftService.swift @@ -263,17 +263,16 @@ class NftService { } extension NftService: IWalletCoinPriceServiceDelegate { - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { - self.updatePriceItems(items: self.items, map: self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: self.items)))) - self.items = self.sort(items: self.items) - self.syncTotalItem() - } - } + let _itemsMap: [String: WalletCoinPriceService.Item] + if let itemsMap { + _itemsMap = itemsMap + } else { + _itemsMap = self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: self.items))) + } - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - self.updatePriceItems(items: self.items, map: itemsMap) + self.updatePriceItems(items: self.items, map: _itemsMap) self.items = self.sort(items: self.items) self.syncTotalItem() } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewModule.swift index c3c4e3ad81..d59f513038 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewModule.swift @@ -4,6 +4,7 @@ enum NftAssetOverviewModule { static func viewController(providerCollectionUid: String, nftUid: NftUid) -> NftAssetOverviewViewController { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewService.swift index 3e74354e07..2b67c5019b 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftAsset/Overview/NftAssetOverviewService.swift @@ -160,24 +160,18 @@ class NftAssetOverviewService { } extension NftAssetOverviewService: IWalletCoinPriceServiceDelegate { - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { guard case let .completed(item) = self.state else { return } - self._fillCoinPrices(item: item, coinUids: self._allCoinUids(item: item)) - self.state = .completed(item) - } - } - - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - guard case let .completed(item) = self.state else { - return + if let itemsMap { + self._fillCoinPrices(item: item, map: itemsMap) + } else { + self._fillCoinPrices(item: item, coinUids: self._allCoinUids(item: item)) } - self._fillCoinPrices(item: item, map: itemsMap) self.state = .completed(item) } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityModule.swift index 776de9f2d6..9a72c5b0df 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityModule.swift @@ -4,7 +4,11 @@ import UIKit enum NftActivityModule { static func viewController(eventListType: NftEventListType, defaultEventType: NftEventMetadata.EventType? = .sale) -> NftActivityViewController { - let coinPriceService = WalletCoinPriceService(currencyManager: App.shared.currencyManager, marketKit: App.shared.marketKit) + let coinPriceService = WalletCoinPriceService( + currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, + marketKit: App.shared.marketKit + ) let service = NftActivityService(eventListType: eventListType, defaultEventType: defaultEventType, nftMetadataManager: App.shared.nftMetadataManager, coinPriceService: coinPriceService) let viewModel = NftActivityViewModel(service: service) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityService.swift index 72f81da1d7..aa57eeaf4e 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Activity/NftActivityService.swift @@ -186,24 +186,20 @@ class NftActivityService { } extension NftActivityService: IWalletCoinPriceServiceDelegate { - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { guard case let .loaded(items, allLoaded) = self.state else { return } - self.updatePriceItems(items: items, map: self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: items)))) - self.state = .loaded(items: items, allLoaded: allLoaded) - } - } - - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - guard case let .loaded(items, allLoaded) = self.state else { - return + let _itemsMap: [String: WalletCoinPriceService.Item] + if let itemsMap { + _itemsMap = itemsMap + } else { + _itemsMap = self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: items))) } - self.updatePriceItems(items: items, map: itemsMap) + self.updatePriceItems(items: items, map: _itemsMap) self.state = .loaded(items: items, allLoaded: allLoaded) } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsModule.swift index cd1bcb9c1f..822e9a4bdf 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsModule.swift @@ -2,7 +2,11 @@ import MarketKit enum NftCollectionAssetsModule { static func viewController(blockchainType: BlockchainType, providerCollectionUid: String) -> NftCollectionAssetsViewController { - let coinPriceService = WalletCoinPriceService(currencyManager: App.shared.currencyManager, marketKit: App.shared.marketKit) + let coinPriceService = WalletCoinPriceService( + currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, + marketKit: App.shared.marketKit + ) let service = NftCollectionAssetsService(blockchainType: blockchainType, providerCollectionUid: providerCollectionUid, nftMetadataManager: App.shared.nftMetadataManager, coinPriceService: coinPriceService) let viewModel = NftCollectionAssetsViewModel(service: service) return NftCollectionAssetsViewController(viewModel: viewModel) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsService.swift index 89e1e4de25..8fa5fd2d3f 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/NftCollection/Assets/NftCollectionAssetsService.swift @@ -120,24 +120,20 @@ class NftCollectionAssetsService { } extension NftCollectionAssetsService: IWalletCoinPriceServiceDelegate { - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { guard case let .loaded(items, allLoaded) = self.state else { return } - self.updatePriceItems(items: items, map: self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: items)))) - self.state = .loaded(items: items, allLoaded: allLoaded) - } - } - - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - guard case let .loaded(items, allLoaded) = self.state else { - return + let _itemsMap: [String: WalletCoinPriceService.Item] + if let itemsMap { + _itemsMap = itemsMap + } else { + _itemsMap = self.coinPriceService.itemMap(coinUids: Array(self.allCoinUids(items: items))) } - self.updatePriceItems(items: items, map: itemsMap) + self.updatePriceItems(items: items, map: _itemsMap) self.state = .loaded(items: items, allLoaded: allLoaded) } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Appearance/AppearanceView.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Appearance/AppearanceView.swift index 94e3f77bd4..1939287bf2 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Appearance/AppearanceView.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Settings/Appearance/AppearanceView.swift @@ -175,7 +175,7 @@ struct AppearanceView: View { func title(priceChangeMode: PriceChangeMode) -> String { switch priceChangeMode { case .hour24: return "appearance.price_change.24h".localized - case .midnightUtc: return "appearance.price_change.midnight_utc".localized + case .day1: return "appearance.price_change.1d".localized } } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceModule.swift index 28595a6a23..42ffec455c 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceModule.swift @@ -8,6 +8,7 @@ enum WalletTokenBalanceModule { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceService.swift index d68de528c0..14928e4350 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/Token/DataSources/WalletTokenBalance/WalletTokenBalanceService.swift @@ -181,6 +181,5 @@ extension WalletTokenBalanceService: IWalletCoinPriceServiceDelegate { } } - func didUpdateBaseCurrency() {} - func didUpdate(itemsMap _: [String: WalletCoinPriceService.Item]) {} + func didUpdate(itemsMap _: [String: WalletCoinPriceService.Item]?) {} } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListService.swift index f2efc74edd..f6821eb8c0 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/TokenList/WalletTokenListService.swift @@ -252,24 +252,21 @@ extension WalletTokenListService: IWalletCoinPriceServiceDelegate { internalState = .loaded(items: _sorted(items: items)) } - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { guard case let .loaded(items) = self.internalState else { return } - let coinUids = Array(Set(items.compactMap(\.element.priceCoinUid))) - self._handleUpdated(priceItemMap: self.coinPriceService.itemMap(coinUids: coinUids), items: items) - } - } - - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - guard case let .loaded(items) = self.internalState else { - return + let _itemsMap: [String: WalletCoinPriceService.Item] + if let itemsMap { + _itemsMap = itemsMap + } else { + let coinUids = Array(Set(items.compactMap(\.element.priceCoinUid))) + _itemsMap = self.coinPriceService.itemMap(coinUids: coinUids) } - self._handleUpdated(priceItemMap: itemsMap, items: items) + self._handleUpdated(priceItemMap: _itemsMap, items: items) } } } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletCoinPriceService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletCoinPriceService.swift index 0e69787dda..92e3318b94 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletCoinPriceService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletCoinPriceService.swift @@ -3,14 +3,14 @@ import Foundation import MarketKit protocol IWalletCoinPriceServiceDelegate: AnyObject { - func didUpdateBaseCurrency() - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) } class WalletCoinPriceService { weak var delegate: IWalletCoinPriceServiceDelegate? private let currencyManager: CurrencyManager + private let priceChangeModeManager: PriceChangeModeManager private let marketKit: MarketKit.Kit private var cancellables = Set() private var coinPriceCancellables = Set() @@ -20,9 +20,10 @@ class WalletCoinPriceService { private var feeCoinUids = Set() private var conversionCoinUids = Set() - init(currencyManager: CurrencyManager, marketKit: MarketKit.Kit) { + init(currencyManager: CurrencyManager, priceChangeModeManager: PriceChangeModeManager, marketKit: MarketKit.Kit) { self.currencyManager = currencyManager self.marketKit = marketKit + self.priceChangeModeManager = priceChangeModeManager currency = currencyManager.baseCurrency @@ -31,12 +32,18 @@ class WalletCoinPriceService { self?.onUpdate(baseCurrency: currency) } .store(in: &cancellables) + + priceChangeModeManager.$priceChangeMode + .sink { [weak self] _ in + self?.delegate?.didUpdate(itemsMap: nil) + } + .store(in: &cancellables) } private func onUpdate(baseCurrency: Currency) { currency = baseCurrency subscribeToCoinPrices() - delegate?.didUpdateBaseCurrency() + delegate?.didUpdate(itemsMap: nil) } private func subscribeToCoinPrices() { @@ -71,9 +78,17 @@ class WalletCoinPriceService { private func item(coinPrice: CoinPrice) -> Item { let currency = currencyManager.baseCurrency + let diff: Decimal? + switch priceChangeModeManager.priceChangeMode { + case .hour24: + diff = coinPrice.diff24h + case .day1: + diff = coinPrice.diff1d + } + return Item( price: CurrencyValue(currency: currency, value: coinPrice.value), - diff: coinPrice.diff, + diff: diff, expired: coinPrice.expired ) } diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift index df2569c4fb..a3b29a668c 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletModule.swift @@ -7,6 +7,7 @@ enum WalletModule { static func viewController() -> UIViewController { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) @@ -58,6 +59,7 @@ enum WalletModule { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) @@ -119,6 +121,7 @@ enum WalletModule { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) @@ -174,6 +177,7 @@ enum WalletModule { if let account = App.shared.accountManager.activeAccount, !account.watchAccount, !account.cexAccount { let coinPriceService = WalletCoinPriceService( currencyManager: App.shared.currencyManager, + priceChangeModeManager: App.shared.priceChangeModeManager, marketKit: App.shared.marketKit ) diff --git a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletService.swift b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletService.swift index 0563aa8784..0e4311ba87 100644 --- a/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletService.swift +++ b/UnstoppableWallet/UnstoppableWallet/Modules/Wallet/WalletService.swift @@ -389,24 +389,21 @@ extension WalletService: IWalletCoinPriceServiceDelegate { _syncTotalItem() } - func didUpdateBaseCurrency() { + func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]?) { queue.async { guard case let .loaded(items) = self.internalState else { return } - let coinUids = Array(Set(items.compactMap(\.element.priceCoinUid))) - self._handleUpdated(priceItemMap: self.coinPriceService.itemMap(coinUids: coinUids), items: items) - } - } - - func didUpdate(itemsMap: [String: WalletCoinPriceService.Item]) { - queue.async { - guard case let .loaded(items) = self.internalState else { - return + let _itemsMap: [String: WalletCoinPriceService.Item] + if let itemsMap { + _itemsMap = itemsMap + } else { + let coinUids = Array(Set(items.compactMap(\.element.priceCoinUid))) + _itemsMap = self.coinPriceService.itemMap(coinUids: coinUids) } - self._handleUpdated(priceItemMap: itemsMap, items: items) + self._handleUpdated(priceItemMap: _itemsMap, items: items) } } } diff --git a/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings b/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings index b662df8c1b..34f768553e 100644 --- a/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings +++ b/UnstoppableWallet/UnstoppableWallet/en.lproj/Localizable.strings @@ -947,7 +947,8 @@ "coin_overview.genesis_date" = "Inception Date"; "coin_overview.trading_volume" = "Trading Volume"; -"coin_overview.roi.hour24" = "1 Day"; +"coin_overview.roi.hour24" = "24 Hours"; +"coin_overview.roi.day1" = "1 Day"; "coin_overview.roi.day7" = "1 Week"; "coin_overview.roi.day14" = "2 Weeks"; "coin_overview.roi.day30" = "1 Month"; @@ -1551,7 +1552,7 @@ "appearance.hide_markets" = "Hide Markets"; "appearance.price_change" = "Price Change"; "appearance.price_change.24h" = "24H"; -"appearance.price_change.midnight_utc" = "Midnight UTC"; +"appearance.price_change.1d" = "Midnight UTC"; "appearance.launch_screen" = "Launch Screen"; "appearance.launch_screen.auto" = "Auto"; diff --git a/UnstoppableWallet/Widget/Misc/ApiProvider.swift b/UnstoppableWallet/Widget/Misc/ApiProvider.swift index b797326253..bd28ece00f 100644 --- a/UnstoppableWallet/Widget/Misc/ApiProvider.swift +++ b/UnstoppableWallet/Widget/Misc/ApiProvider.swift @@ -48,7 +48,7 @@ class ApiProvider { func coinWithPrice(uid: String, currencyCode: String) async throws -> Coin { let parameters: Parameters = [ "uids": uid, - "fields": "uid,name,code,price,price_change_24h", + "fields": "uid,name,code,price,price_change_24h,price_change_1d", "currency": currencyCode.lowercased(), ] @@ -82,6 +82,7 @@ class ApiProvider { enum ListType: String { case priceChange24h = "price_change_24h" + case priceChange1d = "price_change_1d" case priceChange1w = "price_change_1w" case priceChange1m = "price_change_1m" case priceChange3m = "price_change_3m" @@ -97,6 +98,7 @@ struct Coin: ImmutableMappable { let rank: Int? let price: Decimal? let priceChange24h: Decimal? + let priceChange1d: Decimal? let priceChange1w: Decimal? let priceChange1m: Decimal? let priceChange3m: Decimal? @@ -109,6 +111,7 @@ struct Coin: ImmutableMappable { rank = try? map.value("market_cap_rank") price = try? map.value("price", using: Transform.stringToDecimalTransform) priceChange24h = try? map.value("price_change_24h", using: Transform.stringToDecimalTransform) + priceChange1d = try? map.value("price_change_1d", using: Transform.stringToDecimalTransform) priceChange1w = try? map.value("price_change_1w", using: Transform.stringToDecimalTransform) priceChange1m = try? map.value("price_change_1m", using: Transform.stringToDecimalTransform) priceChange3m = try? map.value("price_change_3m", using: Transform.stringToDecimalTransform) diff --git a/UnstoppableWallet/Widget/Misc/Extensions.swift b/UnstoppableWallet/Widget/Misc/Extensions.swift index 2a88505d70..278d656f60 100644 --- a/UnstoppableWallet/Widget/Misc/Extensions.swift +++ b/UnstoppableWallet/Widget/Misc/Extensions.swift @@ -29,7 +29,7 @@ extension Coin { private func priceChange(timePeriod: WatchlistTimePeriod) -> Decimal? { switch timePeriod { - case .day1: return priceChange24h + case .day1: return priceChange1d case .week1: return priceChange1w case .month1: return priceChange1m case .month3: return priceChange3m diff --git a/UnstoppableWallet/Widget/Watchlist/WatchlistProvider.swift b/UnstoppableWallet/Widget/Watchlist/WatchlistProvider.swift index 9f83fc6ae8..66d49cc497 100644 --- a/UnstoppableWallet/Widget/Watchlist/WatchlistProvider.swift +++ b/UnstoppableWallet/Widget/Watchlist/WatchlistProvider.swift @@ -51,7 +51,7 @@ struct WatchlistProvider: TimelineProvider { case .highestCap, .lowestCap: listType = .mcap case .gainers, .losers, .manual: switch watchlistManager.timePeriod { - case .day1: listType = .priceChange24h + case .day1: listType = .priceChange1d case .week1: listType = .priceChange1w case .month1: listType = .priceChange1m case .month3: listType = .priceChange3m