From f9b8a7ed4de8b012394d58aa498fa388accfe177 Mon Sep 17 00:00:00 2001 From: EmmaVandewalle Date: Sat, 17 Aug 2024 22:01:13 +0200 Subject: [PATCH] feat: splashscreen implemented --- .../repos/settings/IUserSettingsRepository.kt | 6 ++-- .../repos/settings/UserSettingsRepository.kt | 25 +++++++------- .../writand/screens/components/WLogoImage.kt | 16 +++++++-- .../re/writand/screens/splash/SplashScreen.kt | 30 ++++++++++++---- .../writand/screens/splash/SplashViewModel.kt | 34 +++++++++++++++++-- 5 files changed, 86 insertions(+), 25 deletions(-) diff --git a/app/src/main/java/be/re/writand/data/repos/settings/IUserSettingsRepository.kt b/app/src/main/java/be/re/writand/data/repos/settings/IUserSettingsRepository.kt index 7af4f55..4e74272 100644 --- a/app/src/main/java/be/re/writand/data/repos/settings/IUserSettingsRepository.kt +++ b/app/src/main/java/be/re/writand/data/repos/settings/IUserSettingsRepository.kt @@ -6,11 +6,13 @@ import be.re.writand.data.local.models.UserSettings import be.re.writand.data.local.models.UserTheme /** - * Repository containing initializer, and setters to interact with all of the user settings. + * Repository containing a check, initializer, and setters to interact with all of the user settings. */ interface IUserSettingsRepository { - suspend fun initializeSettingsIfNull() + suspend fun settingsIsNull(): Boolean + + suspend fun initializeSettings() suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings diff --git a/app/src/main/java/be/re/writand/data/repos/settings/UserSettingsRepository.kt b/app/src/main/java/be/re/writand/data/repos/settings/UserSettingsRepository.kt index 8fc7645..045d8b5 100644 --- a/app/src/main/java/be/re/writand/data/repos/settings/UserSettingsRepository.kt +++ b/app/src/main/java/be/re/writand/data/repos/settings/UserSettingsRepository.kt @@ -39,18 +39,19 @@ class UserSettingsRepository @Inject constructor( toUserSettings(protoSettings) } - override suspend fun initializeSettingsIfNull() { - val currentSettings = dataStore.data.first(); - if (currentSettings == ProtoSettings.getDefaultInstance()) { - val defaultSettings = ProtoSettings.newBuilder() - .setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH) - .setTheme(ProtoTheme.PROTO_THEME_DARK) - .setMaxSavedProjects(3) - .setMaxSavedFiles(5) - .setFontSize(14.0f) - .build() - dataStore.updateData { defaultSettings } - } + override suspend fun settingsIsNull(): Boolean { + return dataStore.data.first() == ProtoSettings.getDefaultInstance() + } + + override suspend fun initializeSettings() { + val defaultSettings = ProtoSettings.newBuilder() + .setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH) + .setTheme(ProtoTheme.PROTO_THEME_DARK) + .setMaxSavedProjects(3) + .setMaxSavedFiles(5) + .setFontSize(14.0f) + .build() + dataStore.updateData { defaultSettings } } override suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings { diff --git a/app/src/main/java/be/re/writand/screens/components/WLogoImage.kt b/app/src/main/java/be/re/writand/screens/components/WLogoImage.kt index 3e16a92..bd53837 100644 --- a/app/src/main/java/be/re/writand/screens/components/WLogoImage.kt +++ b/app/src/main/java/be/re/writand/screens/components/WLogoImage.kt @@ -15,11 +15,23 @@ import be.re.writand.R * appended to the end of the modifier. * @param[alignment] alignment parameter used to place the painterResource in the given bounds * defined by the width and height. + * @param[background] boolean to express whether the logo should be filled in with white. + * Automatically set to true. */ @Composable -fun WLogoImage(modifier: Modifier, alignment: Alignment) { +fun WLogoImage( + modifier: Modifier = Modifier, + alignment: Alignment = Alignment.Center, + background: Boolean = true +) { + val id = if (background) { + R.drawable.writand_with_background + } else { + R.drawable.writand_no_background + } + Image( - painterResource(id = R.drawable.writand_with_background), + painterResource(id = id), contentDescription = "logo", contentScale = ContentScale.Fit, modifier = modifier.fillMaxSize(), diff --git a/app/src/main/java/be/re/writand/screens/splash/SplashScreen.kt b/app/src/main/java/be/re/writand/screens/splash/SplashScreen.kt index 9b9ebf1..c4af424 100644 --- a/app/src/main/java/be/re/writand/screens/splash/SplashScreen.kt +++ b/app/src/main/java/be/re/writand/screens/splash/SplashScreen.kt @@ -1,14 +1,19 @@ package be.re.writand.screens.splash +import androidx.compose.foundation.background import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.size +import androidx.compose.material3.MaterialTheme import androidx.compose.runtime.Composable +import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.collectAsState +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp import androidx.hilt.navigation.compose.hiltViewModel import androidx.navigation.NavHostController -import be.re.writand.navigation.WAppDestinations -import be.re.writand.screens.components.WButton +import be.re.writand.screens.components.WLogoImage /** * Screen displayed on the startup of the app showing the logo while UserSettings are being loaded. @@ -20,13 +25,24 @@ fun SplashScreen( navHostController: NavHostController, vM: SplashViewModel = hiltViewModel() ) { + val timerDone = vM.timer.collectAsState() + val init = vM.initialized.collectAsState() - Box(modifier = Modifier.size(20.dp, 20.dp)) { - WButton( - text = "Some fancy screen where you click...", - // TODO: find out which screen is next - onClick = { navHostController.navigate(WAppDestinations.WELCOME_START) } + Box( + modifier = Modifier + .fillMaxSize() + .background(color = MaterialTheme.colorScheme.secondary), + contentAlignment = Alignment.Center + ) { + WLogoImage( + modifier = Modifier.size(500.dp), + background = false ) } + LaunchedEffect(timerDone.value, init.value) { + if (timerDone.value && init.value) { + navHostController.navigate(vM.getRouteTo()) + } + } } \ No newline at end of file diff --git a/app/src/main/java/be/re/writand/screens/splash/SplashViewModel.kt b/app/src/main/java/be/re/writand/screens/splash/SplashViewModel.kt index d5f1ba6..afa70f7 100644 --- a/app/src/main/java/be/re/writand/screens/splash/SplashViewModel.kt +++ b/app/src/main/java/be/re/writand/screens/splash/SplashViewModel.kt @@ -1,9 +1,13 @@ package be.re.writand.screens.splash -import android.util.Log import be.re.writand.data.repos.settings.UserSettingsRepository +import be.re.writand.navigation.WAppDestinations import be.re.writand.screens.WViewModel import dagger.hilt.android.lifecycle.HiltViewModel +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableStateFlow +import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.flow.asStateFlow import javax.inject.Inject /** @@ -15,12 +19,38 @@ class SplashViewModel @Inject constructor( userSettingsRepository: UserSettingsRepository ): WViewModel() { + private var route: String = "" + + private val _init = MutableStateFlow(false) + val initialized: StateFlow = _init.asStateFlow() + + + private val _timer = MutableStateFlow(false) + val timer: StateFlow = _timer.asStateFlow() + init { + timerCountdown() // this is needed for every start of the app to direct the user: // welcome screen, project picker, editor (--> version 2 is for the editor as well) launchCatching { - userSettingsRepository.initializeSettingsIfNull() + if (userSettingsRepository.settingsIsNull()) { + userSettingsRepository.initializeSettings() + route = WAppDestinations.WELCOME_START + } else { + route = WAppDestinations.PROJECT_PICKER + } + _init.value = true } } + private fun timerCountdown() { + launchCatching { + delay(3000L) + _timer.value = true + } + } + + fun getRouteTo(): String { + return route + } } \ No newline at end of file