diff --git a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/GovernanceNavigationModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/GovernanceNavigationModule.kt index 7334ef1e45..6baa54624d 100644 --- a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/GovernanceNavigationModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/GovernanceNavigationModule.kt @@ -10,6 +10,7 @@ import io.novafoundation.nova.app.root.navigation.navigators.governance.TinderGo import io.novafoundation.nova.common.di.scope.ApplicationScope import io.novafoundation.nova.common.resources.ContextManager import io.novafoundation.nova.feature_account_api.presenatation.account.wallet.list.SelectTracksCommunicator +import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vote.setup.tindergov.TinderGovVoteCommunicator @@ -21,8 +22,9 @@ class GovernanceNavigationModule { fun provideRouter( navigationHoldersRegistry: NavigationHoldersRegistry, commonNavigator: Navigator, - contextManager: ContextManager - ): GovernanceRouter = GovernanceNavigator(navigationHoldersRegistry, commonNavigator, contextManager) + contextManager: ContextManager, + dAppRouter: DAppRouter + ): GovernanceRouter = GovernanceNavigator(navigationHoldersRegistry, commonNavigator, contextManager, dAppRouter) @Provides @ApplicationScope diff --git a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/RelayStakingNavigationModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/RelayStakingNavigationModule.kt index c0fc20e345..9f3d598595 100644 --- a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/RelayStakingNavigationModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/RelayStakingNavigationModule.kt @@ -6,6 +6,7 @@ import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRe import io.novafoundation.nova.app.root.navigation.navigators.Navigator import io.novafoundation.nova.app.root.navigation.navigators.staking.relaychain.RelayStakingNavigator import io.novafoundation.nova.common.di.scope.ApplicationScope +import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter import io.novafoundation.nova.feature_staking_impl.presentation.StakingRouter @@ -17,8 +18,9 @@ class RelayStakingNavigationModule { fun provideRelayStakingRouter( navigationHoldersRegistry: NavigationHoldersRegistry, navigator: Navigator, - dashboardRouter: StakingDashboardRouter + dashboardRouter: StakingDashboardRouter, + dAppRouter: DAppRouter ): StakingRouter { - return RelayStakingNavigator(navigationHoldersRegistry, navigator, dashboardRouter) + return RelayStakingNavigator(navigationHoldersRegistry, navigator, dashboardRouter, dAppRouter) } } diff --git a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/StakingNavigationModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/StakingNavigationModule.kt index e92110bcdf..dd97c19eeb 100644 --- a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/StakingNavigationModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/staking/StakingNavigationModule.kt @@ -21,8 +21,8 @@ class StakingNavigationModule { @Provides @ApplicationScope - fun provideStakingDashboardNavigator(): StakingDashboardNavigator { - return StakingDashboardNavigator() + fun provideStakingDashboardNavigator(navigationHoldersRegistry: NavigationHoldersRegistry): StakingDashboardNavigator { + return StakingDashboardNavigator(navigationHoldersRegistry) } @Provides diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/governance/GovernanceNavigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/governance/GovernanceNavigator.kt index 8147529bf8..53b1fca502 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/governance/GovernanceNavigator.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/governance/GovernanceNavigator.kt @@ -8,7 +8,7 @@ import io.novafoundation.nova.app.root.navigation.navigators.Navigator import io.novafoundation.nova.common.resources.ContextManager import io.novafoundation.nova.common.utils.showBrowser import io.novafoundation.nova.feature_dapp_api.presentation.browser.main.DAppBrowserPayload -import io.novafoundation.nova.feature_dapp_impl.presentation.browser.main.DAppBrowserFragment +import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter import io.novafoundation.nova.feature_governance_impl.BuildConfig import io.novafoundation.nova.feature_governance_impl.presentation.GovernanceRouter import io.novafoundation.nova.feature_governance_impl.presentation.common.description.DescriptionFragment @@ -47,7 +47,8 @@ import io.novafoundation.nova.feature_governance_impl.presentation.referenda.vot class GovernanceNavigator( navigationHoldersRegistry: NavigationHoldersRegistry, private val commonNavigator: Navigator, - private val contextManager: ContextManager + private val contextManager: ContextManager, + private val dAppRouter: DAppRouter ) : BaseNavigator(navigationHoldersRegistry), GovernanceRouter { override fun openReferendum(payload: ReferendumDetailsPayload) { @@ -235,9 +236,7 @@ class GovernanceNavigator( } override fun openDAppBrowser(url: String) { - navigationBuilder().action(R.id.action_referendumDetailsFragment_to_DAppBrowserGraph) - .setArgs(DAppBrowserFragment.getBundle(DAppBrowserPayload.Address(url))) - .navigateInFirstAttachedContext() + dAppRouter.openDAppBrowser(DAppBrowserPayload.Address(url)) } override fun openReferendumDescription(payload: DescriptionPayload) { diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/StakingDashboardNavigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/StakingDashboardNavigator.kt index 5e00d65277..dcccd4be36 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/StakingDashboardNavigator.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/StakingDashboardNavigator.kt @@ -3,11 +3,15 @@ package io.novafoundation.nova.app.root.navigation.navigators.staking import androidx.lifecycle.MutableLiveData import androidx.navigation.NavController import io.novafoundation.nova.app.R +import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator +import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry import io.novafoundation.nova.common.utils.Event import io.novafoundation.nova.common.utils.event import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter -class StakingDashboardNavigator : StakingDashboardRouter { +class StakingDashboardNavigator( + navigationHoldersRegistry: NavigationHoldersRegistry +) : BaseNavigator(navigationHoldersRegistry), StakingDashboardRouter { private var stakingTabNavController: NavController? = null private var pendingAction: Int? = null @@ -36,7 +40,9 @@ class StakingDashboardNavigator : StakingDashboardRouter { } override fun returnToStakingDashboard() { - stakingTabNavController?.navigate(R.id.back_to_main) + navigationBuilder() + .action(R.id.back_to_main) + .navigateInFirstAttachedContext() returnToStakingTabRoot() scrollToDashboardTopEvent.value = Unit.event() diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/relaychain/RelayStakingNavigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/relaychain/RelayStakingNavigator.kt index 53c1d7ad81..9407fd8adb 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/relaychain/RelayStakingNavigator.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/navigators/staking/relaychain/RelayStakingNavigator.kt @@ -5,7 +5,7 @@ import io.novafoundation.nova.app.root.navigation.navigators.BaseNavigator import io.novafoundation.nova.app.root.navigation.navigators.NavigationHoldersRegistry import io.novafoundation.nova.app.root.navigation.navigators.Navigator import io.novafoundation.nova.feature_dapp_api.presentation.browser.main.DAppBrowserPayload -import io.novafoundation.nova.feature_dapp_impl.presentation.browser.main.DAppBrowserFragment +import io.novafoundation.nova.feature_dapp_impl.presentation.DAppRouter import io.novafoundation.nova.feature_staking_impl.domain.staking.redeem.RedeemConsequences import io.novafoundation.nova.feature_staking_impl.presentation.StakingDashboardRouter import io.novafoundation.nova.feature_staking_impl.presentation.StakingRouter @@ -47,6 +47,7 @@ class RelayStakingNavigator( navigationHoldersRegistry: NavigationHoldersRegistry, private val commonNavigator: Navigator, private val stakingDashboardRouter: StakingDashboardRouter, + private val dAppRouter: DAppRouter ) : BaseNavigator(navigationHoldersRegistry), StakingRouter { override fun returnToStakingMain() { @@ -286,8 +287,6 @@ class RelayStakingNavigator( } override fun openDAppBrowser(url: String) { - navigationBuilder().action(R.id.action_open_dappBrowser) - .setArgs(DAppBrowserFragment.getBundle(DAppBrowserPayload.Address(url))) - .navigateInFirstAttachedContext() + dAppRouter.openDAppBrowser(DAppBrowserPayload.Address(url)) } } diff --git a/app/src/main/res/navigation/referendum_details_graph.xml b/app/src/main/res/navigation/referendum_details_graph.xml index a2f4eb2114..03d3d74b9d 100644 --- a/app/src/main/res/navigation/referendum_details_graph.xml +++ b/app/src/main/res/navigation/referendum_details_graph.xml @@ -21,14 +21,6 @@ app:popUpTo="@id/referendumDetailsFragment" app:popUpToInclusive="true" /> - - - - } + +suspend fun DAppMetadataRepository.getDAppIfSyncedOrSync(baseUrl: String): DappMetadata? { + return if (isDAppsSynced()) { + getDAppMetadata(baseUrl) + } else { + syncAndGetDapp(baseUrl) + } +} diff --git a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/RealDAppMetadataRepository.kt b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/RealDAppMetadataRepository.kt index 6064711a70..8c999fc981 100644 --- a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/RealDAppMetadataRepository.kt +++ b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/RealDAppMetadataRepository.kt @@ -24,6 +24,10 @@ class RealDAppMetadataRepository( private val dappMetadatasFlow = MutableSharedFlow(replay = 1, onBufferOverflow = BufferOverflow.DROP_OLDEST) + override suspend fun isDAppsSynced(): Boolean { + return dappMetadatasFlow.replayCache.isNotEmpty() + } + override suspend fun syncDAppMetadatas() { val response = retryUntilDone { dappMetadataApi.getParachainMetadata(remoteApiUrl) } val dappMetadatas = mapDAppMetadataResponseToDAppMetadatas(response) diff --git a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/tabs/RealBrowserTabRepository.kt b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/tabs/RealBrowserTabRepository.kt index 372109b757..f64c320e5c 100644 --- a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/tabs/RealBrowserTabRepository.kt +++ b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/data/repository/tabs/RealBrowserTabRepository.kt @@ -52,11 +52,11 @@ class RealBrowserTabRepository( } override suspend fun changeCurrentUrl(tabId: String, url: String) { - browserTabsDao.updateCurrentUrl(tabId, url) + withContext(Dispatchers.Default) { browserTabsDao.updateCurrentUrl(tabId, url) } } override suspend fun changeKnownDAppMetadata(tabId: String, dappIconUrl: String?) { - browserTabsDao.updateKnownDAppMetadata(tabId, dappIconUrl) + withContext(Dispatchers.Default) { browserTabsDao.updateKnownDAppMetadata(tabId, dappIconUrl) } } } diff --git a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/utils/tabs/RealBrowserTabService.kt b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/utils/tabs/RealBrowserTabService.kt index bf1943e836..7fc9e2381b 100644 --- a/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/utils/tabs/RealBrowserTabService.kt +++ b/feature-dapp-impl/src/main/java/io/novafoundation/nova/feature_dapp_impl/utils/tabs/RealBrowserTabService.kt @@ -5,6 +5,7 @@ import io.novafoundation.nova.common.utils.Urls import io.novafoundation.nova.common.utils.coroutines.RootScope import io.novafoundation.nova.feature_account_api.domain.interfaces.AccountRepository import io.novafoundation.nova.feature_dapp_api.data.repository.DAppMetadataRepository +import io.novafoundation.nova.feature_dapp_api.data.repository.getDAppIfSyncedOrSync import io.novafoundation.nova.feature_dapp_impl.data.repository.tabs.BrowserTabInternalRepository import io.novafoundation.nova.feature_dapp_impl.utils.tabs.models.BrowserTab import io.novafoundation.nova.feature_dapp_impl.utils.tabs.models.CurrentTabState @@ -23,7 +24,6 @@ import kotlinx.coroutines.flow.combine import kotlinx.coroutines.flow.flatMapLatest import kotlinx.coroutines.flow.map import kotlinx.coroutines.launch -import kotlinx.coroutines.withContext class RealBrowserTabService( private val dAppMetadataRepository: DAppMetadataRepository, @@ -47,9 +47,8 @@ class RealBrowserTabService( override val tabStateFlow = combine( selectedTabIdFlow, - accountRepository.selectedMetaAccountFlow(), allTabsFlow - ) { selectedTabId, metaAccount, allTabs -> + ) { selectedTabId, allTabs -> TabsState( tabs = allTabs.values.toList(), selectedTab = currentTabState(selectedTabId, allTabs) @@ -76,18 +75,22 @@ class RealBrowserTabService( selectTab(null) } + // Create a new browser tab and save it to persistent storage + // Then we sync dapp metadata for this tab asynchronously to not block tab creation override suspend fun createNewTab(url: String): BrowserTab { val tab = BrowserTab( id = UUID.randomUUID().toString(), metaId = accountRepository.getSelectedMetaAccount().id, pageSnapshot = PageSnapshot.fromName(Urls.domainOf(url)), currentUrl = url, - knownDAppMetadata = getKnownDappMetadata(url), + knownDAppMetadata = null, creationTime = Date() ) browserTabInternalRepository.saveTab(tab) + deferredSyncKnownDAppMetadata(tab.id, url) + return tab } @@ -144,14 +147,11 @@ class RealBrowserTabService( if (url == null) return launch { - withContext(Dispatchers.Default) { - activeSessions[tabId].currentUrl = url - browserTabInternalRepository.changeCurrentUrl(tabId, url) - - val metadata = getKnownDappMetadata(url) - browserTabInternalRepository.changeKnownDAppMetadata(tabId, metadata?.iconLink) - } + activeSessions[tabId].currentUrl = url + browserTabInternalRepository.changeCurrentUrl(tabId, url) } + + deferredSyncKnownDAppMetadata(tabId, url) } private fun makeTabSnapshot(tabId: String) { @@ -166,8 +166,16 @@ class RealBrowserTabService( } } + private fun deferredSyncKnownDAppMetadata(tabId: String, url: String) { + launch { + getKnownDappMetadata(url)?.let { + browserTabInternalRepository.changeKnownDAppMetadata(tabId, it.iconLink) + } + } + } + private suspend fun getKnownDappMetadata(url: String): BrowserTab.KnownDAppMetadata? { - return dAppMetadataRepository.getDAppMetadata(Urls.normalizeUrl(url))?.let { + return dAppMetadataRepository.getDAppIfSyncedOrSync(Urls.normalizeUrl(url))?.let { BrowserTab.KnownDAppMetadata(it.iconLink) } }