diff --git a/app/build.gradle b/app/build.gradle index 7dbf506abe5..7e063d090b9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -272,7 +272,7 @@ dependencies { implementation 'com.github.horizontalsystems:ethereum-kit-android:f4957a9' implementation 'com.github.horizontalsystems:blockchain-fee-rate-kit-android:1d3bd49' implementation 'com.github.horizontalsystems:binance-chain-kit-android:c1509a2' - implementation 'com.github.horizontalsystems:market-kit-android:7b14372' + implementation 'com.github.horizontalsystems:market-kit-android:a0361bf' implementation 'com.github.horizontalsystems:solana-kit-android:d8bb9f2' implementation 'com.github.horizontalsystems:tron-kit-android:dc3dca7' // Zcash SDK diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/App.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/App.kt index a34b28be233..484dc911124 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/App.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/App.kt @@ -74,6 +74,7 @@ import io.horizontalsystems.bankwallet.core.providers.CexProviderManager import io.horizontalsystems.bankwallet.core.providers.EvmLabelProvider import io.horizontalsystems.bankwallet.core.providers.FeeRateProvider import io.horizontalsystems.bankwallet.core.providers.FeeTokenProvider +import io.horizontalsystems.bankwallet.core.stats.StatsManager import io.horizontalsystems.bankwallet.core.storage.AccountsStorage import io.horizontalsystems.bankwallet.core.storage.AppDatabase import io.horizontalsystems.bankwallet.core.storage.BlockchainSettingsStorage @@ -189,6 +190,7 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory { lateinit var chartIndicatorManager: ChartIndicatorManager lateinit var backupProvider: BackupProvider lateinit var spamManager: SpamManager + lateinit var statsManager: StatsManager } private val coroutineScope = CoroutineScope(Dispatchers.Default) @@ -226,7 +228,6 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory { context = this, hsApiBaseUrl = appConfig.marketApiBaseUrl, hsApiKey = appConfig.marketApiKey, - appConfigProvider = appConfigProvider, subscriptionManager = subscriptionManager ) @@ -352,7 +353,8 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory { pinDbStorage = PinDbStorage(appDatabase.pinDao()) ) - backgroundStateChangeListener = BackgroundStateChangeListener(pinComponent).apply { + statsManager = StatsManager(appDatabase.statsDao(), localStorage, marketKit, appConfigProvider) + backgroundStateChangeListener = BackgroundStateChangeListener(pinComponent, statsManager).apply { backgroundManager.registerListener(this) } @@ -371,7 +373,7 @@ class App : CoreApp(), WorkConfiguration.Provider, ImageLoaderFactory { MarketFavoritesMenuService(localStorage, marketWidgetManager), TopNftCollectionsRepository(marketKit), TopNftCollectionsViewItemFactory(numberFormatter), - TopPlatformsRepository(marketKit, currencyManager, "widget"), + TopPlatformsRepository(marketKit, currencyManager), currencyManager ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt index 2e353513252..732272a1cb3 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/Interfaces.kt @@ -118,6 +118,7 @@ interface ILocalStorage { var pinRandomized: Boolean var utxoExpertModeEnabled: Boolean var rbfEnabled: Boolean + var statsLastSyncTime: Long val utxoExpertModeEnabledFlow: StateFlow diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/MarketKitExtensions.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/MarketKitExtensions.kt index 4af2924cc78..230f9206de6 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/MarketKitExtensions.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/MarketKitExtensions.kt @@ -356,6 +356,18 @@ val TokenType.order: Int } +val TokenType.derivation: TokenType.Derivation? + get() = when (this) { + is TokenType.Derived -> this.derivation + else -> null + } + +val TokenType.bitcoinCashCoinType: TokenType.AddressType? + get() = when (this) { + is TokenType.AddressTyped -> this.type + else -> null + } + val Coin.imageUrl: String get() = "https://cdn.blocksdecoded.com/coin-icons/32px/$uid@3x.png" diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/BackgroundStateChangeListener.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/BackgroundStateChangeListener.kt index ceb31a60ec3..1272c6c3492 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/BackgroundStateChangeListener.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/BackgroundStateChangeListener.kt @@ -1,15 +1,21 @@ package io.horizontalsystems.bankwallet.core.managers import android.app.Activity +import io.horizontalsystems.bankwallet.core.stats.StatsManager +import io.horizontalsystems.bankwallet.modules.keystore.KeyStoreActivity +import io.horizontalsystems.bankwallet.modules.lockscreen.LockScreenActivity import io.horizontalsystems.core.BackgroundManager import io.horizontalsystems.core.IPinComponent class BackgroundStateChangeListener( - private val pinComponent: IPinComponent + private val pinComponent: IPinComponent, + private val statsManager: StatsManager ) : BackgroundManager.Listener { override fun willEnterForeground(activity: Activity) { pinComponent.willEnterForeground(activity) + + statsManager.sendStats() } override fun didEnterBackground() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt index 6b3dcedd832..f50ada537cf 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/LocalStorageManager.kt @@ -79,6 +79,7 @@ class LocalStorageManager( private val PIN_RANDOMIZED = "pin_randomized" private val UTXO_EXPERT_MODE = "utxo_expert_mode" private val RBF_ENABLED = "rbf_enabled" + private val STATS_SYNC_TIME = "stats_sync_time" private val _utxoExpertModeEnabledFlow = MutableStateFlow(false) override val utxoExpertModeEnabledFlow = _utxoExpertModeEnabledFlow @@ -498,4 +499,10 @@ class LocalStorageManager( set(value) { preferences.edit().putBoolean(RBF_ENABLED, value).apply() } + + override var statsLastSyncTime: Long + get() = preferences.getLong(STATS_SYNC_TIME, 0) + set(value) { + preferences.edit().putLong(STATS_SYNC_TIME, value).apply() + } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/MarketKitWrapper.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/MarketKitWrapper.kt index 2fa3957faf8..c863cc3b543 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/MarketKitWrapper.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/managers/MarketKitWrapper.kt @@ -4,7 +4,6 @@ import android.content.Context import io.horizontalsystems.bankwallet.core.InvalidAuthTokenException import io.horizontalsystems.bankwallet.core.NoAuthTokenException import io.horizontalsystems.bankwallet.core.customCoinPrefix -import io.horizontalsystems.bankwallet.core.providers.AppConfigProvider import io.horizontalsystems.marketkit.MarketKit import io.horizontalsystems.marketkit.SyncInfo import io.horizontalsystems.marketkit.models.BlockchainType @@ -25,7 +24,6 @@ class MarketKitWrapper( context: Context, hsApiBaseUrl: String, hsApiKey: String, - appConfigProvider: AppConfigProvider, private val subscriptionManager: SubscriptionManager ) { private val marketKit: MarketKit by lazy { @@ -33,8 +31,6 @@ class MarketKitWrapper( context = context, hsApiBaseUrl = hsApiBaseUrl, hsApiKey = hsApiKey, - appVersion = appConfigProvider.appVersion, - appId = appConfigProvider.appId ) } @@ -78,22 +74,22 @@ class MarketKitWrapper( fun blockchain(uid: String) = marketKit.blockchain(uid) - fun marketInfosSingle(top: Int, currencyCode: String, defi: Boolean, apiTag: String) = marketKit.marketInfosSingle(top, currencyCode, defi, apiTag) + fun marketInfosSingle(top: Int, currencyCode: String, defi: Boolean) = marketKit.marketInfosSingle(top, currencyCode, defi) fun advancedMarketInfosSingle(top: Int = 250, currencyCode: String) = marketKit.advancedMarketInfosSingle(top, currencyCode) - fun marketInfosSingle(coinUids: List, currencyCode: String, apiTag: String): Single> = - marketKit.marketInfosSingle(coinUids.removeCustomCoins(), currencyCode, apiTag) + fun marketInfosSingle(coinUids: List, currencyCode: String): Single> = + marketKit.marketInfosSingle(coinUids.removeCustomCoins(), currencyCode) - fun marketInfosSingle(categoryUid: String, currencyCode: String, apiTag: String) = marketKit.marketInfosSingle(categoryUid, currencyCode, apiTag) + fun marketInfosSingle(categoryUid: String, currencyCode: String) = marketKit.marketInfosSingle(categoryUid, currencyCode) - fun marketInfoOverviewSingle(coinUid: String, currencyCode: String, language: String, apiTag: String) = - marketKit.marketInfoOverviewSingle(coinUid, currencyCode, language, apiTag) + fun marketInfoOverviewSingle(coinUid: String, currencyCode: String, language: String) = + marketKit.marketInfoOverviewSingle(coinUid, currencyCode, language) - fun analyticsSingle(coinUid: String, currencyCode: String, apiTag: String) = - requestWithAuthToken { marketKit.analyticsSingle(it, coinUid, currencyCode, apiTag) } + fun analyticsSingle(coinUid: String, currencyCode: String) = + requestWithAuthToken { marketKit.analyticsSingle(it, coinUid, currencyCode) } - fun analyticsPreviewSingle(coinUid: String, addresses: List, apiTag: String) = marketKit.analyticsPreviewSingle(coinUid, addresses, apiTag) + fun analyticsPreviewSingle(coinUid: String, addresses: List) = marketKit.analyticsPreviewSingle(coinUid, addresses) fun marketInfoTvlSingle(coinUid: String, currencyCode: String, timePeriod: HsTimePeriod) = marketKit.marketInfoTvlSingle(coinUid, currencyCode, timePeriod) @@ -101,7 +97,7 @@ class MarketKitWrapper( fun marketInfoGlobalTvlSingle(chain: String, currencyCode: String, timePeriod: HsTimePeriod) = marketKit.marketInfoGlobalTvlSingle(chain, currencyCode, timePeriod) - fun defiMarketInfosSingle(currencyCode: String, apiTag: String) = marketKit.defiMarketInfosSingle(currencyCode, apiTag) + fun defiMarketInfosSingle(currencyCode: String) = marketKit.defiMarketInfosSingle(currencyCode) // Categories @@ -234,8 +230,8 @@ class MarketKitWrapper( fun globalMarketPointsSingle(currencyCode: String, timePeriod: HsTimePeriod) = marketKit.globalMarketPointsSingle(currencyCode, timePeriod) - fun topPlatformsSingle(currencyCode: String, apiTag: String) = - marketKit.topPlatformsSingle(currencyCode, apiTag) + fun topPlatformsSingle(currencyCode: String) = + marketKit.topPlatformsSingle(currencyCode) fun topPlatformMarketCapStartTimeSingle(platform: String) = marketKit.topPlatformMarketCapStartTimeSingle(platform) @@ -246,8 +242,8 @@ class MarketKitWrapper( periodType: HsPeriodType ) = marketKit.topPlatformMarketCapPointsSingle(chain, currencyCode, periodType) - fun topPlatformCoinListSingle(chain: String, currencyCode: String, apiTag: String) = - marketKit.topPlatformMarketInfosSingle(chain, currencyCode, apiTag) + fun topPlatformCoinListSingle(chain: String, currencyCode: String) = + marketKit.topPlatformMarketInfosSingle(chain, currencyCode) // NFT @@ -272,4 +268,10 @@ class MarketKitWrapper( fun requestPersonalSupport(username: String): Single> = requestWithAuthToken { marketKit.requestPersonalSupport(it, username) } + // Stats + + fun sendStats(stats: String, appVersion: String, appId: String?): Single { + return marketKit.sendStats(stats, appVersion, appId) + } + } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/StatsManager.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/StatsManager.kt new file mode 100644 index 00000000000..ec7308db004 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/StatsManager.kt @@ -0,0 +1,281 @@ +package io.horizontalsystems.bankwallet.core.stats + +import com.google.gson.Gson +import io.horizontalsystems.bankwallet.core.App +import io.horizontalsystems.bankwallet.core.ILocalStorage +import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper +import io.horizontalsystems.bankwallet.core.providers.AppConfigProvider +import io.horizontalsystems.bankwallet.core.storage.StatsDao +import io.horizontalsystems.bankwallet.entities.AccountType +import io.horizontalsystems.bankwallet.entities.StatRecord +import io.horizontalsystems.bankwallet.modules.balance.BalanceSortType +import io.horizontalsystems.bankwallet.modules.coin.CoinModule +import io.horizontalsystems.bankwallet.modules.coin.analytics.CoinAnalyticsModule +import io.horizontalsystems.bankwallet.modules.main.MainModule +import io.horizontalsystems.bankwallet.modules.market.MarketField +import io.horizontalsystems.bankwallet.modules.market.MarketModule +import io.horizontalsystems.bankwallet.modules.market.SortingField +import io.horizontalsystems.bankwallet.modules.market.TimeDuration +import io.horizontalsystems.bankwallet.modules.market.TopMarket +import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesModule +import io.horizontalsystems.bankwallet.modules.market.search.MarketSearchSection +import io.horizontalsystems.bankwallet.modules.metricchart.MetricsType +import io.horizontalsystems.bankwallet.modules.metricchart.ProChartModule +import io.horizontalsystems.bankwallet.modules.transactionInfo.options.TransactionInfoOptionsModule +import io.horizontalsystems.bankwallet.modules.transactions.FilterTransactionType +import io.horizontalsystems.hdwalletkit.HDExtendedKey +import io.horizontalsystems.marketkit.models.HsTimePeriod +import java.time.Instant +import java.util.concurrent.Executors + +fun stat(page: StatPage, section: StatSection? = null, event: StatEvent) { + App.statsManager.logStat(page, section, event) +} + +class StatsManager( + private val statsDao: StatsDao, + private val localStorage: ILocalStorage, + private val marketKit: MarketKitWrapper, + private val appConfigProvider: AppConfigProvider +) { + private val gson by lazy { Gson() } + private val executor = Executors.newCachedThreadPool() + private val syncInterval = 0 //60 * 60 // 1H in seconds + + fun logStat(eventPage: StatPage, eventSection: StatSection? = null, event: StatEvent) { + executor.submit { + try { + val eventMap = buildMap { + put("event_page", eventPage.key) + put("event", event.name) + eventSection?.let { put("event_section", it.key) } + event.params?.let { params -> + putAll(params.map { (param, value) -> param.key to value }) + } + put("time", Instant.now().epochSecond) + } + + val json = gson.toJson(eventMap) +// Log.e("e", json) + statsDao.insert(StatRecord(json)) + } catch (error: Throwable) { +// Log.e("e", "logStat error", error) + } + } + } + + fun sendStats() { + executor.submit { + try { + val statLastSyncTime = localStorage.statsLastSyncTime + val currentTime = Instant.now().epochSecond + + if (currentTime - statLastSyncTime < syncInterval) return@submit + + val stats = statsDao.getAll() + if (stats.isNotEmpty()) { + val statsArray = "[${stats.joinToString { it.json }}]" +// Log.e("e", "send $statsArray") + marketKit.sendStats(statsArray, appConfigProvider.appVersion, appConfigProvider.appId).blockingGet() + + statsDao.delete(stats.map { it.id }) + localStorage.statsLastSyncTime = currentTime + } + + } catch (error: Throwable) { +// Log.e("e", "sendStats error", error) + } + } + } + +} + +val BalanceSortType.statSortType + get() = when (this) { + BalanceSortType.Name -> StatSortType.Name + BalanceSortType.PercentGrowth -> StatSortType.PriceChange + BalanceSortType.Value -> StatSortType.Balance + } + +val ProChartModule.ChartType.statPage + get() = when (this) { + ProChartModule.ChartType.CexVolume -> StatPage.CoinAnalyticsCexVolume + ProChartModule.ChartType.DexVolume -> StatPage.CoinAnalyticsDexVolume + ProChartModule.ChartType.DexLiquidity -> StatPage.CoinAnalyticsDexLiquidity + ProChartModule.ChartType.TxCount -> StatPage.CoinAnalyticsTxCount + ProChartModule.ChartType.AddressesCount -> StatPage.CoinAnalyticsActiveAddresses + ProChartModule.ChartType.Tvl -> StatPage.CoinAnalyticsTvl + } + +val HsTimePeriod?.statPeriod: StatPeriod + get() = when (this) { + HsTimePeriod.Day1 -> StatPeriod.Day1 + HsTimePeriod.Week1 -> StatPeriod.Week1 + HsTimePeriod.Week2 -> StatPeriod.Week2 + HsTimePeriod.Month1 -> StatPeriod.Month1 + HsTimePeriod.Month3 -> StatPeriod.Month3 + HsTimePeriod.Month6 -> StatPeriod.Month6 + HsTimePeriod.Year1 -> StatPeriod.Year1 + HsTimePeriod.Year2 -> StatPeriod.Year2 + HsTimePeriod.Year5 -> StatPeriod.Year5 + null -> StatPeriod.All + } + +val MarketField.statField: StatField + get() = when (this) { + MarketField.PriceDiff -> StatField.Price + MarketField.MarketCap -> StatField.MarketCap + MarketField.Volume -> StatField.Volume + } + +val SortingField.statSortType: StatSortType + get() = when (this) { + SortingField.HighestCap -> StatSortType.HighestCap + SortingField.LowestCap -> StatSortType.LowestCap + SortingField.HighestVolume -> StatSortType.HighestVolume + SortingField.LowestVolume -> StatSortType.LowestVolume + SortingField.TopGainers -> StatSortType.TopGainers + SortingField.TopLosers -> StatSortType.TopLosers + } + + +val CoinModule.Tab.statTab: StatTab + get() = when (this) { + CoinModule.Tab.Overview -> StatTab.Overview + CoinModule.Tab.Details -> StatTab.Analytics + CoinModule.Tab.Market -> StatTab.Markets + } + +val CoinAnalyticsModule.RankType.statPage: StatPage + get() = when (this) { + CoinAnalyticsModule.RankType.CexVolumeRank -> StatPage.CoinRankCexVolume + CoinAnalyticsModule.RankType.DexVolumeRank -> StatPage.CoinRankDexVolume + CoinAnalyticsModule.RankType.DexLiquidityRank -> StatPage.CoinRankDexLiquidity + CoinAnalyticsModule.RankType.AddressesRank -> StatPage.CoinRankAddress + CoinAnalyticsModule.RankType.TransactionCountRank -> StatPage.CoinRankTxCount + CoinAnalyticsModule.RankType.RevenueRank -> StatPage.CoinRankRevenue + CoinAnalyticsModule.RankType.FeeRank -> StatPage.CoinRankFee + CoinAnalyticsModule.RankType.HoldersRank -> StatPage.CoinRankHolders + } + +val AccountType.statAccountType: String + get() = when (this) { + is AccountType.Mnemonic -> { + if (passphrase.isEmpty()) "mnemonic_${words.size}" else "mnemonic_with_passphrase_${words.size}" + } + + is AccountType.BitcoinAddress -> { + "btc_address" + } + + is AccountType.Cex -> { + "cex" + } + + is AccountType.EvmAddress -> { + "evm_address" + } + + is AccountType.EvmPrivateKey -> { + "evm_private_key" + } + + is AccountType.HdExtendedKey -> { + if (hdExtendedKey.isPublic) { + "account_x_pub_key" + } else { + when (hdExtendedKey.derivedType) { + HDExtendedKey.DerivedType.Bip32 -> "bip32" + HDExtendedKey.DerivedType.Master -> "bip32_root_key" + HDExtendedKey.DerivedType.Account -> "account_x_priv_key" + } + } + } + + is AccountType.SolanaAddress -> { + "sol_address" + } + + is AccountType.TonAddress -> { + "ton_address" + } + + is AccountType.TronAddress -> { + "tron_address" + } + } + + +val MetricsType.statPage: StatPage + get() = when (this) { + MetricsType.TotalMarketCap -> StatPage.GlobalMetricsMarketCap + MetricsType.BtcDominance -> StatPage.GlobalMetricsMarketCap + MetricsType.Volume24h -> StatPage.GlobalMetricsVolume + MetricsType.DefiCap -> StatPage.GlobalMetricsDefiCap + MetricsType.TvlInDefi -> StatPage.GlobalMetricsTvlInDefi + } + +val MainModule.MainNavigation.statTab: StatTab + get() = when (this) { + MainModule.MainNavigation.Market -> StatTab.Markets + MainModule.MainNavigation.Balance -> StatTab.Balance + MainModule.MainNavigation.Transactions -> StatTab.Transactions + MainModule.MainNavigation.Settings -> StatTab.Settings + } + +val TopMarket.statMarketTop: StatMarketTop + get() = when (this) { + TopMarket.Top100 -> StatMarketTop.Top100 + TopMarket.Top200 -> StatMarketTop.Top200 + TopMarket.Top300 -> StatMarketTop.Top300 + } + +val MarketModule.ListType.statSection: StatSection + get() = when (this) { + MarketModule.ListType.TopGainers -> StatSection.TopGainers + MarketModule.ListType.TopLosers -> StatSection.TopLosers + } + +val TimeDuration.statPeriod: StatPeriod + get() = when (this) { + TimeDuration.OneDay -> StatPeriod.Day1 + TimeDuration.SevenDay -> StatPeriod.Week1 + TimeDuration.ThirtyDay -> StatPeriod.Month1 + TimeDuration.ThreeMonths -> StatPeriod.Month3 + } + +val MarketModule.Tab.statTab: StatTab + get() = when (this) { + MarketModule.Tab.Overview -> StatTab.Overview + MarketModule.Tab.Posts -> StatTab.News + MarketModule.Tab.Watchlist -> StatTab.Watchlist + } + +val MarketSearchSection.statSection: StatSection + get() = when (this) { + MarketSearchSection.Recent -> StatSection.Recent + MarketSearchSection.Popular -> StatSection.Popular + MarketSearchSection.SearchResults -> StatSection.SearchResults + } + +val MarketFavoritesModule.Period.statPeriod: StatPeriod + get() = when (this) { + MarketFavoritesModule.Period.OneDay -> StatPeriod.Day1 + MarketFavoritesModule.Period.SevenDay -> StatPeriod.Week1 + MarketFavoritesModule.Period.ThirtyDay -> StatPeriod.Month1 + } + +val FilterTransactionType.statTab: StatTab + get() = when (this) { + FilterTransactionType.All -> StatTab.All + FilterTransactionType.Incoming -> StatTab.Incoming + FilterTransactionType.Outgoing -> StatTab.Outgoing + FilterTransactionType.Swap -> StatTab.Swap + FilterTransactionType.Approve -> StatTab.Approve + } + +val TransactionInfoOptionsModule.Type.statResendType: StatResendType + get() = when(this) { + TransactionInfoOptionsModule.Type.SpeedUp -> StatResendType.SpeedUp + TransactionInfoOptionsModule.Type.Cancel -> StatResendType.Cancel + } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/Types.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/Types.kt new file mode 100644 index 00000000000..3b8847c2bb6 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/stats/Types.kt @@ -0,0 +1,552 @@ +package io.horizontalsystems.bankwallet.core.stats + +import io.horizontalsystems.bankwallet.core.bitcoinCashCoinType +import io.horizontalsystems.bankwallet.core.derivation +import io.horizontalsystems.bankwallet.entities.BtcRestoreMode +import io.horizontalsystems.marketkit.models.Token + +enum class StatPage(val key: String) { + AboutApp("about_app"), + Academy("academy"), + AccountExtendedPrivateKey("account_extended_private_key"), + AccountExtendedPublicKey("account_extended_public_key"), + AddEvmSyncSource("add_evm_sync_source"), + AddToken("add_token"), + AdvancedSearch("advanced_search"), + AdvancedSearchResults("advanced_search_results"), + Appearance("appearance"), + BackupManager("backup_manager"), + BackupPromptAfterCreate("backup_prompt_after_create"), + BackupRequired("backup_required"), + Balance("balance"), + BaseCurrency("base_currency"), + BirthdayInput("birthday_input"), + Bip32RootKey("bip32_root_key"), + BlockchainSettings("blockchain_settings"), + BlockchainSettingsBtc("blockchain_settings_btc"), + BlockchainSettingsEvm("blockchain_settings_evm"), + BlockchainSettingsEvmAdd("blockchain_settings_evm_add"), + BlockchainSettingsSolana("blockchain_settings_sol"), + CloudBackup("cloud_backup"), + FileBackup("file_backup"), + CoinAnalytics("coin_analytics"), + CoinAnalyticsCexVolume("coin_analytics_cex_volume"), + CoinAnalyticsDexVolume("coin_analytics_dex_volume"), + CoinAnalyticsDexLiquidity("coin_analytics_dex_liquidity"), + CoinAnalyticsActiveAddresses("coin_analytics_active_addresses"), + CoinAnalyticsTxCount("coin_analytics_tx_count"), + CoinAnalyticsTvl("coin_analytics_tvl"), + CoinManager("coin_manager"), + CoinMarkets("coin_markets"), + CoinOverview("coin_overview"), + CoinPage("coin_page"), + CoinCategory("coin_category"), + CoinRankAddress("coin_rank_address"), + CoinRankCexVolume("coin_rank_cex_volume"), + CoinRankDexLiquidity("coin_rank_dex_liquidity"), + CoinRankDexVolume("coin_rank_dex_volume"), + CoinRankFee("coin_rank_fee"), + CoinRankHolders("coin_rank_holders"), + CoinRankRevenue("coin_rank_revenue"), + CoinRankTxCount("coin_rank_tx_count"), + Contacts("contacts"), + ContactAddToExisting("contact_add_to_existing"), + ContactNew("contact_new"), + ContactUs("contact_us"), + Donate("donate"), + DonateAddressList("donate_address_list"), + DoubleSpend("double_spend"), + EvmAddress("evm_address"), + EvmPrivateKey("evm_private_key"), + ExportFull("export_full"), + ExportFullToFiles("export_full_to_files"), + ExportWalletToFiles("export_wallet_to_files"), + ExternalBlockExplorer("external_block_explorer"), + ExternalCoinWebsite("external_coin_website"), + ExternalCoinWhitePaper("external_coin_white_paper"), + ExternalCompanyWebsite("external_company_website"), + ExternalGithub("external_github"), + ExternalMarketPair("external_market_pair"), + ExternalNews("external_news"), + ExternalReddit("external_reddit"), + ExternalTelegram("external_telegram"), + ExternalTwitter("external_twitter"), + Faq("faq"), + GlobalMetricsMarketCap("global_metrics_market_cap"), + GlobalMetricsVolume("global_metrics_volume"), + GlobalMetricsDefiCap("global_metrics_defi_cap"), + GlobalMetricsTvlInDefi("global_metrics_tvl_in_defi"), + Guide("guide"), + ImportFull("import_full"), + ImportFullFromFiles("import_full_from_files"), + ImportWallet("import_wallet"), + ImportWalletFromKey("import_wallet_from_key"), + ImportWalletFromKeyAdvanced("import_wallet_from_key_advanced"), + ImportWalletFromCloud("import_wallet_from_cloud"), + ImportWalletFromFiles("import_wallet_from_files"), + ImportWalletFromExchangeWallet("import_wallet_from_exchange_wallet"), + ImportWalletNonStandard("import_wallet_non_standard"), + Indicators("indicators"), + Info("info"), + Language("language"), + Main("main"), + ManageWallet("manage_wallet"), + ManageWallets("manage_wallets"), + ManualBackup("manual_backup"), + Markets("markets"), + MarketOverview("market_overview"), + MarketSearch("market_search"), + News("news"), + NewWallet("new_wallet"), + NewWalletAdvanced("new_wallet_advanced"), + PrivateKeys("private_keys"), + PublicKeys("public_keys"), + RateUs("rate_us"), + Receive("receive"), + ReceiveTokenList("receive_token_list"), + RecoveryPhrase("recovery_phrase"), + Resend("resend"), + RestoreSelect("restore_select"), + ScanQrCode("scan_qr_code"), + Security("security"), + Send("send"), + SendTokenList("send_token_list"), + SendConfirmation("send_confirmation"), + Settings("settings"), + Swap("swap"), + SwapApproveConfirmation("swap_approve_confirmation"), + SwapConfirmation("swap_confirmation"), + SwapSettings("swap_settings"), + SwapProvider("swap_provider"), + SwitchWallet("switch_wallet"), + TellFriends("tell_friends"), + TopCoins("top_coins"), + TopMarketPairs("top_market_pairs"), + TopNftCollections("top_nft_collections"), + TopPlatform("top_platform"), + TopPlatforms("top_platforms"), + TokenPage("token_page"), + Transactions("transactions"), + TransactionFilter("transaction_filter"), + TransactionInfo("transaction_info"), + UnlinkWallet("unlink_wallet"), + WalletConnect("wallet_connect"), + Watchlist("watchlist"), + WatchWallet("watch_wallet"), + Widget("widget"), +} + +enum class StatSection(val key: String) { + AddressFrom("address_from"), + AddressRecipient("address_recipient"), + AddressSpender("address_spender"), + AddressTo("address_to"), + Input("input"), + Popular("popular"), + Recent("recent"), + SearchResults("search_results"), + Status("status"), + TimeLock("time_lock"), + TopGainers("top_gainers"), + TopLosers("top_losers"), + TopPlatforms("top_platforms"), +} + +sealed class StatEvent { + + object Send : StatEvent() + + data class AddEvmSource(val chainUid: String) : StatEvent() + data class DeleteCustomEvmSource(val chainUid: String) : StatEvent() + data class DisableToken(val token: Token) : StatEvent() + data class EnableToken(val token: Token) : StatEvent() + + data class ImportWallet(val walletType: String) : StatEvent() + object ImportFull : StatEvent() + + data class ExportWallet(val walletType: String) : StatEvent() + object ExportFull : StatEvent() + + data class OpenBlockchainSettingsBtc(val chainUid: String) : StatEvent() + data class OpenBlockchainSettingsEvm(val chainUid: String) : StatEvent() + data class OpenBlockchainSettingsEvmAdd(val chainUid: String) : StatEvent() + + data class OpenCategory(val categoryUid: String) : StatEvent() + data class OpenCoin(val coinUid: String) : StatEvent() + data class OpenPlatform(val chainUid: String) : StatEvent() + data class OpenReceive(val token: Token) : StatEvent() + data class OpenResend(val chainUid: String, val type: StatResendType) : StatEvent() + data class OpenSend(val token: Token) : StatEvent() + data class OpenTokenPage(val token: Token?, val assetId: String? = null) : StatEvent() + data class OpenTokenInfo(val token: Token) : StatEvent() + data class Open(val page: StatPage) : StatEvent() + + data class SwitchBaseCurrency(val code: String) : StatEvent() + data class SwitchBtcSource(val chainUid: String, val type: BtcRestoreMode) : StatEvent() + data class SwitchEvmSource(val chainUid: String, val type: String) : StatEvent() + data class SwitchTab(val tab: StatTab) : StatEvent() + data class SwitchMarketTop(val marketTop: StatMarketTop) : StatEvent() + data class SwitchPeriod(val period: StatPeriod) : StatEvent() + data class SwitchField(val field: StatField) : StatEvent() + data class SwitchSortType(val sortType: StatSortType) : StatEvent() + data class SwitchChartPeriod(val period: StatPeriod) : StatEvent() + data class SwitchTvlChain(val chain: String) : StatEvent() + data class SwitchFilterType(val type: String) : StatEvent() + object ToggleSortDirection : StatEvent() + object ToggleTvlField : StatEvent() + + object Refresh : StatEvent() + + object ToggleBalanceHidden : StatEvent() + object ToggleConversionCoin : StatEvent() + + + data class AddToWatchlist(val coinUid: String) : StatEvent() + data class RemoveFromWatchlist(val coinUid: String) : StatEvent() + + data class ToggleIndicators(val shown: Boolean) : StatEvent() + object AddToWallet : StatEvent() + object RemoveFromWallet : StatEvent() + + data class Copy(val entity: StatEntity) : StatEvent() + data class CopyAddress(val chainUid: String) : StatEvent() + + data class Share(val entity: StatEntity) : StatEvent() + + object SetAmount : StatEvent() + object RemoveAmount : StatEvent() + + object ToggleHidden : StatEvent() + object TogglePrice : StatEvent() + + data class SwapSelectTokenIn(val token: Token) : StatEvent() + data class SwapSelectTokenOut(val token: Token) : StatEvent() + data class SwapSelectProvider(val uid: String) : StatEvent() + object SwapSwitchPairs : StatEvent() + + data class Select(val entity: StatEntity) : StatEvent() + data class Edit(val entity: StatEntity) : StatEvent() + data class Delete(val entity: StatEntity) : StatEvent() + + data class ScanQr(val entity: StatEntity) : StatEvent() + data class Paste(val entity: StatEntity) : StatEvent() + data class Clear(val entity: StatEntity) : StatEvent() + + data class CreateWallet(val walletType: String) : StatEvent() + data class WatchWallet(val walletType: String) : StatEvent() + + data class Add(val entity: StatEntity) : StatEvent() + data class AddToken(val token: Token) : StatEvent() + + val name: String + get() = when (this) { + is AddEvmSource -> "add_evm_source" + is DeleteCustomEvmSource -> "delete_custom_evm_source" + is DisableToken -> "disable_token" + is EnableToken -> "enable_token" + + is ImportFull -> "import_full" + is ImportWallet -> "import_wallet" + + is ExportFull -> "export_full" + is ExportWallet -> "export_wallet" + + is OpenBlockchainSettingsBtc, + is OpenBlockchainSettingsEvm, + is OpenBlockchainSettingsEvmAdd, + is OpenCategory, + is OpenCoin, + is OpenPlatform, + is OpenReceive, + is OpenSend, + is OpenTokenPage, + is OpenResend, + is Open -> "open_page" + + is OpenTokenInfo -> "open_token_info" + + is SwapSelectTokenIn -> "swap_select_token_in" + is SwapSelectTokenOut -> "swap_select_token_out" + is SwapSelectProvider -> "swap_select_provider" + is SwapSwitchPairs -> "swap_switch_pairs" + + is Send -> "send" + is SwitchBaseCurrency -> "switch_base_currency" + is SwitchBtcSource -> "switch_btc_source" + is SwitchEvmSource -> "switch_evm_source" + is SwitchTab -> "switch_tab" + is SwitchMarketTop -> "switch_market_top" + is SwitchPeriod -> "switch_period" + is SwitchField -> "switch_field" + is SwitchSortType -> "switch_sort_type" + is SwitchChartPeriod -> "switch_chart_period" + is SwitchTvlChain -> "switch_tvl_platform" + is SwitchFilterType -> "switch_filter_type" + is ToggleSortDirection -> "toggle_sort_direction" + is ToggleTvlField -> "toggle_tvl_field" + is Refresh -> "refresh" + is ToggleBalanceHidden -> "toggle_balance_hidden" + is ToggleConversionCoin -> "toggle_conversion_coin" + is TogglePrice -> "toggle_price" + + is AddToWatchlist -> "add_to_watchlist" + is RemoveFromWatchlist -> "remove_from_watchlist" + is ToggleIndicators -> "toggle_indicators" + is AddToWallet -> "add_to_wallet" + is RemoveFromWallet -> "remove_from_wallet" + is Copy, + is CopyAddress -> "copy" + + is Share -> "share" + is SetAmount -> "set_amount" + is RemoveAmount -> "remove_amount" + is ToggleHidden -> "toggle_hidden" + is Select -> "select" + is Edit -> "edit" + is Delete -> "delete" + is ScanQr -> "scan_qr" + is Paste -> "paste" + is Clear -> "clear" + is CreateWallet -> "create_wallet" + is WatchWallet -> "watch_wallet" + is Add -> "add" + is AddToken -> "add_token" + } + + val params: Map? + get() = when (this) { + + is AddEvmSource -> mapOf( + StatParam.ChainUid to chainUid + ) + + is DeleteCustomEvmSource -> mapOf( + StatParam.ChainUid to chainUid + ) + + is DisableToken -> tokenParams(token) + + is EnableToken -> tokenParams(token) + + is OpenBlockchainSettingsBtc -> mapOf( + StatParam.Page to StatPage.BlockchainSettingsBtc.key, + StatParam.ChainUid to chainUid + ) + + is OpenBlockchainSettingsEvm -> mapOf( + StatParam.Page to StatPage.BlockchainSettingsEvm.key, + StatParam.ChainUid to chainUid + ) + + is OpenBlockchainSettingsEvmAdd -> mapOf( + StatParam.Page to StatPage.BlockchainSettingsEvmAdd.key, + StatParam.ChainUid to chainUid + ) + + is OpenCategory -> mapOf( + StatParam.Page to StatPage.CoinCategory.key, + StatParam.CategoryUid to categoryUid + ) + + is OpenCoin -> mapOf( + StatParam.Page to StatPage.CoinPage.key, + StatParam.CoinUid to coinUid + ) + + is OpenPlatform -> mapOf( + StatParam.Page to StatPage.TopPlatform.key, + StatParam.ChainUid to chainUid + ) + + is OpenReceive -> mapOf(StatParam.Page to StatPage.Receive.key) + tokenParams(token) + + is OpenSend -> mapOf(StatParam.Page to StatPage.Send.key) + tokenParams(token) + + is OpenTokenPage -> buildMap { + put(StatParam.Page, StatPage.TokenPage.key) + putAll(tokenParams(token)) + assetId?.let { put(StatParam.AssetId, it) } + } + + is OpenTokenInfo -> tokenParams(token) + + is OpenResend -> mapOf(StatParam.Page to StatPage.Resend.key, StatParam.ChainUid to chainUid, StatParam.Type to type.key) + + is Open -> mapOf(StatParam.Page to page.key) + + is SwapSelectTokenIn -> tokenParams(token) + + is SwapSelectTokenOut -> tokenParams(token) + + is SwapSelectProvider -> mapOf(StatParam.Provider to uid) + + is SwitchBaseCurrency -> mapOf(StatParam.CurrencyCode to code) + + is SwitchBtcSource -> mapOf(StatParam.ChainUid to chainUid, StatParam.Type to type.raw) + + is SwitchEvmSource -> mapOf(StatParam.ChainUid to chainUid, StatParam.Type to type) + + is SwitchTab -> mapOf(StatParam.Tab to tab.key) + + is SwitchMarketTop -> mapOf(StatParam.MarketTop to marketTop.key) + + is SwitchPeriod -> mapOf(StatParam.Period to period.key) + + is SwitchField -> mapOf(StatParam.Field to this.field.key) + + is SwitchSortType -> mapOf(StatParam.Type to sortType.key) + + is SwitchChartPeriod -> mapOf(StatParam.Period to period.key) + + is SwitchTvlChain -> mapOf(StatParam.TvlChain to chain) + + is SwitchFilterType -> mapOf(StatParam.Type to type) + + is AddToWatchlist -> mapOf(StatParam.CoinUid to coinUid) + + is RemoveFromWatchlist -> mapOf(StatParam.CoinUid to coinUid) + + is ToggleIndicators -> mapOf(StatParam.Shown to shown) + + is Copy -> mapOf(StatParam.Entity to entity.key) + + is CopyAddress -> mapOf(StatParam.ChainUid to chainUid) + + is Select -> mapOf(StatParam.Entity to entity.key) + + is Edit -> mapOf(StatParam.Entity to entity.key) + + is Delete -> mapOf(StatParam.Entity to entity.key) + + is ScanQr -> mapOf(StatParam.Entity to entity.key) + + is Paste -> mapOf(StatParam.Entity to entity.key) + + is Clear -> mapOf(StatParam.Entity to entity.key) + + is CreateWallet -> mapOf(StatParam.WalletType to walletType) + + is ExportWallet -> mapOf(StatParam.WalletType to walletType) + + is ImportWallet -> mapOf(StatParam.WalletType to walletType) + + is WatchWallet -> mapOf(StatParam.WalletType to walletType) + + is Add -> mapOf(StatParam.Entity to entity.key) + + is AddToken -> tokenParams(token) + mapOf(StatParam.Entity to StatEntity.Token.key) + + is Share -> mapOf(StatParam.Entity to StatEntity.ReceiveAddress.key) + + else -> null + } + + private fun tokenParams(token: Token?) = buildMap { + token?.let { + put(StatParam.CoinUid, token.coin.uid) + put(StatParam.ChainUid, token.blockchainType.uid) + + token.type.derivation?.let { put(StatParam.Derivation, it.name.lowercase()) } + token.type.bitcoinCashCoinType?.let { put(StatParam.BitcoinCashCoinType, it.name.lowercase()) } + } + } +} + +enum class StatParam(val key: String) { + AssetId("asset_id"), + BitcoinCashCoinType("bitcoin_cash_coin_type"), + CategoryUid("category_uid"), + ChainUid("chain_uid"), + CoinUid("coin_uid"), + CurrencyCode("currency_code"), + Derivation("derivation"), + Entity("entity"), + Field("field"), + MarketTop("market_top"), + Page("page"), + Period("period"), + Provider("provider"), + Shown("shown"), + Tab("tab"), + TvlChain("tvl_chain"), + Type("type"), + WalletType("wallet_type") +} + +enum class StatTab(val key: String) { + Markets("markets"), + Balance("balance"), + Transactions("transactions"), + Settings("settings"), + Overview("overview"), + News("news"), + Watchlist("watchlist"), + Analytics("analytics"), + All("all"), + Incoming("incoming"), + Outgoing("outgoing"), + Swap("swap"), + Approve("approve") +} + +enum class StatSortType(val key: String) { + Balance("balance"), + Name("name"), + PriceChange("price_change"), + HighestCap("highest_cap"), + LowestCap("lowest_cap"), + HighestVolume("highest_volume"), + LowestVolume("lowest_volume"), + TopGainers("top_gainers"), + TopLosers("top_losers"), +} + +enum class StatPeriod(val key: String) { + Day1("1d"), + Week1("1w"), + Week2("2w"), + Month1("1m"), + Month3("3m"), + Month6("6m"), + Year1("1y"), + Year2("2y"), + Year5("5y"), + All("all") +} + +enum class StatField(val key: String) { + MarketCap("market_cap"), + Volume("volume"), + Price("price") +} + +enum class StatMarketTop(val key: String) { + Top100("top100"), + Top200("top200"), + Top300("top300"), +} + +enum class StatEntity(val key: String) { + Account("account"), + Address("address"), + Blockchain("blockchain"), + CloudBackup("cloud_backup"), + ContractAddress("contract_address"), + Derivation("derivation"), + EvmAddress("evm_address"), + EvmPrivateKey("evm_private_key"), + Key("key"), + Passphrase("passphrase"), + ReceiveAddress("receive_address"), + RecoveryPhrase("recovery_phrase"), + RawTransaction("raw_transaction"), + Token("token"), + TransactionId("transaction_id"), + Wallet("wallet"), + WalletName("wallet_name") +} + +enum class StatResendType(val key: String) { + SpeedUp("speed_up"), + Cancel("cancel") +} diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/AppDatabase.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/AppDatabase.kt index 0e44f41dd04..0807ec30089 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/AppDatabase.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/AppDatabase.kt @@ -6,8 +6,46 @@ import androidx.room.Room import androidx.room.RoomDatabase import androidx.room.TypeConverters import io.horizontalsystems.bankwallet.core.providers.CexAssetRaw -import io.horizontalsystems.bankwallet.core.storage.migrations.* -import io.horizontalsystems.bankwallet.entities.* +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_31_32 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_32_33 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_33_34 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_34_35 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_35_36 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_36_37 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_37_38 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_38_39 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_39_40 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_40_41 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_41_42 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_42_43 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_43_44 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_44_45 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_45_46 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_46_47 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_47_48 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_48_49 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_49_50 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_50_51 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_51_52 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_52_53 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_53_54 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_54_55 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_55_56 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_56_57 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_57_58 +import io.horizontalsystems.bankwallet.core.storage.migrations.Migration_58_59 +import io.horizontalsystems.bankwallet.entities.ActiveAccount +import io.horizontalsystems.bankwallet.entities.BlockchainSettingRecord +import io.horizontalsystems.bankwallet.entities.EnabledWallet +import io.horizontalsystems.bankwallet.entities.EnabledWalletCache +import io.horizontalsystems.bankwallet.entities.EvmAddressLabel +import io.horizontalsystems.bankwallet.entities.EvmMethodLabel +import io.horizontalsystems.bankwallet.entities.EvmSyncSourceRecord +import io.horizontalsystems.bankwallet.entities.LogEntry +import io.horizontalsystems.bankwallet.entities.RestoreSettingRecord +import io.horizontalsystems.bankwallet.entities.StatRecord +import io.horizontalsystems.bankwallet.entities.SyncerState +import io.horizontalsystems.bankwallet.entities.TokenAutoEnabledBlockchain import io.horizontalsystems.bankwallet.entities.nft.NftAssetBriefMetadataRecord import io.horizontalsystems.bankwallet.entities.nft.NftAssetRecord import io.horizontalsystems.bankwallet.entities.nft.NftCollectionRecord @@ -18,10 +56,10 @@ import io.horizontalsystems.bankwallet.modules.pin.core.Pin import io.horizontalsystems.bankwallet.modules.pin.core.PinDao import io.horizontalsystems.bankwallet.modules.profeatures.storage.ProFeaturesDao import io.horizontalsystems.bankwallet.modules.profeatures.storage.ProFeaturesSessionKey -import io.horizontalsystems.bankwallet.modules.walletconnect.storage.WalletConnectV2Session import io.horizontalsystems.bankwallet.modules.walletconnect.storage.WCSessionDao +import io.horizontalsystems.bankwallet.modules.walletconnect.storage.WalletConnectV2Session -@Database(version = 58, exportSchema = false, entities = [ +@Database(version = 59, exportSchema = false, entities = [ EnabledWallet::class, EnabledWalletCache::class, AccountRecord::class, @@ -44,6 +82,7 @@ import io.horizontalsystems.bankwallet.modules.walletconnect.storage.WCSessionDa CexAssetRaw::class, ChartIndicatorSetting::class, Pin::class, + StatRecord::class ]) @TypeConverters(DatabaseConverters::class) @@ -67,6 +106,7 @@ abstract class AppDatabase : RoomDatabase() { abstract fun syncerStateDao(): SyncerStateDao abstract fun tokenAutoEnabledBlockchainDao(): TokenAutoEnabledBlockchainDao abstract fun pinDao(): PinDao + abstract fun statsDao(): StatsDao companion object { @@ -111,6 +151,7 @@ abstract class AppDatabase : RoomDatabase() { Migration_55_56, Migration_56_57, Migration_57_58, + Migration_58_59 ) .build() } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/StatsDao.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/StatsDao.kt new file mode 100644 index 00000000000..f66809823f5 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/StatsDao.kt @@ -0,0 +1,21 @@ +package io.horizontalsystems.bankwallet.core.storage + +import androidx.room.Dao +import androidx.room.Insert +import androidx.room.OnConflictStrategy +import androidx.room.Query +import io.horizontalsystems.bankwallet.entities.StatRecord + +@Dao +interface StatsDao { + + @Insert(onConflict = OnConflictStrategy.REPLACE) + fun insert(statRecord: StatRecord) + + @Query("SELECT * FROM StatRecord ORDER BY id") + fun getAll(): List + + @Query("DELETE FROM StatRecord WHERE id IN (:ids)") + fun delete(ids: List): Int + +} diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/migrations/Migration_58_59.kt b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/migrations/Migration_58_59.kt new file mode 100644 index 00000000000..36147e28c22 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/bankwallet/core/storage/migrations/Migration_58_59.kt @@ -0,0 +1,10 @@ +package io.horizontalsystems.bankwallet.core.storage.migrations + +import androidx.room.migration.Migration +import androidx.sqlite.db.SupportSQLiteDatabase + +object Migration_58_59 : Migration(58, 59) { + override fun migrate(database: SupportSQLiteDatabase) { + database.execSQL("CREATE TABLE IF NOT EXISTS `StatRecord` (`json` TEXT NOT NULL, `id` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL)") + } +} diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/entities/StatRecord.kt b/app/src/main/java/io/horizontalsystems/bankwallet/entities/StatRecord.kt new file mode 100644 index 00000000000..4c7a446de53 --- /dev/null +++ b/app/src/main/java/io/horizontalsystems/bankwallet/entities/StatRecord.kt @@ -0,0 +1,10 @@ +package io.horizontalsystems.bankwallet.entities + +import androidx.room.Entity +import androidx.room.PrimaryKey + +@Entity +data class StatRecord(val json: String) { + @PrimaryKey(autoGenerate = true) + var id: Int = 0 +} diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/addtoken/AddTokenService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/addtoken/AddTokenService.kt index 3e14e14e3f8..5cfd2c8fdb4 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/addtoken/AddTokenService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/addtoken/AddTokenService.kt @@ -6,6 +6,9 @@ import io.horizontalsystems.bankwallet.core.ICoinManager import io.horizontalsystems.bankwallet.core.IWalletManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper import io.horizontalsystems.bankwallet.core.order +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Wallet import io.horizontalsystems.marketkit.models.Blockchain import io.horizontalsystems.marketkit.models.BlockchainType @@ -71,6 +74,8 @@ class AddTokenService( val account = accountManager.activeAccount ?: return val wallet = Wallet(token.token, account) walletManager.save(listOf(wallet)) + + stat(page = StatPage.AddToken, event = StatEvent.AddToken(token.token)) } sealed class TokenError : Exception() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backupalert/BackupRecoveryPhraseDialog.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backupalert/BackupRecoveryPhraseDialog.kt index 99c25a7d97b..1bd435a7df4 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backupalert/BackupRecoveryPhraseDialog.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backupalert/BackupRecoveryPhraseDialog.kt @@ -26,6 +26,9 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.requireInput import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimary @@ -85,6 +88,8 @@ fun BackupRecoveryPhraseScreen(navController: NavController, account: Account) { iconTint = ComposeAppTheme.colors.dark, onClick = { navController.slideFromBottom(R.id.backupKeyFragment, account) + + stat(page = StatPage.BackupPromptAfterCreate, event = StatEvent.Open(StatPage.ManualBackup)) } ) VSpacer(12.dp) @@ -97,6 +102,8 @@ fun BackupRecoveryPhraseScreen(navController: NavController, account: Account) { iconTint = ComposeAppTheme.colors.claude, onClick = { navController.slideFromBottom(R.id.backupLocalFragment, account) + + stat(page = StatPage.BackupPromptAfterCreate, event = StatEvent.Open(StatPage.FileBackup)) } ) VSpacer(12.dp) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/fullbackup/BackupManagerFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/fullbackup/BackupManagerFragment.kt index 4aaa81a26a3..66aef71646d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/fullbackup/BackupManagerFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/fullbackup/BackupManagerFragment.kt @@ -28,6 +28,9 @@ import io.horizontalsystems.bankwallet.core.authorizedAction import io.horizontalsystems.bankwallet.core.navigateWithTermsAccepted import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.contacts.screen.ConfirmationBottomSheet import io.horizontalsystems.bankwallet.modules.importwallet.getFileName import io.horizontalsystems.bankwallet.modules.restorelocal.RestoreLocalFragment @@ -56,14 +59,19 @@ class BackupManagerFragment : BaseComposeFragment() { R.id.backupManagerFragment, false, jsonString, - fileName + fileName, + StatPage.ImportFullFromFiles ) ) + + stat(page = StatPage.BackupManager, event = StatEvent.Open(StatPage.ImportFullFromFiles)) } }, onCreateBackup = { navController.authorizedAction { navController.slideFromRight(R.id.backupLocalFragment) + + stat(page = StatPage.BackupManager, event = StatEvent.Open(StatPage.ExportFullToFiles)) } } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/password/BackupLocalPasswordViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/password/BackupLocalPasswordViewModel.kt index 2a62dc76dd9..d5af9082f5c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/password/BackupLocalPasswordViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/backuplocal/password/BackupLocalPasswordViewModel.kt @@ -7,6 +7,10 @@ import io.horizontalsystems.bankwallet.core.PasswordError import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.managers.PassphraseValidator import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.modules.backuplocal.fullbackup.BackupProvider import kotlinx.coroutines.Dispatchers @@ -110,11 +114,15 @@ class BackupLocalPasswordViewModel( if (!account.isFileBackedUp) { accountManager.update(account.copy(isFileBackedUp = true)) } + + stat(page = StatPage.ExportWalletToFiles, event = StatEvent.ExportWallet(account.type.statAccountType)) } } is BackupType.FullBackup -> { // FullBackup doesn't change account's backup state + + stat(page = StatPage.ExportFullToFiles, event = StatEvent.ExportFull) } } delay(1700) //Wait for showing Snackbar (SHORT duration ~ 1500ms) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceService.kt index cf92c3ba67e..24a1718863d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceService.kt @@ -6,6 +6,10 @@ import io.horizontalsystems.bankwallet.core.IAccountManager import io.horizontalsystems.bankwallet.core.ILocalStorage import io.horizontalsystems.bankwallet.core.isNative import io.horizontalsystems.bankwallet.core.managers.ConnectivityManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statSortType import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.entities.Wallet @@ -41,6 +45,8 @@ class BalanceService( localStorage.sortType = value sortAndEmitItems() + + stat(page = StatPage.Balance, event = StatEvent.SwitchSortType(value.statSortType)) } var isWatchAccount = false diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceViewModel.kt index 858541c5d9f..a839f9d0d31 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/BalanceViewModel.kt @@ -12,6 +12,9 @@ import io.horizontalsystems.bankwallet.core.ILocalStorage import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.factories.uriScheme import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.core.supported import io.horizontalsystems.bankwallet.core.utils.AddressUriParser import io.horizontalsystems.bankwallet.core.utils.AddressUriResult @@ -157,6 +160,8 @@ class BalanceViewModel( return } + stat(page = StatPage.Balance, event = StatEvent.Refresh) + viewModelScope.launch { isRefreshing = true emitState() @@ -185,6 +190,8 @@ class BalanceViewModel( fun disable(viewItem: BalanceViewItem2) { service.disable(viewItem.wallet) + + stat(page = StatPage.Balance, event = StatEvent.DisableToken(viewItem.wallet.token)) } fun getSyncErrorDetails(viewItem: BalanceViewItem2): SyncError = when { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/cex/asset/CexAssetFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/cex/asset/CexAssetFragment.kt index bf2cc807f5f..45e23222a8f 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/cex/asset/CexAssetFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/cex/asset/CexAssetFragment.kt @@ -218,7 +218,7 @@ private fun ButtonsRow(viewItem: BalanceCexViewItem, navController: NavControlle viewItem.coinUid?.let { coinUid -> navController.slideFromRight( R.id.coinFragment, - CoinFragment.Input(coinUid, "cex_asset") + CoinFragment.Input(coinUid) ) } }, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/token/TokenBalanceScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/token/TokenBalanceScreen.kt index 171eff5e364..d939675bdc1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/token/TokenBalanceScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/token/TokenBalanceScreen.kt @@ -39,6 +39,9 @@ import io.horizontalsystems.bankwallet.core.isCustom import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.balance.BackupRequiredError import io.horizontalsystems.bankwallet.modules.balance.BalanceViewItem import io.horizontalsystems.bankwallet.modules.balance.BalanceViewModel @@ -138,6 +141,8 @@ private fun onTransactionClick( transactionsViewModel.tmpItemToShow = transactionItem navController.slideFromBottom(R.id.transactionInfoFragment) + + stat(page = StatPage.TokenPage, event = StatEvent.Open(StatPage.TransactionInfo)) } @Composable @@ -169,6 +174,8 @@ private fun TokenBalanceHeader( onClick = { viewModel.toggleBalanceVisibility() HudHelper.vibrate(context) + + stat(page = StatPage.TokenPage, event = StatEvent.ToggleBalanceHidden) } ), text = if (balanceViewItem.primaryValue.visible) balanceViewItem.primaryValue.value else "*****", @@ -334,7 +341,10 @@ private fun onSyncErrorClicked(viewItem: BalanceViewItem, viewModel: TokenBalanc private fun ButtonsRow(viewItem: BalanceViewItem, navController: NavController, viewModel: TokenBalanceViewModel) { val onClickReceive = { try { - navController.slideFromRight(R.id.receiveFragment, viewModel.getWalletForReceive()) + val wallet = viewModel.getWalletForReceive() + navController.slideFromRight(R.id.receiveFragment, wallet) + + stat(page = StatPage.TokenPage, event = StatEvent.OpenReceive(wallet.token)) } catch (e: BackupRequiredError) { val text = Translator.getString( R.string.ManageAccount_BackupRequired_Description, @@ -345,6 +355,8 @@ private fun ButtonsRow(viewItem: BalanceViewItem, navController: NavController, R.id.backupRequiredDialog, BackupRequiredDialog.Input(e.account, text) ) + + stat(page = StatPage.TokenPage, event = StatEvent.Open(StatPage.BackupRequired)) } } @@ -367,6 +379,8 @@ private fun ButtonsRow(viewItem: BalanceViewItem, navController: NavController, R.id.sendXFragment, SendFragment.Input(viewItem.wallet, sendTitle) ) + + stat(page = StatPage.TokenPage, event = StatEvent.OpenSend(viewItem.wallet.token)) }, enabled = viewItem.sendEnabled ) @@ -391,6 +405,8 @@ private fun ButtonsRow(viewItem: BalanceViewItem, navController: NavController, contentDescription = stringResource(R.string.Swap), onClick = { navController.slideFromRight(R.id.multiswap, viewItem.wallet.token) + + stat(page = StatPage.TokenPage, event = StatEvent.Open(StatPage.Swap)) }, enabled = viewItem.swapEnabled ) @@ -403,9 +419,11 @@ private fun ButtonsRow(viewItem: BalanceViewItem, navController: NavController, enabled = !viewItem.wallet.token.isCustom, onClick = { val coinUid = viewItem.wallet.coin.uid - val arguments = CoinFragment.Input(coinUid, "wallet_token_balance") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.TokenPage, event = StatEvent.OpenCoin(coinUid)) }, ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceForAccount.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceForAccount.kt index 2c8171f8868..9cdea92a938 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceForAccount.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceForAccount.kt @@ -34,6 +34,9 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.Caution import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.core.utils.ModuleField import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.backupalert.BackupAlert @@ -131,6 +134,8 @@ fun BalanceForAccount(navController: NavController, accountViewItem: AccountView when (val state = viewModel.getWalletConnectSupportState()) { WCManager.SupportState.Supported -> { qrScannerLauncher.launch(QRScannerActivity.getScanQrIntent(context, true)) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.ScanQrCode)) } WCManager.SupportState.NotSupportedDueToNoActiveAccount -> { @@ -143,6 +148,8 @@ fun BalanceForAccount(navController: NavController, accountViewItem: AccountView R.id.backupRequiredDialog, BackupRequiredDialog.Input(state.account, text) ) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.BackupRequired)) } is WCManager.SupportState.NotSupported -> { @@ -200,6 +207,8 @@ fun BalanceTitleRow( R.id.manageAccountsFragment, ManageAccountsModule.Mode.Switcher ) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.ManageWallets)) }, verticalAlignment = Alignment.CenterVertically ) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceItems.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceItems.kt index 9c81dfd6d6f..8f389452ce3 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceItems.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceItems.kt @@ -50,6 +50,9 @@ import io.horizontalsystems.bankwallet.core.managers.FaqManager import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.balance.AccountViewItem import io.horizontalsystems.bankwallet.modules.balance.BalanceSortType import io.horizontalsystems.bankwallet.modules.balance.BalanceUiState @@ -200,6 +203,8 @@ fun BalanceItems( R.id.tokenBalanceFragment, it.wallet ) + + stat(page = StatPage.Balance, event = StatEvent.OpenTokenPage(it.wallet.token)) } } @@ -241,12 +246,16 @@ fun BalanceItems( { viewModel.toggleBalanceVisibility() HudHelper.vibrate(context) + + stat(page = StatPage.Balance, event = StatEvent.ToggleBalanceHidden) } }, onClickSubtitle = remember { { viewModel.toggleTotalType() HudHelper.vibrate(context) + + stat(page = StatPage.Balance, event = StatEvent.ToggleConversionCoin) } } ) @@ -263,6 +272,8 @@ fun BalanceItems( title = stringResource(R.string.Balance_Send), onClick = { navController.slideFromRight(R.id.sendTokenSelectFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.SendTokenList)) } ) HSpacer(8.dp) @@ -273,6 +284,8 @@ fun BalanceItems( when (val receiveAllowedState = viewModel.getReceiveAllowedState()) { ReceiveAllowedState.Allowed -> { navController.slideFromRight(R.id.receiveFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.ReceiveTokenList)) } is ReceiveAllowedState.BackupRequired -> { @@ -285,6 +298,8 @@ fun BalanceItems( R.id.backupRequiredDialog, BackupRequiredDialog.Input(account, text) ) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.BackupRequired)) } null -> Unit @@ -297,6 +312,8 @@ fun BalanceItems( contentDescription = stringResource(R.string.Swap), onClick = { navController.slideFromRight(R.id.multiswap) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.Swap)) } ) } @@ -335,6 +352,8 @@ fun BalanceItems( contentDescription = stringResource(R.string.ManageCoins_title), onClick = { navController.slideFromRight(R.id.manageWalletsFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.CoinManager)) } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceNoAccount.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceNoAccount.kt index eabae0fd171..2cf0d965285 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceNoAccount.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/balance/ui/BalanceNoAccount.kt @@ -24,6 +24,9 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.navigateWithTermsAccepted import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryDefault import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryTransparent @@ -63,6 +66,8 @@ fun BalanceNoAccount(navController: NavController) { onClick = { navController.navigateWithTermsAccepted { navController.slideFromRight(R.id.createAccountFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.NewWallet)) } } ) @@ -75,6 +80,8 @@ fun BalanceNoAccount(navController: NavController) { onClick = { navController.navigateWithTermsAccepted { navController.slideFromRight(R.id.importWalletFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.ImportWallet)) } } ) @@ -86,6 +93,8 @@ fun BalanceNoAccount(navController: NavController) { title = stringResource(R.string.ManageAccounts_WatchAddress), onClick = { navController.slideFromRight(R.id.watchAddressFragment) + + stat(page = StatPage.Balance, event = StatEvent.Open(StatPage.WatchWallet)) } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/basecurrency/BaseCurrencySettingsViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/basecurrency/BaseCurrencySettingsViewModel.kt index b1ce9977eb7..adb25c6a8de 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/basecurrency/BaseCurrencySettingsViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/basecurrency/BaseCurrencySettingsViewModel.kt @@ -5,6 +5,9 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import io.horizontalsystems.bankwallet.core.managers.CurrencyManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Currency class BaseCurrencySettingsViewModel(private val currencyManager: CurrencyManager) : ViewModel() { @@ -62,6 +65,8 @@ class BaseCurrencySettingsViewModel(private val currencyManager: CurrencyManager private fun doSetBaseCurrency(v: Currency) { baseCurrency = v closeScreen = true + + stat(page = StatPage.BaseCurrency, event = StatEvent.SwitchBaseCurrency(v.code)) } fun closeDisclaimer() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/blockchainsettings/BlockchainSettingsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/blockchainsettings/BlockchainSettingsFragment.kt index 7a60c104e2f..a6ac0f64a0e 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/blockchainsettings/BlockchainSettingsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/blockchainsettings/BlockchainSettingsFragment.kt @@ -22,6 +22,9 @@ import coil.compose.rememberAsyncImagePainter import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.AppBar import io.horizontalsystems.bankwallet.ui.compose.components.CellUniversalLawrenceSection @@ -100,14 +103,20 @@ private fun onClick( when (item.blockchainItem) { is BlockchainSettingsModule.BlockchainItem.Btc -> { navController.slideFromBottom(R.id.btcBlockchainSettingsFragment, item.blockchainItem.blockchain) + + stat(page = StatPage.BlockchainSettings, event = StatEvent.OpenBlockchainSettingsBtc(item.blockchainItem.blockchain.uid)) } is BlockchainSettingsModule.BlockchainItem.Evm -> { navController.slideFromBottom(R.id.evmNetworkFragment, item.blockchainItem.blockchain) + + stat(page = StatPage.BlockchainSettings, event = StatEvent.OpenBlockchainSettingsEvm(item.blockchainItem.blockchain.uid)) } is BlockchainSettingsModule.BlockchainItem.Solana -> { navController.slideFromBottom(R.id.solanaNetworkFragment) + + stat(page = StatPage.BlockchainSettings, event = StatEvent.Open(StatPage.BlockchainSettingsSolana)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/btcblockchainsettings/BtcBlockchainSettingsService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/btcblockchainsettings/BtcBlockchainSettingsService.kt index 65f32b364e3..ca97a3c521a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/btcblockchainsettings/BtcBlockchainSettingsService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/btcblockchainsettings/BtcBlockchainSettingsService.kt @@ -1,6 +1,9 @@ package io.horizontalsystems.bankwallet.modules.btcblockchainsettings import io.horizontalsystems.bankwallet.core.managers.BtcBlockchainManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.BtcRestoreMode import io.horizontalsystems.marketkit.models.Blockchain import io.reactivex.Observable @@ -24,6 +27,8 @@ class BtcBlockchainSettingsService( fun save() { if (restoreMode != btcBlockchainManager.restoreMode(blockchain.type)) { btcBlockchainManager.save(restoreMode, blockchain.type) + + stat(page = StatPage.BlockchainSettingsBtc, event = StatEvent.SwitchBtcSource(blockchain.uid, restoreMode)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/CoinFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/CoinFragment.kt index 706f3961ee4..bdb54b9bd3c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/CoinFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/CoinFragment.kt @@ -18,12 +18,21 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statTab import io.horizontalsystems.bankwallet.modules.coin.analytics.CoinAnalyticsScreen import io.horizontalsystems.bankwallet.modules.coin.coinmarkets.CoinMarketsScreen import io.horizontalsystems.bankwallet.modules.coin.overview.ui.CoinOverviewScreen import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.TabItem +import io.horizontalsystems.bankwallet.ui.compose.components.Tabs import io.horizontalsystems.core.helpers.HudHelper import kotlinx.coroutines.delay import kotlinx.coroutines.launch @@ -35,11 +44,9 @@ class CoinFragment : BaseComposeFragment() { override fun GetContent(navController: NavController) { val input = navController.getInput() val coinUid = input?.coinUid ?: "" - val apiTag = input?.apiTag ?: "" CoinScreen( coinUid, - apiTag, coinViewModel(coinUid), navController, childFragmentManager @@ -56,19 +63,18 @@ class CoinFragment : BaseComposeFragment() { } @Parcelize - data class Input(val coinUid: String, val apiTag: String) : Parcelable + data class Input(val coinUid: String) : Parcelable } @Composable fun CoinScreen( coinUid: String, - apiTag: String, coinViewModel: CoinViewModel?, navController: NavController, fragmentManager: FragmentManager ) { if (coinViewModel != null) { - CoinTabs(apiTag, coinViewModel, navController, fragmentManager) + CoinTabs(coinViewModel, navController, fragmentManager) } else { CoinNotFound(coinUid, navController) } @@ -77,7 +83,6 @@ fun CoinScreen( @OptIn(ExperimentalFoundationApi::class) @Composable fun CoinTabs( - apiTag: String, viewModel: CoinViewModel, navController: NavController, fragmentManager: FragmentManager @@ -101,7 +106,11 @@ fun CoinTabs( title = TranslatableString.ResString(R.string.CoinPage_Unfavorite), icon = R.drawable.ic_filled_star_24, tint = ComposeAppTheme.colors.jacob, - onClick = { viewModel.onUnfavoriteClick() } + onClick = { + viewModel.onUnfavoriteClick() + + stat(page = StatPage.CoinPage, event = StatEvent.RemoveFromWatchlist(viewModel.fullCoin.coin.uid)) + } ) ) } else { @@ -109,7 +118,11 @@ fun CoinTabs( MenuItem( title = TranslatableString.ResString(R.string.CoinPage_Favorite), icon = R.drawable.ic_star_24, - onClick = { viewModel.onFavoriteClick() } + onClick = { + viewModel.onFavoriteClick() + + stat(page = StatPage.CoinPage, event = StatEvent.AddToWatchlist(viewModel.fullCoin.coin.uid)) + } ) ) } @@ -125,6 +138,8 @@ fun CoinTabs( coroutineScope.launch { pagerState.scrollToPage(tab.ordinal) + stat(page = StatPage.CoinPage, event = StatEvent.SwitchTab(tab.statTab)) + if (tab == CoinModule.Tab.Details && viewModel.shouldShowSubscriptionInfo()) { viewModel.subscriptionInfoShown() @@ -141,7 +156,6 @@ fun CoinTabs( when (tabs[page]) { CoinModule.Tab.Overview -> { CoinOverviewScreen( - apiTag = apiTag, fullCoin = viewModel.fullCoin, navController = navController ) @@ -153,7 +167,6 @@ fun CoinTabs( CoinModule.Tab.Details -> { CoinAnalyticsScreen( - apiTag = apiTag, fullCoin = viewModel.fullCoin, navController = navController, fragmentManager = fragmentManager diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsModule.kt index a278ac69ad3..4a324d0bc9b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsModule.kt @@ -23,13 +23,12 @@ import kotlinx.parcelize.Parcelize object CoinAnalyticsModule { - class Factory(private val fullCoin: FullCoin, private val apiTag: String) : ViewModelProvider.Factory { + class Factory(private val fullCoin: FullCoin) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { val service = CoinAnalyticsService( fullCoin, - apiTag, App.marketKit, App.currencyManager, App.subscriptionManager, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsScreen.kt index e388f40234d..5847db83a4b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsScreen.kt @@ -52,13 +52,12 @@ import io.horizontalsystems.marketkit.models.FullCoin @Composable fun CoinAnalyticsScreen( - apiTag: String, fullCoin: FullCoin, navController: NavController, fragmentManager: FragmentManager ) { val viewModel = - viewModel(factory = CoinAnalyticsModule.Factory(fullCoin, apiTag)) + viewModel(factory = CoinAnalyticsModule.Factory(fullCoin)) val uiState = viewModel.uiState HSSwipeRefresh( diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsService.kt index 5fa034b7316..5722b6970e5 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/analytics/CoinAnalyticsService.kt @@ -20,7 +20,6 @@ import kotlinx.coroutines.rx2.await class CoinAnalyticsService( val fullCoin: FullCoin, - private val apiTag: String, private val marketKit: MarketKitWrapper, private val currencyManager: CurrencyManager, private val subscriptionManager: SubscriptionManager, @@ -58,7 +57,7 @@ class CoinAnalyticsService( _stateFlow.emit(DataState.Loading) try { - marketKit.analyticsSingle(fullCoin.coin.uid, currency.code, apiTag).await() + marketKit.analyticsSingle(fullCoin.coin.uid, currency.code).await() .let { _stateFlow.emit(DataState.Success(AnalyticData(analytics = it))) } @@ -87,7 +86,7 @@ class CoinAnalyticsService( } try { - marketKit.analyticsPreviewSingle(fullCoin.coin.uid, addresses, apiTag).await() + marketKit.analyticsPreviewSingle(fullCoin.coin.uid, addresses).await() .let { _stateFlow.emit(DataState.Success(AnalyticData(analyticsPreview = it))) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewChartService.kt index 811c9d098d5..4d850f788db 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewChartService.kt @@ -3,6 +3,10 @@ package io.horizontalsystems.bankwallet.modules.coin.overview import android.util.Log import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartIndicatorManager @@ -98,6 +102,12 @@ class CoinOverviewChartService( ) } + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(page = StatPage.CoinOverview, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } + private fun getItemsByPeriodType( currency: Currency, periodType: HsPeriodType, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewModule.kt index 0f8e1e4ccba..e5e6dd80ccf 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewModule.kt @@ -6,14 +6,17 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.modules.chart.ChartCurrencyValueFormatterSignificant import io.horizontalsystems.bankwallet.modules.chart.ChartModule import io.horizontalsystems.bankwallet.modules.chart.ChartViewModel -import io.horizontalsystems.bankwallet.modules.coin.* +import io.horizontalsystems.bankwallet.modules.coin.CoinDataItem +import io.horizontalsystems.bankwallet.modules.coin.CoinLink +import io.horizontalsystems.bankwallet.modules.coin.CoinViewFactory +import io.horizontalsystems.bankwallet.modules.coin.RoiViewItem import io.horizontalsystems.marketkit.models.FullCoin import io.horizontalsystems.marketkit.models.MarketInfoOverview import io.horizontalsystems.marketkit.models.Token object CoinOverviewModule { - class Factory(private val fullCoin: FullCoin, private val apiTag: String) : ViewModelProvider.Factory { + class Factory(private val fullCoin: FullCoin) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { @@ -22,7 +25,6 @@ object CoinOverviewModule { val currency = App.currencyManager.baseCurrency val service = CoinOverviewService( fullCoin, - apiTag, App.marketKit, App.currencyManager, App.appConfigProvider, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewService.kt index d5519a2a884..f3b74f60c6a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/CoinOverviewService.kt @@ -17,7 +17,6 @@ import java.net.URL class CoinOverviewService( val fullCoin: FullCoin, - private val apiTag: String, private val marketKit: MarketKitWrapper, private val currencyManager: CurrencyManager, private val appConfigProvider: AppConfigProvider, @@ -57,7 +56,7 @@ class CoinOverviewService( private fun fetchCoinOverview() { coroutineScope.launch { try { - val marketInfoOverview = marketKit.marketInfoOverviewSingle(fullCoin.coin.uid, currencyManager.baseCurrency.code, languageManager.currentLanguage, apiTag).await() + val marketInfoOverview = marketKit.marketInfoOverviewSingle(fullCoin.coin.uid, currencyManager.baseCurrency.code, languageManager.currentLanguage).await() coinOverviewSubject.onNext(DataState.Success(CoinOverviewItem(fullCoin.coin.code, marketInfoOverview, guideUrl))) } catch (e: Throwable) { coinOverviewSubject.onNext(DataState.Error(e)) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/ui/CoinOverviewScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/ui/CoinOverviewScreen.kt index 5cfe6c64bab..d267d6c5b34 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/ui/CoinOverviewScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/overview/ui/CoinOverviewScreen.kt @@ -31,6 +31,10 @@ import io.horizontalsystems.bankwallet.core.iconPlaceholder import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.slideFromBottomForResult import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.chart.ChartViewModel import io.horizontalsystems.bankwallet.modules.coin.CoinLink @@ -61,11 +65,10 @@ import io.horizontalsystems.marketkit.models.LinkType @Composable fun CoinOverviewScreen( - apiTag: String, fullCoin: FullCoin, navController: NavController ) { - val vmFactory by lazy { CoinOverviewModule.Factory(fullCoin, apiTag) } + val vmFactory by lazy { CoinOverviewModule.Factory(fullCoin) } val viewModel = viewModel(factory = vmFactory) val chartViewModel = viewModel(factory = vmFactory) @@ -156,6 +159,8 @@ fun CoinOverviewScreen( title = stringResource(id = R.string.Button_Hide), onClick = { viewModel.disableChartIndicators() + + stat(page = StatPage.CoinOverview, event = StatEvent.ToggleIndicators(false)) } ) } else { @@ -163,6 +168,8 @@ fun CoinOverviewScreen( title = stringResource(id = R.string.Button_Show), onClick = { viewModel.enableChartIndicators() + + stat(page = StatPage.CoinOverview, event = StatEvent.ToggleIndicators(true)) } ) } @@ -171,6 +178,8 @@ fun CoinOverviewScreen( icon = R.drawable.ic_setting_20 ) { navController.slideFromRight(R.id.indicatorsFragment) + + stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.Indicators)) } } } @@ -192,16 +201,24 @@ fun CoinOverviewScreen( tokenVariants = tokenVariants, onClickAddToWallet = { manageWalletsViewModel.enable(it) + + stat(page = StatPage.CoinOverview, event = StatEvent.AddToWallet) }, onClickRemoveWallet = { manageWalletsViewModel.disable(it) + + stat(page = StatPage.CoinOverview, event = StatEvent.RemoveFromWallet) }, onClickCopy = { TextHelper.copyText(it) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + stat(page = StatPage.CoinOverview, event = StatEvent.Copy(StatEntity.ContractAddress)) }, onClickExplorer = { LinkHelper.openLinkInAppBrowser(context, it) + + stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalBlockExplorer)) }, ) } @@ -247,6 +264,16 @@ private fun onClick(coinLink: CoinLink, context: Context, navController: NavCont } else -> LinkHelper.openLinkInAppBrowser(context, absoluteUrl) } + + when(coinLink.linkType) { + LinkType.Guide -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.Guide)) + LinkType.Website -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalCoinWebsite)) + LinkType.Whitepaper -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalCoinWhitePaper)) + LinkType.Twitter -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalTwitter)) + LinkType.Telegram -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalTelegram)) + LinkType.Reddit -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalReddit)) + LinkType.Github -> stat(page = StatPage.CoinOverview, event = StatEvent.Open(StatPage.ExternalGithub)) + } } private fun getAbsoluteUrl(coinLink: CoinLink) = when (coinLink.linkType) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankFragment.kt index e635761df8c..75135201970 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankFragment.kt @@ -39,6 +39,9 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPage import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.analytics.CoinAnalyticsModule.RankType @@ -53,7 +56,6 @@ import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryTogg import io.horizontalsystems.bankwallet.ui.compose.components.DescriptionCard import io.horizontalsystems.bankwallet.ui.compose.components.HSpacer import io.horizontalsystems.bankwallet.ui.compose.components.HeaderSorting -import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView import io.horizontalsystems.bankwallet.ui.compose.components.ListErrorView import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem import io.horizontalsystems.bankwallet.ui.compose.components.RowUniversal @@ -163,7 +165,7 @@ private fun CoinRankScreen( } } } - coinRankList(viewItems, navController) + coinRankList(viewItems, type, navController) } } } @@ -173,6 +175,7 @@ private fun CoinRankScreen( private fun LazyListScope.coinRankList( items: List, + type: RankType, navController: NavController ) { item { @@ -189,8 +192,10 @@ private fun LazyListScope.coinRankList( iconUrl = item.iconUrl, value = item.value, onClick = { - val arguments = CoinFragment.Input(item.coinUid, "coin_rank") + val arguments = CoinFragment.Input(item.coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = type.statPage, event = StatEvent.OpenCoin(item.coinUid)) } ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankViewModel.kt index 934e2329808..50208749a1d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/ranks/CoinRankViewModel.kt @@ -160,10 +160,10 @@ class CoinRankViewModel( RankType.CexVolumeRank, RankType.DexVolumeRank, RankType.DexLiquidityRank, - RankType.HoldersRank, RankType.RevenueRank, RankType.FeeRank -> numberFormatter.formatFiatShort(value, currency.symbol, 2) + RankType.HoldersRank, RankType.AddressesRank, RankType.TransactionCountRank -> numberFormatter.formatNumberShort(value, 0) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/tweets/CoinTweetsService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/tweets/CoinTweetsService.kt index f4586d52f96..8ae9da11f3c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/tweets/CoinTweetsService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/coin/tweets/CoinTweetsService.kt @@ -50,8 +50,7 @@ class CoinTweetsService( val marketInfoOverview = marketKit.marketInfoOverviewSingle( coinUid, "USD", - "en", - "market_tweets" + "en" ).await() val username = marketInfoOverview.links[LinkType.Twitter] if (username.isNullOrBlank()) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountAdvanced.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountAdvanced.kt index 1b758c71eb0..c5efeff8f64 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountAdvanced.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountAdvanced.kt @@ -26,6 +26,10 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.displayNameStringRes +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString import io.horizontalsystems.bankwallet.ui.compose.components.AppBar @@ -55,17 +59,19 @@ fun CreateAccountAdvancedScreen( val viewModel = viewModel(factory = CreateAccountModule.Factory()) val view = LocalView.current - LaunchedEffect(viewModel.successMessage) { - viewModel.successMessage?.let { + LaunchedEffect(viewModel.success) { + viewModel.success?.let { accountType -> HudHelper.showSuccessMessage( contenView = view, - resId = it, + resId = R.string.Hud_Text_Created, icon = R.drawable.icon_add_to_wallet_24, iconTint = R.color.white ) delay(300) onFinish.invoke() viewModel.onSuccessMessageShown() + + stat(page = StatPage.NewWalletAdvanced, event = StatEvent.CreateWallet(accountType.statAccountType)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountFragment.kt index c7acb27d4ee..590052c6520 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountFragment.kt @@ -28,6 +28,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.composablePage import io.horizontalsystems.bankwallet.core.getInput +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.modules.manageaccounts.ManageAccountsModule import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString @@ -89,11 +93,11 @@ private fun CreateAccountIntroScreen( val viewModel = viewModel(factory = CreateAccountModule.Factory()) val view = LocalView.current - LaunchedEffect(viewModel.successMessage) { - viewModel.successMessage?.let { + LaunchedEffect(viewModel.success) { + viewModel.success?.let { accountType -> HudHelper.showSuccessMessage( contenView = view, - resId = it, + resId = R.string.Hud_Text_Created, icon = R.drawable.icon_add_to_wallet_24, iconTint = R.color.white ) @@ -101,6 +105,8 @@ private fun CreateAccountIntroScreen( onFinish.invoke() viewModel.onSuccessMessageShown() + + stat(page = StatPage.NewWallet, event = StatEvent.CreateWallet(accountType.statAccountType)) } } @@ -138,6 +144,8 @@ private fun CreateAccountIntroScreen( .fillMaxSize() .clickable { openCreateAdvancedScreen.invoke() + + stat(page = StatPage.NewWallet, event = StatEvent.Open(StatPage.NewWalletAdvanced)) } .padding(horizontal = 16.dp), verticalAlignment = Alignment.CenterVertically, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountViewModel.kt index 2b8fd9c91ab..ac882e22aaf 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/createaccount/CreateAccountViewModel.kt @@ -53,7 +53,7 @@ class CreateAccountViewModel( var passphraseState by mutableStateOf(null) private set - var successMessage by mutableStateOf(null) + var success by mutableStateOf(null) private set fun createAccount() { @@ -73,7 +73,7 @@ class CreateAccountViewModel( accountManager.save(account) activateDefaultWallets(account) predefinedBlockchainSettingsProvider.prepareNew(account, BlockchainType.Zcash) - successMessage = R.string.Hud_Text_Created + success = accountType } fun onChangeAccountName(name: String) { @@ -111,7 +111,7 @@ class CreateAccountViewModel( } fun onSuccessMessageShown() { - successMessage = null + success = null } private fun passphraseIsInvalid(): Boolean { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/EvmNetworkFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/EvmNetworkFragment.kt index 6e8a7d37b6d..81d98be6770 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/EvmNetworkFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/EvmNetworkFragment.kt @@ -45,6 +45,9 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.composablePopup import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.requireInput +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.EvmSyncSource import io.horizontalsystems.bankwallet.modules.btcblockchainsettings.BlockchainSettingCell import io.horizontalsystems.bankwallet.modules.evmnetwork.addrpc.AddRpcScreen @@ -164,6 +167,8 @@ private fun EvmNetworkScreen( CellUniversalLawrenceSection(viewModel.viewState.defaultItems) { item -> BlockchainSettingCell(item.name, item.url, item.selected, null) { viewModel.onSelectSyncSource(item.syncSource) + + stat(page = StatPage.BlockchainSettingsEvm, event = StatEvent.SwitchEvmSource(blockchain.uid, item.name)) } } } @@ -174,6 +179,8 @@ private fun EvmNetworkScreen( revealedCardId, onClick = { syncSource -> viewModel.onSelectSyncSource(syncSource) + + stat(page = StatPage.BlockchainSettingsEvm, event = StatEvent.SwitchEvmSource(blockchain.uid, "custom")) }, onReveal = { id -> if (revealedCardId != id) { @@ -186,6 +193,8 @@ private fun EvmNetworkScreen( ) { viewModel.onRemoveCustomRpc(it) HudHelper.showErrorMessage(view, R.string.Hud_Removed) + + stat(page = StatPage.BlockchainSettingsEvm, event = StatEvent.DeleteCustomEvmSource(blockchain.uid)) } } @@ -193,6 +202,8 @@ private fun EvmNetworkScreen( Spacer(Modifier.height(32.dp)) AddButton { navController.navigate(AddRpcPage) + + stat(page = StatPage.BlockchainSettingsEvm, event = StatEvent.OpenBlockchainSettingsEvmAdd(blockchain.uid)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/addrpc/AddRpcViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/addrpc/AddRpcViewModel.kt index 22b89ee1ae7..5be0dbabfd8 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/addrpc/AddRpcViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/evmnetwork/addrpc/AddRpcViewModel.kt @@ -8,6 +8,9 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.Caution import io.horizontalsystems.bankwallet.core.managers.EvmSyncSourceManager import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.marketkit.models.Blockchain import java.net.MalformedURLException import java.net.URI @@ -64,6 +67,8 @@ class AddRpcViewModel( evmSyncSourceManager.saveSyncSource(blockchain.type, url, auth) viewState = AddRpcViewState(null, true) + + stat(page = StatPage.BlockchainSettingsEvmAdd, event = StatEvent.AddEvmSource(blockchain.uid)) } private fun syncState() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/importwallet/ImportWalletFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/importwallet/ImportWalletFragment.kt index f86257fbca3..5322ee2f2b4 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/importwallet/ImportWalletFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/importwallet/ImportWalletFragment.kt @@ -32,6 +32,9 @@ import io.horizontalsystems.bankwallet.core.Caution import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.navigateWithTermsAccepted import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.backuplocal.fullbackup.BackupFileValidator import io.horizontalsystems.bankwallet.modules.contacts.screen.ConfirmationBottomSheet import io.horizontalsystems.bankwallet.modules.manageaccounts.ManageAccountsModule @@ -91,9 +94,12 @@ private fun ImportWalletScreen( popUpToInclusiveId, inclusive, jsonString, - fileName + fileName, + StatPage.ImportWalletFromFiles ) ) + + stat(page = StatPage.ImportWallet, event = StatEvent.Open(StatPage.ImportWalletFromFiles)) } } } catch (e: Throwable) { @@ -153,7 +159,10 @@ private fun ImportWalletScreen( navController.navigateWithTermsAccepted { navController.slideFromBottom( R.id.restoreAccountFragment, - ManageAccountsModule.Input(popUpToInclusiveId, inclusive) ) + ManageAccountsModule.Input(popUpToInclusiveId, inclusive) + ) + + stat(page = StatPage.ImportWallet, event = StatEvent.Open(StatPage.ImportWalletFromKey)) } } ) @@ -174,7 +183,10 @@ private fun ImportWalletScreen( onClick = { navController.slideFromBottom( R.id.importCexAccountFragment, - ManageAccountsModule.Input(popUpToInclusiveId, inclusive) ) + ManageAccountsModule.Input(popUpToInclusiveId, inclusive) + ) + + stat(page = StatPage.ImportWallet, event = StatEvent.Open(StatPage.ImportWalletFromExchangeWallet)) } ) VSpacer(12.dp) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainFragment.kt index b0519780399..ad0ce5487d7 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainFragment.kt @@ -44,6 +44,11 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.managers.RateAppManager import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statTab import io.horizontalsystems.bankwallet.modules.balance.ui.BalanceScreen import io.horizontalsystems.bankwallet.modules.main.MainModule.MainNavigation import io.horizontalsystems.bankwallet.modules.manageaccount.dialogs.BackupRequiredDialog @@ -147,6 +152,8 @@ private fun MainScreen( coroutineScope.launch { modalBottomSheetState.hide() viewModel.onSelect(it) + + stat(page = StatPage.SwitchWallet, event = StatEvent.Select(StatEntity.Wallet)) } }, onCancelClick = { @@ -183,11 +190,17 @@ private fun MainScreen( enabled = item.enabled, selectedContentColor = ComposeAppTheme.colors.jacob, unselectedContentColor = if (item.enabled) ComposeAppTheme.colors.grey else ComposeAppTheme.colors.grey50, - onClick = { viewModel.onSelect(item.mainNavItem) }, + onClick = { + viewModel.onSelect(item.mainNavItem) + + stat(page = StatPage.Main, event = StatEvent.SwitchTab(item.mainNavItem.statTab)) + }, onLongClick = { if (item.mainNavItem == MainNavigation.Balance) { coroutineScope.launch { modalBottomSheetState.show() + + stat(page = StatPage.Main, event = StatEvent.Open(StatPage.SwitchWallet)) } } } @@ -263,6 +276,8 @@ private fun MainScreen( R.id.backupRequiredDialog, BackupRequiredDialog.Input(wcSupportState.account, text) ) + + stat(page = StatPage.Main, event = StatEvent.Open(StatPage.BackupRequired)) } is SupportState.NotSupported -> { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainViewModel.kt index f9d2a990938..3629ebc09ce 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/main/MainViewModel.kt @@ -17,6 +17,9 @@ import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.managers.ActiveAccountState import io.horizontalsystems.bankwallet.core.managers.ReleaseNotesManager import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.entities.LaunchPage @@ -302,7 +305,9 @@ class MainViewModel( when { deeplinkString.contains("coin-page") -> { uid?.let { - deeplinkPage = DeeplinkPage(R.id.coinFragment, CoinFragment.Input(it, "widget")) + deeplinkPage = DeeplinkPage(R.id.coinFragment, CoinFragment.Input(it)) + + stat(page = StatPage.Widget, event = StatEvent.OpenCoin(it)) } } @@ -310,6 +315,8 @@ class MainViewModel( val blockchainTypeUid = deepLink.getQueryParameter("blockchainTypeUid") if (uid != null && blockchainTypeUid != null) { deeplinkPage = DeeplinkPage(R.id.nftCollectionFragment, NftCollectionFragment.Input(uid, blockchainTypeUid)) + + stat(page = StatPage.Widget, event = StatEvent.Open(StatPage.TopNftCollections)) } } @@ -318,6 +325,8 @@ class MainViewModel( if (title != null && uid != null) { val platform = Platform(uid, title) deeplinkPage = DeeplinkPage(R.id.marketPlatformFragment, platform) + + stat(page = StatPage.Widget, event = StatEvent.Open(StatPage.TopPlatforms)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ManageAccountFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ManageAccountFragment.kt index 8d7a58b790d..99c3c281b68 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ManageAccountFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ManageAccountFragment.kt @@ -26,6 +26,10 @@ import io.horizontalsystems.bankwallet.core.managers.FaqManager import io.horizontalsystems.bankwallet.core.requireInput import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.modules.balance.HeaderNote import io.horizontalsystems.bankwallet.modules.balance.ui.NoteError @@ -101,6 +105,8 @@ fun ManageAccountScreen(navController: NavController, accountId: String) { hint = "", onValueChange = { viewModel.onChange(it) + + stat(page = StatPage.ManageWallet, event = StatEvent.Edit(StatEntity.WalletName)) } ) @@ -156,6 +162,8 @@ fun ManageAccountScreen(navController: NavController, accountId: String) { R.id.unlinkConfirmationDialog, viewModel.account ) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.UnlinkWallet)) } }) VSpacer(32.dp) @@ -187,6 +195,8 @@ private fun BackupActions( R.id.backupKeyFragment, account ) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.ManualBackup)) } } } @@ -201,6 +211,8 @@ private fun BackupActions( ) { navController.authorizedAction { navController.slideFromBottom(R.id.backupLocalFragment, account) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.FileBackup)) } } } @@ -243,6 +255,8 @@ private fun KeyActions( R.id.recoveryPhraseFragment, viewModel.account ) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.RecoveryPhrase)) } } } @@ -258,6 +272,8 @@ private fun KeyActions( R.id.privateKeysFragment, viewModel.account ) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.PrivateKeys)) } } } @@ -272,6 +288,8 @@ private fun KeyActions( R.id.publicKeysFragment, viewModel.account ) + + stat(page = StatPage.ManageWallet, event = StatEvent.Open(StatPage.PublicKeys)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/dialogs/BackupRequiredDialog.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/dialogs/BackupRequiredDialog.kt index d6bd25b7e9d..417a1172771 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/dialogs/BackupRequiredDialog.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/dialogs/BackupRequiredDialog.kt @@ -19,6 +19,9 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryDefaultWithIcon @@ -84,6 +87,8 @@ fun BackupRequiredScreen(navController: NavController, account: Account, text: S R.id.backupKeyFragment, account ) + + stat(page = StatPage.BackupRequired, event = StatEvent.Open(StatPage.ManualBackup)) } ) VSpacer(12.dp) @@ -96,6 +101,8 @@ fun BackupRequiredScreen(navController: NavController, account: Account, text: S iconTint = ComposeAppTheme.colors.claude, onClick = { navController.slideFromBottom(R.id.backupLocalFragment, account) + + stat(page = StatPage.BackupRequired, event = StatEvent.Open(StatPage.FileBackup)) } ) VSpacer(12.dp) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmaddress/EvmAddressFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmaddress/EvmAddressFragment.kt index 803fadca5b1..3ded7073fc9 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmaddress/EvmAddressFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmaddress/EvmAddressFragment.kt @@ -18,6 +18,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.managers.FaqManager +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ActionButton import io.horizontalsystems.bankwallet.modules.manageaccount.ui.HidableContent import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme @@ -57,6 +61,8 @@ private fun EvmAddressScreen(evmAddress: String, navController: NavController) { icon = R.drawable.ic_info_24, onClick = { FaqManager.showFaqPage(navController, FaqManager.faqPathPrivateKeys) + + stat(page = StatPage.EvmAddress, event = StatEvent.Open(StatPage.Info)) } ) ) @@ -74,6 +80,8 @@ private fun EvmAddressScreen(evmAddress: String, navController: NavController) { ActionButton(R.string.Alert_Copy) { TextHelper.copyText(evmAddress) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + stat(page = StatPage.EvmAddress, event = StatEvent.Copy(StatEntity.EvmAddress)) } } } \ No newline at end of file diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmprivatekey/EvmPrivateKeyFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmprivatekey/EvmPrivateKeyFragment.kt index ffe5f41e2dd..03eb160288b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmprivatekey/EvmPrivateKeyFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/evmprivatekey/EvmPrivateKeyFragment.kt @@ -1,10 +1,20 @@ package io.horizontalsystems.bankwallet.modules.manageaccount.evmprivatekey import android.os.Parcelable -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource @@ -14,12 +24,19 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.managers.FaqManager +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ActionButton import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ConfirmCopyBottomSheet import io.horizontalsystems.bankwallet.modules.manageaccount.ui.HidableContent import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantWarning import io.horizontalsystems.bankwallet.ui.helpers.TextHelper import io.horizontalsystems.core.helpers.HudHelper import kotlinx.coroutines.launch @@ -62,6 +79,8 @@ private fun EvmPrivateKeyScreen( TextHelper.copyText(evmPrivateKey) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) sheetState.hide() + + stat(page = StatPage.EvmPrivateKey, event = StatEvent.Copy(StatEntity.EvmPrivateKey)) } }, onCancel = { @@ -84,6 +103,8 @@ private fun EvmPrivateKeyScreen( icon = R.drawable.ic_info_24, onClick = { FaqManager.showFaqPage(navController, FaqManager.faqPathPrivateKeys) + + stat(page = StatPage.EvmPrivateKey, event = StatEvent.Open(StatPage.Info)) } ) ) @@ -101,7 +122,9 @@ private fun EvmPrivateKeyScreen( text = stringResource(R.string.PrivateKeys_NeverShareWarning) ) Spacer(Modifier.height(24.dp)) - HidableContent(evmPrivateKey, stringResource(R.string.EvmPrivateKey_ShowPrivateKey)) + HidableContent(evmPrivateKey, stringResource(R.string.EvmPrivateKey_ShowPrivateKey)) { + stat(page = StatPage.EvmPrivateKey, event = StatEvent.ToggleHidden) + } } ActionButton(R.string.Alert_Copy) { coroutineScope.launch { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/privatekeys/PrivateKeysFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/privatekeys/PrivateKeysFragment.kt index ddaa8bc8f27..c735d5c23a1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/privatekeys/PrivateKeysFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/privatekeys/PrivateKeysFragment.kt @@ -20,6 +20,9 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.authorizedAction import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.modules.manageaccount.evmprivatekey.EvmPrivateKeyFragment import io.horizontalsystems.bankwallet.modules.manageaccount.showextendedkey.ShowExtendedKeyFragment @@ -74,6 +77,8 @@ fun ManageAccountScreen(navController: NavController, account: Account) { R.id.evmPrivateKeyFragment, EvmPrivateKeyFragment.Input(key) ) + + stat(page = StatPage.PrivateKeys, event = StatEvent.Open(StatPage.EvmPrivateKey)) } } } @@ -90,6 +95,8 @@ fun ManageAccountScreen(navController: NavController, account: Account) { key.displayKeyType ) ) + + stat(page = StatPage.PrivateKeys, event = StatEvent.Open(StatPage.Bip32RootKey)) } } } @@ -103,6 +110,8 @@ fun ManageAccountScreen(navController: NavController, account: Account) { R.id.showExtendedKeyFragment, ShowExtendedKeyFragment.Input(key.hdKey, key.displayKeyType) ) + + stat(page = StatPage.PrivateKeys, event = StatEvent.Open(StatPage.AccountExtendedPrivateKey)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/publickeys/PublicKeysFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/publickeys/PublicKeysFragment.kt index 138e2c8d023..61b60ad3adb 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/publickeys/PublicKeysFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/publickeys/PublicKeysFragment.kt @@ -19,6 +19,9 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.modules.manageaccount.evmaddress.EvmAddressFragment import io.horizontalsystems.bankwallet.modules.manageaccount.showextendedkey.ShowExtendedKeyFragment @@ -73,6 +76,8 @@ fun ManageAccountScreen(navController: NavController, account: Account) { R.id.evmAddressFragment, EvmAddressFragment.Input(evmAddress) ) + + stat(page = StatPage.PublicKeys, event = StatEvent.Open(StatPage.EvmAddress)) } } viewModel.viewState.extendedPublicKey?.let { publicKey -> @@ -87,6 +92,8 @@ fun ManageAccountScreen(navController: NavController, account: Account) { publicKey.accountPublicKey ) ) + + stat(page = StatPage.PublicKeys, event = StatEvent.Open(StatPage.AccountExtendedPublicKey)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/recoveryphrase/RecoveryPhraseFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/recoveryphrase/RecoveryPhraseFragment.kt index 3285b4f5ae1..fb771291495 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/recoveryphrase/RecoveryPhraseFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/recoveryphrase/RecoveryPhraseFragment.kt @@ -1,9 +1,23 @@ package io.horizontalsystems.bankwallet.modules.manageaccount.recoveryphrase -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* -import androidx.compose.material.* -import androidx.compose.runtime.* +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.rememberScrollState +import androidx.compose.foundation.verticalScroll +import androidx.compose.material.ExperimentalMaterialApi +import androidx.compose.material.ModalBottomSheetLayout +import androidx.compose.material.ModalBottomSheetValue +import androidx.compose.material.rememberModalBottomSheetState +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope +import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalView import androidx.compose.ui.res.stringResource @@ -14,6 +28,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.managers.FaqManager import io.horizontalsystems.bankwallet.core.requireInput +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ActionButton import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ConfirmCopyBottomSheet @@ -21,7 +39,10 @@ import io.horizontalsystems.bankwallet.modules.manageaccount.ui.PassphraseCell import io.horizontalsystems.bankwallet.modules.manageaccount.ui.SeedPhraseList import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantWarning import io.horizontalsystems.bankwallet.ui.helpers.TextHelper import io.horizontalsystems.core.helpers.HudHelper import kotlinx.coroutines.launch @@ -62,6 +83,8 @@ private fun RecoveryPhraseScreen( TextHelper.copyText(viewModel.words.joinToString(" ")) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) sheetState.hide() + + stat(page = StatPage.RecoveryPhrase, event = StatEvent.Copy(StatEntity.RecoveryPhrase)) } }, onCancel = { @@ -84,6 +107,8 @@ private fun RecoveryPhraseScreen( icon = R.drawable.ic_info_24, onClick = { FaqManager.showFaqPage(navController, FaqManager.faqPathPrivateKeys) + + stat(page = StatPage.RecoveryPhrase, event = StatEvent.Open(StatPage.Info)) } ) ) @@ -104,6 +129,8 @@ private fun RecoveryPhraseScreen( var hidden by remember { mutableStateOf(true) } SeedPhraseList(viewModel.wordsNumbered, hidden) { hidden = !hidden + + stat(page = StatPage.RecoveryPhrase, event = StatEvent.ToggleHidden) } Spacer(Modifier.height(24.dp)) PassphraseCell(viewModel.passphrase, hidden) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyFragment.kt index 4ac557fcbc1..230276f805d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyFragment.kt @@ -37,6 +37,9 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.managers.FaqManager import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.modules.manageaccount.showextendedkey.ShowExtendedKeyModule.DisplayKeyType import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ActionButton import io.horizontalsystems.bankwallet.modules.manageaccount.ui.ConfirmCopyBottomSheet @@ -118,6 +121,8 @@ private fun ShowExtendedKeyScreen( TextHelper.copyText(viewModel.extendedKey) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) sheetState.hide() + + viewModel.logEvent(StatEvent.Copy(StatEntity.Key)) } }, onCancel = { @@ -140,6 +145,8 @@ private fun ShowExtendedKeyScreen( icon = R.drawable.ic_info_24, onClick = { FaqManager.showFaqPage(navController, FaqManager.faqPathPrivateKeys) + + viewModel.logEvent(StatEvent.Open(StatPage.Info)) } ) ) @@ -204,7 +211,9 @@ private fun ShowExtendedKeyScreen( Spacer(Modifier.height(32.dp)) if (viewModel.displayKeyType.isPrivate) { - HidableContent(viewModel.extendedKey, stringResource(R.string.ExtendedKey_TapToShowPrivateKey)) + HidableContent(viewModel.extendedKey, stringResource(R.string.ExtendedKey_TapToShowPrivateKey)) { + viewModel.logEvent(StatEvent.ToggleHidden) + } } else { HidableContent(viewModel.extendedKey) } @@ -260,6 +269,8 @@ private fun ShowExtendedKeyScreen( } else { TextHelper.copyText(viewModel.extendedKey) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + viewModel.logEvent(StatEvent.Copy(StatEntity.Key)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyViewModel.kt index 4de19d7ad2f..1e85c1bc16d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/showextendedkey/ShowExtendedKeyViewModel.kt @@ -5,6 +5,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import io.horizontalsystems.bankwallet.R +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.manageaccount.showextendedkey.ShowExtendedKeyModule.DisplayKeyType import io.horizontalsystems.bankwallet.ui.compose.TranslatableString import io.horizontalsystems.bitcoincash.MainNetBitcoinCash @@ -51,20 +55,36 @@ class ShowExtendedKeyViewModel( return if (displayKeyType.isPrivate) key.serializePrivate(version.value) else key.serializePublic(version.value) } + private val statPage = when (displayKeyType) { + is DisplayKeyType.AccountPrivateKey -> StatPage.AccountExtendedPrivateKey + is DisplayKeyType.AccountPublicKey -> StatPage.AccountExtendedPublicKey + DisplayKeyType.Bip32RootKey -> StatPage.Bip32RootKey + } + fun set(purpose: HDWallet.Purpose) { this.purpose = purpose if (purpose != HDWallet.Purpose.BIP44 && (blockchain != Blockchain.Bitcoin && blockchain != Blockchain.Litecoin)) { blockchain = Blockchain.Bitcoin } + + logEvent(StatEvent.Select(StatEntity.Derivation)) } fun set(blockchain: Blockchain) { this.blockchain = blockchain + + logEvent(StatEvent.Select(StatEntity.Blockchain)) } fun set(account: Int) { this.account = account + + logEvent(StatEvent.Select(StatEntity.Account)) + } + + fun logEvent(event: StatEvent) { + stat(page = statPage, event = event) } private val Blockchain.extendedKeyCoinType: ExtendedKeyCoinType @@ -76,7 +96,7 @@ class ShowExtendedKeyViewModel( } private val ExtendedKeyCoinType.blockchain: Blockchain - get() = when(this) { + get() = when (this) { ExtendedKeyCoinType.Bitcoin -> Blockchain.Bitcoin ExtendedKeyCoinType.Litecoin -> Blockchain.Litecoin } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ui/SharedComponents.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ui/SharedComponents.kt index da5de799a5a..852b39c50ef 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ui/SharedComponents.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccount/ui/SharedComponents.kt @@ -68,6 +68,7 @@ fun ActionButton(title: Int, onClick: () -> Unit) { fun HidableContent( content: String, hideScreenText: String? = null, + onToggleHidden: (() -> Unit)? = null ) { var hidden by remember { mutableStateOf(hideScreenText != null) } Box( @@ -76,7 +77,10 @@ fun HidableContent( .padding(horizontal = 16.dp) .clip(RoundedCornerShape(24.dp)) .border(1.dp, ComposeAppTheme.colors.steel20, RoundedCornerShape(24.dp)) - .clickable(enabled = hideScreenText != null, onClick = { hidden = !hidden }) + .clickable(enabled = hideScreenText != null, onClick = { + hidden = !hidden + onToggleHidden?.invoke() + }) ) { D2( diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccounts/ManageAccountsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccounts/ManageAccountsFragment.kt index 1d7948b0b5d..4e7ca12e03a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccounts/ManageAccountsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/manageaccounts/ManageAccountsFragment.kt @@ -21,6 +21,10 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.navigateWithTermsAccepted import io.horizontalsystems.bankwallet.core.requireInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.backupalert.BackupAlert import io.horizontalsystems.bankwallet.modules.manageaccount.ManageAccountFragment import io.horizontalsystems.bankwallet.modules.manageaccounts.ManageAccountsModule.AccountViewItem @@ -91,13 +95,19 @@ fun ManageAccountsScreen(navController: NavController, mode: ManageAccountsModul ActionViewItem(R.drawable.ic_plus, R.string.ManageAccounts_CreateNewWallet) { navController.navigateWithTermsAccepted { navController.slideFromRight(R.id.createAccountFragment, args) + + stat(page = StatPage.ManageWallets, event = StatEvent.Open(StatPage.NewWallet)) } }, ActionViewItem(R.drawable.ic_download_20, R.string.ManageAccounts_ImportWallet) { navController.slideFromRight(R.id.importWalletFragment, args) + + stat(page = StatPage.ManageWallets, event = StatEvent.Open(StatPage.ImportWallet)) }, ActionViewItem(R.drawable.icon_binocule_20, R.string.ManageAccounts_WatchAddress) { navController.slideFromRight(R.id.watchAddressFragment, args) + + stat(page = StatPage.ManageWallets, event = StatEvent.Open(StatPage.WatchWallet)) } ) CellUniversalLawrenceSection(actions) { @@ -124,7 +134,11 @@ fun ManageAccountsScreen(navController: NavController, mode: ManageAccountsModul private fun AccountsSection(accounts: List, viewModel: ManageAccountsViewModel, navController: NavController) { CellUniversalLawrenceSection(items = accounts) { accountViewItem -> RowUniversal( - onClick = { viewModel.onSelect(accountViewItem) } + onClick = { + viewModel.onSelect(accountViewItem) + + stat(page = StatPage.ManageWallets, event = StatEvent.Select(StatEntity.Wallet)) + } ) { if (accountViewItem.selected) { Icon( @@ -182,6 +196,8 @@ private fun AccountsSection(accounts: List, viewModel: ManageAc R.id.manageAccountFragment, ManageAccountFragment.Input(accountViewItem.accountId) ) + + stat(page = StatPage.ManageWallets, event = StatEvent.Open(StatPage.ManageWallet)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/managewallets/ManageWalletsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/managewallets/ManageWalletsFragment.kt index dca2f5737ae..1cd4daa166b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/managewallets/ManageWalletsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/managewallets/ManageWalletsFragment.kt @@ -3,7 +3,14 @@ package io.horizontalsystems.bankwallet.modules.managewallets import androidx.compose.animation.ExperimentalAnimationApi import androidx.compose.foundation.Image import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.items import androidx.compose.foundation.shape.RoundedCornerShape @@ -26,12 +33,23 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromBottomForResult import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.enablecoin.restoresettings.RestoreSettingsViewModel import io.horizontalsystems.bankwallet.modules.restoreaccount.restoreblockchains.CoinViewItem import io.horizontalsystems.bankwallet.modules.zcashconfigure.ZcashConfigure import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.HsIconButton +import io.horizontalsystems.bankwallet.ui.compose.components.HsSwitch +import io.horizontalsystems.bankwallet.ui.compose.components.ListEmptyView +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.RowUniversal +import io.horizontalsystems.bankwallet.ui.compose.components.SearchBar +import io.horizontalsystems.bankwallet.ui.compose.components.VSpacer +import io.horizontalsystems.bankwallet.ui.compose.components.body_leah +import io.horizontalsystems.bankwallet.ui.compose.components.subhead2_grey import io.horizontalsystems.marketkit.models.Token class ManageWalletsFragment : BaseComposeFragment() { @@ -70,6 +88,8 @@ private fun ManageWalletsScreen( restoreSettingsViewModel.onCancelEnterBirthdayHeight() } } + + stat(page = StatPage.CoinManager, event = StatEvent.Open(StatPage.BirthdayInput)) } Column( @@ -85,6 +105,8 @@ private fun ManageWalletsScreen( icon = R.drawable.ic_add_yellow, onClick = { navController.slideFromRight(R.id.addTokenFragment) + + stat(page = StatPage.CoinManager, event = StatEvent.Open(StatPage.AddToken)) } )) } else { @@ -117,12 +139,18 @@ private fun ManageWalletsScreen( onItemClick = { if (viewItem.enabled) { viewModel.disable(viewItem.item) + + stat(page = StatPage.CoinManager, event = StatEvent.DisableToken(viewItem.item)) } else { viewModel.enable(viewItem.item) + + stat(page = StatPage.CoinManager, event = StatEvent.EnableToken(viewItem.item)) } }, onInfoClick = { navController.slideFromBottom(R.id.configuredTokenInfo, viewItem.item) + + stat(page = StatPage.CoinManager, event = StatEvent.OpenTokenInfo(viewItem.item)) } ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketScreen.kt index 428d4984d83..2326678e45c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/MarketScreen.kt @@ -13,6 +13,10 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statTab import io.horizontalsystems.bankwallet.modules.market.favorites.MarketFavoritesScreen import io.horizontalsystems.bankwallet.modules.market.overview.MarketOverviewScreen import io.horizontalsystems.bankwallet.modules.market.posts.MarketPostsScreen @@ -41,6 +45,8 @@ fun MarketScreen(navController: NavController) { icon = R.drawable.icon_search, onClick = { navController.slideFromRight(R.id.marketSearchFragment) + + stat(page = StatPage.Markets, event = StatEvent.Open(StatPage.MarketSearch)) } ), MenuItem( @@ -48,6 +54,8 @@ fun MarketScreen(navController: NavController) { icon = R.drawable.ic_manage_2_24, onClick = { navController.slideFromRight(R.id.marketAdvancedSearchFragment) + + stat(page = StatPage.Markets, event = StatEvent.Open(StatPage.AdvancedSearch)) } ), ) @@ -61,6 +69,8 @@ fun MarketScreen(navController: NavController) { } Tabs(tabItems, onClick = { marketViewModel.onSelect(it) + + stat(page = StatPage.Markets, event = StatEvent.SwitchTab(it.statTab)) }) HorizontalPager( diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/CoinCategoryMarketDataChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/CoinCategoryMarketDataChartService.kt index bd065d84b26..1b8a08b9103 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/CoinCategoryMarketDataChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/CoinCategoryMarketDataChartService.kt @@ -2,6 +2,10 @@ package io.horizontalsystems.bankwallet.modules.market.category import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartPointsWrapper @@ -33,4 +37,9 @@ class CoinCategoryMarketDataChartService( Single.error(e) } + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(page = StatPage.CoinCategory, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryFragment.kt index a58b64be563..2ea1728baa3 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryFragment.kt @@ -21,6 +21,9 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.requireInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.chart.ChartViewModel import io.horizontalsystems.bankwallet.modules.coin.CoinFragment @@ -55,9 +58,11 @@ class MarketCategoryFragment : BaseComposeFragment() { } private fun onCoinClick(coinUid: String, navController: NavController) { - val arguments = CoinFragment.Input(coinUid, "market_category") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.CoinCategory, event = StatEvent.OpenCoin(coinUid)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryRepository.kt index c88bb6cb79d..5d618a6971e 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryRepository.kt @@ -21,7 +21,7 @@ class MarketCategoryRepository( @Synchronized private fun getMarketItems(coinCategoryUid: String, forceRefresh: Boolean, baseCurrency: Currency): List = if (forceRefresh && (cacheTimestamp + cacheValidPeriodInMillis < System.currentTimeMillis()) || cache.isEmpty()) { - val marketInfoList = marketKit.marketInfosSingle(coinCategoryUid, baseCurrency.code, "market_category").blockingGet() + val marketInfoList = marketKit.marketInfosSingle(coinCategoryUid, baseCurrency.code).blockingGet() val marketItems = marketInfoList.map { marketInfo -> MarketItem.createFromCoinMarket(marketInfo, baseCurrency) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryViewModel.kt index 4d4c551f7f9..5ddbd00e9d7 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/category/MarketCategoryViewModel.kt @@ -3,6 +3,11 @@ package io.horizontalsystems.bankwallet.modules.market.category import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statField +import io.horizontalsystems.bankwallet.core.stats.statSortType import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.market.ImageSource @@ -95,6 +100,8 @@ class MarketCategoryViewModel( fun onSelectSortingField(sortingField: SortingField) { service.setSortingField(sortingField) selectorDialogStateLiveData.postValue(SelectorDialogState.Closed) + + stat(page = StatPage.CoinCategory, event = StatEvent.SwitchSortType(sortingField.statSortType)) } fun onSelectMarketField(marketField: MarketField) { @@ -102,6 +109,8 @@ class MarketCategoryViewModel( syncMarketViewItems() syncMenu() + + stat(page = StatPage.CoinCategory, event = StatEvent.SwitchField(marketField.statField)) } fun onSelectorDialogDismiss() { @@ -128,9 +137,13 @@ class MarketCategoryViewModel( fun onAddFavorite(uid: String) { service.addFavorite(uid) + + stat(page = StatPage.CoinCategory, event = StatEvent.AddToWatchlist(uid)) } fun onRemoveFavorite(uid: String) { service.removeFavorite(uid) + + stat(page = StatPage.CoinCategory, event = StatEvent.RemoveFromWatchlist(uid)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt index 9e74c6bafaa..5974ee1034a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesRepository.kt @@ -24,7 +24,7 @@ class MarketFavoritesRepository( val favoriteCoinUids = favoriteCoins.map { it.coinUid } return marketKit - .marketInfosSingle(favoriteCoinUids, currency.code, "watchlist").await() + .marketInfosSingle(favoriteCoinUids, currency.code).await() .map { marketInfo -> MarketItem.createFromCoinMarket( marketInfo = marketInfo, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt index f4732578b12..c6d56f691ac 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/favorites/MarketFavoritesScreen.kt @@ -18,6 +18,10 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading @@ -47,6 +51,8 @@ fun MarketFavoritesScreen( refreshing = isRefreshing, onRefresh = { viewModel.refresh() + + stat(page = StatPage.Watchlist, event = StatEvent.Refresh) } ) { Crossfade( @@ -75,18 +81,32 @@ fun MarketFavoritesScreen( items = data.marketItems, scrollToTop = scrollToTopAfterUpdate, onAddFavorite = { /*not used */ }, - onRemoveFavorite = { uid -> viewModel.removeFromFavorites(uid) }, + onRemoveFavorite = { uid -> + viewModel.removeFromFavorites(uid) + + stat(page = StatPage.Watchlist, event = StatEvent.RemoveFromWatchlist(uid)) + }, onCoinClick = { coinUid -> - val arguments = CoinFragment.Input(coinUid, "market_watchlist") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.Watchlist, event = StatEvent.OpenCoin(coinUid)) }, preItems = { stickyHeader { MarketFavoritesMenu( sortDescending = data.sortingDescending, periodSelect = data.periodSelect, - onSortingToggle = viewModel::onSortToggle, - onSelectPeriod = viewModel::onSelectTimeDuration + onSortingToggle = { + viewModel.onSortToggle() + + stat(page = StatPage.Watchlist, event = StatEvent.ToggleSortDirection) + }, + onSelectPeriod = { + viewModel.onSelectTimeDuration(it) + + stat(page = StatPage.Watchlist, event = StatEvent.SwitchPeriod(it.statPeriod)) + } ) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultViewModel.kt index 91a6f7d1153..5b6693f2048 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultViewModel.kt @@ -5,6 +5,10 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statField import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.market.MarketField @@ -74,6 +78,8 @@ class MarketFiltersResultViewModel( syncMarketViewItems() syncMenu() + + stat(page = StatPage.AdvancedSearchResults, event = StatEvent.SwitchField(marketField.statField)) } fun onAddFavorite(uid: String) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultsFragment.kt index 24f051d308d..eef60895c35 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/filtersresult/MarketFiltersResultsFragment.kt @@ -2,7 +2,12 @@ package io.horizontalsystems.bankwallet.modules.market.filtersresult import androidx.compose.animation.Crossfade import androidx.compose.foundation.ExperimentalFoundationApi -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding import androidx.compose.material.Surface import androidx.compose.runtime.Composable import androidx.compose.runtime.getValue @@ -19,13 +24,23 @@ import androidx.navigation.navGraphViewModels import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.market.filters.MarketFiltersViewModel import io.horizontalsystems.bankwallet.modules.market.topcoins.SelectorDialogState import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AlertGroup +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryToggle +import io.horizontalsystems.bankwallet.ui.compose.components.CoinList +import io.horizontalsystems.bankwallet.ui.compose.components.HeaderSorting +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.ListErrorView +import io.horizontalsystems.bankwallet.ui.compose.components.SortMenu class MarketFiltersResultsFragment : BaseComposeFragment() { @@ -89,13 +104,19 @@ private fun SearchResultsScreen( scrollToTop = scrollToTopAfterUpdate, onAddFavorite = { uid -> viewModel.onAddFavorite(uid) + + stat(page = StatPage.AdvancedSearchResults, event = StatEvent.AddToWatchlist(uid)) }, onRemoveFavorite = { uid -> viewModel.onRemoveFavorite(uid) + + stat(page = StatPage.AdvancedSearchResults, event = StatEvent.RemoveFromWatchlist(uid)) }, onCoinClick = { coinUid -> - val arguments = CoinFragment.Input(coinUid, "market_advanced_search_results") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.AdvancedSearchResults, event = StatEvent.OpenCoin(coinUid)) }, preItems = { stickyHeader { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageChartService.kt index e4de72497ab..ee9b259d93d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageChartService.kt @@ -1,6 +1,10 @@ package io.horizontalsystems.bankwallet.modules.market.metricspage import io.horizontalsystems.bankwallet.core.managers.CurrencyManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPage +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartPointsWrapper @@ -42,4 +46,10 @@ class MetricsPageChartService( ChartPointsWrapper(it) } } + + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(page = metricsType.statPage, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageFragment.kt index d0073cd4154..fb43cb30503 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageFragment.kt @@ -3,7 +3,11 @@ package io.horizontalsystems.bankwallet.modules.market.metricspage import androidx.compose.animation.Crossfade import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyListState import androidx.compose.foundation.lazy.items @@ -17,32 +21,50 @@ import androidx.compose.ui.unit.dp import androidx.fragment.app.viewModels import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R -import io.horizontalsystems.bankwallet.core.* +import io.horizontalsystems.bankwallet.core.BaseComposeFragment +import io.horizontalsystems.bankwallet.core.iconPlaceholder +import io.horizontalsystems.bankwallet.core.imageUrl +import io.horizontalsystems.bankwallet.core.requireInput +import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPage import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.chart.ChartViewModel import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Chart import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.market.MarketField +import io.horizontalsystems.bankwallet.modules.metricchart.MetricsType import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.HSSwipeRefresh import io.horizontalsystems.bankwallet.ui.compose.TranslatableString -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryToggle +import io.horizontalsystems.bankwallet.ui.compose.components.DescriptionCard +import io.horizontalsystems.bankwallet.ui.compose.components.HeaderSorting +import io.horizontalsystems.bankwallet.ui.compose.components.ListErrorView +import io.horizontalsystems.bankwallet.ui.compose.components.MarketCoinClear +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem class MetricsPageFragment : BaseComposeFragment() { @Composable override fun GetContent(navController: NavController) { - val factory = MetricsPageModule.Factory(navController.requireInput()) + val metricsType = navController.requireInput() + val factory = MetricsPageModule.Factory(metricsType) val chartViewModel by viewModels { factory } val viewModel by viewModels { factory } MetricsPage(viewModel, chartViewModel, navController) { onCoinClick(it, navController) + + stat(page = metricsType.statPage, event = StatEvent.OpenCoin(it)) } } private fun onCoinClick(coinUid: String, navController: NavController) { - val arguments = CoinFragment.Input(coinUid, "market_metrics") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageModule.kt index 6400147f7ee..710b616e57b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageModule.kt @@ -18,7 +18,7 @@ object MetricsPageModule { @Suppress("UNCHECKED_CAST") class Factory(private val metricsType: MetricsType) : ViewModelProvider.Factory { private val globalMarketRepository by lazy { - GlobalMarketRepository(App.marketKit, "market_global_metrics_${metricsType.name}") + GlobalMarketRepository(App.marketKit) } override fun create(modelClass: Class): T { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageViewModel.kt index a9e7b2b33be..1332d3ddbff 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/metricspage/MetricsPageViewModel.kt @@ -4,6 +4,11 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statField +import io.horizontalsystems.bankwallet.core.stats.statPage import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.market.MarketField import io.horizontalsystems.bankwallet.modules.market.MarketItem @@ -22,6 +27,8 @@ class MetricsPageViewModel( private val marketFields = MarketField.values().toList() private var marketField: MarketField private var marketItems: List = listOf() + private val metricsType: MetricsType = service.metricsType + private val statPage: StatPage = metricsType.statPage val isRefreshingLiveData = MutableLiveData() val marketLiveData = MutableLiveData() @@ -32,9 +39,6 @@ class MetricsPageViewModel( icon = metricsType.headerIcon ) - val metricsType: MetricsType - get() = service.metricsType - init { marketField = when (metricsType) { MetricsType.Volume24h -> MarketField.Volume @@ -81,15 +85,21 @@ class MetricsPageViewModel( fun onToggleSortType() { service.sortDescending = !service.sortDescending + + stat(page = statPage, event = StatEvent.ToggleSortDirection) } fun onSelectMarketField(marketField: MarketField) { this.marketField = marketField syncMarketItems(marketItems) + + stat(page = statPage, event = StatEvent.SwitchField(marketField.statField)) } fun refresh() { refreshWithMinLoadingSpinnerPeriod() + + stat(page = statPage, event = StatEvent.Refresh) } fun onErrorClick() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/MarketOverviewScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/MarketOverviewScreen.kt index 11118fc6c74..04e12684b68 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/MarketOverviewScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/MarketOverviewScreen.kt @@ -17,6 +17,13 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.StatSection +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statMarketTop +import io.horizontalsystems.bankwallet.core.stats.statPeriod +import io.horizontalsystems.bankwallet.core.stats.statSection import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.market.overview.ui.BoardsView @@ -46,6 +53,8 @@ fun MarketOverviewScreen( refreshing = isRefreshing, onRefresh = { viewModel.refresh() + + stat(page = StatPage.MarketOverview, event = StatEvent.Refresh) } ) { Crossfade(viewState, label = "") { viewState -> @@ -80,9 +89,13 @@ fun MarketOverviewScreen( marketField ) ) + + stat(page = StatPage.MarketOverview, section = listType.statSection, event = StatEvent.Open(StatPage.TopCoins)) }, onSelectTopMarket = { topMarket, listType -> viewModel.onSelectTopMarket(topMarket, listType) + + stat(page = StatPage.MarketOverview, section = listType.statSection, event = StatEvent.SwitchMarketTop(topMarket.statMarketTop)) } ) @@ -91,19 +104,27 @@ fun MarketOverviewScreen( onItemClick = { it.tradeUrl?.let { LinkHelper.openLinkInAppBrowser(context, it) + + stat(page = StatPage.MarketOverview, event = StatEvent.Open(StatPage.ExternalMarketPair)) } } ) { navController.slideFromBottom(R.id.topPairsFragment) + + stat(page = StatPage.MarketOverview, event = StatEvent.Open(StatPage.TopMarketPairs)) } TopPlatformsBoardView( viewItem.topPlatformsBoard, onSelectTimeDuration = { timeDuration -> viewModel.onSelectTopPlatformsTimeDuration(timeDuration) + + stat(page = StatPage.MarketOverview, section = StatSection.TopPlatforms, event = StatEvent.SwitchPeriod(timeDuration.statPeriod)) }, onItemClick = { navController.slideFromRight(R.id.marketPlatformFragment, it) + + stat(page = StatPage.MarketOverview, event = StatEvent.OpenPlatform(it.uid)) }, onClickSeeAll = { val timeDuration = viewModel.topPlatformsTimeDuration @@ -112,6 +133,8 @@ fun MarketOverviewScreen( R.id.marketTopPlatformsFragment, timeDuration ) + + stat(page = StatPage.MarketOverview, event = StatEvent.Open(StatPage.TopPlatforms)) } ) @@ -122,6 +145,8 @@ fun MarketOverviewScreen( R.id.marketCategoryFragment, coinCategory ) + + stat(page = StatPage.MarketOverview, event = StatEvent.OpenCategory(coinCategory.uid)) } VSpacer(height = 32.dp) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewBoards.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewBoards.kt index 17d7f2ae466..e221e72874c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewBoards.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewBoards.kt @@ -19,6 +19,10 @@ import androidx.compose.ui.unit.dp import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statSection import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.market.MarketModule import io.horizontalsystems.bankwallet.modules.market.MarketViewItem @@ -41,7 +45,7 @@ fun BoardsView( { navController.slideFromRight( R.id.coinFragment, - CoinFragment.Input(it.coinUid, "market_overview") + CoinFragment.Input(it.coinUid) ) } } @@ -63,7 +67,11 @@ fun BoardsView( .background(ComposeAppTheme.colors.lawrence) ){ boardItem.marketViewItems.forEach { coin -> - MarketCoinWithBackground(coin) { onItemClick.invoke(coin) } + MarketCoinWithBackground(coin) { + onItemClick.invoke(coin) + + stat(page = StatPage.MarketOverview, section = boardItem.type.statSection, event = StatEvent.OpenCoin(coin.coinUid)) + } } SeeAllButton { onClickSeeAll(boardItem.type) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewMetrics.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewMetrics.kt index 8a44e5561fe..2de0b60873d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewMetrics.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/overview/ui/MarketOverviewMetrics.kt @@ -23,6 +23,10 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPage import io.horizontalsystems.bankwallet.modules.market.overview.MarketOverviewModule import io.horizontalsystems.bankwallet.modules.metricchart.MetricsType import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme @@ -115,4 +119,6 @@ private fun openMetricsPage(metricsType: MetricsType, navController: NavControll } else { navController.slideFromBottom(R.id.metricsPageFragment, metricsType) } + + stat(page = StatPage.MarketOverview, event = StatEvent.Open(metricsType.statPage)) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformCoinsRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformCoinsRepository.kt index 6deae8a3c5c..22f34c94fee 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformCoinsRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformCoinsRepository.kt @@ -26,7 +26,7 @@ class MarketPlatformCoinsRepository( val items = if (forceRefresh || currentCache == null) { val marketInfoItems = marketKit - .topPlatformCoinListSingle(platform.uid, currencyManager.baseCurrency.code, "market_top_platform") + .topPlatformCoinListSingle(platform.uid, currencyManager.baseCurrency.code) .await() marketInfoItems.map { marketInfo -> diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformFragment.kt index 1a1866b0aa3..f153cd006d7 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/MarketPlatformFragment.kt @@ -29,6 +29,11 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statField +import io.horizontalsystems.bankwallet.core.stats.statSortType import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.chart.ChartViewModel import io.horizontalsystems.bankwallet.modules.coin.CoinFragment @@ -67,8 +72,10 @@ class MarketPlatformFragment : BaseComposeFragment() { factory = factory, onCloseButtonClick = { navController.popBackStack() }, onCoinClick = { coinUid -> - val arguments = CoinFragment.Input(coinUid, "market_platform") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.TopPlatform, event = StatEvent.OpenCoin(coinUid)) } ) } @@ -94,6 +101,8 @@ private fun PlatformScreen( refreshing = viewModel.isRefreshing, onRefresh = { viewModel.refresh() + + stat(page = StatPage.TopPlatform, event = StatEvent.Refresh) } ) { Crossfade(viewModel.viewState) { state -> @@ -116,9 +125,13 @@ private fun PlatformScreen( scrollToTop = scrollToTopAfterUpdate, onAddFavorite = { uid -> viewModel.onAddFavorite(uid) + + stat(page = StatPage.TopPlatform, event = StatEvent.AddToWatchlist(uid)) }, onRemoveFavorite = { uid -> viewModel.onRemoveFavorite(uid) + + stat(page = StatPage.TopPlatform, event = StatEvent.RemoveFromWatchlist(uid)) }, onCoinClick = onCoinClick, preItems = { @@ -146,7 +159,11 @@ private fun PlatformScreen( ) { ButtonSecondaryToggle( select = viewModel.menu.marketFieldSelect, - onSelect = viewModel::onSelectMarketField + onSelect = { + viewModel.onSelectMarketField(it) + + stat(page = StatPage.TopPlatform, event = StatEvent.SwitchField(it.statField)) + } ) } } @@ -171,6 +188,8 @@ private fun PlatformScreen( { selected -> viewModel.onSelectSortingField(selected) scrollToTopAfterUpdate = true + + stat(page = StatPage.TopPlatform, event = StatEvent.SwitchSortType(selected.statSortType)) }, { viewModel.onSelectorDialogDismiss() } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/PlatformChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/PlatformChartService.kt index 730b20364bb..0440063f0f1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/PlatformChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/platform/PlatformChartService.kt @@ -3,6 +3,10 @@ package io.horizontalsystems.bankwallet.modules.market.platform import android.util.Log import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartPointsWrapper @@ -58,6 +62,12 @@ class PlatformChartService( return getChartPointsWrapper(currency, HsPeriodType.ByPeriod(chartInterval)) } + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(page = StatPage.TopPlatform, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } + private fun getChartPointsWrapper( currency: Currency, periodType: HsPeriodType, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/posts/MarketPostsScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/posts/MarketPostsScreen.kt index a130b138b83..7065dea8c96 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/posts/MarketPostsScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/posts/MarketPostsScreen.kt @@ -16,6 +16,9 @@ import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme @@ -35,6 +38,8 @@ fun MarketPostsScreen(viewModel: MarketPostsViewModel = viewModel(factory = Mark refreshing = isRefreshing, onRefresh = { viewModel.refresh() + + stat(page = StatPage.News, event = StatEvent.Refresh) } ) { Crossfade(viewState) { viewState -> @@ -56,6 +61,8 @@ fun MarketPostsScreen(viewModel: MarketPostsViewModel = viewModel(factory = Mark date = postItem.timeAgo, ) { LinkHelper.openLinkInAppBrowser(context, postItem.url) + + stat(page = StatPage.News, event = StatEvent.Open(StatPage.ExternalNews)) } } item { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchFragment.kt index 827824ccf8d..d19f25a09e1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchFragment.kt @@ -41,6 +41,10 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.iconPlaceholder import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statSection import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.market.MarketDataValue import io.horizontalsystems.bankwallet.modules.market.search.MarketSearchModule.CoinItem @@ -57,7 +61,7 @@ import io.horizontalsystems.marketkit.models.Coin import kotlinx.coroutines.delay import kotlinx.coroutines.launch import java.util.Optional -import kotlin.jvm.optionals.getOrDefault +import kotlin.jvm.optionals.getOrNull class MarketSearchFragment : BaseComposeFragment() { @Composable @@ -94,14 +98,14 @@ fun MarketSearchScreen(viewModel: MarketSearchViewModel, navController: NavContr val itemSections = when (uiState.page) { is MarketSearchViewModel.Page.Discovery -> { mapOf( - Optional.of(stringResource(R.string.Market_Search_Sections_RecentTitle)) to uiState.page.recent, - Optional.of(stringResource(R.string.Market_Search_Sections_PopularTitle)) to uiState.page.popular, + MarketSearchSection.Recent to uiState.page.recent, + MarketSearchSection.Popular to uiState.page.popular, ) } is MarketSearchViewModel.Page.SearchResults -> { mapOf( - Optional.ofNullable(null) to uiState.page.items + MarketSearchSection.SearchResults to uiState.page.items ) } } @@ -109,12 +113,14 @@ fun MarketSearchScreen(viewModel: MarketSearchViewModel, navController: NavContr MarketSearchResults( uiState.listId, itemSections = itemSections, - onCoinClick = { coin -> + onCoinClick = { coin, section -> viewModel.onCoinOpened(coin) navController.slideFromRight( R.id.coinFragment, - CoinFragment.Input(coin.uid, "market_search") + CoinFragment.Input(coin.uid) ) + + stat(page = StatPage.MarketSearch, section = section.statSection, event = StatEvent.OpenCoin(coin.uid)) } ) { favorited, coinUid -> viewModel.onFavoriteClick(favorited, coinUid) @@ -122,12 +128,18 @@ fun MarketSearchScreen(viewModel: MarketSearchViewModel, navController: NavContr } } +enum class MarketSearchSection(val title: Optional) { + Recent(Optional.of(R.string.Market_Search_Sections_RecentTitle)), + Popular(Optional.of(R.string.Market_Search_Sections_PopularTitle)), + SearchResults(Optional.empty()) +} + @OptIn(ExperimentalFoundationApi::class) @Composable fun MarketSearchResults( vararg inputs: Any?, - itemSections: Map, List>, - onCoinClick: (Coin) -> Unit, + itemSections: Map>, + onCoinClick: (Coin, MarketSearchSection) -> Unit, onFavoriteClick: (Boolean, String) -> Unit, ) { if (itemSections.all { (_, items) -> items.isEmpty() }) { @@ -147,12 +159,12 @@ fun MarketSearchResults( LazyListState() } ) { - itemSections.forEach { (title, coinItems) -> - title.ifPresent { + itemSections.forEach { (section, coinItems) -> + section.title.ifPresent { stickyHeader { HeaderStick( borderTop = true, - text = title.get() + text = stringResource(id = section.title.get()) ) } } @@ -189,7 +201,7 @@ fun MarketSearchResults( contentDescription = stringResource(if (item.favourited) R.string.CoinPage_Unfavorite else R.string.CoinPage_Favorite), ) } - val cardId = title.getOrDefault("") + coin.uid + val cardId = (section.title.getOrNull()?.let { stringResource(id = it) } ?: "") + coin.uid DraggableCardSimple( key = cardId, isRevealed = revealedCardId == cardId, @@ -209,7 +221,7 @@ fun MarketSearchResults( coinName = coin.name, coinIconUrl = coin.imageUrl, coinIconPlaceholder = item.fullCoin.iconPlaceholder, - onClick = { onCoinClick(coin) } + onClick = { onCoinClick(coin, section) } ) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchViewModel.kt index 2dc965b1ea4..30cbc8bd8d6 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/search/MarketSearchViewModel.kt @@ -6,6 +6,9 @@ import androidx.compose.runtime.setValue import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.horizontalsystems.bankwallet.core.managers.MarketFavoritesManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.marketkit.models.Coin import io.horizontalsystems.marketkit.models.FullCoin import kotlinx.coroutines.launch @@ -91,8 +94,12 @@ class MarketSearchViewModel( fun onFavoriteClick(favourited: Boolean, coinUid: String) { if (favourited) { marketFavoritesManager.remove(coinUid) + + stat(page = StatPage.MarketSearch, event = StatEvent.RemoveFromWatchlist(coinUid)) } else { marketFavoritesManager.add(coinUid) + + stat(page = StatPage.MarketSearch, event = StatEvent.AddToWatchlist(coinUid)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopCoinsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopCoinsFragment.kt index 31d219d13e0..5d97d21a491 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopCoinsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopCoinsFragment.kt @@ -26,6 +26,12 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statField +import io.horizontalsystems.bankwallet.core.stats.statMarketTop +import io.horizontalsystems.bankwallet.core.stats.statSortType import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading @@ -65,9 +71,11 @@ class MarketTopCoinsFragment : BaseComposeFragment() { } private fun onCoinClick(coinUid: String, navController: NavController) { - val arguments = CoinFragment.Input(coinUid, "market_overview_top_coins") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.TopCoins, event = StatEvent.OpenCoin(coinUid)) } @Parcelize @@ -118,8 +126,16 @@ fun TopCoinsScreen( CoinList( items = it, scrollToTop = scrollToTopAfterUpdate, - onAddFavorite = { uid -> viewModel.onAddFavorite(uid) }, - onRemoveFavorite = { uid -> viewModel.onRemoveFavorite(uid) }, + onAddFavorite = { uid -> + viewModel.onAddFavorite(uid) + + stat(page = StatPage.TopCoins, event = StatEvent.AddToWatchlist(uid)) + }, + onRemoveFavorite = { uid -> + viewModel.onRemoveFavorite(uid) + + stat(page = StatPage.TopCoins, event = StatEvent.RemoveFromWatchlist(uid)) + }, onCoinClick = onCoinClick, preItems = { header?.let { header -> @@ -158,6 +174,8 @@ fun TopCoinsScreen( viewModel.onSelectTopMarket( topMarket ) + + stat(page = StatPage.TopCoins, event = StatEvent.SwitchMarketTop(topMarket.statMarketTop)) } ) } @@ -166,7 +184,11 @@ fun TopCoinsScreen( Box(modifier = Modifier.padding(start = 8.dp)) { ButtonSecondaryToggle( select = menu.marketFieldSelect, - onSelect = viewModel::onSelectMarketField + onSelect = { + viewModel.onSelectMarketField(it) + + stat(page = StatPage.TopCoins, event = StatEvent.SwitchField(it.statField)) + } ) } } @@ -195,6 +217,8 @@ fun TopCoinsScreen( { selected -> scrollToTopAfterUpdate = true viewModel.onSelectSortingField(selected) + + stat(page = StatPage.TopCoins, event = StatEvent.SwitchSortType(selected.statSortType)) }, { viewModel.onSelectorDialogDismiss() } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopMoversRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopMoversRepository.kt index 7bdb5d8cf90..c3104160af0 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopMoversRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topcoins/MarketTopMoversRepository.kt @@ -26,8 +26,7 @@ class MarketTopMoversRepository( ): Single> = Single.create { emitter -> try { - val appTag = "market_top_${size}_${sortingField.name}_${marketField.name}" - val marketInfoList = marketKit.marketInfosSingle(size, baseCurrency.code, false, appTag).blockingGet() + val marketInfoList = marketKit.marketInfosSingle(size, baseCurrency.code, false).blockingGet() val marketItemList = marketInfoList.map { marketInfo -> MarketItem.createFromCoinMarket( marketInfo, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/toppairs/TopPairsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/toppairs/TopPairsFragment.kt index 2639dbb0df5..a2c4f4e288d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/toppairs/TopPairsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/toppairs/TopPairsFragment.kt @@ -16,6 +16,9 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.market.ImageSource @@ -56,12 +59,14 @@ fun TopPairsScreen(navController: NavController) { ViewState.Loading -> { Loading() } + is ViewState.Error -> { ListErrorView( stringResource(R.string.SyncError), viewModel::onErrorClick ) } + ViewState.Success -> { LazyColumn( modifier = Modifier.fillMaxSize() @@ -77,6 +82,8 @@ fun TopPairsScreen(navController: NavController) { TopPairItem(item, borderTop = i == 0, borderBottom = true) { it.tradeUrl?.let { LinkHelper.openLinkInAppBrowser(context, it) + + stat(page = StatPage.TopMarketPairs, event = StatEvent.Open(StatPage.ExternalMarketPair)) } } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsFragment.kt index 4071b7a434d..df9c2324d94 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsFragment.kt @@ -33,6 +33,11 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod +import io.horizontalsystems.bankwallet.core.stats.statSortType import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.market.ImageSource @@ -117,6 +122,8 @@ fun TopPlatformsScreen( R.id.marketPlatformFragment, it ) + + stat(page = StatPage.TopPlatforms, event = StatEvent.OpenPlatform(it.uid)) }, preItems = { item { @@ -146,6 +153,8 @@ fun TopPlatformsScreen( it, viewModel.periodOptions ) + + stat(page = StatPage.TopPlatforms, event = StatEvent.SwitchPeriod(it.statPeriod)) } ) Spacer(modifier = Modifier.width(16.dp)) @@ -167,6 +176,8 @@ fun TopPlatformsScreen( option.select, { selected -> viewModel.onSelectSortingField(selected) + + stat(page = StatPage.TopPlatforms, event = StatEvent.SwitchSortType(selected.statSortType)) }, { viewModel.onSelectorDialogDismiss() } ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsModule.kt index 9a22c2ce4e0..267393534f8 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsModule.kt @@ -19,7 +19,7 @@ object TopPlatformsModule { class Factory(private val timeDuration: TimeDuration?) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - val repository = TopPlatformsRepository(App.marketKit, App.currencyManager, "market_top_platforms") + val repository = TopPlatformsRepository(App.marketKit, App.currencyManager) val service = TopPlatformsService(repository, App.currencyManager) return TopPlatformsViewModel(service, timeDuration) as T } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsRepository.kt index 14915592e4a..0ec74244d78 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/topplatforms/TopPlatformsRepository.kt @@ -13,8 +13,7 @@ import kotlinx.coroutines.withContext class TopPlatformsRepository( private val marketKit: MarketKitWrapper, - private val currencyManager: CurrencyManager, - private val apiTag: String, + private val currencyManager: CurrencyManager ) { private var itemsCache: List? = null @@ -27,7 +26,7 @@ class TopPlatformsRepository( val currentCache = itemsCache val items = if (forceRefresh || currentCache == null) { - marketKit.topPlatformsSingle(currencyManager.baseCurrency.code, apiTag).await() + marketKit.topPlatformsSingle(currencyManager.baseCurrency.code).await() } else { currentCache } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/GlobalMarketRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/GlobalMarketRepository.kt index 4ef72e56d54..26555da6534 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/GlobalMarketRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/GlobalMarketRepository.kt @@ -14,8 +14,7 @@ import io.reactivex.Single import java.math.BigDecimal class GlobalMarketRepository( - private val marketKit: MarketKitWrapper, - private val apiTag: String + private val marketKit: MarketKitWrapper ) { private var cache: List = listOf() @@ -60,7 +59,7 @@ class GlobalMarketRepository( sortDescending: Boolean, metricsType: MetricsType ): Single> { - return marketKit.marketInfosSingle(250, currency.code, defi = metricsType == MetricsType.DefiCap, apiTag) + return marketKit.marketInfosSingle(250, currency.code, defi = metricsType == MetricsType.DefiCap) .map { coinMarkets -> val marketItems = coinMarkets.map { MarketItem.createFromCoinMarket(it, currency) } val sortingField = when (metricsType) { @@ -90,7 +89,7 @@ class GlobalMarketRepository( private fun defiMarketInfos(currencyCode: String, forceRefresh: Boolean): List = if (forceRefresh || cache.isEmpty()) { - val defiMarketInfo = marketKit.defiMarketInfosSingle(currencyCode, apiTag).blockingGet() + val defiMarketInfo = marketKit.defiMarketInfosSingle(currencyCode).blockingGet() cache = defiMarketInfo diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlChartService.kt index 27ff591df53..f4153530415 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlChartService.kt @@ -1,6 +1,10 @@ package io.horizontalsystems.bankwallet.modules.market.tvl import io.horizontalsystems.bankwallet.core.managers.CurrencyManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartPointsWrapper @@ -45,4 +49,10 @@ class TvlChartService( ChartPointsWrapper(it) } } + + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(page = StatPage.GlobalMetricsTvlInDefi, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlFragment.kt index 9bc100b7ae7..6237fe5703f 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlFragment.kt @@ -32,6 +32,9 @@ import coil.compose.rememberAsyncImagePainter import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.CurrencyValue import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.CoinFragment @@ -71,8 +74,10 @@ class TvlFragment : BaseComposeFragment() { private fun onCoinClick(coinUid: String?, navController: NavController) { if (coinUid != null) { - val arguments = CoinFragment.Input(coinUid, "market_tvl") + val arguments = CoinFragment.Input(coinUid) navController.slideFromRight(R.id.coinFragment, arguments) + + stat(page = StatPage.GlobalMetricsTvlInDefi, event = StatEvent.OpenCoin(coinUid)) } else { HudHelper.showWarningMessage(requireView(), R.string.MarketGlobalMetrics_NoCoin) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlModule.kt index 3ecb0fafbe3..a5b15b4f0af 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlModule.kt @@ -19,7 +19,7 @@ object TvlModule { @Suppress("UNCHECKED_CAST") class Factory : ViewModelProvider.Factory { private val globalMarketRepository: GlobalMarketRepository by lazy { - GlobalMarketRepository(App.marketKit, "market_global_tvl_metrics") + GlobalMarketRepository(App.marketKit) } override fun create(modelClass: Class): T { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlViewModel.kt index b995803ce1d..8a2a9d7dc5f 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/market/tvl/TvlViewModel.kt @@ -4,6 +4,9 @@ import androidx.lifecycle.MutableLiveData import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.market.MarketModule import io.horizontalsystems.bankwallet.modules.market.tvl.TvlModule.SelectorDialogState @@ -75,14 +78,20 @@ class TvlViewModel( fun onSelectChain(chain: TvlModule.Chain) { service.chain = chain chainSelectorDialogStateLiveData.postValue(SelectorDialogState.Closed) + + stat(page = StatPage.GlobalMetricsTvlInDefi, event = StatEvent.SwitchTvlChain(chain.name)) } fun onToggleSortType() { service.sortDescending = !service.sortDescending + + stat(page = StatPage.GlobalMetricsTvlInDefi, event = StatEvent.ToggleSortDirection) } fun onToggleTvlDiffType() { tvlDiffType = if (tvlDiffType == TvlDiffType.Percent) TvlDiffType.Currency else TvlDiffType.Percent + + stat(page = StatPage.GlobalMetricsTvlInDefi, event = StatEvent.ToggleTvlField) } fun onClickChainSelector() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/metricchart/ProChartService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/metricchart/ProChartService.kt index 0b024574eaf..a7179d7abd8 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/metricchart/ProChartService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/metricchart/ProChartService.kt @@ -2,6 +2,10 @@ package io.horizontalsystems.bankwallet.modules.metricchart import io.horizontalsystems.bankwallet.core.managers.CurrencyManager import io.horizontalsystems.bankwallet.core.managers.MarketKitWrapper +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statPage +import io.horizontalsystems.bankwallet.core.stats.statPeriod import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.chart.AbstractChartService import io.horizontalsystems.bankwallet.modules.chart.ChartPointsWrapper @@ -53,6 +57,12 @@ class ProChartService( ProChartModule.ChartType.TxCount -> ChartViewType.Bar } + override fun updateChartInterval(chartInterval: HsTimePeriod?) { + super.updateChartInterval(chartInterval) + + stat(chartType.statPage, event = StatEvent.SwitchChartPeriod(chartInterval.statPeriod)) + } + override fun getItems( chartInterval: HsTimePeriod, currency: Currency, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmFragment.kt index 7a4374a1b16..9868a2f46fe 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmFragment.kt @@ -32,6 +32,7 @@ import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.setNavigationResultX import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.entities.CoinValue import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.entities.CurrencyValue @@ -181,7 +182,7 @@ fun SwapConfirmScreen(navController: NavController) { uiState.amountOut?.let { amountOut -> VSpacer(height = 16.dp) SectionUniversalLawrence { - PriceField(uiState.tokenIn, uiState.tokenOut, uiState.amountIn, amountOut) + PriceField(uiState.tokenIn, uiState.tokenOut, uiState.amountIn, amountOut, StatPage.SwapConfirmation) PriceImpactField(uiState.priceImpact, uiState.priceImpactLevel, navController) uiState.amountOutMin?.let { amountOutMin -> val subvalue = uiState.fiatAmountOutMin?.let { fiatAmountOutMin -> diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmViewModel.kt index 94319380624..5aeebcd248a 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapConfirmViewModel.kt @@ -7,6 +7,9 @@ import io.horizontalsystems.bankwallet.core.HSCaution import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.ethereum.CautionViewItem import io.horizontalsystems.bankwallet.core.managers.CurrencyManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.multiswap.providers.IMultiSwapProvider import io.horizontalsystems.bankwallet.modules.multiswap.sendtransaction.ISendTransactionService @@ -182,6 +185,8 @@ class SwapConfirmViewModel( emitState() fetchFinalQuote() + + stat(page = StatPage.SwapConfirmation, event = StatEvent.Refresh) } private fun fetchFinalQuote() { @@ -206,6 +211,8 @@ class SwapConfirmViewModel( } suspend fun swap() = withContext(Dispatchers.Default) { + stat(page = StatPage.SwapConfirmation, event = StatEvent.Send) + sendTransactionService.sendTransaction() } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapFragment.kt index 7400c4a9c6e..7678807379e 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapFragment.kt @@ -58,6 +58,9 @@ import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromBottomForResult import io.horizontalsystems.bankwallet.core.slideFromRight import io.horizontalsystems.bankwallet.core.slideFromRightForResult +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.CoinValue import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.evmfee.FeeSettingsInfoDialog @@ -134,9 +137,13 @@ fun SwapScreen(navController: NavController, tokenIn: Token?) { onEnterFiatAmount = viewModel::onEnterFiatAmount, onClickProvider = { navController.slideFromBottom(R.id.swapSelectProvider) + + stat(page = StatPage.Swap, event = StatEvent.Open(StatPage.SwapProvider)) }, onClickProviderSettings = { navController.slideFromRight(R.id.swapSettings) + + stat(page = StatPage.Swap, event = StatEvent.Open(StatPage.SwapSettings)) }, onTimeout = viewModel::reQuote, onClickNext = { @@ -145,6 +152,8 @@ fun SwapScreen(navController: NavController, tokenIn: Token?) { navController.popBackStack() } } + + stat(page = StatPage.Swap, event = StatEvent.Open(StatPage.SwapConfirmation)) }, onActionStarted = { viewModel.onActionStarted() @@ -327,7 +336,7 @@ private fun SwapScreenInner( if (quote != null) { CardsSwapInfo { ProviderField(quote.provider, onClickProvider, onClickProviderSettings) - PriceField(quote.tokenIn, quote.tokenOut, quote.amountIn, quote.amountOut) + PriceField(quote.tokenIn, quote.tokenOut, quote.amountIn, quote.amountOut, StatPage.Swap) PriceImpactField(uiState.priceImpact, uiState.priceImpactLevel, navController) quote.fields.forEach { it.GetContent(navController, false) @@ -484,7 +493,7 @@ private fun ProviderField( } @Composable -fun PriceField(tokenIn: Token, tokenOut: Token, amountIn: BigDecimal, amountOut: BigDecimal) { +fun PriceField(tokenIn: Token, tokenOut: Token, amountIn: BigDecimal, amountOut: BigDecimal, statPage: StatPage) { var showRegularPrice by remember { mutableStateOf(true) } val swapPriceUIHelper = SwapPriceUIHelper(tokenIn, tokenOut, amountIn, amountOut) @@ -500,6 +509,8 @@ fun PriceField(tokenIn: Token, tokenOut: Token, amountIn: BigDecimal, amountOut: indication = null, onClick = { showRegularPrice = !showRegularPrice + + stat(page = statPage, event = StatEvent.TogglePrice) } ), verticalAlignment = Alignment.CenterVertically, diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapSelectProviderFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapSelectProviderFragment.kt index 5d01216ade7..a7f6d0fcf67 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapSelectProviderFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapSelectProviderFragment.kt @@ -24,6 +24,9 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.TranslatableString import io.horizontalsystems.bankwallet.ui.compose.components.AppBar @@ -63,6 +66,8 @@ fun SwapSelectProviderScreen(navController: NavController) { ) { swapViewModel.onSelectQuote(it) navController.popBackStack() + + stat(page = StatPage.SwapProvider, event = StatEvent.SwapSelectProvider(it.provider.id)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapViewModel.kt index 70dc8aa092a..365be0db151 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/multiswap/SwapViewModel.kt @@ -7,6 +7,9 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.HSCaution import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.managers.CurrencyManager +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Currency import io.horizontalsystems.bankwallet.modules.multiswap.action.ISwapProviderAction import io.horizontalsystems.bankwallet.modules.multiswap.providers.IMultiSwapProvider @@ -183,9 +186,22 @@ class SwapViewModel( quoteService.setAmount(amount) } - fun onSelectTokenIn(token: Token) = quoteService.setTokenIn(token) - fun onSelectTokenOut(token: Token) = quoteService.setTokenOut(token) - fun onSwitchPairs() = quoteService.switchPairs() + fun onSelectTokenIn(token: Token) { + quoteService.setTokenIn(token) + + stat(page = StatPage.Swap, event = StatEvent.SwapSelectTokenIn(token)) + } + fun onSelectTokenOut(token: Token) { + quoteService.setTokenOut(token) + + stat(page = StatPage.Swap, event = StatEvent.SwapSelectTokenOut(token)) + } + fun onSwitchPairs() { + quoteService.switchPairs() + + stat(page = StatPage.Swap, event = StatEvent.SwapSwitchPairs) + } + fun onUpdateSettings(settings: Map) = quoteService.setSwapSettings(settings) fun onEnterFiatAmount(v: BigDecimal?) = fiatServiceIn.setFiatAmount(v) fun reQuote() = quoteService.reQuote() diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ReceiveFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ReceiveFragment.kt index 09f133e4d2c..2a00f8ac245 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ReceiveFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ReceiveFragment.kt @@ -19,6 +19,9 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.composablePage import io.horizontalsystems.bankwallet.core.getInput +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Wallet import io.horizontalsystems.bankwallet.modules.receive.ReceiveRoutes.BCH_ADDRESS_FORMAT_SCREEN import io.horizontalsystems.bankwallet.modules.receive.ReceiveRoutes.COIN_SELECT_SCREEN @@ -139,8 +142,7 @@ fun ReceiveScreen( navController.navigate(NETWORK_SELECT_SCREEN) }, onCoinClick = { wallet -> - viewModel.wallet = wallet - navController.navigate(RECEIVE_ADDRESS_SCREEN) + onSelectWallet(wallet, viewModel, navController) }, onBackPress = navigateBack(fragmentNavController, navController), ) @@ -159,8 +161,7 @@ fun ReceiveScreen( addressFormatItems = bchAddressViewModel.items, description = stringResource(R.string.Balance_Receive_AddressFormat_RecommendedAddressType), onSelect = { wallet -> - viewModel.wallet = wallet - navController.navigate(RECEIVE_ADDRESS_SCREEN) + onSelectWallet(wallet, viewModel, navController) }, onBackPress = navigateBack(fragmentNavController, navController) ) @@ -179,8 +180,7 @@ fun ReceiveScreen( addressFormatItems = derivationViewModel.items, description = stringResource(R.string.Balance_Receive_AddressFormat_RecommendedDerivation), onSelect = { wallet -> - viewModel.wallet = wallet - navController.navigate(RECEIVE_ADDRESS_SCREEN) + onSelectWallet(wallet, viewModel, navController) }, onBackPress = navigateBack(fragmentNavController, navController) ) @@ -198,8 +198,7 @@ fun ReceiveScreen( activeAccount = activeAccount, fullCoin = fullCoin, onSelect = { wallet -> - viewModel.wallet = wallet - navController.navigate(RECEIVE_ADDRESS_SCREEN) + onSelectWallet(wallet, viewModel, navController) } ) } @@ -207,6 +206,13 @@ fun ReceiveScreen( } } +private fun onSelectWallet(wallet: Wallet, viewModel: ReceiveSharedViewModel, navController: NavController) { + viewModel.wallet = wallet + navController.navigate(RECEIVE_ADDRESS_SCREEN) + + stat(page = StatPage.ReceiveTokenList, event = StatEvent.OpenReceive(wallet.token)) +} + @Composable fun CloseWithMessage(navController: NavController) { val view = LocalView.current diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ui/ReceiveAddressScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ui/ReceiveAddressScreen.kt index d3608c69411..65cd31c7f28 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ui/ReceiveAddressScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/receive/ui/ReceiveAddressScreen.kt @@ -59,6 +59,10 @@ import androidx.core.content.res.ResourcesCompat import androidx.core.graphics.drawable.toBitmap import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.UsedAddress +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.coin.overview.ui.Loading import io.horizontalsystems.bankwallet.modules.receive.ReceiveModule @@ -185,6 +189,8 @@ fun ReceiveAddressScreen( .clickable { TextHelper.copyText(uiState.uri) HudHelper.showSuccessMessage(localView, R.string.Hud_Text_Copied) + + stat(page = StatPage.Receive, event = StatEvent.Copy(StatEntity.ReceiveAddress)) }, horizontalAlignment = Alignment.CenterHorizontally, ) { @@ -240,7 +246,11 @@ fun ReceiveAddressScreen( if (uiState.additionalItems.isNotEmpty()) { AdditionalDataSection( items = uiState.additionalItems, - onClearAmount = { setAmount(null) }, + onClearAmount = { + setAmount(null) + + stat(page = StatPage.Receive, event = StatEvent.RemoveAmount) + }, showAccountNotActiveWarningDialog = { scope.launch { sheetState.show() } } @@ -298,6 +308,8 @@ fun ReceiveAddressScreen( onAmountConfirm = { amount -> setAmount(amount) openAmountDialog.value = false + + stat(page = StatPage.Receive, event = StatEvent.SetAmount) } ) } @@ -341,7 +353,7 @@ private fun ActionButtonsRow( .padding(horizontal = 48.dp), horizontalArrangement = if (watchAccount) Arrangement.Center else Arrangement.SpaceBetween, ) { - val itemModifier = if(watchAccount) Modifier else Modifier.weight(1f) + val itemModifier = if (watchAccount) Modifier else Modifier.weight(1f) if (!watchAccount) { ReceiveActionButton( modifier = itemModifier, @@ -358,6 +370,8 @@ private fun ActionButtonsRow( buttonText = stringResource(R.string.Button_Share), onClick = { onShareClick.invoke(uri) + + stat(page = StatPage.Receive, event = StatEvent.Share(StatEntity.ReceiveAddress)) }, ) if (watchAccount) { @@ -370,6 +384,8 @@ private fun ActionButtonsRow( onClick = { TextHelper.copyText(uri) HudHelper.showSuccessMessage(localView, R.string.Hud_Text_Copied) + + stat(page = StatPage.Receive, event = StatEvent.Copy(StatEntity.ReceiveAddress)) }, ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreAccountFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreAccountFragment.kt index fa4c09bcf8f..c983368ce40 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreAccountFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreAccountFragment.kt @@ -11,6 +11,9 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.composablePage import io.horizontalsystems.bankwallet.core.composablePopup import io.horizontalsystems.bankwallet.core.getInput +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.manageaccounts.ManageAccountsModule import io.horizontalsystems.bankwallet.modules.restoreaccount.restoreblockchains.ManageWalletsScreen import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremenu.RestoreMenuModule @@ -65,7 +68,11 @@ private fun RestoreAccountNavHost( restoreMenuViewModel = restoreMenuViewModel, mainViewModel = mainViewModel, openSelectCoinsScreen = { navController.navigate("restore_select_coins") }, - openNonStandardRestore = { navController.navigate("restore_phrase_nonstandard") }, + openNonStandardRestore = { + navController.navigate("restore_phrase_nonstandard") + + stat(page = StatPage.ImportWalletFromKeyAdvanced, event = StatEvent.Open(StatPage.ImportWalletNonStandard)) + }, onBackClick = { navController.popBackStack() } ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreViewModel.kt index b686511af14..47e66b9dd72 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/RestoreViewModel.kt @@ -1,6 +1,7 @@ package io.horizontalsystems.bankwallet.modules.restoreaccount import androidx.lifecycle.ViewModel +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.modules.enablecoin.restoresettings.ZCashConfig @@ -21,13 +22,17 @@ class RestoreViewModel: ViewModel() { var zCashConfig: ZCashConfig? = null private set + var statPage: StatPage? = null + private set + var cancelZCashConfig: Boolean = false - fun setAccountData(accountType: AccountType, accountName: String, manualBackup: Boolean, fileBackup: Boolean) { + fun setAccountData(accountType: AccountType, accountName: String, manualBackup: Boolean, fileBackup: Boolean, statPage: StatPage) { this.accountType = accountType this.accountName = accountName this.manualBackup = manualBackup this.fileBackup = fileBackup + this.statPage = statPage } fun setZCashConfig(config: ZCashConfig?) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchains.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchains.kt index e9fd75bcd2e..83aa1e1f29d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchains.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchains.kt @@ -35,6 +35,9 @@ import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.enablecoin.blockchaintokens.BlockchainTokensViewModel import io.horizontalsystems.bankwallet.modules.enablecoin.restoresettings.RestoreSettingsViewModel import io.horizontalsystems.bankwallet.modules.restoreaccount.RestoreViewModel @@ -67,10 +70,17 @@ fun ManageWalletsScreen( onBackClick.invoke() return } + + val statPage = mainViewModel.statPage ?: run { + Toast.makeText(App.instance, "Error: statPage is NULL", Toast.LENGTH_SHORT).show() + onBackClick.invoke() + return + } + val manualBackup = mainViewModel.manualBackup val fileBackup = mainViewModel.fileBackup - val factory = RestoreBlockchainsModule.Factory(mainViewModel.accountName, accountType, manualBackup, fileBackup) + val factory = RestoreBlockchainsModule.Factory(mainViewModel.accountName, accountType, manualBackup, fileBackup, statPage) val viewModel: RestoreBlockchainsViewModel = viewModel(factory = factory) val restoreSettingsViewModel: RestoreSettingsViewModel = viewModel(factory = factory) val blockchainTokensViewModel: BlockchainTokensViewModel = viewModel(factory = factory) @@ -94,6 +104,8 @@ fun ManageWalletsScreen( if (restoreSettingsViewModel.openZcashConfigure != null) { restoreSettingsViewModel.zcashConfigureOpened() openZCashConfigure.invoke() + + stat(page = StatPage.RestoreSelect, event = StatEvent.Open(StatPage.BirthdayInput)) } LaunchedEffect(restored) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsModule.kt index 82e18880899..527061d67cd 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsModule.kt @@ -3,6 +3,7 @@ package io.horizontalsystems.bankwallet.modules.restoreaccount.restoreblockchain import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.horizontalsystems.bankwallet.core.App +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.modules.enablecoin.blockchaintokens.BlockchainTokensService import io.horizontalsystems.bankwallet.modules.enablecoin.blockchaintokens.BlockchainTokensViewModel @@ -16,7 +17,8 @@ object RestoreBlockchainsModule { private val accountName: String, private val accountType: AccountType, private val manualBackup: Boolean, - private val fileBackup: Boolean + private val fileBackup: Boolean, + private val statPage: StatPage ) : ViewModelProvider.Factory { private val restoreSettingsService by lazy { @@ -38,7 +40,8 @@ object RestoreBlockchainsModule { App.marketKit, App.tokenAutoEnableManager, blockchainTokensService, - restoreSettingsService + restoreSettingsService, + statPage ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsService.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsService.kt index 4f6ebe49558..986e52b18f1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsService.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreblockchains/RestoreBlockchainsService.kt @@ -11,6 +11,10 @@ import io.horizontalsystems.bankwallet.core.managers.TokenAutoEnableManager import io.horizontalsystems.bankwallet.core.nativeTokenQueries import io.horizontalsystems.bankwallet.core.order import io.horizontalsystems.bankwallet.core.restoreSettingTypes +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.core.supported import io.horizontalsystems.bankwallet.core.supports import io.horizontalsystems.bankwallet.entities.AccountOrigin @@ -40,7 +44,8 @@ class RestoreBlockchainsService( private val marketKit: MarketKitWrapper, private val tokenAutoEnableManager: TokenAutoEnableManager, private val blockchainTokensService: BlockchainTokensService, - private val restoreSettingsService: RestoreSettingsService + private val restoreSettingsService: RestoreSettingsService, + private val statPage: StatPage ) : Clearable { private val coroutineScope = CoroutineScope(Dispatchers.Default) @@ -204,6 +209,8 @@ class RestoreBlockchainsService( val wallets = enabledTokens.map { Wallet(it, account) } walletManager.save(wallets) + + stat(page = statPage, event = StatEvent.ImportWallet(accountType.statAccountType)) } override fun clear() { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonic/RestorePhraseScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonic/RestorePhraseScreen.kt index 2f4f50bcd49..6771098a4a5 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonic/RestorePhraseScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonic/RestorePhraseScreen.kt @@ -6,16 +6,38 @@ import android.view.inputmethod.InputMethodManager import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.* -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.Image +import androidx.compose.foundation.background +import androidx.compose.foundation.border +import androidx.compose.foundation.clickable +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.layout.width import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.items +import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.foundation.verticalScroll import androidx.compose.material.Icon -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -31,13 +53,20 @@ import androidx.compose.ui.text.SpanStyle import androidx.compose.ui.text.TextRange import androidx.compose.ui.text.buildAnnotatedString import androidx.compose.ui.text.font.FontWeight -import androidx.compose.ui.text.input.* +import androidx.compose.ui.text.input.KeyboardType +import androidx.compose.ui.text.input.OffsetMapping +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.text.input.TransformedText import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.displayNameStringRes +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.core.utils.ModuleField import io.horizontalsystems.bankwallet.core.utils.Utils import io.horizontalsystems.bankwallet.entities.DataState @@ -47,8 +76,31 @@ import io.horizontalsystems.bankwallet.modules.qrscanner.QRScannerActivity import io.horizontalsystems.bankwallet.modules.restoreaccount.RestoreViewModel import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremenu.RestoreByMenu import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremenu.RestoreMenuViewModel -import io.horizontalsystems.bankwallet.ui.compose.* -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.ColoredTextStyle +import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme +import io.horizontalsystems.bankwallet.ui.compose.Keyboard +import io.horizontalsystems.bankwallet.ui.compose.TranslatableString +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.BoxTyler44 +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondary +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryDefault +import io.horizontalsystems.bankwallet.ui.compose.components.CellSingleLineLawrenceSection +import io.horizontalsystems.bankwallet.ui.compose.components.CellUniversalLawrenceSection +import io.horizontalsystems.bankwallet.ui.compose.components.CustomKeyboardWarningDialog +import io.horizontalsystems.bankwallet.ui.compose.components.FormsInput +import io.horizontalsystems.bankwallet.ui.compose.components.FormsInputPassword +import io.horizontalsystems.bankwallet.ui.compose.components.HeaderText +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.SelectorDialogCompose +import io.horizontalsystems.bankwallet.ui.compose.components.SelectorItem +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantWarning +import io.horizontalsystems.bankwallet.ui.compose.components.body_grey50 +import io.horizontalsystems.bankwallet.ui.compose.components.body_leah +import io.horizontalsystems.bankwallet.ui.compose.components.caption_lucian +import io.horizontalsystems.bankwallet.ui.compose.components.subhead1_leah +import io.horizontalsystems.bankwallet.ui.compose.observeKeyboardState import io.horizontalsystems.core.helpers.HudHelper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay @@ -67,6 +119,7 @@ fun RestorePhrase( val viewModel = viewModel(factory = RestoreMnemonicModule.Factory()) val uiState = viewModel.uiState val context = LocalContext.current + val statPage = if (advanced) StatPage.ImportWalletFromKeyAdvanced else StatPage.ImportWalletFromKey var textState by rememberSaveable("", stateSaver = TextFieldValue.Saver) { mutableStateOf(TextFieldValue("")) @@ -212,6 +265,8 @@ fun RestorePhrase( onClick = { textState = textState.copy(text = "", selection = TextRange(0)) viewModel.onEnterMnemonicPhrase("", "".length) + + stat(page = statPage, event = StatEvent.Clear(StatEntity.RecoveryPhrase)) } ) } else { @@ -222,6 +277,8 @@ fun RestorePhrase( qrScannerLauncher.launch( QRScannerActivity.getScanQrIntent(context) ) + + stat(page = statPage, event = StatEvent.ScanQr(StatEntity.RecoveryPhrase)) } ) @@ -240,6 +297,8 @@ fun RestorePhrase( textInClipboard.length ) } + + stat(page = statPage, event = StatEvent.Paste(StatEntity.RecoveryPhrase)) }, ) } @@ -316,9 +375,11 @@ fun RestorePhrase( } uiState.accountType?.let { accountType -> - mainViewModel.setAccountData(accountType, viewModel.accountName, true, false) + mainViewModel.setAccountData(accountType, viewModel.accountName, true, false, statPage) openSelectCoins.invoke() viewModel.onSelectCoinsShown() + + stat(page = statPage, event = StatEvent.Open(StatPage.RestoreSelect)) } if (showCustomKeyboardDialog) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonicnonstandard/RestorePhraseNonStandardScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonicnonstandard/RestorePhraseNonStandardScreen.kt index 915b5426a84..798378bcb3f 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonicnonstandard/RestorePhraseNonStandardScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoremnemonicnonstandard/RestorePhraseNonStandardScreen.kt @@ -8,15 +8,30 @@ import androidx.activity.result.ActivityResult import androidx.activity.result.contract.ActivityResultContracts import androidx.compose.foundation.background import androidx.compose.foundation.border -import androidx.compose.foundation.layout.* +import androidx.compose.foundation.layout.Arrangement +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.defaultMinSize +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.height +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.KeyboardOptions import androidx.compose.foundation.verticalScroll import androidx.compose.material.Icon -import androidx.compose.runtime.* +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember +import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.saveable.rememberSaveable +import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.ExperimentalComposeUiApi import androidx.compose.ui.Modifier @@ -42,6 +57,10 @@ import androidx.compose.ui.unit.sp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.displayNameStringRes +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.core.utils.ModuleField import io.horizontalsystems.bankwallet.core.utils.Utils import io.horizontalsystems.bankwallet.entities.DataState @@ -49,8 +68,29 @@ import io.horizontalsystems.bankwallet.modules.createaccount.MnemonicLanguageCel import io.horizontalsystems.bankwallet.modules.qrscanner.QRScannerActivity import io.horizontalsystems.bankwallet.modules.restoreaccount.RestoreViewModel import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremnemonic.SuggestionsBar -import io.horizontalsystems.bankwallet.ui.compose.* -import io.horizontalsystems.bankwallet.ui.compose.components.* +import io.horizontalsystems.bankwallet.ui.compose.ColoredTextStyle +import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme +import io.horizontalsystems.bankwallet.ui.compose.Keyboard +import io.horizontalsystems.bankwallet.ui.compose.TranslatableString +import io.horizontalsystems.bankwallet.ui.compose.components.AppBar +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryCircle +import io.horizontalsystems.bankwallet.ui.compose.components.ButtonSecondaryDefault +import io.horizontalsystems.bankwallet.ui.compose.components.CellSingleLineLawrenceSection +import io.horizontalsystems.bankwallet.ui.compose.components.CustomKeyboardWarningDialog +import io.horizontalsystems.bankwallet.ui.compose.components.FormsInput +import io.horizontalsystems.bankwallet.ui.compose.components.FormsInputPassword +import io.horizontalsystems.bankwallet.ui.compose.components.HeaderText +import io.horizontalsystems.bankwallet.ui.compose.components.HsBackButton +import io.horizontalsystems.bankwallet.ui.compose.components.HsSwitch +import io.horizontalsystems.bankwallet.ui.compose.components.InfoText +import io.horizontalsystems.bankwallet.ui.compose.components.MenuItem +import io.horizontalsystems.bankwallet.ui.compose.components.SelectorDialogCompose +import io.horizontalsystems.bankwallet.ui.compose.components.SelectorItem +import io.horizontalsystems.bankwallet.ui.compose.components.TextImportantWarning +import io.horizontalsystems.bankwallet.ui.compose.components.body_grey50 +import io.horizontalsystems.bankwallet.ui.compose.components.body_leah +import io.horizontalsystems.bankwallet.ui.compose.components.caption_lucian +import io.horizontalsystems.bankwallet.ui.compose.observeKeyboardState import io.horizontalsystems.core.helpers.HudHelper import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay @@ -206,6 +246,8 @@ fun RestorePhraseNonStandard( onClick = { textState = textState.copy(text = "", selection = TextRange(0)) viewModel.onEnterMnemonicPhrase("", "".length) + + stat(page = StatPage.ImportWalletNonStandard, event = StatEvent.Clear(StatEntity.RecoveryPhrase)) } ) } else { @@ -216,6 +258,8 @@ fun RestorePhraseNonStandard( qrScannerLauncher.launch( QRScannerActivity.getScanQrIntent(context) ) + + stat(page = StatPage.ImportWalletNonStandard, event = StatEvent.ScanQr(StatEntity.RecoveryPhrase)) } ) @@ -233,6 +277,8 @@ fun RestorePhraseNonStandard( textInClipboard, textInClipboard.length ) + + stat(page = StatPage.ImportWalletNonStandard, event = StatEvent.Paste(StatEntity.RecoveryPhrase)) } }, ) @@ -284,9 +330,11 @@ fun RestorePhraseNonStandard( } uiState.accountType?.let { accountType -> - mainViewModel.setAccountData(accountType, viewModel.accountName, true, false) + mainViewModel.setAccountData(accountType, viewModel.accountName, true, false, StatPage.ImportWalletNonStandard) openSelectCoinsScreen.invoke() viewModel.onSelectCoinsShown() + + stat(page = StatPage.ImportWalletNonStandard, event = StatEvent.Open(StatPage.RestoreSelect)) } if (showCustomKeyboardDialog) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreprivatekey/RestorePrivateKeyScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreprivatekey/RestorePrivateKeyScreen.kt index da7acece0d8..d9236a22229 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreprivatekey/RestorePrivateKeyScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restoreaccount/restoreprivatekey/RestorePrivateKeyScreen.kt @@ -13,6 +13,10 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import androidx.lifecycle.viewmodel.compose.viewModel import io.horizontalsystems.bankwallet.R +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.restoreaccount.RestoreViewModel import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremenu.RestoreByMenu import io.horizontalsystems.bankwallet.modules.restoreaccount.restoremenu.RestoreMenuViewModel @@ -47,8 +51,10 @@ fun RestorePrivateKey( title = TranslatableString.ResString(R.string.Button_Next), onClick = { viewModel.resolveAccountType()?.let { accountType -> - mainViewModel.setAccountData(accountType, viewModel.accountName, true, false) + mainViewModel.setAccountData(accountType, viewModel.accountName, true, false, StatPage.ImportWalletFromKeyAdvanced) openSelectCoinsScreen.invoke() + + stat(page = StatPage.ImportWalletFromKeyAdvanced, event = StatEvent.Open(StatPage.RestoreSelect)) } } ) @@ -82,9 +88,18 @@ fun RestorePrivateKey( hint = stringResource(id = R.string.Restore_PrivateKeyHint), state = viewModel.inputState, qrScannerEnabled = true, - ) { - viewModel.onEnterPrivateKey(it) - } + onValueChange = { + viewModel.onEnterPrivateKey(it) + }, + onClear = { + stat(page = StatPage.ImportWalletFromKeyAdvanced, event = StatEvent.Clear(StatEntity.Key)) + }, + onPaste = { + stat(page = StatPage.ImportWalletFromKeyAdvanced, event = StatEvent.Paste(StatEntity.Key)) + }, + onScanQR = { + stat(page = StatPage.ImportWalletFromKeyAdvanced, event = StatEvent.ScanQr(StatEntity.Key)) + }) Spacer(Modifier.height(32.dp)) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalFragment.kt index 9dbb160999a..f92eb5a791e 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalFragment.kt @@ -42,7 +42,10 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.Caution import io.horizontalsystems.bankwallet.core.composablePage import io.horizontalsystems.bankwallet.core.composablePopup -import io.horizontalsystems.bankwallet.core.getInput +import io.horizontalsystems.bankwallet.core.requireInput +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.backuplocal.fullbackup.OtherBackupItems import io.horizontalsystems.bankwallet.modules.contacts.screen.ConfirmationBottomSheet import io.horizontalsystems.bankwallet.modules.evmfee.ButtonsGroupWithShade @@ -75,13 +78,14 @@ class RestoreLocalFragment : BaseComposeFragment() { @Composable override fun GetContent(navController: NavController) { - val input = navController.getInput() + val input = navController.requireInput() RestoreLocalNavHost( - input?.jsonFile, - input?.fileName, + input.jsonFile, + input.fileName, + input.statPage, navController, - input?.popOffOnSuccess ?: R.id.restoreAccountFragment, - input?.popOffInclusive ?: false + input.popOffOnSuccess, + input.popOffInclusive ) { activity?.let { MainModule.startAsNewTask(it) } } } @@ -91,6 +95,7 @@ class RestoreLocalFragment : BaseComposeFragment() { val popOffInclusive: Boolean, val jsonFile: String, val fileName: String?, + val statPage: StatPage ) : Parcelable } @@ -98,6 +103,7 @@ class RestoreLocalFragment : BaseComposeFragment() { private fun RestoreLocalNavHost( backupJsonString: String?, fileName: String?, + statPage: StatPage, fragmentNavController: NavController, popUpToInclusiveId: Int, popUpInclusive: Boolean, @@ -105,7 +111,7 @@ private fun RestoreLocalNavHost( ) { val navController = rememberNavController() val mainViewModel: RestoreViewModel = viewModel() - val viewModel = viewModel(factory = RestoreLocalModule.Factory(backupJsonString, fileName)) + val viewModel = viewModel(factory = RestoreLocalModule.Factory(backupJsonString, fileName, statPage)) NavHost( navController = navController, startDestination = "restore_local", @@ -114,6 +120,7 @@ private fun RestoreLocalNavHost( RestoreLocalScreen( viewModel = viewModel, mainViewModel = mainViewModel, + statPage = statPage, onBackClick = { fragmentNavController.popBackStack() }, close = { fragmentNavController.popBackStack(popUpToInclusiveId, popUpInclusive) }, openSelectCoins = { navController.navigate("restore_select_coins") }, @@ -155,6 +162,7 @@ private fun RestoreLocalNavHost( private fun RestoreLocalScreen( viewModel: RestoreLocalViewModel, mainViewModel: RestoreViewModel, + statPage: StatPage, onBackClick: () -> Unit, close: () -> Unit, openSelectCoins: () -> Unit, @@ -187,11 +195,13 @@ private fun RestoreLocalScreen( LaunchedEffect(uiState.showSelectCoins) { uiState.showSelectCoins?.let { accountType -> - mainViewModel.setAccountData(accountType, viewModel.accountName, uiState.manualBackup, true) + mainViewModel.setAccountData(accountType, viewModel.accountName, uiState.manualBackup, true, statPage) keyboardController?.hide() delay(300) openSelectCoins.invoke() viewModel.onSelectCoinsShown() + + stat(page = statPage, event = StatEvent.Open(StatPage.RestoreSelect)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalModule.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalModule.kt index 607bafe93be..74ab5f119b6 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalModule.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalModule.kt @@ -3,6 +3,7 @@ package io.horizontalsystems.bankwallet.modules.restorelocal import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModelProvider import io.horizontalsystems.bankwallet.core.App +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.modules.backuplocal.fullbackup.BackupViewItemFactory @@ -11,10 +12,21 @@ import io.horizontalsystems.bankwallet.modules.backuplocal.fullbackup.SelectBack object RestoreLocalModule { - class Factory(private val backupJsonString: String?, private val fileName: String?) : ViewModelProvider.Factory { + class Factory( + private val backupJsonString: String?, + private val fileName: String?, + private val statPage: StatPage + ) : ViewModelProvider.Factory { @Suppress("UNCHECKED_CAST") override fun create(modelClass: Class): T { - return RestoreLocalViewModel(backupJsonString, App.accountFactory, App.backupProvider, BackupViewItemFactory(), fileName) as T + return RestoreLocalViewModel( + backupJsonString = backupJsonString, + accountFactory = App.accountFactory, + backupProvider = App.backupProvider, + backupViewItemFactory = BackupViewItemFactory(), + statPage = statPage, + fileName = fileName + ) as T } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalViewModel.kt index 700f115a017..646f4849359 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/restorelocal/RestoreLocalViewModel.kt @@ -6,6 +6,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.IAccountFactory import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.entities.DataState import io.horizontalsystems.bankwallet.modules.backuplocal.BackupLocalModule.WalletBackup @@ -27,6 +31,7 @@ class RestoreLocalViewModel( private val accountFactory: IAccountFactory, private val backupProvider: BackupProvider, private val backupViewItemFactory: BackupViewItemFactory, + private val statPage: StatPage, fileName: String?, ) : ViewModelUiState() { @@ -155,6 +160,8 @@ class RestoreLocalViewModel( try { backupProvider.restoreFullBackup(decryptedFullBackup, passphrase) restored = true + + stat(page = statPage, event = StatEvent.ImportFull) } catch (keyException: RestoreException.EncryptionKeyException) { parseError = keyException } catch (invalidPassword: RestoreException.InvalidPasswordException) { @@ -186,6 +193,8 @@ class RestoreLocalViewModel( backupProvider.restoreSingleWalletBackup(type, accountName, backup) restored = true } + + stat(page = statPage, event = StatEvent.ImportWallet(type.statAccountType)) } catch (keyException: RestoreException.EncryptionKeyException) { parseError = keyException } catch (invalidPassword: RestoreException.InvalidPasswordException) { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt index aea16b4bc36..92442e0f77c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/SendConfirmationScreen.kt @@ -25,6 +25,11 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.imageUrl +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.StatSection +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Address import io.horizontalsystems.bankwallet.entities.CurrencyValue import io.horizontalsystems.bankwallet.modules.amount.AmountInputType @@ -165,7 +170,16 @@ fun SendConfirmationScreen( value = address.hex, showAdd = contact == null, blockchainType = blockchainType, - navController = navController + navController = navController, + onCopy = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactNew)) + } ) } contact?.let { @@ -217,7 +231,11 @@ fun SendConfirmationScreen( .align(Alignment.BottomCenter) .padding(start = 16.dp, end = 16.dp, bottom = 32.dp), sendResult = sendResult, - onClickSend = onClickSend + onClickSend = { + onClickSend() + + stat(page = StatPage.SendConfirmation, event = StatEvent.Send) + } ) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/evm/confirmation/SendEvmConfirmationFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/evm/confirmation/SendEvmConfirmationFragment.kt index 469a1fe2aa5..bdd3f7ef28d 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/evm/confirmation/SendEvmConfirmationFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/evm/confirmation/SendEvmConfirmationFragment.kt @@ -23,6 +23,9 @@ import io.horizontalsystems.bankwallet.core.AppLogger import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInputX import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.evmfee.ButtonsGroupWithShade import io.horizontalsystems.bankwallet.modules.evmfee.EvmFeeCellViewModel import io.horizontalsystems.bankwallet.modules.send.evm.SendEvmData @@ -90,6 +93,8 @@ class SendEvmConfirmationFragment : BaseComposeFragment() { onSendClick = { logger.info("click send button") sendEvmTransactionViewModel.send(logger) + + stat(page = StatPage.SendConfirmation, event = StatEvent.Send) }) } @@ -168,7 +173,8 @@ private fun SendEvmConfirmationScreen( sendEvmTransactionViewModel, feeViewModel, nonceViewModel, - navController + navController, + StatPage.SendConfirmation ) } ButtonsGroupWithShade { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/tron/SendTronConfirmationScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/tron/SendTronConfirmationScreen.kt index 264e0459ae6..ae5d94dcbb1 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/tron/SendTronConfirmationScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/send/tron/SendTronConfirmationScreen.kt @@ -32,6 +32,11 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.HSCaution import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.StatSection +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.amount.AmountInputModeViewModel import io.horizontalsystems.bankwallet.modules.evmfee.FeeSettingsInfoDialog import io.horizontalsystems.bankwallet.modules.fee.HSFeeRaw @@ -95,7 +100,6 @@ fun SendTronConfirmationScreen( val activationFee = confirmationData.activationFee val resourcesConsumed = confirmationData.resourcesConsumed val memo = confirmationData.memo - val onClickSend = sendViewModel::onClickSend val view = LocalView.current when (sendResult) { @@ -181,7 +185,16 @@ fun SendTronConfirmationScreen( value = address.hex, showAdd = contact == null, blockchainType = blockchainType, - navController = navController + navController = navController, + onCopy = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = StatPage.SendConfirmation, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactNew)) + } ) } if (isInactiveAddress) { @@ -262,7 +275,11 @@ fun SendTronConfirmationScreen( .padding(start = 16.dp, end = 16.dp, bottom = 32.dp), sendResult = sendResult, - onClickSend = onClickSend, + onClickSend = { + sendViewModel.onClickSend() + + stat(page = StatPage.SendConfirmation, event = StatEvent.Send) + }, enabled = sendEnabled ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionView.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionView.kt index c7d0b732289..fb5da139959 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionView.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionView.kt @@ -24,6 +24,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.iconPlaceholder import io.horizontalsystems.bankwallet.core.imageUrl import io.horizontalsystems.bankwallet.core.shorten +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.evmfee.Cautions import io.horizontalsystems.bankwallet.modules.evmfee.EvmFeeCellViewModel import io.horizontalsystems.bankwallet.modules.fee.FeeCell @@ -59,6 +63,7 @@ fun SendEvmTransactionView( feeCellViewModel: EvmFeeCellViewModel, nonceViewModel: SendEvmNonceViewModel, navController: NavController, + statPage: StatPage ) { val items by transactionViewModel.viewItemsLiveData.observeAsState(listOf()) @@ -67,7 +72,7 @@ fun SendEvmTransactionView( Column { items.forEach { sectionViewItem -> - SectionView(sectionViewItem.viewItems, navController) + SectionView(sectionViewItem.viewItems, navController, statPage) } NonceView(nonceViewModel) @@ -120,7 +125,7 @@ private fun NonceView(nonceViewModel: SendEvmNonceViewModel) { } @Composable -private fun SectionView(viewItems: List, navController: NavController) { +private fun SectionView(viewItems: List, navController: NavController, statPage: StatPage) { Spacer(Modifier.height(16.dp)) CellUniversalLawrenceSection(viewItems) { item -> when (item) { @@ -131,7 +136,24 @@ private fun SectionView(viewItems: List, navController: NavController) is ViewItem.Amount -> Amount(item) is ViewItem.AmountWithTitle -> AmountWithTitle(item) is ViewItem.NftAmount -> NftAmount(item) - is ViewItem.Address -> TransactionInfoAddressCell(item.title, item.value, item.showAdd, item.blockchainType, navController) + is ViewItem.Address -> { + TransactionInfoAddressCell( + title = item.title, + value = item.value, + showAdd = item.showAdd, + blockchainType = item.blockchainType, + navController = navController, + onCopy = { + stat(page = statPage, section = item.statSection, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = statPage, section = item.statSection, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = statPage, section = item.statSection, event = StatEvent.Open(StatPage.ContactNew)) + } + ) + } is ViewItem.ContactItem -> TransactionInfoContactCell(item.contact.name) is ViewItem.Input -> TitleValueHex("Input", item.value.shorten(), item.value) is ViewItem.TokenItem -> Token(item) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionViewModel.kt index 3ee75d52ec4..ffd3be1970c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/sendevmtransaction/SendEvmTransactionViewModel.kt @@ -12,6 +12,7 @@ import io.horizontalsystems.bankwallet.core.ethereum.CautionViewItem import io.horizontalsystems.bankwallet.core.ethereum.CautionViewItemFactory import io.horizontalsystems.bankwallet.core.ethereum.EvmCoinServiceFactory import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatSection import io.horizontalsystems.bankwallet.modules.contacts.ContactsRepository import io.horizontalsystems.bankwallet.modules.contacts.model.Contact import io.horizontalsystems.bankwallet.modules.send.SendModule @@ -233,7 +234,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.Send_Confirmation_To), addressValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressTo ) ) @@ -273,7 +275,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.SwapSettings_RecipientAddressTitle), addressValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressRecipient ) ) contact?.let { @@ -403,7 +406,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.Send_Confirmation_To), addressValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressTo ) ) contact?.let { @@ -454,7 +458,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.Approve_Spender), addressValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressSpender ) ) contact?.let { @@ -511,7 +516,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.Send_Confirmation_To), toValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressTo ) ) contact?.let { @@ -550,7 +556,8 @@ class SendEvmTransactionViewModel( Translator.getString(R.string.Send_Confirmation_To), toValue, contact == null, - blockchainType + blockchainType, + StatSection.AddressTo ) ) contact?.let { @@ -701,7 +708,7 @@ sealed class ViewItem { val type: ValueType, ) : ViewItem() - class Address(val title: String, val value: String, val showAdd: Boolean, val blockchainType: BlockchainType) : ViewItem() + class Address(val title: String, val value: String, val showAdd: Boolean, val blockchainType: BlockchainType, val statSection: StatSection) : ViewItem() class Input(val value: String) : ViewItem() class TokenItem(val token: Token) : ViewItem() class ContactItem(val contact: Contact) : ViewItem() diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateAddressesFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateAddressesFragment.kt index 4aaf1cc7418..fa137feaba5 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateAddressesFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateAddressesFragment.kt @@ -20,6 +20,9 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.imageUrl +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.core.title import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.AppBar @@ -71,7 +74,8 @@ fun DonateScreen( DonateAddress( coinImageUrl = blockchainType.imageUrl, coinName = blockchainType.title, - address = address + address = address, + chainUid = blockchainType.uid ) VSpacer(24.dp) } @@ -86,7 +90,8 @@ fun DonateScreen( private fun DonateAddress( coinImageUrl: String, coinName: String, - address: String + address: String, + chainUid: String ) { val localView = LocalView.current @@ -97,6 +102,8 @@ private fun DonateAddress( onClick = { TextHelper.copyText(address) HudHelper.showSuccessMessage(localView, R.string.Hud_Text_Copied) + + stat(page = StatPage.DonateAddressList, event = StatEvent.CopyAddress(chainUid)) } ) { Image( @@ -120,6 +127,8 @@ private fun DonateAddress( onClick = { TextHelper.copyText(address) HudHelper.showSuccessMessage(localView, R.string.Hud_Text_Copied) + + stat(page = StatPage.DonateAddressList, event = StatEvent.CopyAddress(chainUid)) } ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateTokenSelectFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateTokenSelectFragment.kt index 72393870c20..d1201a7346c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateTokenSelectFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/donate/DonateTokenSelectFragment.kt @@ -20,6 +20,9 @@ import io.horizontalsystems.bankwallet.core.App import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.send.SendFragment import io.horizontalsystems.bankwallet.modules.tokenselect.TokenSelectScreen import io.horizontalsystems.bankwallet.modules.tokenselect.TokenSelectViewModel @@ -48,6 +51,8 @@ class DonateTokenSelectFragment : BaseComposeFragment() { donateAddress, ) ) + + stat(page = StatPage.Donate, event = StatEvent.OpenSend(it.wallet.token)) }, viewModel = viewModel(factory = TokenSelectViewModel.FactoryForSend()), emptyItemsText = stringResource(R.string.Balance_NoAssetsToSend) @@ -78,6 +83,8 @@ private fun DonateHeader(navController: NavController) { GetAddressCell { navController.slideFromRight(R.id.donateAddressesFragment) + + stat(page = StatPage.Donate, event = StatEvent.Open(StatPage.DonateAddressList)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/main/MainSettingsScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/main/MainSettingsScreen.kt index 01deb69ec55..9d2240bf0b5 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/main/MainSettingsScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/settings/main/MainSettingsScreen.kt @@ -39,6 +39,9 @@ import io.horizontalsystems.bankwallet.core.managers.RateAppManager import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.contacts.ContactsFragment import io.horizontalsystems.bankwallet.modules.contacts.Mode import io.horizontalsystems.bankwallet.modules.manageaccount.dialogs.BackupRequiredDialog @@ -100,6 +103,8 @@ private fun SettingSections( ComposeAppTheme.colors.jacob, onClick = { navController.slideFromRight(R.id.donateTokenSelectFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Donate)) } ) } @@ -118,6 +123,8 @@ private fun SettingSections( R.id.manageAccountsFragment, ManageAccountsModule.Mode.Manage ) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.ManageWallets)) } ) }, { @@ -126,6 +133,8 @@ private fun SettingSections( R.drawable.ic_blocks_20, onClick = { navController.slideFromRight(R.id.blockchainSettingsFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.BlockchainSettings)) } ) }, { @@ -138,6 +147,8 @@ private fun SettingSections( when (val state = viewModel.getWalletConnectSupportState()) { WCManager.SupportState.Supported -> { navController.slideFromRight(R.id.wcListFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.WalletConnect)) } WCManager.SupportState.NotSupportedDueToNoActiveAccount -> { @@ -150,6 +161,8 @@ private fun SettingSections( R.id.backupRequiredDialog, BackupRequiredDialog.Input(state.account, text) ) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.BackupRequired)) } is WCManager.SupportState.NotSupported -> { @@ -167,6 +180,8 @@ private fun SettingSections( R.drawable.ic_file_24, onClick = { navController.slideFromRight(R.id.backupManagerFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.BackupManager)) } ) } @@ -184,6 +199,8 @@ private fun SettingSections( showAlert = showAlertSecurityCenter, onClick = { navController.slideFromRight(R.id.securitySettingsFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Security)) } ) }, @@ -196,6 +213,8 @@ private fun SettingSections( R.id.contactsFragment, ContactsFragment.Input(Mode.Full) ) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Contacts)) } ) }, @@ -205,6 +224,8 @@ private fun SettingSections( R.drawable.ic_brush_20, onClick = { navController.slideFromRight(R.id.appearanceFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Appearance)) } ) }, @@ -230,6 +251,8 @@ private fun SettingSections( ComposeAppTheme.colors.jacob, onClick = { LinkHelper.openLinkInAppBrowser(context, App.appConfigProvider.appTelegramLink) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.ExternalTelegram)) } ) }, { @@ -239,6 +262,8 @@ private fun SettingSections( ComposeAppTheme.colors.jacob, onClick = { LinkHelper.openLinkInAppBrowser(context, App.appConfigProvider.appTwitterLink) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.ExternalTwitter)) } ) }) @@ -256,6 +281,8 @@ private fun SettingSections( R.drawable.ic_faq_20, onClick = { navController.slideFromRight(R.id.faqListFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Faq)) } ) }, { @@ -264,6 +291,8 @@ private fun SettingSections( R.drawable.ic_academy_20, onClick = { navController.slideFromRight(R.id.academyFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.Academy)) } ) }) @@ -279,25 +308,39 @@ private fun SettingSections( showAlert = showAlertAboutApp, onClick = { navController.slideFromRight(R.id.aboutAppFragment) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.AboutApp)) } ) }, { HsSettingCell( R.string.Settings_RateUs, R.drawable.ic_star_20, - onClick = { RateAppManager.openPlayMarket(context) } + onClick = { + RateAppManager.openPlayMarket(context) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.RateUs)) + } ) }, { HsSettingCell( R.string.Settings_ShareThisWallet, R.drawable.ic_share_20, - onClick = { shareAppLink(viewModel.appWebPageLink, context) } + onClick = { + shareAppLink(viewModel.appWebPageLink, context) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.TellFriends)) + } ) }, { HsSettingCell( R.string.SettingsContact_Title, R.drawable.ic_mail_24, - onClick = { navController.slideFromBottom(R.id.contactOptionsDialog) }, + onClick = { + navController.slideFromBottom(R.id.contactOptionsDialog) + + stat(page = StatPage.Settings, event = StatEvent.Open(StatPage.ContactUs)) + }, ) }) ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/swap/approve/confirmation/SwapApproveConfirmationFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/swap/approve/confirmation/SwapApproveConfirmationFragment.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/swap/confirmation/BaseSwapConfirmationFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/swap/confirmation/BaseSwapConfirmationFragment.kt new file mode 100644 index 00000000000..e69de29bb2d diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoFragment.kt index 941333c926e..c8dd413320b 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoFragment.kt @@ -15,6 +15,10 @@ import androidx.navigation.navGraphViewModels import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.coin.CoinFragment import io.horizontalsystems.bankwallet.modules.transactions.TransactionsModule import io.horizontalsystems.bankwallet.modules.transactions.TransactionsViewModel @@ -141,7 +145,11 @@ fun TransactionInfoSection( badge = viewItem.badge, coinIconPlaceholder = viewItem.coinIconPlaceholder, onClick = viewItem.coinUid?.let { - { navController.slideFromRight(R.id.coinFragment, CoinFragment.Input(it, "transaction_info")) } + { + navController.slideFromRight(R.id.coinFragment, CoinFragment.Input(it)) + + stat(page = StatPage.TransactionInfo, event = StatEvent.OpenCoin(it)) + } } ) } @@ -186,7 +194,16 @@ fun TransactionInfoSection( value = viewItem.value, showAdd = viewItem.showAdd, blockchainType = viewItem.blockchainType, - navController = navController + navController = navController, + onCopy = { + stat(page = StatPage.TransactionInfo, section = viewItem.statSection, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = StatPage.TransactionInfo, section = viewItem.statSection, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = StatPage.TransactionInfo, section = viewItem.statSection, event = StatEvent.Open(StatPage.ContactNew)) + } ) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItem.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItem.kt index 58cbdd82c6b..c4a25d05741 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItem.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItem.kt @@ -1,6 +1,7 @@ package io.horizontalsystems.bankwallet.modules.transactionInfo import androidx.compose.runtime.Composable +import io.horizontalsystems.bankwallet.core.stats.StatSection import io.horizontalsystems.bankwallet.modules.contacts.model.Contact import io.horizontalsystems.bankwallet.modules.transactions.TransactionStatus import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme @@ -33,7 +34,7 @@ sealed class TransactionInfoViewItem { class PriceWithToggle(val title: String, val valueOne: String, val valueTwo: String) : TransactionInfoViewItem() - class Address(val title: String, val value: String, val showAdd: Boolean, val blockchainType: BlockchainType) : TransactionInfoViewItem() + class Address(val title: String, val value: String, val showAdd: Boolean, val blockchainType: BlockchainType, val statSection: StatSection) : TransactionInfoViewItem() class ContactItem(val contact: Contact) : TransactionInfoViewItem() diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItemFactory.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItemFactory.kt index 7d170393812..ca6e88b80d0 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItemFactory.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/TransactionInfoViewItemFactory.kt @@ -6,6 +6,7 @@ import io.horizontalsystems.bankwallet.core.adapters.TonTransactionRecord import io.horizontalsystems.bankwallet.core.isCustom import io.horizontalsystems.bankwallet.core.managers.EvmLabelManager import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatSection import io.horizontalsystems.bankwallet.entities.CurrencyValue import io.horizontalsystems.bankwallet.entities.LastBlockInfo import io.horizontalsystems.bankwallet.entities.TransactionValue @@ -532,7 +533,7 @@ class TransactionInfoViewItemFactory( if (!mint && fromAddress != null) { val contact = getContact(fromAddress) items.add( - Address(getString(R.string.TransactionInfo_From), fromAddress, contact == null, blockchainType) + Address(getString(R.string.TransactionInfo_From), fromAddress, contact == null, blockchainType, StatSection.AddressFrom) ) contact?.let { items.add( @@ -578,7 +579,7 @@ class TransactionInfoViewItemFactory( if (!burn && toAddress != null) { val contact = getContact(toAddress) items.add( - Address(getString(R.string.TransactionInfo_To), toAddress, contact == null, blockchainType) + Address(getString(R.string.TransactionInfo_To), toAddress, contact == null, blockchainType, StatSection.AddressTo) ) contact?.let { @@ -757,7 +758,7 @@ class TransactionInfoViewItemFactory( value.badge, AmountType.Approved ), - Address(getString(R.string.TransactionInfo_Spender), spenderAddress, contact == null, blockchainType) + Address(getString(R.string.TransactionInfo_Spender), spenderAddress, contact == null, blockchainType, StatSection.AddressSpender) ) contact?.let { @@ -831,7 +832,8 @@ class TransactionInfoViewItemFactory( getString(R.string.TransactionInfo_RecipientHash), recipient, contact == null, - blockchainType + blockchainType, + StatSection.AddressRecipient ) ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/options/TransactionSpeedUpCancelFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/options/TransactionSpeedUpCancelFragment.kt index 4527f7abc5c..7e45ed6f899 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/options/TransactionSpeedUpCancelFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/options/TransactionSpeedUpCancelFragment.kt @@ -25,6 +25,7 @@ import io.horizontalsystems.bankwallet.core.AppLogger import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInputX import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatPage import io.horizontalsystems.bankwallet.modules.evmfee.ButtonsGroupWithShade import io.horizontalsystems.bankwallet.modules.evmfee.EvmFeeCellViewModel import io.horizontalsystems.bankwallet.modules.send.evm.settings.SendEvmNonceViewModel @@ -179,6 +180,7 @@ private fun TransactionSpeedUpCancelScreen( feeViewModel, nonceViewModel, navController, + StatPage.Resend ) } ButtonsGroupWithShade { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/resendbitcoin/ResendBitcoinFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/resendbitcoin/ResendBitcoinFragment.kt index d2ab146293f..025a38736bb 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/resendbitcoin/ResendBitcoinFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactionInfo/resendbitcoin/ResendBitcoinFragment.kt @@ -26,6 +26,11 @@ import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.HSCaution import io.horizontalsystems.bankwallet.core.getInputX import io.horizontalsystems.bankwallet.core.imageUrl +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.StatSection +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.transactionrecords.bitcoin.BitcoinOutgoingTransactionRecord import io.horizontalsystems.bankwallet.modules.amount.AmountInputType import io.horizontalsystems.bankwallet.modules.evmfee.EvmSettingsInput @@ -170,7 +175,16 @@ class ResendBitcoinFragment : BaseComposeFragment() { value = uiState.address.hex, showAdd = uiState.contact == null, blockchainType = uiState.blockchainType, - navController = navController + navController = navController, + onCopy = { + stat(page = StatPage.Resend, section = StatSection.AddressTo, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = StatPage.Resend, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = StatPage.Resend, section = StatSection.AddressTo, event = StatEvent.Open(StatPage.ContactNew)) + } ) } uiState.contact?.let { diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactions/TransactionsScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactions/TransactionsScreen.kt index ac3021c10ea..b91b865411e 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactions/TransactionsScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/transactions/TransactionsScreen.kt @@ -42,6 +42,10 @@ import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statTab import io.horizontalsystems.bankwallet.entities.ViewState import io.horizontalsystems.bankwallet.modules.balance.BalanceAccountsViewModel import io.horizontalsystems.bankwallet.modules.balance.BalanceModule @@ -89,6 +93,8 @@ fun TransactionsScreen( showAlertDot = showFilterAlertDot, onClick = { navController.slideFromRight(R.id.transactionFilterFragment) + + stat(page = StatPage.Transactions, event = StatEvent.Open(StatPage.TransactionFilter)) }, ) ) @@ -96,7 +102,11 @@ fun TransactionsScreen( filterTypes?.let { filterTypes -> FilterTypeTabs( filterTypes = filterTypes, - onTransactionTypeClick = viewModel::setFilterTransactionType + onTransactionTypeClick = { + viewModel.setFilterTransactionType(it) + + stat(page = StatPage.Transactions, event = StatEvent.SwitchTab(it.statTab)) + } ) } @@ -160,6 +170,8 @@ private fun onTransactionClick( viewModel.tmpItemToShow = transactionItem navController.slideFromBottom(R.id.transactionInfoFragment) + + stat(page = StatPage.Transactions, event = StatEvent.Open(StatPage.TransactionInfo)) } @OptIn(ExperimentalFoundationApi::class) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/unlinkaccount/UnlinkAccountDialog.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/unlinkaccount/UnlinkAccountDialog.kt index 7e3ad1ebbb6..74d81fe9b85 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/unlinkaccount/UnlinkAccountDialog.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/unlinkaccount/UnlinkAccountDialog.kt @@ -21,6 +21,10 @@ import androidx.lifecycle.viewmodel.compose.viewModel import androidx.navigation.NavController import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.requireInput +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.entities.Account import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme import io.horizontalsystems.bankwallet.ui.compose.components.ButtonPrimaryRed @@ -111,6 +115,8 @@ private fun UnlinkAccountScreen(navController: NavController, account: Account) viewModel.onUnlink() HudHelper.showSuccessMessage(view, doneConfirmationMessage) navController.popBackStack() + + stat(page = StatPage.UnlinkWallet, event = StatEvent.Delete(StatEntity.Wallet)) }, enabled = unlinkEnabled ) diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/walletconnect/request/sendtransaction/WCSendEthScreen.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/walletconnect/request/sendtransaction/WCSendEthScreen.kt index 59e3ad4486a..f82379b6ab0 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/walletconnect/request/sendtransaction/WCSendEthScreen.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/walletconnect/request/sendtransaction/WCSendEthScreen.kt @@ -18,6 +18,10 @@ import io.horizontalsystems.bankwallet.core.AppLogger import io.horizontalsystems.bankwallet.core.providers.Translator import io.horizontalsystems.bankwallet.core.shorten import io.horizontalsystems.bankwallet.core.slideFromBottom +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.evmfee.Cautions import io.horizontalsystems.bankwallet.modules.evmfee.EvmFeeCellViewModel import io.horizontalsystems.bankwallet.modules.fee.FeeCell @@ -105,13 +109,25 @@ fun WCSendEthRequestScreen( item.type ) - is ViewItem.Address -> TransactionInfoAddressCell( - item.title, - item.value, - item.showAdd, - item.blockchainType, - navController - ) + is ViewItem.Address -> { + TransactionInfoAddressCell( + item.title, + item.value, + item.showAdd, + item.blockchainType, + navController, + onCopy = { + stat(page = StatPage.WalletConnect, section = item.statSection, event = StatEvent.Copy(StatEntity.Address)) + }, + onAddToExisting = { + stat(page = StatPage.WalletConnect, section = item.statSection, event = StatEvent.Open(StatPage.ContactAddToExisting)) + }, + onAddToNew = { + stat(page = StatPage.WalletConnect, section = item.statSection, event = StatEvent.Open(StatPage.ContactNew)) + } + ) + + } is ViewItem.ContactItem -> TransactionInfoContactCell( item.contact.name diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressFragment.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressFragment.kt index ebb84036e5d..8ba485458df 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressFragment.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressFragment.kt @@ -20,6 +20,10 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.BaseComposeFragment import io.horizontalsystems.bankwallet.core.getInput import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat import io.horizontalsystems.bankwallet.modules.manageaccounts.ManageAccountsModule import io.horizontalsystems.bankwallet.modules.watchaddress.selectblockchains.SelectBlockchainsFragment import io.horizontalsystems.bankwallet.ui.compose.ComposeAppTheme @@ -135,10 +139,20 @@ fun WatchAddressScreen(navController: NavController, popUpToInclusiveId: Int, in modifier = Modifier.padding(horizontal = 16.dp), hint = stringResource(id = R.string.Watch_Address_Hint), qrScannerEnabled = true, - state = uiState.inputState - ) { - viewModel.onEnterInput(it) - } + state = uiState.inputState, + onValueChange = { + viewModel.onEnterInput(it) + }, + onClear = { + stat(page = StatPage.WatchWallet, event = StatEvent.Clear(StatEntity.Key)) + }, + onScanQR = { + stat(page = StatPage.WatchWallet, event = StatEvent.ScanQr(StatEntity.Key)) + }, + onPaste = { + stat(page = StatPage.WatchWallet, event = StatEvent.Paste(StatEntity.Key)) + } + ) Spacer(Modifier.height(32.dp)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressViewModel.kt index 5f3503a2bf8..4a3b80857f7 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/WatchAddressViewModel.kt @@ -4,6 +4,10 @@ import androidx.lifecycle.viewModelScope import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.providers.Translator +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.entities.Address import io.horizontalsystems.bankwallet.entities.BitcoinAddress @@ -177,6 +181,8 @@ class WatchAddressViewModel( accountCreated = true emitState() + + stat(page = StatPage.WatchWallet, event = StatEvent.WatchWallet(accountType.statAccountType)) } catch (_: Exception) { } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/selectblockchains/SelectBlockchainsViewModel.kt b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/selectblockchains/SelectBlockchainsViewModel.kt index db04cac5fd5..2610b6f2959 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/selectblockchains/SelectBlockchainsViewModel.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/modules/watchaddress/selectblockchains/SelectBlockchainsViewModel.kt @@ -5,6 +5,10 @@ import io.horizontalsystems.bankwallet.core.ViewModelUiState import io.horizontalsystems.bankwallet.core.badge import io.horizontalsystems.bankwallet.core.description import io.horizontalsystems.bankwallet.core.imageUrl +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statAccountType import io.horizontalsystems.bankwallet.entities.AccountType import io.horizontalsystems.bankwallet.modules.market.ImageSource import io.horizontalsystems.bankwallet.modules.restoreaccount.restoreblockchains.CoinViewItem @@ -97,6 +101,8 @@ class SelectBlockchainsViewModel( service.watchTokens(accountType, selectedCoins.toList(), accountName) accountCreated = true emitState() + + stat(page = StatPage.WatchWallet, event = StatEvent.WatchWallet(accountType.statAccountType)) } } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/Forms.kt b/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/Forms.kt index eef77e6bf89..7828457f10c 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/Forms.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/Forms.kt @@ -393,6 +393,9 @@ fun FormsInputMultiline( visualTransformation: VisualTransformation = VisualTransformation.None, keyboardOptions: KeyboardOptions = KeyboardOptions.Default, onValueChange: (String) -> Unit, + onClear: (() -> Unit)? = null, + onPaste: (() -> Unit)? = null, + onScanQR: (() -> Unit)? = null ) { val context = LocalContext.current @@ -510,6 +513,8 @@ fun FormsInputMultiline( val text = textPreprocessor.process("") textState = textState.copy(text = text, selection = TextRange(0)) onValueChange.invoke(text) + + onClear?.invoke() } ) } else { @@ -529,6 +534,8 @@ fun FormsInputMultiline( icon = R.drawable.ic_qr_scan_20, onClick = { qrScannerLauncher.launch(QRScannerActivity.getScanQrIntent(context)) + + onScanQR?.invoke() } ) } @@ -546,6 +553,8 @@ fun FormsInputMultiline( textState = textState.copy(text = textProcessed, selection = TextRange(textProcessed.length)) onValueChange.invoke(textProcessed) } + + onPaste?.invoke() }, ) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/TransactionInfoCells.kt b/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/TransactionInfoCells.kt index a90c49f6ab4..3d37d9c2191 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/TransactionInfoCells.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/ui/compose/components/TransactionInfoCells.kt @@ -34,6 +34,12 @@ import io.horizontalsystems.bankwallet.R import io.horizontalsystems.bankwallet.core.shorten import io.horizontalsystems.bankwallet.core.slideFromBottom import io.horizontalsystems.bankwallet.core.slideFromRight +import io.horizontalsystems.bankwallet.core.stats.StatEntity +import io.horizontalsystems.bankwallet.core.stats.StatEvent +import io.horizontalsystems.bankwallet.core.stats.StatPage +import io.horizontalsystems.bankwallet.core.stats.StatSection +import io.horizontalsystems.bankwallet.core.stats.stat +import io.horizontalsystems.bankwallet.core.stats.statResendType import io.horizontalsystems.bankwallet.modules.contacts.ContactsFragment import io.horizontalsystems.bankwallet.modules.contacts.ContactsModule import io.horizontalsystems.bankwallet.modules.contacts.Mode @@ -127,7 +133,7 @@ fun TransactionNftAmountCell( Column { subhead2_leah(text = title) VSpacer(height = 1.dp) - caption_grey(text = badge ?: stringResource(id =R.string.CoinPlatforms_Native)) + caption_grey(text = badge ?: stringResource(id = R.string.CoinPlatforms_Native)) } HSpacer(8.dp) Column( @@ -177,7 +183,7 @@ fun TransactionAmountCell( Column { subhead2_leah(text = title) VSpacer(height = 1.dp) - caption_grey(text = badge ?: stringResource(id =R.string.CoinPlatforms_Native)) + caption_grey(text = badge ?: stringResource(id = R.string.CoinPlatforms_Native)) } HFillSpacer(minWidth = 8.dp) Column(horizontalAlignment = Alignment.End) { @@ -224,7 +230,11 @@ fun PriceWithToggleCell( ) HSpacer(8.dp) HsIconButton( - onClick = { showValueOne = !showValueOne }, + onClick = { + showValueOne = !showValueOne + + stat(page = StatPage.TransactionInfo, event = StatEvent.TogglePrice) + }, modifier = Modifier .size(28.dp) .clip(CircleShape), @@ -239,7 +249,16 @@ fun PriceWithToggleCell( } @Composable -fun TransactionInfoAddressCell(title: String, value: String, showAdd: Boolean, blockchainType: BlockchainType?, navController: NavController? = null) { +fun TransactionInfoAddressCell( + title: String, + value: String, + showAdd: Boolean, + blockchainType: BlockchainType?, + navController: NavController? = null, + onCopy: (() -> Unit)? = null, + onAddToExisting: (() -> Unit)? = null, + onAddToNew: (() -> Unit)? = null, +) { val view = LocalView.current var showSaveAddressDialog by remember { mutableStateOf(false) } RowUniversal( @@ -268,6 +287,8 @@ fun TransactionInfoAddressCell(title: String, value: String, showAdd: Boolean, b onClick = { TextHelper.copyText(value) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + onCopy?.invoke() } ) } @@ -285,10 +306,12 @@ fun TransactionInfoAddressCell(title: String, value: String, showAdd: Boolean, b blockchainType?.let { val args = when (action) { ContactsModule.AddAddressAction.AddToNewContact -> { + onAddToNew?.invoke() ContactsFragment.Input(Mode.AddAddressToNewContact(blockchainType, value)) - } + ContactsModule.AddAddressAction.AddToExistingContact -> { + onAddToExisting?.invoke() ContactsFragment.Input(Mode.AddAddressToExistingContact(blockchainType, value)) } } @@ -327,14 +350,21 @@ fun TransactionInfoStatusCell( Spacer(modifier = Modifier.width(8.dp)) HsIconButton( modifier = Modifier.size(20.dp), - onClick = { navController.slideFromBottom(R.id.statusInfoDialog) } + onClick = { + navController.slideFromBottom(R.id.statusInfoDialog) + stat(page = StatPage.TransactionInfo, section = StatSection.Status, event = StatEvent.Open(StatPage.Info)) + } ) { Image( painter = painterResource(R.drawable.ic_info_20), contentDescription = null ) } - Spacer(Modifier.weight(1f).defaultMinSize(minWidth = 8.dp)) + Spacer( + Modifier + .weight(1f) + .defaultMinSize(minWidth = 8.dp) + ) subhead1_leah( text = stringResource(statusTitle(status)), maxLines = 1, @@ -350,6 +380,7 @@ fun TransactionInfoStatusCell( tint = ComposeAppTheme.colors.remus ) } + TransactionStatus.Failed -> { Icon( painter = painterResource(id = R.drawable.ic_attention_20), @@ -357,9 +388,11 @@ fun TransactionInfoStatusCell( tint = ComposeAppTheme.colors.lucian ) } + TransactionStatus.Pending -> { HSCircularProgressIndicator(progress = 0.15f, size = 20.dp) } + is TransactionStatus.Processing -> { HSCircularProgressIndicator(progress = status.progress, size = 20.dp) } @@ -461,6 +494,8 @@ fun TransactionInfoTransactionHashCell(transactionHash: String) { onClick = { TextHelper.copyText(transactionHash) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + stat(page = StatPage.TransactionInfo, event = StatEvent.Copy(StatEntity.TransactionId)) } ) Spacer(modifier = Modifier.width(8.dp)) @@ -472,6 +507,8 @@ fun TransactionInfoTransactionHashCell(transactionHash: String) { putExtra(Intent.EXTRA_TEXT, transactionHash) type = "text/plain" }) + + stat(page = StatPage.TransactionInfo, event = StatEvent.Share(StatEntity.TransactionId)) } ) } @@ -485,7 +522,11 @@ fun TransactionInfoExplorerCell( val context = LocalContext.current RowUniversal( modifier = Modifier.padding(horizontal = 16.dp), - onClick = { LinkHelper.openLinkInAppBrowser(context, url) } + onClick = { + LinkHelper.openLinkInAppBrowser(context, url) + + stat(page = StatPage.TransactionInfo, event = StatEvent.Open(StatPage.ExternalBlockExplorer)) + } ) { Image( modifier = Modifier.size(20.dp), @@ -523,6 +564,8 @@ fun TransactionInfoRawTransaction(rawTransaction: () -> String?) { rawTransaction()?.let { TextHelper.copyText(it) HudHelper.showSuccessMessage(view, R.string.Hud_Text_Copied) + + stat(page = StatPage.TransactionInfo, event = StatEvent.Copy(StatEntity.RawTransaction)) } } ) @@ -555,6 +598,8 @@ fun TransactionInfoBtcLockCell( R.id.transactionLockTimeInfoFragment, TransactionLockTimeInfoFragment.Input(lockTime) ) + + stat(page = StatPage.TransactionInfo, section = StatSection.TimeLock, event = StatEvent.Open(StatPage.Info)) } ) { Icon( @@ -597,6 +642,8 @@ fun TransactionInfoDoubleSpendCell( conflictingHash ) ) + + stat(page = StatPage.TransactionInfo, event = StatEvent.Open(StatPage.DoubleSpend)) } ) { Icon( @@ -680,6 +727,8 @@ private fun openTransactionOptionsModule( BlockchainType.Ton, is BlockchainType.Unsupported -> Unit } + + stat(page = StatPage.TransactionInfo, event = StatEvent.OpenResend(blockchainType.uid, type.statResendType)) } private fun statusTitle(status: TransactionStatus) = when (status) { @@ -695,12 +744,15 @@ private fun SubHead2ColoredValue(value: ColoredValue) { ColorName.Remus -> { subhead2_remus(text = value.value) } + ColorName.Lucian -> { subhead2_lucian(text = value.value) } + ColorName.Grey -> { subhead2_grey(text = value.value) } + ColorName.Leah -> { subhead2_leah(text = value.value) } @@ -714,12 +766,15 @@ private fun SubHead1ColoredValue(value: ColoredValue) { ColorName.Remus -> { subhead1_remus(text = value.value) } + ColorName.Lucian -> { subhead1_lucian(text = value.value) } + ColorName.Grey -> { subhead1_grey(text = value.value) } + ColorName.Leah -> { subhead2_leah(text = value.value) } diff --git a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt index b67d8758c77..ac19e9de995 100644 --- a/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt +++ b/app/src/main/java/io/horizontalsystems/bankwallet/widgets/MarketWidgetRepository.kt @@ -102,7 +102,7 @@ class MarketWidgetRepository( } private suspend fun getTopGainers(): List { - val marketItems = marketKit.marketInfosSingle(topGainers, currency.code, false, "widget") + val marketItems = marketKit.marketInfosSingle(topGainers, currency.code, false) .await() .map { MarketItem.createFromCoinMarket(it, currency) } @@ -121,7 +121,7 @@ class MarketWidgetRepository( if (favoriteCoins.isNotEmpty()) { val favoriteCoinUids = favoriteCoins.map { it.coinUid } val sortingField = if(sortDescending) SortingField.TopGainers else SortingField.TopLosers - marketItems = marketKit.marketInfosSingle(favoriteCoinUids, currency.code, "widget") + marketItems = marketKit.marketInfosSingle(favoriteCoinUids, currency.code) .await() .map { marketInfo -> MarketItem.createFromCoinMarket(marketInfo, currency, period)