diff --git a/app/build.gradle b/app/build.gradle index 5de8b10ff5..75f6c1561c 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -189,6 +189,9 @@ dependencies { implementation project(':feature-vote') + implementation project(':feature-versions-api') + implementation project(':feature-versions-impl') + implementation kotlinDep implementation androidDep diff --git a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/NavigationModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/NavigationModule.kt index 1729ccc945..cec8cc097f 100644 --- a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/NavigationModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/NavigationModule.kt @@ -22,7 +22,8 @@ import io.novafoundation.nova.splash.SplashRouter LedgerNavigationModule::class, CurrencyNavigationModule::class, GovernanceNavigationModule::class, - VoteNavigationModule::class + VoteNavigationModule::class, + VersionsNavigationModule::class ] ) class NavigationModule { diff --git a/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/VersionsNavigationModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/VersionsNavigationModule.kt new file mode 100644 index 0000000000..30fc876e33 --- /dev/null +++ b/app/src/main/java/io/novafoundation/nova/app/di/app/navigation/VersionsNavigationModule.kt @@ -0,0 +1,16 @@ +package io.novafoundation.nova.app.di.app.navigation + +import dagger.Module +import dagger.Provides +import io.novafoundation.nova.app.root.navigation.NavigationHolder +import io.novafoundation.nova.app.root.navigation.versions.VersionsNavigator +import io.novafoundation.nova.common.di.scope.ApplicationScope +import io.novafoundation.nova.feature_versions_api.presentation.VersionsRouter + +@Module +class VersionsNavigationModule { + + @Provides + @ApplicationScope + fun provideRouter(navigationHolder: NavigationHolder): VersionsRouter = VersionsNavigator(navigationHolder) +} diff --git a/app/src/main/java/io/novafoundation/nova/app/di/deps/ComponentHolderModule.kt b/app/src/main/java/io/novafoundation/nova/app/di/deps/ComponentHolderModule.kt index 7b21b0a0cf..6cf80365af 100644 --- a/app/src/main/java/io/novafoundation/nova/app/di/deps/ComponentHolderModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/di/deps/ComponentHolderModule.kt @@ -32,6 +32,8 @@ import io.novafoundation.nova.feature_onboarding_api.di.OnboardingFeatureApi import io.novafoundation.nova.feature_onboarding_impl.di.OnboardingFeatureHolder import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi import io.novafoundation.nova.feature_staking_impl.di.StakingFeatureHolder +import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi +import io.novafoundation.nova.feature_versions_impl.di.VersionsFeatureHolder import io.novafoundation.nova.feature_vote.di.VoteFeatureApi import io.novafoundation.nova.feature_vote.di.VoteFeatureHolder import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi @@ -143,4 +145,10 @@ interface ComponentHolderModule { @ClassKey(NftFeatureApi::class) @IntoMap fun provideNftFeature(holder: NftFeatureHolder): FeatureApiHolder + + @ApplicationScope + @Binds + @ClassKey(VersionsFeatureApi::class) + @IntoMap + fun provideVersionsFeature(holder: VersionsFeatureHolder): FeatureApiHolder } diff --git a/app/src/main/java/io/novafoundation/nova/app/root/di/RootComponent.kt b/app/src/main/java/io/novafoundation/nova/app/root/di/RootComponent.kt index d9ed8e4101..106c84a8b8 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/di/RootComponent.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/di/RootComponent.kt @@ -14,6 +14,7 @@ import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi +import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi import io.novafoundation.nova.runtime.di.RuntimeApi @@ -51,7 +52,8 @@ interface RootComponent { CurrencyFeatureApi::class, DbApi::class, CommonApi::class, - RuntimeApi::class + RuntimeApi::class, + VersionsFeatureApi::class ] ) interface RootFeatureDependenciesComponent : RootDependencies diff --git a/app/src/main/java/io/novafoundation/nova/app/root/di/RootDependencies.kt b/app/src/main/java/io/novafoundation/nova/app/root/di/RootDependencies.kt index 471dfab786..889232a8c8 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/di/RootDependencies.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/di/RootDependencies.kt @@ -15,6 +15,7 @@ import io.novafoundation.nova.feature_crowdloan_api.domain.contributions.Contrib import io.novafoundation.nova.feature_staking_api.domain.api.StakingRepository import io.novafoundation.nova.feature_wallet_api.di.Wallet import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor +import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor import io.novafoundation.nova.feature_wallet_api.domain.interfaces.WalletRepository import io.novafoundation.nova.runtime.multiNetwork.ChainRegistry import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection @@ -22,6 +23,8 @@ import kotlinx.coroutines.flow.MutableStateFlow interface RootDependencies { + fun updateNotificationsInteractor(): UpdateNotificationsInteractor + fun contributionsInteractor(): ContributionsInteractor fun crowdloanRepository(): CrowdloanRepository diff --git a/app/src/main/java/io/novafoundation/nova/app/root/di/RootFeatureHolder.kt b/app/src/main/java/io/novafoundation/nova/app/root/di/RootFeatureHolder.kt index adcdec64a3..44a2ded293 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/di/RootFeatureHolder.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/di/RootFeatureHolder.kt @@ -11,6 +11,7 @@ import io.novafoundation.nova.feature_assets.di.AssetsFeatureApi import io.novafoundation.nova.feature_crowdloan_api.di.CrowdloanFeatureApi import io.novafoundation.nova.feature_currency_api.di.CurrencyFeatureApi import io.novafoundation.nova.feature_staking_api.di.StakingFeatureApi +import io.novafoundation.nova.feature_versions_api.di.VersionsFeatureApi import io.novafoundation.nova.feature_wallet_api.di.WalletFeatureApi import io.novafoundation.nova.runtime.di.RuntimeApi import javax.inject.Inject @@ -33,6 +34,7 @@ class RootFeatureHolder @Inject constructor( .currencyFeatureApi(getFeature(CurrencyFeatureApi::class.java)) .crowdloanFeatureApi(getFeature(CrowdloanFeatureApi::class.java)) .runtimeApi(getFeature(RuntimeApi::class.java)) + .versionsFeatureApi(getFeature(VersionsFeatureApi::class.java)) .build() return DaggerRootComponent.factory() diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/Navigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/Navigator.kt index 40fc23d1df..3f86b1f385 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/navigation/Navigator.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/Navigator.kt @@ -462,6 +462,10 @@ class Navigator( } } + override fun openUpdateNotifications() { + navController?.navigate(R.id.action_open_update_notifications) + } + override fun returnToWallet() { // to achieve smooth animation postToUiThread { diff --git a/app/src/main/java/io/novafoundation/nova/app/root/navigation/versions/VersionsNavigator.kt b/app/src/main/java/io/novafoundation/nova/app/root/navigation/versions/VersionsNavigator.kt new file mode 100644 index 0000000000..b3f227cae9 --- /dev/null +++ b/app/src/main/java/io/novafoundation/nova/app/root/navigation/versions/VersionsNavigator.kt @@ -0,0 +1,28 @@ +package io.novafoundation.nova.app.root.navigation.versions + +import android.content.ActivityNotFoundException +import android.content.Intent +import android.net.Uri +import io.novafoundation.nova.app.root.navigation.NavigationHolder +import io.novafoundation.nova.feature_versions_api.presentation.VersionsRouter + +class VersionsNavigator( + private val navigationHolder: NavigationHolder +) : VersionsRouter { + + override fun openInstallUpdates() { + val activity = navigationHolder.contextManager.getActivity() + require(activity != null) + val packageName = activity.packageName + + try { + activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=$packageName"))) + } catch (e: ActivityNotFoundException) { + activity.startActivity(Intent(Intent.ACTION_VIEW, Uri.parse("https://play.google.com/store/apps/details?id=$packageName"))) + } + } + + override fun back() { + navigationHolder.navController?.popBackStack() + } +} diff --git a/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootRouter.kt b/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootRouter.kt index bb9f88614e..66b4a16143 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootRouter.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootRouter.kt @@ -5,4 +5,6 @@ interface RootRouter { fun returnToWallet() fun nonCancellableVerify() + + fun openUpdateNotifications() } diff --git a/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootViewModel.kt b/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootViewModel.kt index 47efc563d9..e135bd9b62 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootViewModel.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/presentation/RootViewModel.kt @@ -12,6 +12,7 @@ import io.novafoundation.nova.common.utils.sequrity.BackgroundAccessObserver import io.novafoundation.nova.core.updater.Updater import io.novafoundation.nova.feature_crowdloan_api.domain.contributions.ContributionsInteractor import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor +import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection.ExternalRequirement import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.launchIn @@ -27,7 +28,8 @@ class RootViewModel( private val networkStateMixin: NetworkStateMixin, private val contributionsInteractor: ContributionsInteractor, private val backgroundAccessObserver: BackgroundAccessObserver, - private val safeModeService: SafeModeService + private val safeModeService: SafeModeService, + private val updateNotificationsInteractor: UpdateNotificationsInteractor ) : BaseViewModel(), NetworkStateUi by networkStateMixin { private var willBeClearedForLanguageChange = false @@ -44,11 +46,22 @@ class RootViewModel( .onEach { verifyUserIfNeed() } .launchIn(this) + checkForUpdates() + syncCurrencies() updatePhishingAddresses() } + private fun checkForUpdates() { + launch { + updateNotificationsInteractor.waitPermissionToUpdate() + if (updateNotificationsInteractor.hasImportantUpdates()) { + rootRouter.openUpdateNotifications() + } + } + } + private fun syncCurrencies() { launch { currencyInteractor.syncCurrencies() } } diff --git a/app/src/main/java/io/novafoundation/nova/app/root/presentation/di/RootActivityModule.kt b/app/src/main/java/io/novafoundation/nova/app/root/presentation/di/RootActivityModule.kt index d82a0ed81f..36233f6037 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/presentation/di/RootActivityModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/presentation/di/RootActivityModule.kt @@ -17,6 +17,7 @@ import io.novafoundation.nova.common.sequrity.SafeModeService import io.novafoundation.nova.common.utils.sequrity.BackgroundAccessObserver import io.novafoundation.nova.feature_crowdloan_api.domain.contributions.ContributionsInteractor import io.novafoundation.nova.feature_currency_api.domain.CurrencyInteractor +import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor import io.novafoundation.nova.runtime.multiNetwork.connection.ChainConnection import kotlinx.coroutines.flow.MutableStateFlow @@ -39,7 +40,8 @@ class RootActivityModule { externalRequirementsFlow: MutableStateFlow, contributionsInteractor: ContributionsInteractor, backgroundAccessObserver: BackgroundAccessObserver, - safeModeService: SafeModeService + safeModeService: SafeModeService, + updateNotificationsInteractor: UpdateNotificationsInteractor ): ViewModel { return RootViewModel( interactor, @@ -50,7 +52,8 @@ class RootActivityModule { networkStateMixin, contributionsInteractor, backgroundAccessObserver, - safeModeService + safeModeService, + updateNotificationsInteractor ) } diff --git a/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/MainViewModel.kt b/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/MainViewModel.kt index 77ceb8b8d2..18a4d71666 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/MainViewModel.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/MainViewModel.kt @@ -2,11 +2,17 @@ package io.novafoundation.nova.app.root.presentation.main import io.novafoundation.nova.app.root.domain.RootInteractor import io.novafoundation.nova.common.base.BaseViewModel +import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor class MainViewModel( interactor: RootInteractor, + updateNotificationsInteractor: UpdateNotificationsInteractor ) : BaseViewModel() { val stakingAvailableLiveData = interactor.stakingAvailableFlow() .asLiveData() + + init { + updateNotificationsInteractor.allowInAppUpdateCheck() + } } diff --git a/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/di/MainFragmentModule.kt b/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/di/MainFragmentModule.kt index d0f7e2d0c9..0d1e5b4976 100644 --- a/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/di/MainFragmentModule.kt +++ b/app/src/main/java/io/novafoundation/nova/app/root/presentation/main/di/MainFragmentModule.kt @@ -10,6 +10,7 @@ import io.novafoundation.nova.app.root.domain.RootInteractor import io.novafoundation.nova.app.root.presentation.main.MainViewModel import io.novafoundation.nova.common.di.viewmodel.ViewModelKey import io.novafoundation.nova.common.di.viewmodel.ViewModelModule +import io.novafoundation.nova.feature_versions_api.domain.UpdateNotificationsInteractor @Module( includes = [ @@ -22,9 +23,10 @@ class MainFragmentModule { @IntoMap @ViewModelKey(MainViewModel::class) fun provideViewModel( - interactor: RootInteractor + interactor: RootInteractor, + updateNotificationsInteractor: UpdateNotificationsInteractor ): ViewModel { - return MainViewModel(interactor) + return MainViewModel(interactor, updateNotificationsInteractor) } @Provides diff --git a/app/src/main/res/navigation/root_nav_graph.xml b/app/src/main/res/navigation/root_nav_graph.xml index 8938018391..956c781579 100644 --- a/app/src/main/res/navigation/root_nav_graph.xml +++ b/app/src/main/res/navigation/root_nav_graph.xml @@ -35,6 +35,14 @@ app:popEnterAnim="@anim/fragment_open_enter" app:popExitAnim="@anim/fragment_open_exit" /> + + + + \ No newline at end of file diff --git a/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManager.kt b/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManager.kt index 12be08d183..a5176190c2 100644 --- a/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManager.kt +++ b/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManager.kt @@ -21,6 +21,7 @@ interface ResourceManager { fun measureInPx(dp: Int): Int + fun formatDateTime(timestamp: Long): String fun formatDate(timestamp: Long): String fun formatDuration(elapsedTime: Long): String diff --git a/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManagerImpl.kt b/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManagerImpl.kt index 23a148893f..651b514955 100644 --- a/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManagerImpl.kt +++ b/common/src/main/java/io/novafoundation/nova/common/resources/ResourceManagerImpl.kt @@ -52,10 +52,18 @@ class ResourceManagerImpl( return px.toInt() } - override fun formatDate(timestamp: Long): String { + override fun formatDateTime(timestamp: Long): String { return timestamp.formatDateTime().toString() } + override fun formatDate(timestamp: Long): String { + return DateUtils.formatDateTime( + contextManager.getApplicationContext(), + timestamp, + DateUtils.FORMAT_SHOW_DATE or DateUtils.FORMAT_SHOW_YEAR or DateUtils.FORMAT_ABBREV_MONTH + ) + } + override fun formatTime(timestamp: Long): String { return DateUtils.formatDateTime(contextManager.getApplicationContext(), timestamp, DateUtils.FORMAT_SHOW_TIME) } diff --git a/common/src/main/java/io/novafoundation/nova/common/utils/formatting/NumberFormatters.kt b/common/src/main/java/io/novafoundation/nova/common/utils/formatting/NumberFormatters.kt index 49b446dcc6..a81db4e05d 100644 --- a/common/src/main/java/io/novafoundation/nova/common/utils/formatting/NumberFormatters.kt +++ b/common/src/main/java/io/novafoundation/nova/common/utils/formatting/NumberFormatters.kt @@ -3,6 +3,7 @@ package io.novafoundation.nova.common.utils.formatting import android.content.Context import android.text.format.DateUtils import io.novafoundation.nova.common.R +import io.novafoundation.nova.common.resources.ResourceManager import io.novafoundation.nova.common.utils.daysFromMillis import io.novafoundation.nova.common.utils.fractionToPercentage import io.novafoundation.nova.common.utils.isNonNegative @@ -15,7 +16,8 @@ import java.util.* import java.util.concurrent.TimeUnit import kotlin.time.Duration -const val DATE_ISO_8601 = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" +const val DATE_ISO_8601_FULL = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'" +const val DATE_ISO_8601_NO_MS = "yyyy-MM-dd'T'HH:mm:ss'Z'" private const val DECIMAL_PATTERN_BASE = "###,###." @@ -26,7 +28,8 @@ private const val FULL_PRECISION = 5 const val ABBREVIATED_PRECISION = 2 private val dateTimeFormat = SimpleDateFormat.getDateTimeInstance() -private val dateTimeFormatISO_8601 by lazy { SimpleDateFormat(DATE_ISO_8601, Locale.getDefault()) } +private val dateTimeFormatISO_8601 by lazy { SimpleDateFormat(DATE_ISO_8601_FULL, Locale.getDefault()) } +private val dateTimeFormatISO_8601_NoMs by lazy { SimpleDateFormat(DATE_ISO_8601_NO_MS, Locale.getDefault()) } private val defaultAbbreviationFormatter = FixedPrecisionFormatter(ABBREVIATED_PRECISION) private val defaultFullFormatter = FixedPrecisionFormatter(FULL_PRECISION) @@ -91,6 +94,20 @@ fun BigDecimal.formatFractionAsPercentage(): String { return fractionToPercentage().formatAsPercentage() } +fun Date.formatDateSinceEpoch(resourceManager: ResourceManager): String { + val currentDays = System.currentTimeMillis().daysFromMillis() + val diff = currentDays - time.daysFromMillis() + + if (diff < 0) throw IllegalArgumentException("Past date should be less than current") + return when (diff) { + 0L -> resourceManager.getString(R.string.today) + 1L -> resourceManager.getString(R.string.yesterday) + else -> { + resourceManager.formatDate(time) + } + } +} + fun Long.formatDaysSinceEpoch(context: Context): String? { val currentDays = System.currentTimeMillis().daysFromMillis() val diff = currentDays - this @@ -113,6 +130,10 @@ fun parseDateISO_8601(value: String): Date? { return runCatching { dateTimeFormatISO_8601.parse(value) }.getOrNull() } +fun parseDateISO_8601_NoMs(value: String): Date? { + return runCatching { dateTimeFormatISO_8601_NoMs.parse(value) }.getOrNull() +} + fun decimalFormatterFor(pattern: String): DecimalFormat { return DecimalFormat(pattern).apply { val symbols = decimalFormatSymbols diff --git a/common/src/main/java/io/novafoundation/nova/common/view/BannerView.kt b/common/src/main/java/io/novafoundation/nova/common/view/BannerView.kt index b3e3535dee..42e2f8516e 100644 --- a/common/src/main/java/io/novafoundation/nova/common/view/BannerView.kt +++ b/common/src/main/java/io/novafoundation/nova/common/view/BannerView.kt @@ -51,6 +51,10 @@ class BannerView @JvmOverloads constructor( } } + fun setBannerBackground(@DrawableRes backgroundRes: Int) { + bannerBackground.setBackgroundResource(backgroundRes) + } + fun setImage(@DrawableRes imageRes: Int) { bannerImage.setImageResource(imageRes) } diff --git a/common/src/main/res/drawable-hdpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-hdpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..2e52ccf540 Binary files /dev/null and b/common/src/main/res/drawable-hdpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-hdpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-hdpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..29527562f7 Binary files /dev/null and b/common/src/main/res/drawable-hdpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-hdpi/ic_critical_update.png b/common/src/main/res/drawable-hdpi/ic_critical_update.png new file mode 100644 index 0000000000..dd6226e428 Binary files /dev/null and b/common/src/main/res/drawable-hdpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-hdpi/ic_major_update.png b/common/src/main/res/drawable-hdpi/ic_major_update.png new file mode 100644 index 0000000000..febd7c4e76 Binary files /dev/null and b/common/src/main/res/drawable-hdpi/ic_major_update.png differ diff --git a/common/src/main/res/drawable-ldpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-ldpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..33e9d9eda6 Binary files /dev/null and b/common/src/main/res/drawable-ldpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-ldpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-ldpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..20e279fc61 Binary files /dev/null and b/common/src/main/res/drawable-ldpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-ldpi/ic_critical_update.png b/common/src/main/res/drawable-ldpi/ic_critical_update.png new file mode 100644 index 0000000000..9b1236ac30 Binary files /dev/null and b/common/src/main/res/drawable-ldpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-ldpi/ic_major_update.png b/common/src/main/res/drawable-ldpi/ic_major_update.png new file mode 100644 index 0000000000..95c0e15b07 Binary files /dev/null and b/common/src/main/res/drawable-ldpi/ic_major_update.png differ diff --git a/common/src/main/res/drawable-mdpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-mdpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..69cec58a5d Binary files /dev/null and b/common/src/main/res/drawable-mdpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-mdpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-mdpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..9d21fd8cc8 Binary files /dev/null and b/common/src/main/res/drawable-mdpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-mdpi/ic_critical_update.png b/common/src/main/res/drawable-mdpi/ic_critical_update.png new file mode 100644 index 0000000000..d5b246b7d9 Binary files /dev/null and b/common/src/main/res/drawable-mdpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-mdpi/ic_major_update.png b/common/src/main/res/drawable-mdpi/ic_major_update.png new file mode 100644 index 0000000000..2ac1456e1f Binary files /dev/null and b/common/src/main/res/drawable-mdpi/ic_major_update.png differ diff --git a/common/src/main/res/drawable-xhdpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-xhdpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..8845722e86 Binary files /dev/null and b/common/src/main/res/drawable-xhdpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-xhdpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-xhdpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..368689d744 Binary files /dev/null and b/common/src/main/res/drawable-xhdpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-xhdpi/ic_critical_update.png b/common/src/main/res/drawable-xhdpi/ic_critical_update.png new file mode 100644 index 0000000000..3aac974cc3 Binary files /dev/null and b/common/src/main/res/drawable-xhdpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-xhdpi/ic_major_update.png b/common/src/main/res/drawable-xhdpi/ic_major_update.png new file mode 100644 index 0000000000..9352d62cd5 Binary files /dev/null and b/common/src/main/res/drawable-xhdpi/ic_major_update.png differ diff --git a/common/src/main/res/drawable-xxhdpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-xxhdpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..e7d5ebce35 Binary files /dev/null and b/common/src/main/res/drawable-xxhdpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-xxhdpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-xxhdpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..e18e239ff1 Binary files /dev/null and b/common/src/main/res/drawable-xxhdpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-xxhdpi/ic_critical_update.png b/common/src/main/res/drawable-xxhdpi/ic_critical_update.png new file mode 100644 index 0000000000..bfbff409fa Binary files /dev/null and b/common/src/main/res/drawable-xxhdpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-xxhdpi/ic_major_update.png b/common/src/main/res/drawable-xxhdpi/ic_major_update.png new file mode 100644 index 0000000000..22c81e3b38 Binary files /dev/null and b/common/src/main/res/drawable-xxhdpi/ic_major_update.png differ diff --git a/common/src/main/res/drawable-xxxhdpi/ic_banner_turquoise_gradient.png b/common/src/main/res/drawable-xxxhdpi/ic_banner_turquoise_gradient.png new file mode 100644 index 0000000000..f23a4ad6e1 Binary files /dev/null and b/common/src/main/res/drawable-xxxhdpi/ic_banner_turquoise_gradient.png differ diff --git a/common/src/main/res/drawable-xxxhdpi/ic_banner_yellow_gradient.png b/common/src/main/res/drawable-xxxhdpi/ic_banner_yellow_gradient.png new file mode 100644 index 0000000000..da0e57531f Binary files /dev/null and b/common/src/main/res/drawable-xxxhdpi/ic_banner_yellow_gradient.png differ diff --git a/common/src/main/res/drawable-xxxhdpi/ic_critical_update.png b/common/src/main/res/drawable-xxxhdpi/ic_critical_update.png new file mode 100644 index 0000000000..44c861af83 Binary files /dev/null and b/common/src/main/res/drawable-xxxhdpi/ic_critical_update.png differ diff --git a/common/src/main/res/drawable-xxxhdpi/ic_major_update.png b/common/src/main/res/drawable-xxxhdpi/ic_major_update.png new file mode 100644 index 0000000000..26e7ba3d8f Binary files /dev/null and b/common/src/main/res/drawable-xxxhdpi/ic_major_update.png differ diff --git a/common/src/main/res/values/strings.xml b/common/src/main/res/values/strings.xml index 45a21f7995..58c07820ac 100644 --- a/common/src/main/res/values/strings.xml +++ b/common/src/main/res/values/strings.xml @@ -1,6 +1,22 @@ + Version %s + + See all available updates + Latest + Critical + Major + + Critical update + To avoid any issues and improve the user experience, we strongly recommend install the updates as soon as possible. + + Major update + Select another account as a controller to delegate staking management operations to it + + Update available + Install the updates + Enable Safe mode Screen recording and screenshots will not be available. The minimized app will not display the content diff --git a/common/src/main/res/values/themes.xml b/common/src/main/res/values/themes.xml index aed07710df..63d4520bbc 100644 --- a/common/src/main/res/values/themes.xml +++ b/common/src/main/res/values/themes.xml @@ -46,6 +46,9 @@ @style/BottomSheetDialog @style/Widget.Nova.Input.Text + + @color/text_primary + @color/text_primary