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
/**
* 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

View file

@ -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 {

View file

@ -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(),

View file

@ -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())
}
}
}

View file

@ -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<Boolean> = _init.asStateFlow()
private val _timer = MutableStateFlow(false)
val timer: StateFlow<Boolean> = _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
}
}