Refactor and start fixing edge to edge

pull/5/head
avalin 11 months ago
parent b40788676f
commit b6c6f2c005

@ -17,6 +17,7 @@
<activity <activity
android:name=".ui.MainActivity" android:name=".ui.MainActivity"
android:exported="true" android:exported="true"
android:windowSoftInputMode="adjustPan"
android:theme="@style/Theme.Allin"> android:theme="@style/Theme.Allin">
<intent-filter> <intent-filter>
<action android:name="android.intent.action.MAIN" /> <action android:name="android.intent.action.MAIN" />

@ -2,6 +2,7 @@ package fr.iut.alldev.allin
import android.app.Application import android.app.Application
import dagger.hilt.android.HiltAndroidApp import dagger.hilt.android.HiltAndroidApp
import racra.compose.smooth_corner_rect_library.BuildConfig
import timber.log.Timber import timber.log.Timber
@HiltAndroidApp @HiltAndroidApp

@ -5,6 +5,7 @@ import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.activity.ComponentActivity import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent import androidx.activity.compose.setContent
import androidx.activity.enableEdgeToEdge
import androidx.compose.runtime.SideEffect import androidx.compose.runtime.SideEffect
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.graphics.toArgb
@ -18,25 +19,11 @@ import fr.iut.alldev.allin.theme.AllInTheme
@AndroidEntryPoint @AndroidEntryPoint
class MainActivity : ComponentActivity() { class MainActivity : ComponentActivity() {
override fun onCreate(savedInstanceState: Bundle?) { override fun onCreate(savedInstanceState: Bundle?) {
enableEdgeToEdge()
super.onCreate(savedInstanceState) super.onCreate(savedInstanceState)
setContent { setContent {
AllInTheme{ AllInTheme{
val view = LocalView.current
if (!view.isInEditMode) {
SideEffect {
with((view.context as Activity)) {
window.statusBarColor = Color.Transparent.toArgb()
window.navigationBarColor = Color.Transparent.toArgb()
if (Build.VERSION.SDK_INT > 30) {
window.insetsController?.hide(WindowInsetsCompat.Type.statusBars())
window.insetsController?.hide(WindowInsetsCompat.Type.navigationBars())
WindowCompat.setDecorFitsSystemWindows(window, false)
}
}
}
}
AllInNavHost() AllInNavHost()
} }
} }

@ -8,11 +8,14 @@ import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth 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.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.material.ExperimentalMaterialApi import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh import androidx.compose.material.pullrefresh.pullRefresh
@ -28,6 +31,7 @@ import androidx.compose.ui.Modifier
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.platform.LocalDensity import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalHapticFeedback
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 androidx.hilt.navigation.compose.hiltViewModel import androidx.hilt.navigation.compose.hiltViewModel
@ -46,18 +50,16 @@ fun BetScreen(
viewModel: BetViewModel = hiltViewModel(), viewModel: BetViewModel = hiltViewModel(),
selectBet: (Bet, Boolean) -> Unit, selectBet: (Bet, Boolean) -> Unit,
) { ) {
val haptic = LocalHapticFeedback.current
val bets by viewModel.bets.collectAsState() val bets by viewModel.bets.collectAsState()
val horizontalPadding = 23.dp
val refreshing by viewModel.isRefreshing.collectAsState() val refreshing by viewModel.isRefreshing.collectAsState()
val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.refresh() }) val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.refresh() })
val progressAnimation by animateFloatAsState(pullRefreshState.progress * 15, label = "") val progressAnimation by animateFloatAsState(pullRefreshState.progress * 15, label = "")
LazyColumn( LazyColumn(
Modifier modifier = Modifier
.pullRefresh(pullRefreshState) .pullRefresh(pullRefreshState)
.padding(top = with(LocalDensity.current) { .padding(top = with(LocalDensity.current) {
progressAnimation.toDp() progressAnimation.toDp()
@ -97,7 +99,7 @@ fun BetScreen(
horizontalArrangement = Arrangement.spacedBy(9.dp) horizontalArrangement = Arrangement.spacedBy(9.dp)
) { ) {
item { item {
Spacer(modifier = Modifier.width(horizontalPadding)) Spacer(modifier = Modifier.width(23.dp))
} }
items(items) { items(items) {
var isSelected by remember { mutableStateOf(false) } var isSelected by remember { mutableStateOf(false) }
@ -109,11 +111,11 @@ fun BetScreen(
}) })
} }
item { item {
Spacer(modifier = Modifier.width(horizontalPadding)) Spacer(modifier = Modifier.width(23.dp))
} }
} }
} }
items(bets) { itemsIndexed(bets) { idx, it ->
BetScreenCard( BetScreenCard(
creator = it.creator, creator = it.creator,
category = it.theme, category = it.theme,
@ -123,11 +125,17 @@ fun BetScreen(
players = List(3) { null }, players = List(3) { null },
onClickParticipate = { selectBet(it, true) }, onClickParticipate = { selectBet(it, true) },
onClickCard = { selectBet(it, false) }, onClickCard = { selectBet(it, false) },
modifier = Modifier.padding(horizontal = horizontalPadding) modifier = Modifier.padding(horizontal = 23.dp)
) )
if (idx != bets.lastIndex) {
Spacer(modifier = Modifier.height(24.dp)) Spacer(modifier = Modifier.height(24.dp))
} }
} }
item {
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
} }
val items = listOf( val items = listOf(

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
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.layout.safeContentPadding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
@ -271,6 +272,7 @@ fun BetConfirmationBottomSheetContent(
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxSize() .fillMaxSize()
.safeContentPadding()
.padding(16.dp) .padding(16.dp)
) { ) {
IconButton( IconButton(

@ -1,35 +1,22 @@
package fr.iut.alldev.allin.ui.betCreation package fr.iut.alldev.allin.ui.betCreation
import androidx.compose.foundation.interaction.MutableInteractionSource import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf 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.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
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.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
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenAnswerTab import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenContent
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenQuestionTab
import fr.iut.alldev.allin.ui.core.AllInAlertDialog import fr.iut.alldev.allin.ui.core.AllInAlertDialog
import fr.iut.alldev.allin.ui.core.AllInDatePicker import fr.iut.alldev.allin.ui.core.AllInDatePicker
import fr.iut.alldev.allin.ui.core.AllInSections
import fr.iut.alldev.allin.ui.core.AllInTimePicker import fr.iut.alldev.allin.ui.core.AllInTimePicker
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.SectionElement
import fr.iut.alldev.allin.ui.core.SelectionElement import fr.iut.alldev.allin.ui.core.SelectionElement
import java.time.Instant import java.time.Instant
import java.time.ZoneId import java.time.ZoneId
@ -41,8 +28,7 @@ fun BetCreationScreen(
setLoading: (Boolean) -> Unit, setLoading: (Boolean) -> Unit,
onCreation: () -> Unit onCreation: () -> Unit
) { ) {
val interactionSource = remember { MutableInteractionSource() } val betTypes = remember { BetType.entries }
val betTypes = remember { BetType.values().toList() }
var hasError by remember { mutableStateOf(false) } var hasError by remember { mutableStateOf(false) }
var theme by remember { viewModel.theme } var theme by remember { viewModel.theme }
@ -60,7 +46,6 @@ fun BetCreationScreen(
val selectedFriends = remember { mutableListOf<Int>() } val selectedFriends = remember { mutableListOf<Int>() }
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) }
val focus = LocalFocusManager.current
val themeFieldName = stringResource(id = R.string.Theme) val themeFieldName = stringResource(id = R.string.Theme)
val phraseFieldName = stringResource(id = R.string.Bet_Phrase) val phraseFieldName = stringResource(id = R.string.Bet_Phrase)
@ -85,68 +70,30 @@ fun BetCreationScreen(
val (showRegisterTimePicker, setRegisterTimePicker) = remember { mutableStateOf(false) } val (showRegisterTimePicker, setRegisterTimePicker) = remember { mutableStateOf(false) }
val (showEndTimePicker, setEndTimePicker) = remember { mutableStateOf(false) } val (showEndTimePicker, setEndTimePicker) = remember { mutableStateOf(false) }
Box( BetCreationScreenContent(
Modifier
.fillMaxSize()
.padding(top = 20.dp)
) {
AllInSections(
onLoadSection = {
focus.clearFocus()
},
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxSize()
.padding(bottom = 90.dp),
sections = listOf(
SectionElement(stringResource(id = R.string.Question)) {
BetCreationScreenQuestionTab(
isPublic = isPublic,
setIsPublic = { isPublic = it },
betPhrase = phrase,
setBetPhrase = { phrase = it },
betTheme = theme,
setBetTheme = { theme = it },
nbFriends = 42, nbFriends = 42,
selectedFriends = selectedFriends, betTheme = theme,
registerDate = registerDate,
betDate = betDate,
setRegisterDateDialog = { setRegisterDatePicker(it) },
setEndDateDialog = { setEndDatePicker(it) },
setRegisterTimeDialog = { setRegisterTimePicker(it) },
setEndTimeDialog = { setEndTimePicker(it) },
interactionSource = interactionSource,
betThemeError = themeError.errorResource(), betThemeError = themeError.errorResource(),
setBetTheme = { theme = it },
betPhrase = phrase,
betPhraseError = phraseError.errorResource(), betPhraseError = phraseError.errorResource(),
setBetPhrase = { phrase = it },
isPublic = isPublic,
setIsPublic = { isPublic = it },
registerDate = registerDate,
registerDateError = registerDateError.errorResource(), registerDateError = registerDateError.errorResource(),
betDate = betDate,
betDateError = betDateError.errorResource(), betDateError = betDateError.errorResource(),
modifier = Modifier selectedFriends = selectedFriends,
.fillMaxSize() setRegisterDateDialog = setRegisterDatePicker,
.verticalScroll(rememberScrollState()) setEndDateDialog = setEndDatePicker,
.padding(vertical = 12.dp, horizontal = 20.dp) setRegisterTimeDialog = setRegisterTimePicker,
) setEndTimeDialog = setEndTimePicker,
}, selectedBetTypeElement = selectedBetTypeElement,
SectionElement(stringResource(id = R.string.Answer)) {
BetCreationScreenAnswerTab(
selectedBetType = selectedBetType, selectedBetType = selectedBetType,
selected = selectedBetTypeElement, setSelectedBetTypeElement = { selectedBetTypeElement = it },
setSelected = { selectedBetTypeElement = it }, selectionBetType = selectionElements,
elements = selectionElements, onCreateBet = {
modifier = Modifier
.fillMaxSize()
.padding(vertical = 12.dp, horizontal = 20.dp)
)
}
)
)
RainbowButton(
text = stringResource(id = R.string.Publish),
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 14.dp)
.padding(horizontal = 20.dp),
onClick = {
viewModel.createBet( viewModel.createBet(
themeFieldName = themeFieldName, themeFieldName = themeFieldName,
phraseFieldName = phraseFieldName, phraseFieldName = phraseFieldName,
@ -158,7 +105,7 @@ fun BetCreationScreen(
) )
} }
) )
}
if (showRegisterDatePicker || showEndDatePicker) { if (showRegisterDatePicker || showEndDatePicker) {
val dateToEdit = if (showRegisterDatePicker) registerDate else betDate val dateToEdit = if (showRegisterDatePicker) registerDate else betDate
AllInDatePicker( AllInDatePicker(

@ -0,0 +1,150 @@
package fr.iut.alldev.allin.ui.betCreation.components
import androidx.compose.foundation.background
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.runtime.Composable
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.platform.LocalFocusManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenAnswerTab
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenQuestionTab
import fr.iut.alldev.allin.ui.core.AllInSections
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.SectionElement
import fr.iut.alldev.allin.ui.core.SelectionElement
import java.time.ZonedDateTime
@Composable
fun BetCreationScreenContent(
nbFriends: Int,
betTheme: String,
betThemeError: String?,
setBetTheme: (String) -> Unit,
betPhrase: String,
betPhraseError: String?,
setBetPhrase: (String) -> Unit,
isPublic: Boolean,
setIsPublic: (Boolean) -> Unit,
registerDate: ZonedDateTime,
registerDateError: String?,
betDate: ZonedDateTime,
betDateError: String?,
selectedFriends: MutableList<Int>,
setRegisterDateDialog: (Boolean) -> Unit,
setEndDateDialog: (Boolean) -> Unit,
setRegisterTimeDialog: (Boolean) -> Unit,
setEndTimeDialog: (Boolean) -> Unit,
selectedBetTypeElement: SelectionElement?,
selectedBetType: BetType,
setSelectedBetTypeElement: (SelectionElement) -> Unit,
selectionBetType: List<SelectionElement>,
onCreateBet: () -> Unit
) {
val interactionSource = remember { MutableInteractionSource() }
val focus = LocalFocusManager.current
Box(Modifier.fillMaxSize()) {
AllInSections(
onLoadSection = { focus.clearFocus() },
modifier = Modifier.align(Alignment.TopCenter),
sections = listOf(
SectionElement(stringResource(id = R.string.Question)) {
BetCreationScreenQuestionTab(
isPublic = isPublic,
setIsPublic = setIsPublic,
betPhrase = betPhrase,
setBetPhrase = setBetPhrase,
betTheme = betTheme,
setBetTheme = setBetTheme,
nbFriends = nbFriends,
selectedFriends = selectedFriends,
registerDate = registerDate,
betDate = betDate,
setRegisterDateDialog = setRegisterDateDialog,
setEndDateDialog = setEndDateDialog,
setRegisterTimeDialog = setRegisterTimeDialog,
setEndTimeDialog = setEndTimeDialog,
interactionSource = interactionSource,
betThemeError = betThemeError,
betPhraseError = betPhraseError,
registerDateError = registerDateError,
betDateError = betDateError
)
},
SectionElement(stringResource(id = R.string.Answer)) {
BetCreationScreenAnswerTab(
selectedBetType = selectedBetType,
selected = selectedBetTypeElement,
setSelected = setSelectedBetTypeElement,
elements = selectionBetType
)
}
)
)
Box(
modifier = Modifier
.align(Alignment.BottomCenter)
.background(
Brush.verticalGradient(
0f to Color.Transparent,
0.50f to AllInTheme.themeColors.mainSurface
)
),
) {
RainbowButton(
text = stringResource(id = R.string.Publish),
modifier = Modifier
.padding(bottom = 14.dp)
.padding(horizontal = 20.dp)
.safeContentPadding(),
onClick = onCreateBet
)
}
}
}
@Preview
@Composable
private fun BetCreationScreenContentPreview() {
AllInTheme {
BetCreationScreenContent(
nbFriends = 8900,
betTheme = "Ina",
betThemeError = null,
setBetTheme = { },
betPhrase = "Bryon",
betPhraseError = null,
setBetPhrase = { },
isPublic = false,
setIsPublic = { },
registerDate = ZonedDateTime.now(),
registerDateError = null,
betDate = ZonedDateTime.now(),
betDateError = null,
selectedFriends = mutableListOf(),
setRegisterDateDialog = { },
setEndDateDialog = { },
setRegisterTimeDialog = { },
setEndTimeDialog = { },
selectedBetTypeElement = null,
selectedBetType = BetType.BINARY,
setSelectedBetTypeElement = { },
selectionBetType = listOf(),
onCreateBet = { }
)
}
}

@ -12,10 +12,12 @@ 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.stringResource import androidx.compose.ui.res.stringResource
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.bet.BetType import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.ext.getTitleId import fr.iut.alldev.allin.ext.getTitleId
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.core.AllInSelectionBox import fr.iut.alldev.allin.ui.core.AllInSelectionBox
import fr.iut.alldev.allin.ui.core.SelectionElement import fr.iut.alldev.allin.ui.core.SelectionElement
@ -26,7 +28,7 @@ fun BetCreationScreenAnswerTab(
selected: SelectionElement?, selected: SelectionElement?,
selectedBetType: BetType, selectedBetType: BetType,
setSelected: (SelectionElement) -> Unit, setSelected: (SelectionElement) -> Unit,
elements: List<SelectionElement>, elements: List<SelectionElement>
) { ) {
var isOpen by remember { var isOpen by remember {
mutableStateOf(false) mutableStateOf(false)
@ -67,3 +69,16 @@ fun BetCreationScreenAnswerTab(
} }
} }
} }
@Preview
@Composable
private fun BetCreationScreenAnswerTabPreview() {
AllInTheme {
BetCreationScreenAnswerTab(
selected = null,
selectedBetType = BetType.BINARY,
setSelected = { },
elements = listOf()
)
}
}

@ -1,14 +1,19 @@
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.ui.Modifier import androidx.compose.ui.Modifier
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.ext.formatToTime
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
@ -37,7 +42,7 @@ fun BetCreationScreenQuestionTab(
setEndTimeDialog: (Boolean) -> Unit, setEndTimeDialog: (Boolean) -> Unit,
interactionSource: MutableInteractionSource interactionSource: MutableInteractionSource
) { ) {
Column(modifier) { Column(modifier = modifier) {
QuestionTabThemePhraseSection( QuestionTabThemePhraseSection(
betTheme = betTheme, betTheme = betTheme,
betThemeError = betThemeError, betThemeError = betThemeError,
@ -69,5 +74,34 @@ fun BetCreationScreenQuestionTab(
selectedFriends = selectedFriends, selectedFriends = selectedFriends,
interactionSource = interactionSource interactionSource = interactionSource
) )
Spacer(modifier = Modifier.height(120.dp))
}
}
@Preview
@Composable
private fun BetCreationScreenQuestionTabPreview() {
AllInTheme {
BetCreationScreenQuestionTab(
nbFriends = 4651,
betTheme = "Elly",
betThemeError = null,
setBetTheme = { },
betPhrase = "Trinh",
betPhraseError = null,
setBetPhrase = { },
isPublic = true,
setIsPublic = { },
registerDate = ZonedDateTime.now(),
registerDateError = null,
betDate = ZonedDateTime.now(),
betDateError = null,
selectedFriends = mutableListOf(),
setRegisterDateDialog = { },
setEndDateDialog = { },
setRegisterTimeDialog = { },
setEndTimeDialog = { },
interactionSource = remember { MutableInteractionSource() }
)
} }
} }

@ -2,8 +2,11 @@ package fr.iut.alldev.allin.ui.betHistory.components
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -56,5 +59,9 @@ fun <T> GenericHistory(
won = getWon(it) won = getWon(it)
) )
} }
item {
Spacer(modifier = Modifier.navigationBarsPadding())
}
} }
} }

@ -37,7 +37,6 @@ fun BetStatusBottomSheet(
sheetVisibility: Boolean, sheetVisibility: Boolean,
sheetBackVisibility: Boolean, sheetBackVisibility: Boolean,
betDetail: BetDetail?, betDetail: BetDetail?,
paddingValues: PaddingValues,
userCoinAmount: MutableIntState, userCoinAmount: MutableIntState,
onParticipate: (stake: Int, response: String) -> Unit, onParticipate: (stake: Int, response: String) -> Unit,
onDismiss: () -> Unit, onDismiss: () -> Unit,
@ -82,7 +81,6 @@ fun BetStatusBottomSheet(
sheetVisibility = participateSheetVisibility && sheetVisibility = participateSheetVisibility &&
betDetail.bet.betStatus == BetStatus.IN_PROGRESS && betDetail.bet.betStatus == BetStatus.IN_PROGRESS &&
state.hasExpandedState, state.hasExpandedState,
safeBottomPadding = paddingValues.calculateBottomPadding(),
odds = betDetail.answers.getOrNull(selectedAnswer)?.odds ?: 1f, odds = betDetail.answers.getOrNull(selectedAnswer)?.odds ?: 1f,
betPhrase = betDetail.bet.phrase, betPhrase = betDetail.bet.phrase,
coinAmount = userCoinAmount.intValue, coinAmount = userCoinAmount.intValue,

@ -30,7 +30,6 @@ import kotlin.math.roundToInt
@Composable @Composable
fun BetStatusParticipationBottomSheet( fun BetStatusParticipationBottomSheet(
sheetVisibility: Boolean, sheetVisibility: Boolean,
safeBottomPadding: Dp,
betPhrase: String, betPhrase: String,
coinAmount: Int, coinAmount: Int,
onDismiss: () -> Unit, onDismiss: () -> Unit,
@ -52,7 +51,6 @@ fun BetStatusParticipationBottomSheet(
containerColor = AllInTheme.themeColors.background2 containerColor = AllInTheme.themeColors.background2
) { ) {
BetStatusParticipationBottomSheetContent( BetStatusParticipationBottomSheetContent(
safeBottomPadding = safeBottomPadding,
betPhrase = betPhrase, betPhrase = betPhrase,
coinAmount = coinAmount, coinAmount = coinAmount,
elements = elements, elements = elements,
@ -73,8 +71,7 @@ fun BetStatusParticipationBottomSheet(
} }
@Composable @Composable
private fun ColumnScope.BetStatusParticipationBottomSheetContent( private fun BetStatusParticipationBottomSheetContent(
safeBottomPadding: Dp,
betPhrase: String, betPhrase: String,
coinAmount: Int, coinAmount: Int,
enabled: Boolean, enabled: Boolean,
@ -139,8 +136,7 @@ private fun ColumnScope.BetStatusParticipationBottomSheetContent(
Column( Column(
modifier = Modifier modifier = Modifier
.background(AllInTheme.themeColors.background) .background(AllInTheme.themeColors.background)
.padding(horizontal = 7.dp) .padding(7.dp),
.padding(bottom = safeBottomPadding, top = 7.dp),
verticalArrangement = Arrangement.spacedBy(7.dp) verticalArrangement = Arrangement.spacedBy(7.dp)
) { ) {
Row( Row(
@ -164,7 +160,8 @@ private fun ColumnScope.BetStatusParticipationBottomSheetContent(
text = stringResource(id = R.string.Participate), text = stringResource(id = R.string.Participate),
textColor = AllInTheme.colors.white, textColor = AllInTheme.colors.white,
radius = 5.dp, radius = 5.dp,
onClick = onButtonClick onClick = onButtonClick,
modifier = Modifier.navigationBarsPadding()
) )
} }
} }
@ -176,7 +173,6 @@ private fun BetStatusParticipationBottomSheetContentPreview() {
AllInTheme { AllInTheme {
Column { Column {
BetStatusParticipationBottomSheetContent( BetStatusParticipationBottomSheetContent(
safeBottomPadding = 0.dp,
betPhrase = "Bet phrase", betPhrase = "Bet phrase",
coinAmount = 3620, coinAmount = 3620,
onButtonClick = {}, onButtonClick = {},

@ -5,6 +5,7 @@ import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontStyle import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.tooling.preview.PreviewParameterProvider
@ -36,7 +37,9 @@ fun BinaryStatBar(
style = AllInTheme.typography.h1, style = AllInTheme.typography.h1,
fontStyle = FontStyle.Italic, fontStyle = FontStyle.Italic,
fontSize = 30.sp, fontSize = 30.sp,
color = AllInTheme.colors.allInBarPink color = AllInTheme.colors.allInBarPink,
textAlign = TextAlign.End,
modifier = Modifier.weight(1f)
) )
} }
StatBar(percentage = response1Percentage) StatBar(percentage = response1Percentage)

@ -12,7 +12,9 @@ import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxHeight import androidx.compose.foundation.layout.fillMaxHeight
import androidx.compose.foundation.layout.fillMaxWidth 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.padding import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.layout.size import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn import androidx.compose.foundation.lazy.LazyColumn
@ -21,14 +23,14 @@ import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.EmojiEvents import androidx.compose.material.icons.filled.EmojiEvents
import androidx.compose.material.icons.filled.People import androidx.compose.material.icons.filled.People
import androidx.compose.material.icons.filled.WorkspacePremium import androidx.compose.material.icons.filled.WorkspacePremium
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
@ -67,8 +69,6 @@ import java.util.Locale
class BetStatusBottomSheetBetDisplayer( class BetStatusBottomSheetBetDisplayer(
val openParticipateSheet: () -> Unit val openParticipateSheet: () -> Unit
) : BetDisplayer { ) : BetDisplayer {
val paddingValues = mutableStateOf(PaddingValues())
@Composable @Composable
private fun DisplayBinaryBet( private fun DisplayBinaryBet(
betDetail: BetDetail, betDetail: BetDetail,
@ -77,15 +77,13 @@ class BetStatusBottomSheetBetDisplayer(
response1Display: String = response1, response1Display: String = response1,
response2Display: String = response2 response2Display: String = response2
) { ) {
val safeBottomPadding = paddingValues.value.calculateBottomPadding()
val configuration = LocalConfiguration.current val configuration = LocalConfiguration.current
val locale = val locale = remember { ConfigurationCompat.getLocales(configuration).get(0) ?: Locale.getDefault() }
remember { ConfigurationCompat.getLocales(configuration).get(0) ?: Locale.getDefault() }
val response1Answer = remember { betDetail.getAnswerOfResponse(response1) } val response1Answer = remember { betDetail.getAnswerOfResponse(response1) }
val response2Answer = remember { betDetail.getAnswerOfResponse(response2) } val response2Answer = remember { betDetail.getAnswerOfResponse(response2) }
Box(Modifier.padding(bottom = safeBottomPadding)) { Box(Modifier.navigationBarsPadding()) {
Column { Column {
Column(Modifier.padding(horizontal = 20.dp)) { Column(Modifier.padding(horizontal = 20.dp)) {
BetTitleHeader( BetTitleHeader(
@ -125,12 +123,13 @@ class BetStatusBottomSheetBetDisplayer(
} else { } else {
HorizontalDivider(color = AllInTheme.themeColors.border) HorizontalDivider(color = AllInTheme.themeColors.border)
} }
Column( LazyColumn(
Modifier modifier = Modifier
.fillMaxHeight() .fillMaxHeight()
.background(AllInTheme.themeColors.background2) .background(AllInTheme.themeColors.background2),
.padding(horizontal = 20.dp) contentPadding = PaddingValues(horizontal = 20.dp)
) { ) {
item {
Spacer(modifier = Modifier.height(20.dp)) Spacer(modifier = Modifier.height(20.dp))
BinaryStatBar( BinaryStatBar(
response1Percentage = remember { response1Percentage = remember {
@ -172,12 +171,7 @@ class BetStatusBottomSheetBetDisplayer(
style = AllInTheme.typography.h1, style = AllInTheme.typography.h1,
modifier = Modifier.padding(vertical = 36.dp) modifier = Modifier.padding(vertical = 36.dp)
) )
LazyColumn( }
verticalArrangement = Arrangement.spacedBy(8.dp),
horizontalAlignment = Alignment.CenterHorizontally,
contentPadding = PaddingValues(horizontal = 13.dp, vertical = 8.dp),
modifier = Modifier.fillMaxHeight()
) {
betDetail.userParticipation?.let { betDetail.userParticipation?.let {
item { item {
BetStatusParticipant( BetStatusParticipant(
@ -196,8 +190,15 @@ class BetStatusBottomSheetBetDisplayer(
username = it.username, username = it.username,
allCoinsAmount = it.stake allCoinsAmount = it.stake
) )
Spacer(modifier = Modifier.height(8.dp))
} }
} }
item {
if (betDetail.bet.betStatus != BetStatus.FINISHED && betDetail.userParticipation == null) {
Spacer(modifier = Modifier.height(48.dp))
}
Spacer(modifier = Modifier.navigationBarsPadding())
} }
} }
} }
@ -205,7 +206,14 @@ class BetStatusBottomSheetBetDisplayer(
RainbowButton( RainbowButton(
modifier = Modifier modifier = Modifier
.align(Alignment.BottomCenter) .align(Alignment.BottomCenter)
.padding(horizontal = 7.dp), .background(
Brush.verticalGradient(
.2f to Color.Transparent,
.5f to AllInTheme.themeColors.background2
)
)
.padding(7.dp)
.navigationBarsPadding(),
text = stringResource(id = R.string.Participate), text = stringResource(id = R.string.Participate),
enabled = betDetail.bet.betStatus == BetStatus.IN_PROGRESS, enabled = betDetail.bet.betStatus == BetStatus.IN_PROGRESS,
onClick = openParticipateSheet onClick = openParticipateSheet
@ -214,7 +222,6 @@ class BetStatusBottomSheetBetDisplayer(
} }
} }
@OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
override fun DisplayYesNoBet(betDetail: BetDetail) { override fun DisplayYesNoBet(betDetail: BetDetail) {
DisplayBinaryBet( DisplayBinaryBet(

@ -35,7 +35,7 @@ fun AllInBottomSheet(
WindowInsets( WindowInsets(
left = it.getLeft(localDensity, localLayoutDirection), left = it.getLeft(localDensity, localLayoutDirection),
right = it.getRight(localDensity, localLayoutDirection), right = it.getRight(localDensity, localLayoutDirection),
top = it.getTop(localDensity), top = 0,
bottom = 0, bottom = 0,
) )
}, },

@ -20,6 +20,8 @@ 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.hapticfeedback.HapticFeedbackType
import androidx.compose.ui.platform.LocalHapticFeedback
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
@ -98,6 +100,7 @@ fun AllInBouncyCard(
borderBrush: Brush? = null, borderBrush: Brush? = null,
content: @Composable () -> Unit, content: @Composable () -> Unit,
) { ) {
val haptic = LocalHapticFeedback.current
val interactionSource = remember { MutableInteractionSource() } val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState() val isPressed by interactionSource.collectIsPressedAsState()
@ -106,14 +109,17 @@ fun AllInBouncyCard(
animationSpec = spring( animationSpec = spring(
Spring.DampingRatioHighBouncy, Spring.DampingRatioHighBouncy,
Spring.StiffnessMediumLow Spring.StiffnessMediumLow
) ), label = ""
) )
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,

@ -2,16 +2,35 @@ package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.* import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
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.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.safeContentPadding
import androidx.compose.foundation.layout.wrapContentHeight
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyItemScope
import androidx.compose.foundation.lazy.LazyListScope
import androidx.compose.foundation.lazy.LazyRow import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.itemsIndexed import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.pager.HorizontalPager import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.* import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
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 androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
@ -20,27 +39,38 @@ import kotlinx.coroutines.launch
class SectionElement( class SectionElement(
val text: String, val text: String,
val content: @Composable ()->Unit val content: @Composable () -> Unit
) )
@OptIn(ExperimentalFoundationApi::class) @OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun AllInSections( fun AllInSections(
sections: List<SectionElement>, sections: List<SectionElement>,
interSectionsPadding: Dp = 56.dp,
modifier: Modifier = Modifier, modifier: Modifier = Modifier,
onLoadSection: ()->Unit = {} interSectionsPadding: Dp = 56.dp,
onLoadSection: ()->Unit = { }
) { ) {
val pagerState = rememberPagerState(pageCount = { val pagerState = rememberPagerState(pageCount = { sections.size })
sections.size
})
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
Column( LazyColumn(
modifier = modifier, modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally horizontalAlignment = Alignment.CenterHorizontally
){ ){
stickyHeader {
Box(
modifier = Modifier
.fillMaxWidth()
.background(
Brush.verticalGradient(
0.75f to AllInTheme.themeColors.mainSurface,
1f to Color.Transparent
)
),
contentAlignment = Alignment.Center
) {
LazyRow( LazyRow(
horizontalArrangement = Arrangement.spacedBy(interSectionsPadding) horizontalArrangement = Arrangement.spacedBy(interSectionsPadding),
modifier = Modifier.padding(vertical = 12.dp)
) { ) {
itemsIndexed(sections) { index, section -> itemsIndexed(sections) { index, section ->
AllInSectionButton( AllInSectionButton(
@ -54,15 +84,22 @@ fun AllInSections(
) )
} }
} }
HorizontalPager(state = pagerState) { page ->
LaunchedEffect(key1 = page){
onLoadSection()
} }
}
item {
HorizontalPager(
state = pagerState
) { page ->
LaunchedEffect(key1 = page) { onLoadSection() }
Column(
modifier = Modifier.padding(horizontal = 20.dp)
) {
sections[page].content() sections[page].content()
} }
} }
}
}
} }
@Preview @Preview

@ -16,9 +16,9 @@ import androidx.compose.material3.SnackbarHost
import androidx.compose.material3.SnackbarHostState import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.Surface import androidx.compose.material3.Surface
import androidx.compose.material3.SwipeToDismissBox import androidx.compose.material3.SwipeToDismissBox
import androidx.compose.material3.SwipeToDismissValue import androidx.compose.material3.SwipeToDismissBoxValue
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.rememberSwipeToDismissState import androidx.compose.material3.rememberSwipeToDismissBoxState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
@ -40,9 +40,9 @@ fun AllInSnackbar(
SnackbarHost( SnackbarHost(
hostState = snackbarState hostState = snackbarState
) { snackbarData -> ) { snackbarData ->
val dismissState = rememberSwipeToDismissState( val dismissState = rememberSwipeToDismissBoxState(
confirmValueChange = { value -> confirmValueChange = { value ->
if (value != SwipeToDismissValue.Settled) { if (value != SwipeToDismissBoxValue.Settled) {
snackbarState.currentSnackbarData?.dismiss() snackbarState.currentSnackbarData?.dismiss()
true true
} else { } else {

@ -2,12 +2,18 @@ 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.height
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding 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.TopAppBarDefaults
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -23,17 +29,16 @@ fun AllInTopBar(
onMenuClicked: () -> Unit, onMenuClicked: () -> Unit,
coinAmount: Int, coinAmount: Int,
) { ) {
Box( TopAppBar(
modifier = Modifier modifier = Modifier.background(AllInTheme.colors.allInMainGradient),
.height(86.dp) colors = TopAppBarDefaults.topAppBarColors(
.fillMaxWidth() containerColor = Color.Transparent
.background(brush = AllInTheme.colors.allInMainGradient) ),
) { title = { },
navigationIcon = {
IconButton( IconButton(
onClick = onMenuClicked, onClick = onMenuClicked,
modifier = Modifier modifier = Modifier
.padding(start = 19.dp)
.align(Alignment.CenterStart)
) { ) {
Icon( Icon(
painterResource(id = R.drawable.allin_menu), painterResource(id = R.drawable.allin_menu),
@ -42,6 +47,11 @@ fun AllInTopBar(
tint = Color.White tint = Color.White
) )
} }
},
actions = {
Box(
modifier = Modifier.fillMaxWidth()
) {
Icon( Icon(
painter = painterResource(R.drawable.allin), painter = painterResource(R.drawable.allin),
contentDescription = null, contentDescription = null,
@ -54,8 +64,11 @@ fun AllInTopBar(
amount = coinAmount, amount = coinAmount,
modifier = Modifier modifier = Modifier
.align(Alignment.CenterEnd) .align(Alignment.CenterEnd)
.offset(x = 4.dp)
) )
} }
}
)
} }
@Preview @Preview

@ -10,6 +10,7 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
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.layout.safeContentPadding
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
@ -27,6 +28,7 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -70,6 +72,7 @@ fun LoginScreen(
.fillMaxSize() .fillMaxSize()
.background(AllInTheme.themeColors.mainSurface) .background(AllInTheme.themeColors.mainSurface)
.padding(horizontal = 44.dp) .padding(horizontal = 44.dp)
.safeContentPadding()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
) { ) {
Column( Column(
@ -108,6 +111,7 @@ fun LoginScreen(
placeholder = stringResource(id = R.string.password), placeholder = stringResource(id = R.string.password),
value = password, value = password,
modifier = Modifier.fillMaxWidth(), modifier = Modifier.fillMaxWidth(),
keyboardType = KeyboardType.Password,
imeAction = ImeAction.Done, imeAction = ImeAction.Done,
keyboardActions = keyboardActions, keyboardActions = keyboardActions,
onValueChange = setPassword onValueChange = setPassword

@ -131,9 +131,6 @@ fun MainScreen(
drawerState = drawerState, drawerState = drawerState,
snackbarHostState = snackbarHostState snackbarHostState = snackbarHostState
) { ) {
LaunchedEffect(key1 = it) {
betStatusDisplayer.paddingValues.value = it
}
Column( Column(
modifier = Modifier modifier = Modifier
.padding(top = it.calculateTopPadding()) .padding(top = it.calculateTopPadding())
@ -176,7 +173,6 @@ fun MainScreen(
sheetBackVisibility = sheetBackVisibility.value, sheetBackVisibility = sheetBackVisibility.value,
onDismiss = { setStatusVisibility(false) }, onDismiss = { setStatusVisibility(false) },
betDetail = selectedBet, betDetail = selectedBet,
paddingValues = betStatusDisplayer.paddingValues.value,
displayBet = { betStatusDisplayer.DisplayBet(it) }, displayBet = { betStatusDisplayer.DisplayBet(it) },
userCoinAmount = mainViewModel.currentUserState.userCoins, userCoinAmount = mainViewModel.currentUserState.userCoins,
onParticipate = { stake, response -> mainViewModel.participateToBet(stake, response) }, onParticipate = { stake, response -> mainViewModel.participateToBet(stake, response) },

@ -1,6 +1,7 @@
package fr.iut.alldev.allin.ui.main.components package fr.iut.alldev.allin.ui.main.components
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
import androidx.compose.material3.DrawerState import androidx.compose.material3.DrawerState
import androidx.compose.material3.Scaffold import androidx.compose.material3.Scaffold
@ -9,6 +10,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableFloatStateOf
import androidx.compose.runtime.mutableStateOf 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
@ -28,22 +30,23 @@ fun AllInScaffold(
content: @Composable (PaddingValues) -> Unit, content: @Composable (PaddingValues) -> Unit,
) { ) {
var drawerWidth by remember { var drawerWidth by remember { mutableFloatStateOf(drawerState.currentOffset) }
mutableStateOf(drawerState.currentOffset)
}
LaunchedEffect(drawerState.currentOffset.isNaN()) { LaunchedEffect(drawerState.currentOffset.isNaN()) {
drawerWidth = drawerState.currentOffset drawerWidth = drawerState.currentOffset
} }
val localDensity = LocalDensity.current val localDensity = LocalDensity.current
val contentOffset by derivedStateOf { val contentOffset by remember {
derivedStateOf {
if (drawerWidth.isNaN() || drawerWidth == 0f) 0.dp if (drawerWidth.isNaN() || drawerWidth == 0f) 0.dp
else with(localDensity) { else with(localDensity) {
(abs(drawerWidth) + drawerState.currentOffset).toDp() (abs(drawerWidth) + drawerState.currentOffset).toDp()
} }
} }
}
Scaffold( Scaffold(
contentWindowInsets = WindowInsets(0.dp),
modifier = Modifier.offset(x = contentOffset), modifier = Modifier.offset(x = contentOffset),
snackbarHost = { snackbarHost = {
AllInSnackbar(snackbarState = snackbarHostState) AllInSnackbar(snackbarState = snackbarHostState)

@ -47,12 +47,12 @@ class BetDetailPreviewProvider : PreviewParameterProvider<BetDetail> {
stake = 150 stake = 150
) )
), ),
userParticipation = Participation( userParticipation = null /*Participation(
betId = it.id, betId = it.id,
username = "MyUser", username = "MyUser",
response = NO_VALUE, response = NO_VALUE,
stake = 150 stake = 150
) )*/
) )
} }
} }

@ -2,6 +2,7 @@ package fr.iut.alldev.allin.ui.register
import androidx.compose.foundation.* import androidx.compose.foundation.*
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.ClickableText import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.Text import androidx.compose.material3.Text
@ -25,8 +26,8 @@ import fr.iut.alldev.allin.ui.core.AllInGradientButton
import fr.iut.alldev.allin.ui.core.AllInLoading import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.core.AllInPasswordField import fr.iut.alldev.allin.ui.core.AllInPasswordField
import fr.iut.alldev.allin.ui.core.AllInTextField import fr.iut.alldev.allin.ui.core.AllInTextField
import fr.iut.alldev.allin.ui.register.components.RegisterScreenContent
@OptIn(ExperimentalFoundationApi::class)
@Composable @Composable
fun RegisterScreen( fun RegisterScreen(
navigateToDashboard: () -> Unit, navigateToDashboard: () -> Unit,
@ -48,8 +49,6 @@ fun RegisterScreen(
val (password, setPassword) = remember { registerViewModel.password } val (password, setPassword) = remember { registerViewModel.password }
val (passwordValidation, setPasswordValidation) = remember { registerViewModel.passwordValidation } val (passwordValidation, setPasswordValidation) = remember { registerViewModel.passwordValidation }
val scrollState = rememberScrollState()
val usernameFieldName = stringResource(id = R.string.username) val usernameFieldName = stringResource(id = R.string.username)
val emailFieldName = stringResource(id = R.string.email) val emailFieldName = stringResource(id = R.string.email)
val passwordFieldName = stringResource(id = R.string.password) val passwordFieldName = stringResource(id = R.string.password)
@ -71,128 +70,33 @@ fun RegisterScreen(
) )
} }
Column( RegisterScreenContent(
Modifier navigateToLogin = navigateToLogin,
.fillMaxSize() onRegister = {
.background(AllInTheme.themeColors.mainSurface)
.padding(horizontal = 44.dp)
) {
Column(
Modifier
.weight(1f)
.verticalScroll(scrollState),
verticalArrangement = Arrangement.Center
) {
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Hello_x, username),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_title),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp
)
Spacer(modifier = Modifier.height(23.dp))
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_subtitle),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.p1,
textAlign = TextAlign.Center,
fontSize = 23.sp
)
Spacer(modifier = Modifier.height(83.dp))
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
AllInTextField(
placeholder = usernameFieldName,
value = username,
modifier = Modifier.fillMaxWidth(),
maxChar = 20,
onValueChange = setUsername,
errorText = usernameError.errorResource(),
imeAction = ImeAction.Next,
keyboardActions = keyboardActions
)
AllInTextField(
placeholder = emailFieldName,
value = email,
modifier = Modifier.fillMaxWidth(),
onValueChange = setEmail,
errorText = emailError.errorResource(),
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next,
keyboardActions = keyboardActions
)
AllInPasswordField(
placeholder = passwordFieldName,
value = password,
modifier = Modifier.fillMaxWidth(),
imeAction = ImeAction.Next,
keyboardActions = keyboardActions,
errorText = passwordError.errorResource(),
onValueChange = setPassword
)
AllInPasswordField(
placeholder = stringResource(id = R.string.confirm_password),
value = passwordValidation,
modifier = Modifier.fillMaxWidth(),
imeAction = ImeAction.Done,
keyboardActions = keyboardActions,
errorText = passwordValidationError.errorResource(),
onValueChange = setPasswordValidation
)
}
}
Column(
Modifier
.padding(bottom = 32.dp)
) {
AllInGradientButton(
text = stringResource(id = R.string.Register),
onClick = {
registerViewModel.onRegister( registerViewModel.onRegister(
usernameFieldName, usernameFieldName,
emailFieldName, emailFieldName,
passwordFieldName, passwordFieldName,
navigateToDashboard navigateToDashboard
) )
} },
) keyboardActions = keyboardActions,
Spacer(modifier = Modifier.height(30.dp)) loading = loading,
Row( username = username,
horizontalArrangement = Arrangement.Center, usernameFieldName = usernameFieldName,
modifier = Modifier.fillMaxWidth() setUsername = setUsername,
) { usernameError = usernameError.errorResource(),
Text( email = email,
text = stringResource(id = R.string.already_have_account), emailFieldName = emailFieldName,
color = AllInTheme.themeColors.onMainSurface, setEmail = setEmail,
fontSize = 15.sp, emailError = emailError.errorResource(),
style = AllInTheme.typography.p1, passwordFieldName = passwordFieldName,
modifier = Modifier.padding(end = 5.dp) password = password,
) passwordError = passwordError.errorResource(),
ClickableText( setPassword = setPassword,
text = AnnotatedString(stringResource(id = R.string.Login)), passwordValidation = passwordValidation,
style = AllInTheme.typography.p1.copy( passwordValidationError = passwordValidationError.errorResource(),
color = AllInTheme.colors.allInPurple, setPasswordValidation = setPasswordValidation
fontSize = 15.sp,
fontWeight = FontWeight.Bold
) )
) {
navigateToLogin()
}
}
}
}
AllInLoading(visible = loading)
} }

@ -0,0 +1,221 @@
package fr.iut.alldev.allin.ui.register.components
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.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.height
import androidx.compose.foundation.layout.navigationBarsPadding
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.text.ClickableText
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
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.text.input.ImeAction
import androidx.compose.ui.text.input.KeyboardType
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 fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInGradientButton
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.core.AllInPasswordField
import fr.iut.alldev.allin.ui.core.AllInTextField
@Composable
fun RegisterScreenContent(
navigateToLogin: () -> Unit,
onRegister: () -> Unit,
keyboardActions: KeyboardActions,
loading: Boolean,
username: String,
usernameFieldName: String,
setUsername: (String) -> Unit,
usernameError: String?,
email: String,
emailFieldName: String,
setEmail: (String) -> Unit,
emailError: String?,
passwordFieldName: String,
password: String,
passwordError: String?,
setPassword: (String) -> Unit,
passwordValidation: String,
passwordValidationError: String?,
setPasswordValidation: (String) -> Unit
) {
Box(
Modifier
.fillMaxSize()
.background(AllInTheme.themeColors.mainSurface)
) {
LazyColumn(
verticalArrangement = Arrangement.Center,
contentPadding = PaddingValues(40.dp)
) {
item {
Text(
modifier = Modifier
.padding(top = 16.dp)
.fillMaxWidth(),
text = stringResource(id = R.string.Hello_x, username),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp,
overflow = TextOverflow.Ellipsis,
maxLines = 1
)
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_title),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp
)
Spacer(modifier = Modifier.height(23.dp))
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_subtitle),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.p1,
textAlign = TextAlign.Center,
fontSize = 23.sp
)
Spacer(modifier = Modifier.height(83.dp))
Column(
verticalArrangement = Arrangement.spacedBy(20.dp)
) {
AllInTextField(
placeholder = usernameFieldName,
value = username,
modifier = Modifier.fillMaxWidth(),
maxChar = 20,
onValueChange = setUsername,
errorText = usernameError,
imeAction = ImeAction.Next,
keyboardActions = keyboardActions
)
AllInTextField(
placeholder = emailFieldName,
value = email,
modifier = Modifier.fillMaxWidth(),
onValueChange = setEmail,
errorText = emailError,
keyboardType = KeyboardType.Email,
imeAction = ImeAction.Next,
keyboardActions = keyboardActions
)
AllInPasswordField(
placeholder = passwordFieldName,
value = password,
modifier = Modifier.fillMaxWidth(),
imeAction = ImeAction.Next,
keyboardActions = keyboardActions,
keyboardType = KeyboardType.Password,
errorText = passwordError,
onValueChange = setPassword
)
AllInPasswordField(
placeholder = stringResource(id = R.string.confirm_password),
value = passwordValidation,
modifier = Modifier.fillMaxWidth(),
imeAction = ImeAction.Done,
keyboardActions = keyboardActions,
keyboardType = KeyboardType.Password,
errorText = passwordValidationError,
onValueChange = setPasswordValidation
)
}
Spacer(modifier = Modifier.height(120.dp))
Spacer(modifier = Modifier.navigationBarsPadding())
}
}
Column(
Modifier
.align(Alignment.BottomCenter)
.background(
Brush.verticalGradient(
.2f to Color.Transparent,
.5f to AllInTheme.themeColors.background
)
)
.padding(40.dp)
.navigationBarsPadding()
) {
AllInGradientButton(
text = stringResource(id = R.string.Register),
onClick = onRegister
)
Spacer(modifier = Modifier.height(30.dp))
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.p1.copy(
color = AllInTheme.colors.allInPurple,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
)
) {
navigateToLogin()
}
}
}
}
AllInLoading(visible = loading)
}
@Preview
@Composable
private fun RegisterScreenContentPreview() {
AllInTheme {
RegisterScreenContent(
navigateToLogin = { },
onRegister = { },
keyboardActions = KeyboardActions(),
loading = false,
username = "Lekesha",
usernameFieldName = "Justen",
setUsername = { },
usernameError = "Kaitlyn",
email = "Donnell",
emailFieldName = "Camron",
setEmail = { },
emailError = "Tunisia",
passwordFieldName = "Cagney",
password = "Neha",
passwordError = "December",
setPassword = { },
passwordValidation = "Xaviera",
passwordValidationError = "Keegan",
setPasswordValidation = { }
)
}
}

@ -33,6 +33,7 @@ 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 import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.welcome.components.WelcomeScreenContent
@Composable @Composable
fun WelcomeScreen( fun WelcomeScreen(
@ -47,95 +48,9 @@ fun WelcomeScreen(
viewModel.tryAutoLogin(navigateToDashboard) viewModel.tryAutoLogin(navigateToDashboard)
} }
Box( WelcomeScreenContent(
Modifier navigateToRegister = navigateToRegister,
.fillMaxWidth() navigateToLogin = navigateToLogin,
.fillMaxHeight(.5f) loading = loading
.background(AllInTheme.colors.allInLoginGradient)
) )
Box(
Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
.2f to Color.Transparent,
.5f to AllInTheme.themeColors.background
)
)
) {
Column(
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.fillMaxHeight(.5f)
.padding(horizontal = 45.dp)
) {
Text(
text = stringResource(id = R.string.welcome_title),
color = AllInTheme.themeColors.onBackground,
fontSize = 30.sp,
style = AllInTheme.typography.h1
)
Text(
text = stringResource(id = R.string.welcome_appname),
fontSize = 60.sp,
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allInMainGradient
)
)
Spacer(modifier = Modifier.height(43.dp))
Text(
text = stringResource(id = R.string.welcome_subtitle),
color = AllInTheme.themeColors.onBackground,
fontSize = 15.sp,
style = AllInTheme.typography.p1
)
Spacer(modifier = Modifier.height(78.dp))
AllInButton(
color = AllInTheme.themeColors.tint1,
text = stringResource(id = R.string.join),
textColor = AllInTheme.themeColors.background,
onClick = navigateToRegister,
modifier = Modifier.padding(bottom = 13.dp)
)
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.p1.copy(
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
)
) {
navigateToLogin()
}
}
}
}
AllInLoading(visible = loading)
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun WelcomeScreenPreview() {
AllInTheme {
WelcomeScreen(
navigateToRegister = {},
navigateToLogin = {},
navigateToDashboard = {}
)
}
} }

@ -0,0 +1,133 @@
package fr.iut.alldev.allin.ui.welcome.components
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.navigationBarsPadding
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.material3.Text
import androidx.compose.runtime.Composable
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 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
@Composable
fun WelcomeScreenContent(
navigateToRegister: () -> Unit,
navigateToLogin: () -> Unit,
loading: Boolean
) {
Box(
Modifier
.fillMaxWidth()
.fillMaxHeight(.5f)
.background(AllInTheme.colors.allInLoginGradient)
)
Box(
Modifier
.fillMaxSize()
.background(
Brush.verticalGradient(
.2f to Color.Transparent,
.5f to AllInTheme.themeColors.background
)
)
) {
Column(
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.padding(40.dp)
.navigationBarsPadding()
) {
Text(
text = stringResource(id = R.string.welcome_title),
color = AllInTheme.themeColors.onBackground,
fontSize = 30.sp,
style = AllInTheme.typography.h1
)
Text(
text = stringResource(id = R.string.welcome_appname),
fontSize = 60.sp,
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allInMainGradient
)
)
Spacer(modifier = Modifier.height(43.dp))
Text(
text = stringResource(id = R.string.welcome_subtitle),
color = AllInTheme.themeColors.onBackground,
fontSize = 15.sp,
style = AllInTheme.typography.p1
)
Spacer(modifier = Modifier.height(78.dp))
AllInButton(
color = AllInTheme.themeColors.tint1,
text = stringResource(id = R.string.join),
textColor = AllInTheme.themeColors.background,
onClick = navigateToRegister,
modifier = Modifier.padding(bottom = 13.dp)
)
Row(
horizontalArrangement = Arrangement.Center,
modifier = Modifier.fillMaxWidth()
) {
Text(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.p1.copy(
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
),
onClick = { navigateToLogin() }
)
}
}
}
AllInLoading(visible = loading)
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun WelcomeScreenContentPreview() {
AllInTheme {
WelcomeScreenContent(
navigateToRegister = { },
navigateToLogin = { },
loading = false
)
}
}

@ -208,13 +208,6 @@ private val mockUsers = mutableListOf(
) )
private val mockParticipations = mutableListOf( private val mockParticipations = mutableListOf(
ResponseParticipation(
id = "",
betId = "UUID1",
username = mockUsers[0].first.username,
answer = YES_VALUE,
stake = 200
),
ResponseParticipation( ResponseParticipation(
id = "", id = "",
betId = "UUID1", betId = "UUID1",
@ -270,7 +263,7 @@ private val mockBets = mutableListOf(
response = listOf(YES_VALUE, NO_VALUE), response = listOf(YES_VALUE, NO_VALUE),
createdBy = "Armure", createdBy = "Armure",
type = BetType.BINARY, type = BetType.BINARY,
status = BetStatus.WAITING, status = BetStatus.IN_PROGRESS,
), ),
ResponseBet( ResponseBet(
id = "UUID2", id = "UUID2",
@ -282,7 +275,7 @@ private val mockBets = mutableListOf(
response = listOf("Answer 1", "Answer 2", "Answer 3", "Answer 4"), response = listOf("Answer 1", "Answer 2", "Answer 3", "Answer 4"),
createdBy = "User 2", createdBy = "User 2",
type = BetType.BINARY, type = BetType.BINARY,
status = BetStatus.WAITING, status = BetStatus.IN_PROGRESS,
), ),
ResponseBet( ResponseBet(
id = "UUID3", id = "UUID3",

@ -11,19 +11,21 @@ import okhttp3.HttpUrl
import okhttp3.OkHttpClient import okhttp3.OkHttpClient
import javax.inject.Singleton import javax.inject.Singleton
const val mock = false
@Module @Module
@InstallIn(SingletonComponent::class) @InstallIn(SingletonComponent::class)
class ApiModule { class ApiModule {
@Provides @Provides
@Singleton @Singleton
fun provideAllInApi(@AllInUrl url: HttpUrl, okHttpClient: OkHttpClient): AllInApi { fun provideAllInApi(@AllInUrl url: HttpUrl, okHttpClient: OkHttpClient): AllInApi {
return if (mock) { return if (MOCK) {
MockAllInApi() MockAllInApi()
} else { } else {
val retrofit = createRetrofit(url = url, okHttpClient = okHttpClient) val retrofit = createRetrofit(url = url, okHttpClient = okHttpClient)
retrofit.create(AllInApi::class.java) retrofit.create(AllInApi::class.java)
} }
} }
companion object {
const val MOCK = true
}
} }

@ -12,10 +12,9 @@ androidxCore = "1.12.0"
androidxActivity = "1.8.2" androidxActivity = "1.8.2"
androidxSecurity = "1.1.0-alpha06" androidxSecurity = "1.1.0-alpha06"
composeBom = "2023.10.01" composeBom = "2024.04.00"
compose = "1.5.4"
composePreview = "1.6.0-beta03"
composeCompiler = "1.5.5" composeCompiler = "1.5.5"
composePreview = "1.6.5"
composeNavigation = "2.7.6" composeNavigation = "2.7.6"
hilt = "2.48" hilt = "2.48"
@ -55,20 +54,20 @@ test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version
test-espresso = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" } test-espresso = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
hilt-androidTesting = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" } hilt-androidTesting = { group = "com.google.dagger", name = "hilt-android-testing", version.ref = "hilt" }
hilt-androidCompiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" } hilt-androidCompiler = { group = "com.google.dagger", name = "hilt-android-compiler", version.ref = "hilt" }
ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4", version.ref = "compose" } ui-test-junit = { group = "androidx.compose.ui", name = "ui-test-junit4" }
ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "compose" } ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
# Compose # Compose
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" } compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
compose-ui = { module = "androidx.compose.ui:ui" } compose-ui = { module = "androidx.compose.ui:ui" }
compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" } compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version = "1.6.0-beta03" } compose-foundation = { module = "androidx.compose.foundation:foundation" }
compose-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composePreview" } compose-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composePreview" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" } compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
compose-ui-googlefonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts" } compose-ui-googlefonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts" }
compose-material = { module = "androidx.compose.material:material" } compose-material = { module = "androidx.compose.material:material" }
compose-material3 = { group = "androidx.compose.material3", name = "material3", version = "1.2.0-beta01" } compose-material3 = { group = "androidx.compose.material3", name = "material3", version = "1.2.1" }
compose-material-icons = { group = "androidx.compose.material", name = "material-icons-core" } compose-material-icons = { group = "androidx.compose.material", name = "material-icons-core" }
compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" } compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "composeNavigation" } compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "composeNavigation" }

Loading…
Cancel
Save