AllInBottomSheet and storing current user in app
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
b835f1a4f4
commit
6f559862e4
@ -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
|
||||
}
|
@ -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
|
||||
}
|
||||
}
|
@ -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)
|
||||
) {
|
||||
}
|
||||
}
|
||||
}
|
@ -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<BetStatus> {
|
||||
override val values = BetStatus.values().asSequence()
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
private fun BackStatusScreenBackPreview(
|
||||
@PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus
|
||||
) {
|
||||
AllInTheme {
|
||||
BetStatusBottomSheetBack(status = betStatus)
|
||||
}
|
||||
}
|
@ -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
|
||||
)
|
@ -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>, MutableState<Boolean>, (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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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<BetStatus?>(null)
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
@ -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
|
||||
)
|
||||
}
|
@ -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<TopLevelDestination>,
|
||||
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
|
||||
)
|
||||
}
|
@ -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()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
@ -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
|
@ -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
|
@ -0,0 +1,10 @@
|
||||
<vector xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:width="30dp"
|
||||
android:height="30dp"
|
||||
android:viewportWidth="30"
|
||||
android:viewportHeight="30">
|
||||
<path
|
||||
android:pathData="M15,0C6.716,0 0,6.716 0,15C0,23.284 6.716,30 15,30C23.284,30 30,23.284 30,15C30,6.716 23.284,0 15,0ZM19.789,10.596C20.374,11.182 20.374,12.132 19.789,12.717L17.314,15.192L19.789,17.667C20.374,18.253 20.374,19.203 19.789,19.789C19.203,20.374 18.253,20.374 17.667,19.789L15.192,17.314L12.717,19.789C12.132,20.374 11.182,20.374 10.596,19.789C10.01,19.203 10.01,18.253 10.596,17.667L13.071,15.192L10.596,12.717C10.01,12.132 10.01,11.182 10.596,10.596C11.182,10.01 12.132,10.01 12.717,10.596L15.192,13.071L17.667,10.596C18.253,10.01 19.203,10.01 19.789,10.596Z"
|
||||
android:fillColor="#ffffff"
|
||||
android:fillType="evenOdd"/>
|
||||
</vector>
|
@ -0,0 +1,7 @@
|
||||
package fr.iut.alldev.allin.data.model
|
||||
|
||||
enum class BetStatus {
|
||||
FINISHED,
|
||||
IN_PROGRESS,
|
||||
WAITING
|
||||
}
|
Loading…
Reference in new issue