forked from Writand/writand
feat: splashscreen implemented
This commit is contained in:
parent
b7cb3eb27c
commit
f9b8a7ed4d
5 changed files with 86 additions and 25 deletions
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -39,9 +39,11 @@ 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()) {
|
}
|
||||||
|
|
||||||
|
override suspend fun initializeSettings() {
|
||||||
val defaultSettings = ProtoSettings.newBuilder()
|
val defaultSettings = ProtoSettings.newBuilder()
|
||||||
.setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH)
|
.setLanguage(ProtoLanguage.PROTO_LANGUAGE_ENGLISH)
|
||||||
.setTheme(ProtoTheme.PROTO_THEME_DARK)
|
.setTheme(ProtoTheme.PROTO_THEME_DARK)
|
||||||
|
@ -51,7 +53,6 @@ class UserSettingsRepository @Inject constructor(
|
||||||
.build()
|
.build()
|
||||||
dataStore.updateData { defaultSettings }
|
dataStore.updateData { defaultSettings }
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings {
|
override suspend fun toUserSettings(protoSettings: ProtoSettings): UserSettings {
|
||||||
return UserSettings(
|
return UserSettings(
|
||||||
|
|
|
@ -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(),
|
||||||
|
|
|
@ -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())
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -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
|
||||||
|
}
|
||||||
}
|
}
|
Loading…
Reference in a new issue