SplashScreen and ranking screen

pull/5/head
avalin 1 year ago
parent e2d119242c
commit 78b4ab2e05

@ -9,6 +9,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.data.model.bet.BetType import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.ext.getIcon import fr.iut.alldev.allin.ext.getIcon
import fr.iut.alldev.allin.ext.getTitleId import fr.iut.alldev.allin.ext.getTitleId
@ -25,7 +26,6 @@ import java.time.ZonedDateTime
fun BetCreationScreen( fun BetCreationScreen(
viewModel: BetCreationViewModel = hiltViewModel(), viewModel: BetCreationViewModel = hiltViewModel(),
setLoading: (Boolean) -> Unit, setLoading: (Boolean) -> Unit,
openDrawer: () -> Unit,
onCreation: () -> Unit onCreation: () -> Unit
) { ) {
val betTypes = remember { BetType.entries } val betTypes = remember { BetType.entries }
@ -43,7 +43,21 @@ fun BetCreationScreen(
val registerDateError by remember { viewModel.registerDateError } val registerDateError by remember { viewModel.registerDateError }
val betDateError by remember { viewModel.betDateError } val betDateError by remember { viewModel.betDateError }
val selectedFriends = remember { mutableListOf<Int>() } val friends = remember {
buildList {
repeat(10) {
add(
User(
id = "$it",
username = "Dave",
email = "",
coins = 420
)
)
}
}
}
val selectedFriends = remember { mutableListOf<String>() }
var selectionElements by remember { mutableStateOf(listOf<SelectionElement>()) } var selectionElements by remember { mutableStateOf(listOf<SelectionElement>()) }
var selectedBetTypeElement by remember { mutableStateOf<SelectionElement?>(null) } var selectedBetTypeElement by remember { mutableStateOf<SelectionElement?>(null) }
@ -71,7 +85,6 @@ fun BetCreationScreen(
val (showEndTimePicker, setEndTimePicker) = remember { mutableStateOf(false) } val (showEndTimePicker, setEndTimePicker) = remember { mutableStateOf(false) }
BetCreationScreenContent( BetCreationScreenContent(
nbFriends = 42,
betTheme = theme, betTheme = theme,
betThemeError = themeError.errorResource(), betThemeError = themeError.errorResource(),
setBetTheme = { theme = it }, setBetTheme = { theme = it },
@ -84,6 +97,7 @@ fun BetCreationScreen(
registerDateError = registerDateError.errorResource(), registerDateError = registerDateError.errorResource(),
betDate = betDate, betDate = betDate,
betDateError = betDateError.errorResource(), betDateError = betDateError.errorResource(),
friends = friends,
selectedFriends = selectedFriends, selectedFriends = selectedFriends,
setRegisterDateDialog = setRegisterDatePicker, setRegisterDateDialog = setRegisterDatePicker,
setEndDateDialog = setEndDatePicker, setEndDateDialog = setEndDatePicker,
@ -93,7 +107,6 @@ fun BetCreationScreen(
selectedBetType = selectedBetType, selectedBetType = selectedBetType,
setSelectedBetTypeElement = { selectedBetTypeElement = it }, setSelectedBetTypeElement = { selectedBetTypeElement = it },
selectionBetType = selectionElements, selectionBetType = selectionElements,
openDrawer = openDrawer,
onCreateBet = { onCreateBet = {
viewModel.createBet( viewModel.createBet(
themeFieldName = themeFieldName, themeFieldName = themeFieldName,

@ -17,6 +17,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.data.model.bet.BetType import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenAnswerTab import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenAnswerTab
@ -29,7 +30,6 @@ import java.time.ZonedDateTime
@Composable @Composable
fun BetCreationScreenContent( fun BetCreationScreenContent(
nbFriends: Int,
betTheme: String, betTheme: String,
betThemeError: String?, betThemeError: String?,
setBetTheme: (String) -> Unit, setBetTheme: (String) -> Unit,
@ -42,7 +42,8 @@ fun BetCreationScreenContent(
registerDateError: String?, registerDateError: String?,
betDate: ZonedDateTime, betDate: ZonedDateTime,
betDateError: String?, betDateError: String?,
selectedFriends: MutableList<Int>, friends: List<User>,
selectedFriends: MutableList<String>,
setRegisterDateDialog: (Boolean) -> Unit, setRegisterDateDialog: (Boolean) -> Unit,
setEndDateDialog: (Boolean) -> Unit, setEndDateDialog: (Boolean) -> Unit,
setRegisterTimeDialog: (Boolean) -> Unit, setRegisterTimeDialog: (Boolean) -> Unit,
@ -51,7 +52,6 @@ fun BetCreationScreenContent(
selectedBetType: BetType, selectedBetType: BetType,
setSelectedBetTypeElement: (SelectionElement) -> Unit, setSelectedBetTypeElement: (SelectionElement) -> Unit,
selectionBetType: List<SelectionElement>, selectionBetType: List<SelectionElement>,
openDrawer: () -> Unit,
onCreateBet: () -> Unit onCreateBet: () -> Unit
) { ) {
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
@ -59,7 +59,6 @@ fun BetCreationScreenContent(
Box(Modifier.fillMaxSize()) { Box(Modifier.fillMaxSize()) {
AllInSections( AllInSections(
openDrawer = openDrawer,
onLoadSection = { focus.clearFocus() }, onLoadSection = { focus.clearFocus() },
modifier = Modifier.align(Alignment.TopCenter), modifier = Modifier.align(Alignment.TopCenter),
sections = listOf( sections = listOf(
@ -71,7 +70,7 @@ fun BetCreationScreenContent(
setBetPhrase = setBetPhrase, setBetPhrase = setBetPhrase,
betTheme = betTheme, betTheme = betTheme,
setBetTheme = setBetTheme, setBetTheme = setBetTheme,
nbFriends = nbFriends, friends = friends,
selectedFriends = selectedFriends, selectedFriends = selectedFriends,
registerDate = registerDate, registerDate = registerDate,
betDate = betDate, betDate = betDate,
@ -124,7 +123,7 @@ fun BetCreationScreenContent(
private fun BetCreationScreenContentPreview() { private fun BetCreationScreenContentPreview() {
AllInTheme { AllInTheme {
BetCreationScreenContent( BetCreationScreenContent(
nbFriends = 8900, friends = emptyList(),
betTheme = "Ina", betTheme = "Ina",
betThemeError = null, betThemeError = null,
setBetTheme = { }, setBetTheme = { },
@ -146,8 +145,7 @@ private fun BetCreationScreenContentPreview() {
selectedBetType = BetType.BINARY, selectedBetType = BetType.BINARY,
setSelectedBetTypeElement = { }, setSelectedBetTypeElement = { },
selectionBetType = listOf(), selectionBetType = listOf(),
onCreateBet = { }, onCreateBet = { }
openDrawer = { }
) )
} }
} }

@ -1,10 +1,8 @@
package fr.iut.alldev.allin.ui.betCreation.tabs package fr.iut.alldev.allin.ui.betCreation.tabs
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
@ -12,17 +10,18 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.ext.formatToMediumDate import fr.iut.alldev.allin.data.ext.formatToMediumDate
import fr.iut.alldev.allin.data.ext.formatToTime import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabDateTimeSection import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabDateTimeSection
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabPrivacySection import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabPrivacySection
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabThemePhraseSection import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabThemePhraseSection
import java.time.ZonedDateTime import java.time.ZonedDateTime
import fr.iut.alldev.allin.data.ext.formatToTime as formatToTime1
@Composable @Composable
fun BetCreationScreenQuestionTab( fun BetCreationScreenQuestionTab(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
nbFriends: Int, friends: List<User>,
betTheme: String, betTheme: String,
betThemeError: String?, betThemeError: String?,
setBetTheme: (String) -> Unit, setBetTheme: (String) -> Unit,
@ -35,7 +34,7 @@ fun BetCreationScreenQuestionTab(
registerDateError: String?, registerDateError: String?,
betDate: ZonedDateTime, betDate: ZonedDateTime,
betDateError: String?, betDateError: String?,
selectedFriends: MutableList<Int>, selectedFriends: MutableList<String>,
setRegisterDateDialog: (Boolean) -> Unit, setRegisterDateDialog: (Boolean) -> Unit,
setEndDateDialog: (Boolean) -> Unit, setEndDateDialog: (Boolean) -> Unit,
setRegisterTimeDialog: (Boolean) -> Unit, setRegisterTimeDialog: (Boolean) -> Unit,
@ -55,11 +54,11 @@ fun BetCreationScreenQuestionTab(
Spacer(modifier = Modifier.height(35.dp)) Spacer(modifier = Modifier.height(35.dp))
QuestionTabDateTimeSection( QuestionTabDateTimeSection(
registerDate = registerDate.formatToMediumDate(), registerDate = registerDate.formatToMediumDate(),
registerTime = registerDate.formatToTime(), registerTime = registerDate.formatToTime1(),
registerDateError = registerDateError, registerDateError = registerDateError,
betDateError = betDateError, betDateError = betDateError,
endDate = betDate.formatToMediumDate(), endDate = betDate.formatToMediumDate(),
endTime = betDate.formatToTime(), endTime = betDate.formatToTime1(),
setEndDateDialog = setEndDateDialog, setEndDateDialog = setEndDateDialog,
setRegisterDateDialog = setRegisterDateDialog, setRegisterDateDialog = setRegisterDateDialog,
setRegisterTimeDialog = setRegisterTimeDialog, setRegisterTimeDialog = setRegisterTimeDialog,
@ -70,7 +69,7 @@ fun BetCreationScreenQuestionTab(
QuestionTabPrivacySection( QuestionTabPrivacySection(
isPublic = isPublic, isPublic = isPublic,
setIsPublic = setIsPublic, setIsPublic = setIsPublic,
nbFriends = nbFriends, friends = friends,
selectedFriends = selectedFriends, selectedFriends = selectedFriends,
interactionSource = interactionSource interactionSource = interactionSource
) )
@ -83,7 +82,7 @@ fun BetCreationScreenQuestionTab(
private fun BetCreationScreenQuestionTabPreview() { private fun BetCreationScreenQuestionTabPreview() {
AllInTheme { AllInTheme {
BetCreationScreenQuestionTab( BetCreationScreenQuestionTab(
nbFriends = 4651, friends = emptyList(),
betTheme = "Elly", betTheme = "Elly",
betThemeError = null, betThemeError = null,
setBetTheme = { }, setBetTheme = { },
@ -91,16 +90,16 @@ private fun BetCreationScreenQuestionTabPreview() {
betPhraseError = null, betPhraseError = null,
setBetPhrase = { }, setBetPhrase = { },
isPublic = true, isPublic = true,
setIsPublic = { }, setIsPublic = { },
registerDate = ZonedDateTime.now(), registerDate = ZonedDateTime.now(),
registerDateError = null, registerDateError = null,
betDate = ZonedDateTime.now(), betDate = ZonedDateTime.now(),
betDateError = null, betDateError = null,
selectedFriends = mutableListOf(), selectedFriends = mutableListOf(),
setRegisterDateDialog = { }, setRegisterDateDialog = { },
setEndDateDialog = { }, setEndDateDialog = { },
setRegisterTimeDialog = { }, setRegisterTimeDialog = { },
setEndTimeDialog = { }, setEndTimeDialog = { },
interactionSource = remember { MutableInteractionSource() } interactionSource = remember { MutableInteractionSource() }
) )
} }

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Lock import androidx.compose.material.icons.filled.Lock
@ -18,9 +19,11 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.pluralStringResource
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenBottomText import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenFriendLine import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenFriendLine
@ -32,8 +35,8 @@ import fr.iut.alldev.allin.ui.core.AllInTitleInfo
fun QuestionTabPrivacySection( fun QuestionTabPrivacySection(
isPublic: Boolean, isPublic: Boolean,
setIsPublic: (Boolean) -> Unit, setIsPublic: (Boolean) -> Unit,
nbFriends: Int, friends: List<User>,
selectedFriends: MutableList<Int>, selectedFriends: MutableList<String>,
interactionSource: MutableInteractionSource, interactionSource: MutableInteractionSource,
) { ) {
AllInTitleInfo( AllInTitleInfo(
@ -82,25 +85,25 @@ fun QuestionTabPrivacySection(
} }
} else { } else {
AllInRetractableCard( AllInRetractableCard(
text = stringResource( text = pluralStringResource(
id = R.string.n_friends_available, id = R.plurals.n_friends_available,
nbFriends, friends.size,
nbFriends friends.size
), ),
borderWidth = 1.dp, borderWidth = 1.dp,
boldText = nbFriends.toString(), boldText = friends.size.toString(),
isOpen = isOpen, isOpen = isOpen,
setIsOpen = { isOpen = it } setIsOpen = { isOpen = it }
) { ) {
LazyColumn( LazyColumn(
modifier = Modifier.height(165.dp) modifier = Modifier.height(440.dp)
) { ) {
items(nbFriends) { itemsIndexed(friends, key = { _, it -> it.id }) { idx, it ->
var isSelected by remember { var isSelected by remember {
mutableStateOf(selectedFriends.contains(it)) mutableStateOf(selectedFriends.contains(it.id))
} }
if (it != 0) { if (idx != 0) {
HorizontalDivider(color = AllInTheme.themeColors.border) HorizontalDivider(color = AllInTheme.themeColors.border)
} }
BetCreationScreenFriendLine( BetCreationScreenFriendLine(
@ -109,9 +112,9 @@ fun QuestionTabPrivacySection(
isSelected = isSelected isSelected = isSelected
) { ) {
if (isSelected) { if (isSelected) {
selectedFriends.remove(it) selectedFriends.remove(it.id)
} else { } else {
selectedFriends.add(it) selectedFriends.add(it.id)
} }
isSelected = !isSelected isSelected = !isSelected
} }

@ -11,8 +11,8 @@ import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.interaction.collectIsPressedAsState import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.material3.Card import androidx.compose.material3.Card
import androidx.compose.material3.CardDefaults import androidx.compose.material3.CardDefaults
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -20,6 +20,7 @@ import androidx.compose.ui.draw.clip
import androidx.compose.ui.draw.scale import androidx.compose.ui.draw.scale
import androidx.compose.ui.graphics.Brush import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.hapticfeedback.HapticFeedbackType import androidx.compose.ui.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
@ -27,12 +28,12 @@ import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun AllInCard( fun AllInCard(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onClick: (() -> Unit)? = null, onClick: (() -> Unit)? = null,
radius: Dp = 15.dp, radius: Dp = 15.dp,
shape: Shape? = null,
enabled: Boolean = true, enabled: Boolean = true,
backgroundColor: Color = AllInTheme.themeColors.background, backgroundColor: Color = AllInTheme.themeColors.background,
disabledBackgroundColor: Color = AllInTheme.themeColors.disabled, disabledBackgroundColor: Color = AllInTheme.themeColors.disabled,
@ -44,7 +45,7 @@ fun AllInCard(
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val cardShape = AbsoluteSmoothCornerShape(radius, smoothnessAsPercent = 100) val cardShape = shape ?: AbsoluteSmoothCornerShape(radius, smoothnessAsPercent = 100)
val cardModifier = modifier val cardModifier = modifier
.run { .run {
backgroundBrush?.let { backgroundBrush?.let {
@ -111,15 +112,19 @@ fun AllInBouncyCard(
Spring.StiffnessMediumLow Spring.StiffnessMediumLow
), label = "" ), label = ""
) )
LaunchedEffect(key1 = scale < .97f) {
if (scale < .97f) {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}
}
AllInCard( AllInCard(
modifier = modifier modifier = modifier
.combinedClickable( .combinedClickable(
interactionSource = interactionSource, interactionSource = interactionSource,
indication = null, indication = null,
onClick = { onClick?.let { it() } }, onClick = { onClick?.let { it() } }
onLongClick = {
haptic.performHapticFeedback(HapticFeedbackType.LongPress)
}
) )
.scale(scale), .scale(scale),
onClick = null, onClick = null,

@ -39,22 +39,11 @@ fun AllInSections(
sections: List<SectionElement>, sections: List<SectionElement>,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
interSectionsPadding: Dp = 56.dp, interSectionsPadding: Dp = 56.dp,
openDrawer: () -> Unit,
onLoadSection: () -> Unit = { } onLoadSection: () -> Unit = { }
) { ) {
val pagerState = rememberPagerState(pageCount = { sections.size }) val pagerState = rememberPagerState(pageCount = { sections.size })
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
LaunchedEffect(key1 = pagerState.isScrollInProgress) {
if (
pagerState.isScrollInProgress &&
!pagerState.canScrollBackward &&
pagerState.currentPage == pagerState.targetPage
) {
openDrawer()
}
}
Box(modifier = modifier) { Box(modifier = modifier) {
HorizontalPager(state = pagerState) { page -> HorizontalPager(state = pagerState) { page ->
LaunchedEffect(key1 = page) { onLoadSection() } LaunchedEffect(key1 = page) { onLoadSection() }
@ -106,7 +95,6 @@ fun AllInSections(
private fun AllInSectionsPreview() { private fun AllInSectionsPreview() {
AllInTheme { AllInTheme {
AllInSections( AllInSections(
openDrawer = { },
sections = listOf( sections = listOf(
SectionElement("Page 1") { SectionElement("Page 1") {
Text("This is page 1") Text("This is page 1")

@ -2,16 +2,11 @@ package fr.iut.alldev.allin.ui.core.topbar
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.material3.TopAppBarDefaults import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -75,6 +70,6 @@ fun AllInTopBar(
@Composable @Composable
private fun AllInTopBarPreview() { private fun AllInTopBarPreview() {
AllInTheme { AllInTheme {
AllInTopBar(onMenuClicked = { }, coinAmount = 541) AllInTopBar(onMenuClicked = { }, coinAmount = 541)
} }
} }

@ -147,20 +147,14 @@ fun MainScreen(
setStatusVisibility(true) setStatusVisibility(true)
}, },
setLoading = setLoading, setLoading = setLoading,
putSnackbarContent = { mainViewModel.putSnackbarContent(it) }, putSnackbarContent = { mainViewModel.putSnackbarContent(it) }
backHandlers = { ) {
BackHandler(enabled = drawerState.isOpen) { BackHandler(enabled = drawerState.isOpen) {
scope.launch {
drawerState.close()
}
}
},
openDrawer = {
scope.launch { scope.launch {
drawerState.open() drawerState.close()
} }
} }
) }
} }
} }
} }

@ -28,10 +28,13 @@ import fr.iut.alldev.allin.ui.core.snackbar.SnackbarType
import fr.iut.alldev.allin.ui.login.LoginScreen import fr.iut.alldev.allin.ui.login.LoginScreen
import fr.iut.alldev.allin.ui.main.MainScreen import fr.iut.alldev.allin.ui.main.MainScreen
import fr.iut.alldev.allin.ui.main.MainViewModel import fr.iut.alldev.allin.ui.main.MainViewModel
import fr.iut.alldev.allin.ui.ranking.RankingScreen
import fr.iut.alldev.allin.ui.register.RegisterScreen import fr.iut.alldev.allin.ui.register.RegisterScreen
import fr.iut.alldev.allin.ui.splash.SplashScreen
import fr.iut.alldev.allin.ui.welcome.WelcomeScreen import fr.iut.alldev.allin.ui.welcome.WelcomeScreen
object Routes { object Routes {
const val SPLASH = "SPLASH"
const val WELCOME = "WELCOME" const val WELCOME = "WELCOME"
const val REGISTER = "REGISTER" const val REGISTER = "REGISTER"
const val LOGIN = "LOGIN" const val LOGIN = "LOGIN"
@ -41,9 +44,15 @@ object Routes {
const val BET_HISTORY = "BET_HISTORY" const val BET_HISTORY = "BET_HISTORY"
const val BET_CURRENT = "BET_CURRENT" const val BET_CURRENT = "BET_CURRENT"
const val FRIENDS = "FRIENDS" const val FRIENDS = "FRIENDS"
} }
private val fadingRoutes
get() = listOf(
Routes.WELCOME,
Routes.DASHBOARD,
Routes.SPLASH
)
internal fun NavHostController.popUpTo(route: String, baseRoute: String) { internal fun NavHostController.popUpTo(route: String, baseRoute: String) {
this.navigate(route) { this.navigate(route) {
launchSingleTop = true launchSingleTop = true
@ -57,22 +66,18 @@ internal fun NavHostController.popUpTo(route: String, baseRoute: String) {
fun AllInNavHost( fun AllInNavHost(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(), navController: NavHostController = rememberNavController(),
startDestination: String = Routes.WELCOME, startDestination: String = Routes.SPLASH,
) { ) {
NavHost( NavHost(
navController = navController, navController = navController,
startDestination = startDestination, startDestination = startDestination,
enterTransition = { enterTransition = {
if (navController.currentDestination?.route != Routes.DASHBOARD && if (navController.currentDestination?.route !in fadingRoutes) {
navController.currentDestination?.route != Routes.WELCOME
) {
slideInHorizontally(initialOffsetX = { it }) slideInHorizontally(initialOffsetX = { it })
} else fadeIn(animationSpec = tween(1500)) } else fadeIn(animationSpec = tween(1500))
}, },
exitTransition = { exitTransition = {
if (navController.currentDestination?.route != Routes.DASHBOARD && if (navController.currentDestination?.route !in fadingRoutes) {
navController.currentDestination?.route != Routes.WELCOME
) {
slideOutHorizontally(targetOffsetX = { -it / 2 }) slideOutHorizontally(targetOffsetX = { -it / 2 })
} else fadeOut(animationSpec = tween(1500)) } else fadeOut(animationSpec = tween(1500))
}, },
@ -80,6 +85,7 @@ fun AllInNavHost(
.fillMaxSize() .fillMaxSize()
.background(AllInTheme.themeColors.mainSurface), .background(AllInTheme.themeColors.mainSurface),
) { ) {
allInSplashScreen(navController)
allInWelcomeScreen(navController) allInWelcomeScreen(navController)
allInRegisterScreen(navController) allInRegisterScreen(navController)
allInLoginScreen(navController) allInLoginScreen(navController)
@ -90,7 +96,6 @@ fun AllInNavHost(
@Composable @Composable
internal fun AllInDrawerNavHost( internal fun AllInDrawerNavHost(
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
openDrawer: () -> Unit,
navController: NavHostController, navController: NavHostController,
selectBet: (Bet, Boolean) -> Unit, selectBet: (Bet, Boolean) -> Unit,
startDestination: String = Routes.PUBLIC_BETS, startDestination: String = Routes.PUBLIC_BETS,
@ -116,18 +121,16 @@ internal fun AllInDrawerNavHost(
backHandlers() backHandlers()
val creationSuccessMessage = stringResource(id = R.string.bet_creation_success_message) val creationSuccessMessage = stringResource(id = R.string.bet_creation_success_message)
BetCreationScreen( BetCreationScreen(
setLoading = setLoading, setLoading = setLoading
openDrawer = openDrawer, ) {
onCreation = { putSnackbarContent(
putSnackbarContent( MainViewModel.SnackbarContent(
MainViewModel.SnackbarContent( text = creationSuccessMessage,
text = creationSuccessMessage, type = SnackbarType.SUCCESS
type = SnackbarType.SUCCESS
)
) )
navController.popUpTo(Routes.PUBLIC_BETS, Routes.BET_CREATION) )
} navController.popUpTo(Routes.PUBLIC_BETS, Routes.BET_CREATION)
) }
} }
composable( composable(
@ -137,6 +140,13 @@ internal fun AllInDrawerNavHost(
BetHistoryScreen() BetHistoryScreen()
} }
composable(
route = Routes.FRIENDS
) {
backHandlers()
RankingScreen()
}
composable( composable(
route = Routes.BET_CURRENT route = Routes.BET_CURRENT
) { ) {
@ -146,6 +156,21 @@ internal fun AllInDrawerNavHost(
} }
} }
private fun NavGraphBuilder.allInSplashScreen(
navController: NavHostController,
) {
composable(route = Routes.SPLASH) {
SplashScreen(
navigateToWelcomeScreen = {
navController.popUpTo(Routes.WELCOME, Routes.SPLASH)
},
navigateToDashboard = {
navController.popUpTo(Routes.DASHBOARD, Routes.SPLASH)
}
)
}
}
private fun NavGraphBuilder.allInWelcomeScreen( private fun NavGraphBuilder.allInWelcomeScreen(
navController: NavHostController, navController: NavHostController,
) { ) {
@ -156,9 +181,6 @@ private fun NavGraphBuilder.allInWelcomeScreen(
}, },
navigateToLogin = { navigateToLogin = {
navController.popUpTo(Routes.LOGIN, Routes.WELCOME) navController.popUpTo(Routes.LOGIN, Routes.WELCOME)
},
navigateToDashboard = {
navController.popUpTo(Routes.DASHBOARD, Routes.WELCOME)
} }
) )
} }

@ -0,0 +1,110 @@
package fr.iut.alldev.allin.ui.ranking
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.ui.ranking.components.RankingScreenContent
@Composable
fun RankingScreen() {
val users = remember { mockRanking }
RankingScreenContent(
users = users.sortedByDescending { it.coins }
)
}
private val mockRanking by lazy {
listOf(
User(
id = "1",
username = "Owen",
email = "",
coins = 8533
),
User(
id = "2",
username = "Dave",
email = "",
coins = 6942
),
User(
id = "3",
username = "Lucas",
email = "",
coins = 3333
),
User(
id = "4",
username = "Louison",
email = "",
coins = 1970
),
User(
id = "5",
username = "Imri",
email = "",
coins = 1
),
User(
id = "21",
username = "Owen",
email = "",
coins = 8533
),
User(
id = "22",
username = "Dave",
email = "",
coins = 6942
),
User(
id = "23",
username = "Lucas",
email = "",
coins = 3333
),
User(
id = "24",
username = "Louison",
email = "",
coins = 1970
),
User(
id = "25",
username = "Imri",
email = "",
coins = 1
),
User(
id = "31",
username = "Owen",
email = "",
coins = 8533
),
User(
id = "32",
username = "Dave",
email = "",
coins = 6942
),
User(
id = "33",
username = "Lucas",
email = "",
coins = 3333
),
User(
id = "34",
username = "Louison",
email = "",
coins = 1970
),
User(
id = "35",
username = "Imri",
email = "",
coins = 1
)
)
}

@ -0,0 +1,121 @@
package fr.iut.alldev.allin.ui.ranking.components
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun RankingScreenContent(
users: List<User>
) {
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(start = 24.dp, end = 24.dp, top = 18.dp),
verticalArrangement = Arrangement.spacedBy(11.dp),
) {
item {
Text(
text = stringResource(id = R.string.ranking_title),
style = AllInTheme.typography.h1,
color = AllInTheme.colors.allInGrey,
fontSize = 24.sp,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
}
item {
Row(
verticalAlignment = Alignment.Bottom,
horizontalArrangement = Arrangement.spacedBy(11.dp)
) {
users.firstOrNull()?.let { first ->
RankingScreenFirst(
username = first.username,
coins = first.coins,
modifier = Modifier.weight(1f)
)
}
users.getOrNull(1)?.let { second ->
RankingScreenSecond(
username = second.username,
coins = second.coins,
modifier = Modifier.weight(1f)
)
}
}
}
itemsIndexed(users.subList(1, users.size), key = { _, user -> user.id }) { idx, user ->
RankingScreenItem(
position = idx + 3,
username = user.username,
coins = user.coins
)
}
item {
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
}
@Preview
@Composable
private fun RankingScreenContentPreview() {
AllInTheme {
RankingScreenContent(
users = listOf(
User(
id = "1",
username = "Owen",
email = "",
coins = 8533
),
User(
id = "2",
username = "Dave",
email = "",
coins = 6942
),
User(
id = "3",
username = "Lucas",
email = "",
coins = 3333
),
User(
id = "4",
username = "Louison",
email = "",
coins = 1970
),
User(
id = "5",
username = "Imri",
email = "",
coins = 1
)
)
)
}
}

@ -0,0 +1,126 @@
package fr.iut.alldev.allin.ui.ranking.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.ProfilePicture
import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@Composable
fun RankingScreenFirst(
username: String,
coins: Int,
modifier: Modifier = Modifier
) {
Box(modifier) {
AllInCard(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(top = 35.dp),
shape = AbsoluteSmoothCornerShape(
cornerRadiusTL = 41.dp,
smoothnessAsPercentTL = 100,
cornerRadiusTR = 8.dp,
smoothnessAsPercentTR = 100,
cornerRadiusBR = 19.dp,
smoothnessAsPercentBR = 100,
cornerRadiusBL = 19.dp,
smoothnessAsPercentBL = 100
)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(50.dp))
Text(
text = username,
color = AllInTheme.themeColors.onBackground,
style = AllInTheme.typography.h1,
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
fontSize = 20.sp,
modifier = Modifier.padding(8.dp)
)
HorizontalDivider(color = AllInTheme.themeColors.border)
Box(
modifier = Modifier
.fillMaxWidth()
.background(AllInTheme.themeColors.background2)
.padding(16.dp),
contentAlignment = Alignment.Center
) {
AllInCoinCount(
amount = coins,
color = AllInTheme.colors.allInPurple,
size = 20
)
}
}
}
ProfilePicture(
modifier = Modifier
.size(70.dp)
.align(Alignment.TopCenter)
.zIndex(1f),
)
Box(
modifier = Modifier
.align(Alignment.TopCenter)
.padding(vertical = 55.dp)
.zIndex(500f)
.clip(CircleShape)
.background(AllInTheme.colors.allInPurple)
.size(30.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "1",
color = AllInTheme.colors.white,
style = AllInTheme.typography.h1,
fontSize = 20.sp,
modifier = Modifier.padding(4.dp)
)
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun RankingScreenFirstPreview() {
AllInTheme {
RankingScreenFirst(
username = "Username",
coins = 420
)
}
}

@ -0,0 +1,96 @@
package fr.iut.alldev.allin.ui.ranking.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.ProfilePicture
@Composable
fun RankingScreenItem(
position: Int,
username: String,
coins: Int,
modifier: Modifier = Modifier
) {
AllInCard(
modifier = modifier,
radius = 8.dp
) {
Row(
modifier = Modifier
.fillMaxWidth()
.padding(horizontal = 8.dp, vertical = 16.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = "$position",
color = AllInTheme.colors.allInPurple,
style = AllInTheme.typography.h1,
fontSize = 15.sp,
softWrap = false,
modifier = Modifier.size(width = 26.dp, height = 20.dp)
)
ProfilePicture(modifier = Modifier.size(38.dp))
Spacer(modifier = Modifier.width(8.dp))
Text(
text = username,
color = AllInTheme.themeColors.onBackground,
style = AllInTheme.typography.sm2,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
fontSize = 15.sp,
modifier = Modifier.weight(1f)
)
AllInCoinCount(
amount = coins,
color = AllInTheme.colors.allInPurple
)
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun RankingScreenItemPreview() {
AllInTheme {
RankingScreenItem(
position = 3,
username = "Username",
coins = 420
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun RankingScreenItemTenthPreview() {
AllInTheme {
RankingScreenItem(
position = 10,
username = "Username",
coins = 420
)
}
}

@ -0,0 +1,126 @@
package fr.iut.alldev.allin.ui.ranking.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.compose.ui.zIndex
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.ProfilePicture
import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@Composable
fun RankingScreenSecond(
username: String,
coins: Int,
modifier: Modifier = Modifier
) {
Box(modifier) {
AllInCard(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(top = 28.dp),
shape = AbsoluteSmoothCornerShape(
cornerRadiusTL = 8.dp,
smoothnessAsPercentTL = 100,
cornerRadiusTR = 41.dp,
smoothnessAsPercentTR = 100,
cornerRadiusBR = 19.dp,
smoothnessAsPercentBR = 100,
cornerRadiusBL = 19.dp,
smoothnessAsPercentBL = 100
)
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
) {
Spacer(modifier = Modifier.height(30.dp))
Text(
text = username,
color = AllInTheme.themeColors.onBackground,
style = AllInTheme.typography.h1,
textAlign = TextAlign.Center,
maxLines = 2,
overflow = TextOverflow.Ellipsis,
fontSize = 20.sp,
modifier = Modifier.padding(8.dp)
)
HorizontalDivider(color = AllInTheme.themeColors.border)
Box(
modifier = Modifier
.fillMaxWidth()
.background(AllInTheme.themeColors.background2)
.padding(16.dp),
contentAlignment = Alignment.Center
) {
AllInCoinCount(
amount = coins,
color = AllInTheme.colors.allInPurple,
size = 20
)
}
}
}
ProfilePicture(
modifier = Modifier
.size(56.dp)
.align(Alignment.TopCenter)
.zIndex(1f),
)
Box(
modifier = Modifier
.align(Alignment.TopCenter)
.padding(vertical = 44.dp)
.zIndex(500f)
.clip(CircleShape)
.background(AllInTheme.colors.allInPurple)
.size(25.dp),
contentAlignment = Alignment.Center
) {
Text(
text = "2",
color = AllInTheme.colors.white,
style = AllInTheme.typography.h1,
fontSize = 15.sp,
modifier = Modifier.padding(4.dp)
)
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun RankingScreenSecondPreview() {
AllInTheme {
RankingScreenSecond(
username = "Username",
coins = 420
)
}
}

@ -0,0 +1,30 @@
package fr.iut.alldev.allin.ui.splash
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import fr.iut.alldev.allin.ui.splash.components.SplashScreenContent
@Composable
fun SplashScreen(
viewModel: SplashScreenViewModel = hiltViewModel(),
navigateToWelcomeScreen: () -> Unit,
navigateToDashboard: () -> Unit
) {
val state by viewModel.state.collectAsStateWithLifecycle()
LaunchedEffect(key1 = state) {
(state as? SplashScreenViewModel.State.Loaded)?.let { loadedState ->
if (loadedState.isLoggedIn) {
navigateToDashboard()
} else {
navigateToWelcomeScreen()
}
}
}
SplashScreenContent()
}

@ -0,0 +1,51 @@
package fr.iut.alldev.allin.ui.splash
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import fr.iut.alldev.allin.data.repository.UserRepository
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
import kotlinx.coroutines.delay
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.stateIn
import timber.log.Timber
import javax.inject.Inject
@HiltViewModel
class SplashScreenViewModel @Inject constructor(
private val keystoreManager: AllInKeystoreManager,
private val userRepository: UserRepository
) : ViewModel() {
val state: StateFlow<State> by lazy {
flow {
delay(1_000L)
keystoreManager.getToken()?.let { token ->
runCatching {
userRepository
.login(token)
?.let { newToken ->
keystoreManager.putToken(newToken)
Timber.d("Put token $newToken")
}
}.onSuccess {
emit(State.Loaded(true))
}.onFailure {
emit(State.Loaded(false))
}
} ?: emit(State.Loaded(false))
}.stateIn(viewModelScope, SharingStarted.WhileSubscribed(), State.Loading)
}
init {
keystoreManager.createKeystore()
}
sealed interface State {
data object Loading : State
data class Loaded(val isLoggedIn: Boolean) : State
}
}

@ -0,0 +1,38 @@
package fr.iut.alldev.allin.ui.splash.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.Icon
@Composable
fun SplashScreenContent() {
Box(
modifier = Modifier
.fillMaxSize()
.background(AllInTheme.colors.allInLoginGradient),
contentAlignment = Alignment.Center
) {
Icon(
painter = painterResource(R.drawable.allin),
contentDescription = null,
tint = AllInTheme.colors.white,
modifier = Modifier.fillMaxSize(.25f)
)
}
}
@Preview
@Composable
private fun SplashScreenContentPreview() {
AllInTheme {
SplashScreenContent()
}
}

@ -1,56 +1,15 @@
package fr.iut.alldev.allin.ui.welcome package fr.iut.alldev.allin.ui.welcome
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInButton
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.welcome.components.WelcomeScreenContent import fr.iut.alldev.allin.ui.welcome.components.WelcomeScreenContent
@Composable @Composable
fun WelcomeScreen( fun WelcomeScreen(
navigateToRegister: () -> Unit, navigateToRegister: () -> Unit,
navigateToLogin: () -> Unit, navigateToLogin: () -> Unit,
navigateToDashboard: () -> Unit,
viewModel: WelcomeScreenViewModel = hiltViewModel()
) { ) {
val loading by remember { viewModel.loading }
LaunchedEffect(viewModel) {
viewModel.tryAutoLogin(navigateToDashboard)
}
WelcomeScreenContent( WelcomeScreenContent(
navigateToRegister = navigateToRegister, navigateToRegister = navigateToRegister,
navigateToLogin = navigateToLogin, navigateToLogin = navigateToLogin
loading = loading
) )
} }

@ -1,38 +0,0 @@
package fr.iut.alldev.allin.ui.welcome
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import fr.iut.alldev.allin.data.repository.UserRepository
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
import kotlinx.coroutines.launch
import javax.inject.Inject
@HiltViewModel
class WelcomeScreenViewModel @Inject constructor(
private val keystoreManager: AllInKeystoreManager,
private val userRepository: UserRepository
) : ViewModel() {
var loading = mutableStateOf(false)
fun tryAutoLogin(onSuccess: () -> Unit) {
viewModelScope.launch {
loading.value = true
keystoreManager.createKeystore()
keystoreManager.getToken()?.let { token ->
runCatching {
userRepository
.login(token)
?.let { newToken ->
keystoreManager.putToken(newToken)
}
onSuccess()
}
}
loading.value = false
}
}
}

@ -13,8 +13,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.navigationBarsPadding import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.ClickableText
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
@ -31,13 +29,11 @@ import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInButton import fr.iut.alldev.allin.ui.core.AllInButton
import fr.iut.alldev.allin.ui.core.AllInLoading
@Composable @Composable
fun WelcomeScreenContent( fun WelcomeScreenContent(
navigateToRegister: () -> Unit, navigateToRegister: () -> Unit,
navigateToLogin: () -> Unit, navigateToLogin: () -> Unit
loading: Boolean
) { ) {
Box( Box(
Modifier Modifier
@ -115,8 +111,6 @@ fun WelcomeScreenContent(
} }
} }
} }
AllInLoading(visible = loading)
} }
@Preview @Preview
@ -126,8 +120,7 @@ private fun WelcomeScreenContentPreview() {
AllInTheme { AllInTheme {
WelcomeScreenContent( WelcomeScreenContent(
navigateToRegister = { }, navigateToRegister = { },
navigateToLogin = { }, navigateToLogin = { }
loading = false
) )
} }
} }

@ -71,7 +71,11 @@
<string name="End_registration_date">Date de fin des inscriptions</string> <string name="End_registration_date">Date de fin des inscriptions</string>
<string name="End_bet_date">Date de fin du BET</string> <string name="End_bet_date">Date de fin du BET</string>
<string name="Bet_privacy">Confidentialité du bet</string> <string name="Bet_privacy">Confidentialité du bet</string>
<string name="n_friends_available">%d amis disponibles</string> <plurals name="n_friends_available">
<item quantity="one">%d ami disponibles</item>
<item quantity="other">%d amis disponibles</item>
<item quantity="many">%d amis disponibles</item>
</plurals>
<string name="public_bottom_text_1">Votre bet sera visible par tous les utilisateurs.</string> <string name="public_bottom_text_1">Votre bet sera visible par tous les utilisateurs.</string>
<string name="public_bottom_text_2">Tout le monde pourra rejoindre le BET.</string> <string name="public_bottom_text_2">Tout le monde pourra rejoindre le BET.</string>
<string name="private_bottom_text_1">Votre bet sera visible uniquement par vos amis.</string> <string name="private_bottom_text_1">Votre bet sera visible uniquement par vos amis.</string>
@ -136,4 +140,7 @@
<string name="bet_result_odds">Cote totale</string> <string name="bet_result_odds">Cote totale</string>
<string name="bet_result_stake">Mise</string> <string name="bet_result_stake">Mise</string>
<string name="bet_result_winnings">Gains</string> <string name="bet_result_winnings">Gains</string>
<!--Ranking-->
<string name="ranking_title">Classement</string>
</resources> </resources>

@ -74,7 +74,10 @@
<string name="End_registration_date">Registration end date</string> <string name="End_registration_date">Registration end date</string>
<string name="End_bet_date">Bet end date</string> <string name="End_bet_date">Bet end date</string>
<string name="Bet_privacy">Bet privacy</string> <string name="Bet_privacy">Bet privacy</string>
<string name="n_friends_available">%d friends available</string> <plurals name="n_friends_available">
<item quantity="one">%d friend available</item>
<item quantity="other">%d friends available</item>
</plurals>
<string name="public_bottom_text_1">Your bet will be visible by all the users.</string> <string name="public_bottom_text_1">Your bet will be visible by all the users.</string>
<string name="public_bottom_text_2">Everyone will be able to join the bet.</string> <string name="public_bottom_text_2">Everyone will be able to join the bet.</string>
<string name="private_bottom_text_1">Your bet will only be visible by your friends.</string> <string name="private_bottom_text_1">Your bet will only be visible by your friends.</string>
@ -137,5 +140,7 @@
<string name="bet_result_stake">Stake</string> <string name="bet_result_stake">Stake</string>
<string name="bet_result_winnings">Winnings</string> <string name="bet_result_winnings">Winnings</string>
<!--Ranking-->
<string name="ranking_title">Ranking</string>
</resources> </resources>
Loading…
Cancel
Save