diff --git a/src/app/src/main/java/fr/iut/alldev/allin/di/CurrentUserModule.kt b/src/app/src/main/java/fr/iut/alldev/allin/di/CurrentUserModule.kt new file mode 100644 index 0000000..fbce1c3 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/di/CurrentUserModule.kt @@ -0,0 +1,23 @@ +package fr.iut.alldev.allin.di + +import dagger.Module +import dagger.Provides +import dagger.hilt.InstallIn +import dagger.hilt.components.SingletonComponent +import fr.iut.alldev.allin.data.repository.UserRepository +import javax.inject.Qualifier + +@Qualifier +@Retention(AnnotationRetention.BINARY) +annotation class AllInCurrentUser + +@Module +@InstallIn(SingletonComponent::class) +internal object CurrentUserModule { + + @AllInCurrentUser + @Provides + fun provideUser( + userRepository: UserRepository + ) = userRepository.currentUser +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ext/BetStatusExt.kt b/src/app/src/main/java/fr/iut/alldev/allin/ext/BetStatusExt.kt new file mode 100644 index 0000000..e5f5140 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ext/BetStatusExt.kt @@ -0,0 +1,33 @@ +package fr.iut.alldev.allin.ext + +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import fr.iut.alldev.allin.R +import fr.iut.alldev.allin.data.model.BetStatus +import fr.iut.alldev.allin.ui.theme.AllInTheme + +fun BetStatus.getTitle(): Int { + return when (this) { + BetStatus.FINISHED -> R.string.bet_status_finished + BetStatus.IN_PROGRESS -> R.string.bet_status_in_progress + BetStatus.WAITING -> R.string.bet_status_waiting + } +} + +@Composable +fun BetStatus.getColor(): Color { + return when (this) { + BetStatus.FINISHED -> AllInTheme.colors.allIn_BetFinish + BetStatus.IN_PROGRESS -> AllInTheme.colors.allIn_BetInProgress + BetStatus.WAITING -> AllInTheme.colors.allIn_BetWaiting + } +} + +@Composable +fun BetStatus.getTextColor(): Color { + return when (this) { + BetStatus.FINISHED -> AllInTheme.colors.allIn_BetFinishText + BetStatus.IN_PROGRESS -> AllInTheme.colors.allIn_BetInProgressText + BetStatus.WAITING -> AllInTheme.colors.allIn_BetWaitingText + } +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/MainActivity.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/MainActivity.kt index 382e220..8f9038e 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/MainActivity.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/MainActivity.kt @@ -28,11 +28,11 @@ class MainActivity : ComponentActivity() { with((view.context as Activity)) { window.statusBarColor = Color.Transparent.toArgb() window.navigationBarColor = Color.Transparent.toArgb() - WindowCompat.setDecorFitsSystemWindows(window, false) if (Build.VERSION.SDK_INT > 30) { window.insetsController?.hide(WindowInsetsCompat.Type.statusBars()) window.insetsController?.hide(WindowInsetsCompat.Type.navigationBars()) + WindowCompat.setDecorFitsSystemWindows(window, false) } } } diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/bet/BetScreen.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/bet/BetScreen.kt index bbd2cf6..3a6eaf7 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/bet/BetScreen.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/bet/BetScreen.kt @@ -26,10 +26,12 @@ import fr.iut.alldev.allin.ui.bet.components.BetScreenPopularCard import fr.iut.alldev.allin.ui.core.AllInChip import fr.iut.alldev.allin.ui.theme.AllInTheme -@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class) +@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterialApi::class +) @Composable fun BetScreen( viewModel: BetViewModel = hiltViewModel(), + showBetStatus: ()->Unit ){ val horizontalPadding = 23.dp @@ -89,7 +91,9 @@ fun BetScreen( AllInChip( text = stringResource(id = it), isSelected = isSelected, - onClick = { isSelected = !isSelected }) + onClick = { + isSelected = !isSelected + }) } item { Spacer(modifier = Modifier.width(horizontalPadding)) @@ -104,7 +108,7 @@ fun BetScreen( date = "11 Sept.", time = "13:00", players = List(3){ null }, - onClickParticipate = { /* TODO */ }, + onClickParticipate = showBetStatus, modifier = Modifier.padding(horizontal = horizontalPadding) ) Spacer(modifier = Modifier.height(24.dp)) diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/BetStatusBottomSheet.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/BetStatusBottomSheet.kt new file mode 100644 index 0000000..6e7c525 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/BetStatusBottomSheet.kt @@ -0,0 +1,51 @@ +package fr.iut.alldev.allin.ui.betstatus + +import androidx.compose.animation.* +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import fr.iut.alldev.allin.data.model.BetStatus +import fr.iut.alldev.allin.ui.betstatus.components.BetStatusBottomSheetBack +import fr.iut.alldev.allin.ui.core.AllInBottomSheet + + +internal const val SHEET_HEIGHT = .85f + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun BetStatusBottomSheet( + state: SheetState, + sheetVisibility: Boolean, + sheetBackVisibility: Boolean, + betStatus: BetStatus, + onDismiss: ()->Unit +) { + AnimatedVisibility( + visible = sheetBackVisibility, + enter = slideInVertically( + initialOffsetY = { it } + ), + exit = slideOutVertically( + targetOffsetY = { it } + ) + ) { + BetStatusBottomSheetBack( + status = betStatus + ) + } + + AllInBottomSheet( + sheetVisibility = sheetVisibility, + onDismiss = onDismiss, + state = state, + scrimColor = Color.Transparent + ){ + Column( + Modifier + .fillMaxHeight(SHEET_HEIGHT) + ) { + } + } +} diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/components/BetStatusBottomSheetBack.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/components/BetStatusBottomSheetBack.kt new file mode 100644 index 0000000..6282f07 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/betstatus/components/BetStatusBottomSheetBack.kt @@ -0,0 +1,72 @@ +package fr.iut.alldev.allin.ui.betstatus.components + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.Icon +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.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.tooling.preview.PreviewParameter +import androidx.compose.ui.tooling.preview.PreviewParameterProvider +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.BetStatus +import fr.iut.alldev.allin.ext.getColor +import fr.iut.alldev.allin.ext.getTextColor +import fr.iut.alldev.allin.ext.getTitle +import fr.iut.alldev.allin.ui.betstatus.SHEET_HEIGHT +import fr.iut.alldev.allin.ui.theme.AllInTheme + +@Composable +fun BetStatusBottomSheetBack( + status: BetStatus, + modifier: Modifier = Modifier +) { + + Box( + modifier + .fillMaxSize() + .background(status.getColor()) + .padding(horizontal = 25.dp) + ) { + Row( + verticalAlignment = Alignment.CenterVertically, + modifier = Modifier.fillMaxHeight(1-SHEET_HEIGHT) + ) { + Text( + text = stringResource(id = status.getTitle()), + color = status.getTextColor(), + style = AllInTheme.typography.h2.copy( + fontStyle = FontStyle.Italic + ), + fontSize = 20.sp, + modifier = Modifier.weight(1f) + ) + Icon( + painter = painterResource(id = R.drawable.allin_exit), + tint = AllInTheme.colors.white, + contentDescription = null + ) + } + } +} + +private class BetStatusPreviewProvider: PreviewParameterProvider { + override val values = BetStatus.values().asSequence() +} + +@Preview +@Composable +private fun BackStatusScreenBackPreview( + @PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus +) { + AllInTheme { + BetStatusBottomSheetBack(status = betStatus) + } +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInBottomSheet.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInBottomSheet.kt new file mode 100644 index 0000000..3005eb3 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInBottomSheet.kt @@ -0,0 +1,48 @@ +package fr.iut.alldev.allin.ui.core + +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.platform.LocalLayoutDirection +import androidx.compose.ui.unit.dp +import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun AllInBottomSheet( + sheetVisibility: Boolean, + onDismiss: ()->Unit, + state: SheetState, + scrimColor: Color = BottomSheetDefaults.ScrimColor, + content: @Composable ColumnScope.()->Unit +) { + val localDensity = LocalDensity.current + val localLayoutDirection = LocalLayoutDirection.current + + if(sheetVisibility) { + ModalBottomSheet( + onDismissRequest = onDismiss, + sheetState = state, + scrimColor = scrimColor, + shape = sheetShape, + windowInsets = BottomSheetDefaults.windowInsets.let { + WindowInsets( + left = it.getLeft(localDensity, localLayoutDirection), + right = it.getRight(localDensity, localLayoutDirection), + top = it.getTop(localDensity), + bottom = 0, + ) + }, + content = content + ) + } +} + +private val sheetShape = AbsoluteSmoothCornerShape( + cornerRadiusTL = 15.dp, + cornerRadiusTR = 15.dp, + smoothnessAsPercentTL = 100, + smoothnessAsPercentTR = 100 +) \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInTextField.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInTextField.kt index 5628909..95f99b8 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInTextField.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/core/AllInTextField.kt @@ -1,5 +1,6 @@ package fr.iut.alldev.allin.ui.core +import android.content.res.Configuration import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.relocation.BringIntoViewRequester import androidx.compose.foundation.text.KeyboardActions @@ -187,6 +188,7 @@ private fun AllInTextFieldPlaceholderPreview() { @OptIn(ExperimentalFoundationApi::class) @Preview +@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES) @Composable private fun AllInTextFieldValuePreview() { AllInTheme { diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainScreen.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainScreen.kt new file mode 100644 index 0000000..0611601 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainScreen.kt @@ -0,0 +1,137 @@ +package fr.iut.alldev.allin.ui.main + +import androidx.activity.compose.BackHandler +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.* +import androidx.compose.material3.* +import androidx.compose.runtime.* +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.hilt.navigation.compose.hiltViewModel +import androidx.navigation.NavHostController +import androidx.navigation.compose.rememberNavController +import fr.iut.alldev.allin.data.model.BetStatus +import fr.iut.alldev.allin.ui.betstatus.BetStatusBottomSheet +import fr.iut.alldev.allin.ui.main.components.AllInScaffold +import fr.iut.alldev.allin.ui.navigation.AllInDrawerNavHost +import fr.iut.alldev.allin.ui.navigation.Routes +import fr.iut.alldev.allin.ui.navigation.TopLevelDestination +import fr.iut.alldev.allin.ui.navigation.drawer.AllInDrawer +import fr.iut.alldev.allin.ui.navigation.popUpTo +import fr.iut.alldev.allin.ui.theme.AllInTheme +import kotlinx.coroutines.launch + +private val topLevelDestinations = listOf( + TopLevelDestination.PUBLIC_BETS, + TopLevelDestination.BET_CREATION, + TopLevelDestination.BET_HISTORY, + TopLevelDestination.FRIENDS, + TopLevelDestination.CURRENT_BETS +) +@Composable +private fun rememberBetStatusVisibilities(): Triple, MutableState, (Boolean) -> Unit> { + val statusVisibility = remember { + mutableStateOf(false) + } + + val sheetBackVisibility = remember { + mutableStateOf(false) + } + + val setStatusVisibility = { + it: Boolean -> + statusVisibility.value = it + if(it) sheetBackVisibility.value = true + } + return Triple(statusVisibility, sheetBackVisibility, setStatusVisibility) +} + +@OptIn(ExperimentalMaterial3Api::class) +@Composable +fun MainScreen( + navController: NavHostController = rememberNavController(), + drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed), + startDestination: String = Routes.PUBLIC_BETS, + mainViewModel: MainViewModel = hiltViewModel() +) { + + val currentUser = remember{ + mainViewModel.currentUser + } + + val scope = rememberCoroutineScope() + + val (statusVisibility, sheetBackVisibility, setStatusVisibility) + = rememberBetStatusVisibilities() + + val bottomSheetState = rememberModalBottomSheetState( + skipPartiallyExpanded = true, + confirmValueChange = { + if(it == SheetValue.Hidden){ + sheetBackVisibility.value = false + } + true + } + ) + + AllInDrawer( + drawerState = drawerState, + destinations = topLevelDestinations, + scope = scope, + username = currentUser.username, + nbFriends = 5, + nbBets = 35, + bestWin = 362, + navigateTo = {route -> + navController.popUpTo(route, startDestination) + } + ){ + AllInScaffold( + onMenuClicked = { scope.launch { drawerState.open() } }, + coinAmount = currentUser.coins, + drawerState = drawerState + ) { + Column( + modifier = Modifier + .padding(top = it.calculateTopPadding()) + .fillMaxSize() + .background(AllInTheme.themeColors.main_surface), + horizontalAlignment = Alignment.CenterHorizontally + ) { + AllInDrawerNavHost( + navController = navController, + setStatusVisibility = setStatusVisibility + ) + } + } + } + + BetStatusBottomSheet( + state = bottomSheetState, + sheetVisibility = statusVisibility.value, + sheetBackVisibility = sheetBackVisibility.value, + onDismiss = { + setStatusVisibility(false) + }, + betStatus = BetStatus.IN_PROGRESS + ) + + BackHandler( + enabled = drawerState.isOpen + ) { + scope.launch { + drawerState.close() + } + } + + BackHandler( + enabled = statusVisibility.value + ) { + scope.launch { + setStatusVisibility(false) + } + } +} + + + diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainViewModel.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainViewModel.kt new file mode 100644 index 0000000..ceed9b9 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/MainViewModel.kt @@ -0,0 +1,17 @@ +package fr.iut.alldev.allin.ui.main + +import androidx.compose.runtime.mutableStateOf +import androidx.lifecycle.ViewModel +import dagger.hilt.android.lifecycle.HiltViewModel +import fr.iut.alldev.allin.di.AllInCurrentUser +import fr.iut.alldev.allin.data.model.BetStatus +import fr.iut.alldev.allin.data.model.User +import javax.inject.Inject + + +@HiltViewModel +class MainViewModel @Inject constructor( + @AllInCurrentUser val currentUser: User +) : ViewModel() { + val selectedBet = mutableStateOf(null) +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/main/components/AllInScaffold.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/components/AllInScaffold.kt new file mode 100644 index 0000000..02d271c --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/main/components/AllInScaffold.kt @@ -0,0 +1,48 @@ +package fr.iut.alldev.allin.ui.main.components + +import androidx.compose.foundation.layout.PaddingValues +import androidx.compose.foundation.layout.offset +import androidx.compose.material3.DrawerState +import androidx.compose.material3.Scaffold +import androidx.compose.runtime.* +import androidx.compose.ui.Modifier +import androidx.compose.ui.platform.LocalDensity +import androidx.compose.ui.unit.dp +import fr.iut.alldev.allin.ui.core.topbar.AllInTopBar +import kotlin.math.abs + +@Composable +fun AllInScaffold( + onMenuClicked: ()->Unit, + coinAmount: Int, + drawerState: DrawerState, + content: @Composable (PaddingValues)->Unit +) { + + val drawerOffset = derivedStateOf { drawerState.offset.value } + var drawerWidth by remember { + mutableStateOf(drawerState.offset.value) + } + LaunchedEffect(drawerWidth == 0f) { + drawerWidth = drawerState.offset.value + } + + val localDensity = LocalDensity.current + val contentOffset by derivedStateOf { + if (drawerWidth == 0f) 0.dp + else with(localDensity) { + (abs(drawerWidth) + drawerOffset.value).toDp() + } + } + + Scaffold( + modifier = Modifier.offset(x = contentOffset), + topBar = { + AllInTopBar( + onMenuClicked = onMenuClicked, + coinAmount = coinAmount + ) + }, + content = content + ) +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/NavHost.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/NavHost.kt index 1b9a8d7..602f6b9 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/NavHost.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/NavHost.kt @@ -14,7 +14,7 @@ import androidx.navigation.compose.rememberNavController import fr.iut.alldev.allin.ui.bet.BetScreen import fr.iut.alldev.allin.ui.betcreation.BetCreationScreen import fr.iut.alldev.allin.ui.login.LoginScreen -import fr.iut.alldev.allin.ui.navigation.drawer.AllInDrawer +import fr.iut.alldev.allin.ui.main.MainScreen import fr.iut.alldev.allin.ui.register.RegisterScreen import fr.iut.alldev.allin.ui.theme.AllInTheme import fr.iut.alldev.allin.ui.welcome.WelcomeScreen @@ -80,6 +80,7 @@ fun AllInNavHost(modifier: Modifier = Modifier, internal fun AllInDrawerNavHost( modifier: Modifier = Modifier, navController: NavHostController, + setStatusVisibility: (Boolean) -> Unit, startDestination: String = Routes.PUBLIC_BETS ) { NavHost( @@ -89,8 +90,14 @@ internal fun AllInDrawerNavHost( enterTransition = { EnterTransition.None }, exitTransition = { ExitTransition.None } ) { - composable(route = Routes.PUBLIC_BETS) { BetScreen() } - composable(route = Routes.BET_CREATION) { BetCreationScreen() } + composable(route = Routes.PUBLIC_BETS) { + BetScreen( + showBetStatus = { setStatusVisibility(true) } + ) + } + composable(route = Routes.BET_CREATION) { + BetCreationScreen() + } } } private fun NavGraphBuilder.allInWelcomeScreen( @@ -142,6 +149,6 @@ private fun NavGraphBuilder.allInDashboard() { composable( route = Routes.DASHBOARD, ){ - AllInDrawer() + MainScreen() } } \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/TopLevelDestination.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/TopLevelDestination.kt new file mode 100644 index 0000000..78aa308 --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/TopLevelDestination.kt @@ -0,0 +1,41 @@ +package fr.iut.alldev.allin.ui.navigation + +import fr.iut.alldev.allin.R + +sealed class TopLevelDestination( + val route: String, + val title: Int, + val subtitle: Int, + val emoji: Int +) { + object PUBLIC_BETS : TopLevelDestination( + route = Routes.PUBLIC_BETS, + title = R.string.public_bets, + subtitle = R.string.public_bets_subtitle, + emoji = R.drawable.globe + ) + object BET_CREATION : TopLevelDestination( + route = Routes.BET_CREATION, + title = R.string.create_a_bet, + subtitle = R.string.create_a_bet_subtitle, + emoji = R.drawable.video_game + ) + object BET_HISTORY : TopLevelDestination( + route = Routes.BET_HISTORY, + title = R.string.bet_history, + subtitle = R.string.bet_history_subtitle, + emoji = R.drawable.eyes + ) + object FRIENDS : TopLevelDestination( + route = Routes.FRIENDS, + title = R.string.friends, + subtitle = R.string.friends_subtitle, + emoji = R.drawable.holding_hands + ) + object CURRENT_BETS : TopLevelDestination( + route = Routes.CURRENT_BETS, + title = R.string.current_bets, + subtitle = R.string.current_bets_subtitle, + emoji = R.drawable.money_with_wings + ) +} diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/AllInDrawer.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/AllInDrawer.kt new file mode 100644 index 0000000..61449cc --- /dev/null +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/AllInDrawer.kt @@ -0,0 +1,83 @@ +package fr.iut.alldev.allin.ui.navigation.drawer + +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.fillMaxSize +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Settings +import androidx.compose.material3.* +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.RectangleShape +import androidx.compose.ui.res.painterResource +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.unit.dp +import fr.iut.alldev.allin.ui.navigation.TopLevelDestination +import fr.iut.alldev.allin.ui.navigation.drawer.components.DrawerCell +import fr.iut.alldev.allin.ui.navigation.drawer.components.DrawerHeader +import fr.iut.alldev.allin.ui.theme.AllInTheme +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.launch + +@Composable +fun AllInDrawer( + drawerState: DrawerState, + destinations: List, + scope: CoroutineScope, + username: String, + nbBets: Int, + bestWin: Int, + nbFriends: Int, + navigateTo: (String)->Unit, + content: @Composable ()->Unit +) { + ModalNavigationDrawer( + drawerState = drawerState, + drawerContent = { + ModalDrawerSheet( + drawerShape = RectangleShape, + drawerContainerColor = AllInTheme.colors.allIn_Dark + ) { + DrawerHeader( + nbBets = nbBets, + bestWin = bestWin, + nbFriends = nbFriends, + username = username, + modifier = Modifier.padding(top = 39.dp, bottom = 26.dp) + ) + destinations.forEach { item -> + DrawerCell( + title = stringResource(item.title).uppercase(), + subtitle = stringResource(item.subtitle), + emoji = painterResource(id = item.emoji), + onClick = { + scope.launch { drawerState.close() } + navigateTo(item.route) + }, + modifier = Modifier.padding(vertical = 5.dp, horizontal = 13.dp) + ) + } + Box( + Modifier + .fillMaxSize() + .padding(start = 19.dp, bottom = 10.dp) + ) { + IconButton( + onClick = { /*TODO : Settings*/ }, + modifier = Modifier.align(Alignment.BottomStart) + ) { + Icon( + imageVector = Icons.Filled.Settings, + modifier = Modifier.size(40.dp), + tint = AllInTheme.colors.allIn_DarkGrey50, + contentDescription = null + ) + } + } + } + }, + content = content + ) +} \ No newline at end of file diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/Drawer.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/Drawer.kt deleted file mode 100644 index c588bb6..0000000 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/Drawer.kt +++ /dev/null @@ -1,168 +0,0 @@ -package fr.iut.alldev.allin.ui.navigation.drawer - -import androidx.activity.compose.BackHandler -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.* -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Settings -import androidx.compose.material3.* -import androidx.compose.runtime.* -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.graphics.RectangleShape -import androidx.compose.ui.platform.LocalDensity -import androidx.compose.ui.res.painterResource -import androidx.compose.ui.res.stringResource -import androidx.compose.ui.unit.dp -import androidx.navigation.NavHostController -import androidx.navigation.compose.rememberNavController -import fr.iut.alldev.allin.R -import fr.iut.alldev.allin.ui.core.topbar.AllInTopBar -import fr.iut.alldev.allin.ui.navigation.AllInDrawerNavHost -import fr.iut.alldev.allin.ui.navigation.Routes -import fr.iut.alldev.allin.ui.navigation.popUpTo -import fr.iut.alldev.allin.ui.theme.AllInTheme -import kotlinx.coroutines.launch -import kotlin.math.abs - - -sealed class TopLevelDestination( - val route: String, - val title: Int, - val subtitle: Int, - val emoji: Int -) { - object PUBLIC_BETS : TopLevelDestination( - route = Routes.PUBLIC_BETS, - title = R.string.public_bets, - subtitle = R.string.public_bets_subtitle, - emoji = R.drawable.globe - ) - object BET_CREATION : TopLevelDestination( - route = Routes.BET_CREATION, - title = R.string.create_a_bet, - subtitle = R.string.create_a_bet_subtitle, - emoji = R.drawable.video_game - ) - object BET_HISTORY : TopLevelDestination( - route = Routes.BET_HISTORY, - title = R.string.bet_history, - subtitle = R.string.bet_history_subtitle, - emoji = R.drawable.eyes - ) - object FRIENDS : TopLevelDestination( - route = Routes.FRIENDS, - title = R.string.friends, - subtitle = R.string.friends_subtitle, - emoji = R.drawable.holding_hands - ) - object CURRENT_BETS : TopLevelDestination( - route = Routes.CURRENT_BETS, - title = R.string.current_bets, - subtitle = R.string.current_bets_subtitle, - emoji = R.drawable.money_with_wings - ) -} - -val topLevelDestinations = listOf( - TopLevelDestination.PUBLIC_BETS, - TopLevelDestination.BET_CREATION, - TopLevelDestination.BET_HISTORY, - TopLevelDestination.FRIENDS, - TopLevelDestination.CURRENT_BETS -) - -@Composable -fun AllInDrawer( - navController: NavHostController = rememberNavController(), - drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed), - startDestination: String = Routes.PUBLIC_BETS -) { - val scope = rememberCoroutineScope() - val drawerOffset = derivedStateOf { drawerState.offset.value } - var drawerWidth by remember { - mutableStateOf(drawerState.offset.value) - } - LaunchedEffect(drawerWidth == 0f) { - drawerWidth = drawerState.offset.value - } - - val localDensity = LocalDensity.current - val contentOffset by derivedStateOf { - if (drawerWidth == 0f) 0.dp - else with(localDensity) { - (abs(drawerWidth) + drawerOffset.value).toDp() - } - } - - ModalNavigationDrawer( - drawerState = drawerState, - drawerContent = { - ModalDrawerSheet( - drawerShape = RectangleShape, - drawerContainerColor = AllInTheme.colors.allIn_Dark - ) { - DrawerHeader( - nbBets = 135, - bestWin = 365, - nbFriends = 5, - username = "Pseudo", - modifier = Modifier.padding(top = 39.dp, bottom = 26.dp) - - ) - topLevelDestinations.forEach { item -> - DrawerCell( - title = stringResource(item.title).uppercase(), - subtitle = stringResource(item.subtitle), - emoji = painterResource(id = item.emoji), - onClick = { - scope.launch { drawerState.close() } - navController.popUpTo(item.route, startDestination) - }, - modifier = Modifier.padding(vertical = 5.dp, horizontal = 13.dp) - ) - } - Box( - Modifier - .fillMaxSize() - .padding(start = 19.dp, bottom = 10.dp)) { - IconButton(onClick = { /*TODO*/ }, - modifier = Modifier.align(Alignment.BottomStart)){ - Icon(imageVector = Icons.Filled.Settings, - modifier = Modifier.size(40.dp), - tint = AllInTheme.colors.allIn_DarkGrey50, - contentDescription = null) - } - } - } - } - ) { - Scaffold( - modifier = Modifier.offset( x = contentOffset ), - topBar = { AllInTopBar(onMenuClicked = { scope.launch { drawerState.open() } }, coinAmount = 541) }// TODO: CoinAmount - ) { - Column( - modifier = Modifier - .padding(top = it.calculateTopPadding()) - .fillMaxSize() - .background(AllInTheme.themeColors.main_surface), - horizontalAlignment = Alignment.CenterHorizontally - ) { - AllInDrawerNavHost( - navController = navController - ) - } - } - } - - BackHandler( - enabled = drawerState.isOpen - ) { - scope.launch { - drawerState.close() - } - } -} - - - diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerCell.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerCell.kt similarity index 97% rename from src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerCell.kt rename to src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerCell.kt index a402051..b2eec5c 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerCell.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerCell.kt @@ -1,4 +1,4 @@ -package fr.iut.alldev.allin.ui.navigation.drawer +package fr.iut.alldev.allin.ui.navigation.drawer.components import androidx.compose.foundation.BorderStroke import androidx.compose.foundation.Image diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeader.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeader.kt similarity index 96% rename from src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeader.kt rename to src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeader.kt index d2477e0..e980da0 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeader.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeader.kt @@ -1,4 +1,4 @@ -package fr.iut.alldev.allin.ui.navigation.drawer +package fr.iut.alldev.allin.ui.navigation.drawer.components import androidx.compose.foundation.layout.* import androidx.compose.material3.Text diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeaderStat.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeaderStat.kt similarity index 93% rename from src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeaderStat.kt rename to src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeaderStat.kt index f1317f4..64288dd 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/DrawerHeaderStat.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/navigation/drawer/components/DrawerHeaderStat.kt @@ -1,4 +1,4 @@ -package fr.iut.alldev.allin.ui.navigation.drawer +package fr.iut.alldev.allin.ui.navigation.drawer.components import androidx.compose.foundation.layout.Column import androidx.compose.material3.Text diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Color.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Color.kt index 3234143..08a453d 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Color.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Color.kt @@ -29,6 +29,12 @@ data class AllInColors( val allIn_DarkBlue: Color, val allIn_BarPurple: Color, val allIn_BarPink: Color, + val allIn_BetFinish: Color, + val allIn_BetInProgress: Color, + val allIn_BetWaiting: Color, + val allIn_BetFinishText: Color, + val allIn_BetInProgressText: Color, + val allIn_BetWaitingText: Color, val allIn_MainGradient: Brush, val allIn_Bar1stGradient: Brush, val allIn_Bar2ndGradient: Brush, @@ -59,7 +65,12 @@ internal val LocalColors = staticCompositionLocalOf { allIn_Blue = Color.Unspecified, allIn_Mint = Color.Unspecified, allIn_DarkBlue = Color.Unspecified, - + allIn_BetFinish = Color.Unspecified, + allIn_BetInProgress = Color.Unspecified, + allIn_BetWaiting = Color.Unspecified, + allIn_BetFinishText = Color.Unspecified, + allIn_BetInProgressText = Color.Unspecified, + allIn_BetWaitingText = Color.Unspecified, allIn_MainGradient = Brush.linearGradient( 0.0f to Color(0xFFf951a8), 0.5f to Color(0xFFaa7ef3), diff --git a/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Theme.kt b/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Theme.kt index 7efb2e9..eb36e3a 100644 --- a/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Theme.kt +++ b/src/app/src/main/java/fr/iut/alldev/allin/ui/theme/Theme.kt @@ -39,6 +39,12 @@ fun AllInTheme( allIn_Blue = Color(0xFF6a89fa), allIn_Mint = Color(0xFFC4DEE9), allIn_DarkBlue = Color(0xFF323078), + allIn_BetFinish = Color(0xFF353535), + allIn_BetInProgress = Color(0xFF604BDB), + allIn_BetWaiting = Color(0xFFDF3B9A), + allIn_BetFinishText = Color(0xFFA7A7A7), + allIn_BetInProgressText = Color(0xFF4636A3), + allIn_BetWaitingText = Color(0xFF852E6C), allIn_MainGradient = Brush.linearGradient( 0.0f to Color(0xFFf951a8), diff --git a/src/app/src/main/res/drawable/allin_exit.xml b/src/app/src/main/res/drawable/allin_exit.xml new file mode 100644 index 0000000..19796ba --- /dev/null +++ b/src/app/src/main/res/drawable/allin_exit.xml @@ -0,0 +1,10 @@ + + + diff --git a/src/app/src/main/res/values-fr/strings.xml b/src/app/src/main/res/values-fr/strings.xml index dad0440..6731556 100644 --- a/src/app/src/main/res/values-fr/strings.xml +++ b/src/app/src/main/res/values-fr/strings.xml @@ -96,4 +96,10 @@ %s points en jeu %s points en jeu + + + Terminé ! + En cours… + En attente… + \ No newline at end of file diff --git a/src/app/src/main/res/values/strings.xml b/src/app/src/main/res/values/strings.xml index d29c4ec..04dd4bf 100644 --- a/src/app/src/main/res/values/strings.xml +++ b/src/app/src/main/res/values/strings.xml @@ -96,4 +96,8 @@ %s point at stake %s points at stake + + Finished ! + In progress… + Waiting… \ No newline at end of file diff --git a/src/data/src/main/java/fr/iut/alldev/allin/data/api/model/ResponseUser.kt b/src/data/src/main/java/fr/iut/alldev/allin/data/api/model/ResponseUser.kt index 122e39b..985535f 100644 --- a/src/data/src/main/java/fr/iut/alldev/allin/data/api/model/ResponseUser.kt +++ b/src/data/src/main/java/fr/iut/alldev/allin/data/api/model/ResponseUser.kt @@ -1,6 +1,7 @@ package fr.iut.alldev.allin.data.api.model import androidx.annotation.Keep +import fr.iut.alldev.allin.data.model.User import kotlinx.serialization.Serializable @Keep @@ -10,7 +11,14 @@ data class ResponseUser( val email: String, val password: String, var nbCoins: Int, -) +){ + fun toUser() = User( + username = username, + email = email, + id = "", + coins = nbCoins + ) +} @Keep @Serializable diff --git a/src/data/src/main/java/fr/iut/alldev/allin/data/model/BetStatus.kt b/src/data/src/main/java/fr/iut/alldev/allin/data/model/BetStatus.kt new file mode 100644 index 0000000..9f6e04e --- /dev/null +++ b/src/data/src/main/java/fr/iut/alldev/allin/data/model/BetStatus.kt @@ -0,0 +1,7 @@ +package fr.iut.alldev.allin.data.model + +enum class BetStatus { + FINISHED, + IN_PROGRESS, + WAITING +} \ No newline at end of file diff --git a/src/data/src/main/java/fr/iut/alldev/allin/data/repository/UserRepository.kt b/src/data/src/main/java/fr/iut/alldev/allin/data/repository/UserRepository.kt index d441409..bb2001c 100644 --- a/src/data/src/main/java/fr/iut/alldev/allin/data/repository/UserRepository.kt +++ b/src/data/src/main/java/fr/iut/alldev/allin/data/repository/UserRepository.kt @@ -1,6 +1,9 @@ package fr.iut.alldev.allin.data.repository +import fr.iut.alldev.allin.data.model.User + abstract class UserRepository { + lateinit var currentUser: User abstract suspend fun login( username: String, password: String diff --git a/src/data/src/main/java/fr/iut/alldev/allin/data/repository/impl/UserRepositoryImpl.kt b/src/data/src/main/java/fr/iut/alldev/allin/data/repository/impl/UserRepositoryImpl.kt index d946253..e772746 100644 --- a/src/data/src/main/java/fr/iut/alldev/allin/data/repository/impl/UserRepositoryImpl.kt +++ b/src/data/src/main/java/fr/iut/alldev/allin/data/repository/impl/UserRepositoryImpl.kt @@ -9,24 +9,24 @@ import javax.inject.Inject class UserRepositoryImpl @Inject constructor( private val api: AllInApi, ) : UserRepository() { + override suspend fun login(username: String, password: String) { - api.login( + currentUser = api.login( CheckUser( username = username, password = password ) - ) + ).toUser() } override suspend fun register(username: String, email: String, password: String) { - api.register( + currentUser = api.register( ResponseUser( username = username, email = email, password = password, nbCoins = 0 ) - ) + ).toUser() } - } \ No newline at end of file