diff options
| author | David Göransson <david.goransson@mullvad.net> | 2024-06-28 14:45:01 +0200 |
|---|---|---|
| committer | David Göransson <david.goransson@mullvad.net> | 2024-07-04 12:09:36 +0200 |
| commit | d23e892ded487453ef6d8149fc3d9b7d21d72ca9 (patch) | |
| tree | 45b7b78a1ae3bb941ddf8b8ffe76d67202858b5a /android/app/src | |
| parent | 6ec847fea0db4223c32b7297c920ebcc71414abb (diff) | |
| download | mullvadvpn-d23e892ded487453ef6d8149fc3d9b7d21d72ca9.tar.xz mullvadvpn-d23e892ded487453ef6d8149fc3d9b7d21d72ca9.zip | |
Add splash screen
Diffstat (limited to 'android/app/src')
7 files changed, 41 insertions, 8 deletions
diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index 61ef2c7e50..cfe2c7c4df 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -8,10 +8,10 @@ tools:ignore="ScopedStorage" /> <application android:icon="@mipmap/ic_launcher" android:roundIcon="@mipmap/ic_launcher" - android:theme="@style/AppTheme" + android:theme="@style/Theme.App.Starting" android:extractNativeLibs="true" android:allowBackup="false" android:banner="@drawable/banner" android:name=".MullvadApplication" - tools:ignore="DataExtractionRules,GoogleAppIndexingWarning"></application> + tools:ignore="DataExtractionRules,GoogleAppIndexingWarning"/> </manifest> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f6f60cdd1f..f69801a46d 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -26,7 +26,7 @@ android:icon="@mipmap/ic_launcher" android:label="@string/app_name" android:roundIcon="@mipmap/ic_launcher" - android:theme="@style/AppTheme" + android:theme="@style/Theme.App.Starting" tools:ignore="GoogleAppIndexingWarning"> <!-- MainActivity diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt index f5977e7b57..a81fa5f42f 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/compose/screen/SplashScreen.kt @@ -29,7 +29,6 @@ import com.ramcosta.composedestinations.generated.destinations.PrivacyDisclaimer import com.ramcosta.composedestinations.navigation.DestinationsNavigator import net.mullvad.mullvadvpn.R import net.mullvad.mullvadvpn.compose.component.ScaffoldWithTopBar -import net.mullvad.mullvadvpn.compose.transitions.DefaultTransition import net.mullvad.mullvadvpn.compose.util.CollectSideEffectWithLifecycle import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.lib.theme.Dimens @@ -45,7 +44,7 @@ private fun PreviewLoadingScreen() { } // Set this as the start destination of the default nav graph -@Destination<RootGraph>(start = true, style = DefaultTransition::class) +@Destination<RootGraph>(start = true) @Composable fun Splash(navigator: DestinationsNavigator) { val viewModel: SplashViewModel = koinViewModel() diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt index ec940364dc..5ecf8ecbd9 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/di/UiModule.kt @@ -22,6 +22,7 @@ import net.mullvad.mullvadvpn.repository.RelayListFilterRepository import net.mullvad.mullvadvpn.repository.RelayListRepository import net.mullvad.mullvadvpn.repository.RelayOverridesRepository import net.mullvad.mullvadvpn.repository.SettingsRepository +import net.mullvad.mullvadvpn.repository.SplashCompleteRepository import net.mullvad.mullvadvpn.repository.SplitTunnelingRepository import net.mullvad.mullvadvpn.ui.serviceconnection.AppVersionInfoRepository import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager @@ -120,6 +121,7 @@ val uiModule = module { single { SplitTunnelingRepository(get()) } single { ApiAccessRepository(get()) } single { NewDeviceRepository() } + single { SplashCompleteRepository() } single { AccountExpiryNotificationUseCase(get()) } single { TunnelStateNotificationUseCase(get()) } @@ -182,7 +184,7 @@ val uiModule = module { viewModel { PrivacyDisclaimerViewModel(get(), IS_PLAY_BUILD) } viewModel { SelectLocationViewModel(get(), get(), get(), get(), get(), get()) } viewModel { SettingsViewModel(get(), get(), IS_PLAY_BUILD) } - viewModel { SplashViewModel(get(), get(), get()) } + viewModel { SplashViewModel(get(), get(), get(), get()) } viewModel { VoucherDialogViewModel(get()) } viewModel { VpnSettingsViewModel(get(), get(), get()) } viewModel { WelcomeViewModel(get(), get(), get(), get(), isPlayBuild = IS_PLAY_BUILD) } diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SplashCompleteRepository.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SplashCompleteRepository.kt new file mode 100644 index 0000000000..03e5b908f7 --- /dev/null +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/repository/SplashCompleteRepository.kt @@ -0,0 +1,11 @@ +package net.mullvad.mullvadvpn.repository + +class SplashCompleteRepository { + private var splashComplete = false + + fun isSplashComplete() = splashComplete + + fun onSplashCompleted() { + splashComplete = true + } +} diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt index 7d592f468a..8339a25f61 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/ui/MainActivity.kt @@ -5,6 +5,7 @@ import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.setContent import androidx.activity.result.contract.ActivityResultContracts +import androidx.core.splashscreen.SplashScreen.Companion.installSplashScreen import androidx.core.view.WindowCompat import androidx.lifecycle.Lifecycle import androidx.lifecycle.lifecycleScope @@ -17,6 +18,7 @@ import net.mullvad.mullvadvpn.lib.common.util.SdkUtils.requestNotificationPermis import net.mullvad.mullvadvpn.lib.intent.IntentProvider import net.mullvad.mullvadvpn.lib.theme.AppTheme import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository +import net.mullvad.mullvadvpn.repository.SplashCompleteRepository import net.mullvad.mullvadvpn.ui.serviceconnection.ServiceConnectionManager import net.mullvad.mullvadvpn.viewmodel.NoDaemonViewModel import org.koin.android.ext.android.getKoin @@ -31,6 +33,8 @@ class MainActivity : ComponentActivity() { private lateinit var privacyDisclaimerRepository: PrivacyDisclaimerRepository private lateinit var serviceConnectionManager: ServiceConnectionManager + private lateinit var splashCompleteRepository: SplashCompleteRepository + private var isReadyNextDraw: Boolean = false private lateinit var noDaemonViewModel: NoDaemonViewModel private lateinit var intentProvider: IntentProvider @@ -45,16 +49,21 @@ class MainActivity : ComponentActivity() { serviceConnectionManager = get() noDaemonViewModel = get() intentProvider = get() + splashCompleteRepository = get() } lifecycle.addObserver(noDaemonViewModel) + installSplashScreen().setKeepOnScreenCondition { + val isReady = isReadyNextDraw + isReadyNextDraw = splashCompleteRepository.isSplashComplete() + !isReady + } super.onCreate(savedInstanceState) // Needs to be before set content since we want to access the intent in compose if (savedInstanceState == null) { intentProvider.setStartIntent(intent) } - setContent { AppTheme { MullvadApp() } } // This is to protect against tapjacking attacks diff --git a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplashViewModel.kt b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplashViewModel.kt index bd34161e2c..cc97435105 100644 --- a/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplashViewModel.kt +++ b/android/app/src/main/kotlin/net/mullvad/mullvadvpn/viewmodel/SplashViewModel.kt @@ -3,6 +3,8 @@ package net.mullvad.mullvadvpn.viewmodel import androidx.lifecycle.ViewModel import androidx.lifecycle.viewModelScope import kotlinx.coroutines.async +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.filterNotNull import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.flow @@ -14,14 +16,24 @@ import net.mullvad.mullvadvpn.lib.model.DeviceState import net.mullvad.mullvadvpn.lib.shared.AccountRepository import net.mullvad.mullvadvpn.lib.shared.DeviceRepository import net.mullvad.mullvadvpn.repository.PrivacyDisclaimerRepository +import net.mullvad.mullvadvpn.repository.SplashCompleteRepository + +data class SplashScreenState(val splashComplete: Boolean = false) class SplashViewModel( private val privacyDisclaimerRepository: PrivacyDisclaimerRepository, private val accountRepository: AccountRepository, private val deviceRepository: DeviceRepository, + private val splashCompleteRepository: SplashCompleteRepository ) : ViewModel() { - val uiSideEffect = flow { emit(getStartDestination()) } + val uiSideEffect = flow { + emit(getStartDestination()) + splashCompleteRepository.onSplashCompleted() + } + + private val _uiState = MutableStateFlow<SplashScreenState>(SplashScreenState(false)) + val uiState: StateFlow<SplashScreenState> = _uiState private suspend fun getStartDestination(): SplashUiSideEffect { if (!privacyDisclaimerRepository.hasAcceptedPrivacyDisclosure()) { |
