Merge branch 'frontend/splashscreen' into 'main'

feat: splashscreen implemented

Closes #23

See merge request EmmaVandewalle/writand!38
This commit is contained in:
Emma Vandewalle 2024-08-18 13:39:26 +00:00
commit c2277d0c15
5 changed files with 86 additions and 25 deletions

View file

@ -6,11 +6,13 @@ import be.re.writand.data.local.models.UserSettings
import be.re.writand.data.local.models.UserTheme 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 { interface IUserSettingsRepository {
suspend fun initializeSettingsIfNull() suspend fun settingsIsNull(): Boolean
suspend fun initializeSettings()
suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings

View file

@ -39,18 +39,19 @@ class UserSettingsRepository @Inject constructor(
toUserSettings(protoSettings) toUserSettings(protoSettings)
} }
override suspend fun initializeSettingsIfNull() { override suspend fun settingsIsNull(): Boolean {
val currentSettings = dataStore.data.first(); return dataStore.data.first() == ProtoSettings.getDefaultInstance()
if (currentSettings == ProtoSettings.getDefaultInstance()) { }
val defaultSettings = ProtoSettings.newBuilder()
.setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH) override suspend fun initializeSettings() {
.setTheme(ProtoTheme.PROTO_THEME_DARK) val defaultSettings = ProtoSettings.newBuilder()
.setMaxSavedProjects(3) .setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH)
.setMaxSavedFiles(5) .setTheme(ProtoTheme.PROTO_THEME_DARK)
.setFontSize(14.0f) .setMaxSavedProjects(3)
.build() .setMaxSavedFiles(5)
dataStore.updateData { defaultSettings } .setFontSize(14.0f)
} .build()
dataStore.updateData { defaultSettings }
} }
override suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings { override suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings {

View file

@ -15,11 +15,23 @@ import be.re.writand.R
* appended to the end of the modifier. * appended to the end of the modifier.
* @param[alignment] alignment parameter used to place the painterResource in the given bounds * @param[alignment] alignment parameter used to place the painterResource in the given bounds
* defined by the width and height. * 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 @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( Image(
painterResource(id = R.drawable.writand_with_background), painterResource(id = id),
contentDescription = "logo", contentDescription = "logo",
contentScale = ContentScale.Fit, contentScale = ContentScale.Fit,
modifier = modifier.fillMaxSize(), modifier = modifier.fillMaxSize(),

View file

@ -1,14 +1,19 @@
package be.re.writand.screens.splash package be.re.writand.screens.splash
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable 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.Modifier
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController import androidx.navigation.NavHostController
import be.re.writand.navigation.WAppDestinations import be.re.writand.screens.components.WLogoImage
import be.re.writand.screens.components.WButton
/** /**
* Screen displayed on the startup of the app showing the logo while UserSettings are being loaded. * Screen displayed on the startup of the app showing the logo while UserSettings are being loaded.
@ -20,13 +25,24 @@ fun SplashScreen(
navHostController: NavHostController, navHostController: NavHostController,
vM: SplashViewModel = hiltViewModel() vM: SplashViewModel = hiltViewModel()
) { ) {
val timerDone = vM.timer.collectAsState()
val init = vM.initialized.collectAsState()
Box(modifier = Modifier.size(20.dp, 20.dp)) { Box(
WButton( modifier = Modifier
text = "Some fancy screen where you click...", .fillMaxSize()
// TODO: find out which screen is next .background(color = MaterialTheme.colorScheme.secondary),
onClick = { navHostController.navigate(WAppDestinations.WELCOME_START) } 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())
}
}
} }

View file

@ -1,9 +1,13 @@
package be.re.writand.screens.splash package be.re.writand.screens.splash
import android.util.Log
import be.re.writand.data.repos.settings.UserSettingsRepository import be.re.writand.data.repos.settings.UserSettingsRepository
import be.re.writand.navigation.WAppDestinations
import be.re.writand.screens.WViewModel import be.re.writand.screens.WViewModel
import dagger.hilt.android.lifecycle.HiltViewModel 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 import javax.inject.Inject
/** /**
@ -15,12 +19,38 @@ class SplashViewModel @Inject constructor(
userSettingsRepository: UserSettingsRepository userSettingsRepository: UserSettingsRepository
): WViewModel() { ): WViewModel() {
private var route: String = ""
private val _init = MutableStateFlow(false)
val initialized: StateFlow<Boolean> = _init.asStateFlow()
private val _timer = MutableStateFlow(false)
val timer: StateFlow<Boolean> = _timer.asStateFlow()
init { init {
timerCountdown()
// this is needed for every start of the app to direct the user: // 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) // welcome screen, project picker, editor (--> version 2 is for the editor as well)
launchCatching { 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
}
} }