Bet Creation Screen : Answer tab
continuous-integration/drone/push Build is passing Details

pull/3/head
Arthur VALIN 2 years ago
parent 6f9f6e5be0
commit 16c6cb2309

@ -55,6 +55,7 @@ dependencies {
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.compose.material3:material3:1.2.0-alpha08'
implementation "androidx.navigation:navigation-compose:2.7.3"
implementation project(path: ':data')
testImplementation 'junit:junit:4.13.2'
implementation 'androidx.compose.material:material-icons-core'
implementation 'androidx.compose.material:material-icons-extended'

@ -0,0 +1,29 @@
package fr.iut.alldev.allin.ext
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.HelpOutline
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.SportsSoccer
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.res.stringResource
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.BetType
@Composable
fun BetType.getTitle(): String {
return when (this) {
BetType.YES_NO -> stringResource(id = R.string.yes_no)
BetType.MATCH -> stringResource(id = R.string.sport_match)
BetType.CUSTOM -> stringResource(id = R.string.custom_answers)
}
}
@Composable
fun BetType.getIcon(): ImageVector {
return when (this) {
BetType.YES_NO -> Icons.AutoMirrored.Default.HelpOutline
BetType.MATCH -> Icons.Default.SportsSoccer
BetType.CUSTOM -> Icons.Default.Edit
}
}

@ -3,23 +3,28 @@ package fr.iut.alldev.allin.ui.betcreation
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.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.BetType
import fr.iut.alldev.allin.ext.getIcon
import fr.iut.alldev.allin.ext.getTitle
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
@Composable
fun BetCreationScreen(
) {
var theme by remember{
mutableStateOf("")
}
@ -29,15 +34,43 @@ fun BetCreationScreen(
var isPublic by remember{
mutableStateOf(true)
}
val betTypes = remember {
BetType.values().toList()
}
val selectedFriends = remember {
mutableListOf<Int>()
}
val elements = betTypes.map {
SelectionElement(
it.getTitle(),
it.getIcon()
)
}
var selected by remember {
mutableStateOf(elements[0])
}
val selectedBetType by remember {
derivedStateOf {
betTypes[elements.indexOf(selected)]
}
}
Box(
Modifier
.fillMaxSize()
.padding(20.dp)
.padding(top = 20.dp)
) {
AllInSections(
modifier = Modifier
.align(Alignment.TopCenter)
.fillMaxSize(),
.fillMaxSize()
.padding(bottom = 90.dp),
sections = listOf(
SectionElement(stringResource(id = R.string.Question)){
BetCreationScreenQuestionTab(
@ -46,11 +79,25 @@ fun BetCreationScreen(
betPhrase = phrase,
setBetPhrase = { phrase = it },
betTheme = theme,
setBetTheme = { theme = it }
setBetTheme = { theme = it },
nbFriends = 42,
selectedFriends = selectedFriends,
modifier = Modifier
.fillMaxSize()
.verticalScroll(rememberScrollState())
.padding(vertical = 12.dp, horizontal = 20.dp)
)
},
SectionElement(stringResource(id = R.string.Answer)){
BetCreationScreenAnswerTab()
BetCreationScreenAnswerTab(
selectedBetType = selectedBetType,
selected = selected,
setSelected = { selected = it },
elements = elements,
modifier = Modifier
.fillMaxSize()
.padding(vertical = 12.dp, horizontal = 20.dp)
)
}
)
)
@ -58,7 +105,8 @@ fun BetCreationScreen(
text = stringResource(id = R.string.Publish),
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(bottom = 14.dp),
.padding(bottom = 14.dp)
.padding(horizontal = 20.dp),
onClick = {
}
)

@ -1,10 +1,12 @@
package fr.iut.alldev.allin.ui.betcreation.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.alpha
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.ui.theme.AllInTheme
@ -17,8 +19,9 @@ fun BetCreationScreenBottomText(
text = text,
color = AllInTheme.colors.allIn_Purple,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
style = AllInTheme.typography.h2,
modifier = modifier.alpha(.5f)
modifier = modifier.fillMaxWidth().alpha(.5f)
)
}

@ -0,0 +1,86 @@
package fr.iut.alldev.allin.ui.betcreation.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.AllInRadioButton
import fr.iut.alldev.allin.ui.core.ProfilePicture
import fr.iut.alldev.allin.ui.theme.AllInTheme
@Composable
fun BetCreationScreenFriendLine(
username: String,
allCoinsAmount: Int,
isSelected: Boolean,
onClick: ()->Unit
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.background(
if (isSelected) AllInTheme.colors.allIn_Purple.copy(alpha = .13f)
else AllInTheme.themeColors.background
)
.padding(15.dp),
horizontalArrangement = Arrangement.spacedBy(7.dp),
verticalAlignment = Alignment.CenterVertically
) {
AllInRadioButton(
checked = isSelected,
modifier = Modifier.padding(end = 7.dp)
)
ProfilePicture(modifier = Modifier.size(25.dp))
Text(
text = username,
fontWeight = FontWeight.Bold,
style = AllInTheme.typography.h2,
color = AllInTheme.themeColors.on_main_surface,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f)
)
AllInCoinCount(
amount = allCoinsAmount,
color = AllInTheme.colors.allIn_Purple
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetCreationScreenFriendLinePreview() {
AllInTheme {
BetCreationScreenFriendLine(
username = "David",
allCoinsAmount = 542,
isSelected = false) {
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetCreationScreenFriendLineSelectedPreview() {
AllInTheme {
BetCreationScreenFriendLine(
username = "David",
allCoinsAmount = 542,
isSelected = true) {
}
}
}

@ -1,30 +1,54 @@
package fr.iut.alldev.allin.ui.betcreation.tabs
import android.util.Log
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.QuestionAnswer
import androidx.compose.runtime.Composable
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.core.AllInTextAndIcon
import fr.iut.alldev.allin.data.model.BetType
import fr.iut.alldev.allin.ext.getTitle
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.core.AllInSelectionBox
import fr.iut.alldev.allin.ui.core.SelectionElement
@Composable
fun BetCreationScreenAnswerTab() {
Column(
Modifier
.fillMaxSize()
.padding(20.dp)
) {
AllInTextAndIcon(
text = stringResource(id = R.string.Answer),
icon = Icons.Outlined.QuestionAnswer
){
Log.d("ALLINNN", "AAAA")
fun BetCreationScreenAnswerTab(
modifier: Modifier = Modifier,
selected: SelectionElement,
selectedBetType: BetType,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
) {
var isOpen by remember{
mutableStateOf(false)
}
Column(modifier) {
AllInSelectionBox(
isOpen = isOpen,
setIsOpen = { isOpen = it },
selected = selected,
setSelected = setSelected,
elements = elements
)
Spacer(modifier = Modifier.height(26.dp))
when(selectedBetType){
BetType.YES_NO -> {
Column(
modifier = Modifier.padding(vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(17.dp)
) {
BetCreationScreenBottomText(text = stringResource(id = R.string.yes_no_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.yes_no_bottom_text_2))
}
}
BetType.MATCH -> {
BetCreationScreenBottomText(text = selectedBetType.getTitle())
}
BetType.CUSTOM -> {
BetCreationScreenBottomText(text = selectedBetType.getTitle())
}
}
}
}

@ -2,11 +2,13 @@ package fr.iut.alldev.allin.ui.betcreation.tabs
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Public
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
@ -14,7 +16,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenFriendLine
import fr.iut.alldev.allin.ui.core.AllInIconChip
import fr.iut.alldev.allin.ui.core.AllInRetractableCard
import fr.iut.alldev.allin.ui.core.AllInTextAndIcon
import fr.iut.alldev.allin.ui.core.AllInTextField
import fr.iut.alldev.allin.ui.theme.AllInTheme
@ -22,19 +26,18 @@ import fr.iut.alldev.allin.ui.theme.AllInTheme
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun BetCreationScreenQuestionTab(
modifier: Modifier = Modifier,
nbFriends: Int,
betTheme: String,
setBetTheme: (String)->Unit,
betPhrase: String,
setBetPhrase: (String)->Unit,
isPublic: Boolean,
setIsPublic: (Boolean)->Unit
setIsPublic: (Boolean)->Unit,
selectedFriends: MutableList<Int>
) {
val bringIntoViewRequester = remember { BringIntoViewRequester() }
Column(
Modifier
.fillMaxSize()
.padding(20.dp)
){
Column(modifier){
AllInTextAndIcon(
text = stringResource(id = R.string.Theme),
icon = Icons.AutoMirrored.Outlined.HelpOutline,
@ -79,6 +82,7 @@ fun BetCreationScreenQuestionTab(
onClick = {}
)
Row(
modifier = Modifier.padding(bottom = 10.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
){
AllInIconChip(
@ -99,17 +103,71 @@ fun BetCreationScreenQuestionTab(
)
}
Spacer(modifier = Modifier.height(52.dp))
Column(
verticalArrangement = Arrangement.spacedBy(17.dp)
) {
var isOpen by remember{
mutableStateOf(false)
}
if(isPublic){
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_2))
Column(
modifier = Modifier.padding(vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(17.dp)
) {
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_2))
}
}else{
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_2))
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_3))
AllInRetractableCard(
text = stringResource(
id = R.string.n_friends_available,
nbFriends,
nbFriends
),
borderWidth = 1.dp,
boldText = nbFriends.toString(),
isOpen = isOpen,
setIsOpen = { isOpen = it }
) {
LazyColumn(
modifier = Modifier.height(172.dp)
){
items(nbFriends){
val isSelected = remember{
selectedFriends.contains(it)
}
var wasClicked by remember{
mutableStateOf(isSelected)
}
if(it!=0){
HorizontalDivider(color = AllInTheme.themeColors.border)
}
BetCreationScreenFriendLine(
username = "Dave",
allCoinsAmount = 542,
isSelected = wasClicked
) {
wasClicked = ! wasClicked
if (isSelected) {
selectedFriends.remove(it)
} else {
selectedFriends.add(it)
}
}
}
}
}
Column(
modifier = Modifier.padding(vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(17.dp)
) {
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_2))
BetCreationScreenBottomText(text = stringResource(id = R.string.private_bottom_text_3))
}
}
}
}

@ -0,0 +1,56 @@
package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
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.graphics.Color
import androidx.compose.ui.res.painterResource
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.ui.theme.AllInTheme
@Composable
fun AllInCoinCount(
modifier: Modifier = Modifier,
amount: Int,
color: Color
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
Text(
text = amount.toString(),
fontWeight = FontWeight.ExtraBold,
color = color,
style = AllInTheme.typography.h1,
fontSize = 16.sp
)
Icon(
painter = painterResource(id = R.drawable.allcoin),
contentDescription = null,
modifier = Modifier
.size(13.dp),
tint = color
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun AllInCoinCountPreview() {
AllInTheme {
AllInCoinCount(amount = 542, color = AllInTheme.colors.allIn_Purple)
}
}

@ -0,0 +1,48 @@
package fr.iut.alldev.allin.ui.core
import androidx.compose.foundation.layout.size
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.ui.theme.AllInTheme
@Composable
fun AllInRadioButton(
modifier: Modifier = Modifier,
checked: Boolean,
unCheckedColor: Color = Color.Transparent
) {
AllInCard(
radius = 100.dp,
borderColor = AllInTheme.colors.allIn_Mint,
borderWidth = if(!checked) 1.dp else null,
backgroundColor = if (checked) AllInTheme.colors.allIn_Purple else unCheckedColor,
modifier = modifier.size(12.dp)
){}
}
@Preview
@Composable
private fun AllInRadioButtonNotCheckedPreview() {
AllInTheme {
AllInRadioButton(checked = false)
}
}
@Preview
@Composable
private fun AllInRadioButtonNotCheckedFilledPreview() {
AllInTheme {
AllInRadioButton(checked = false, unCheckedColor = AllInTheme.colors.allIn_Mint)
}
}
@Preview
@Composable
private fun AllInRadioButtonCheckedPreview() {
AllInTheme {
AllInRadioButton(checked = true)
}
}

@ -0,0 +1,80 @@
package fr.iut.alldev.allin.ui.core
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.SpanStyle
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.ui.theme.AllInTheme
@Composable
fun AllInRetractableCard(
modifier: Modifier = Modifier,
text: String,
boldText: String = "",
isOpen: Boolean,
setIsOpen: (Boolean)->Unit,
borderWidth: Dp? = null,
interactionSource: MutableInteractionSource = MutableInteractionSource(),
content: @Composable ()->Unit
) {
AllInCard(
modifier = modifier,
borderWidth = borderWidth,
borderColor = AllInTheme.colors.allIn_Purple.copy(.5f)
){
Column(
Modifier.animateContentSize()
) {
Row(
modifier = Modifier
.clickable(
interactionSource = interactionSource,
indication = null,
onClick = { setIsOpen(!isOpen) }
)
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
HighlightedText(
text = text,
query = boldText,
highlightStyle = SpanStyle(
fontWeight = FontWeight.Bold,
color = AllInTheme.themeColors.on_main_surface,
fontStyle = AllInTheme.typography.h2.fontStyle
),
color = AllInTheme.themeColors.on_background_2,
style = AllInTheme.typography.r,
fontSize = 16.sp,
modifier = Modifier.weight(1f)
)
Icon(
imageVector = with(Icons.Default){
if(isOpen) ExpandLess else ExpandMore
},
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
modifier = Modifier.size(30.dp)
)
}
if(isOpen){
HorizontalDivider(color = AllInTheme.themeColors.border)
content()
}
}
}
}

@ -1,36 +1,28 @@
package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration
import androidx.compose.animation.core.Spring
import androidx.compose.animation.core.spring
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.gestures.*
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.itemsIndexed
import androidx.compose.foundation.pager.HorizontalPager
import androidx.compose.foundation.pager.rememberPagerState
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.ui.theme.AllInTheme
import kotlinx.coroutines.launch
class SectionElement(
val text: String,
val content: @Composable ()->Unit
)
enum class DragAnchors(val fraction: Float) {
Start(-2f),
Center(0f),
End(2f),
}
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun AllInSections(
@ -38,97 +30,31 @@ fun AllInSections(
interSectionsPadding: Dp = 56.dp,
modifier: Modifier = Modifier
) {
var selected by remember {
mutableStateOf(sections.firstOrNull())
}
var wasSwiped by remember{
mutableStateOf(false)
}
val density = LocalDensity.current
val draggableState = remember {
AnchoredDraggableState(
initialValue = DragAnchors.Center,
positionalThreshold = { distance: Float -> distance * .5f },
velocityThreshold = { with(density) { 50.dp.toPx() } },
animationSpec = spring(
dampingRatio = 0.66f,
stiffness = Spring.StiffnessMediumLow,
),
){
val idx = sections.indexOf(selected)
val add = when(it.fraction){
DragAnchors.End.fraction-> {
-1
}
DragAnchors.Start.fraction-> {
1
}
else -> 0
}
selected=sections.getOrElse(idx+add){
sections[idx]
}
if(selected!=sections[idx]){
wasSwiped=true
}
false
}
}
val pagerState = rememberPagerState(pageCount = {
sections.size
})
val scope = rememberCoroutineScope()
Column(
modifier = modifier,
horizontalAlignment = Alignment.CenterHorizontally
) {
){
LazyRow(
horizontalArrangement = Arrangement.spacedBy(interSectionsPadding)
) {
items(sections) { section ->
AllInSectionButton(
text = section.text,
isSelected = selected == section,
onClick = { selected = section }
)
}
}
Box(
Modifier
.wrapContentSize()
.anchoredDraggable(draggableState, Orientation.Horizontal)
.onSizeChanged { layoutSize ->
val dragEndPoint = layoutSize.width
draggableState.updateAnchors(
DraggableAnchors {
DragAnchors
.values()
.forEach { anchor ->
anchor at dragEndPoint * anchor.fraction
}
horizontalArrangement = Arrangement.spacedBy(interSectionsPadding)
) {
itemsIndexed(sections) { index, section ->
AllInSectionButton(
text = section.text,
isSelected = index == pagerState.currentPage,
onClick = {
scope.launch {
pagerState.animateScrollToPage(index)
}
}
)
},
){
Box(
Modifier
.wrapContentSize()
.offset {
val offset =
if (
wasSwiped
) {
if (!draggableState.isAnimationRunning) {
wasSwiped = false
}
-draggableState.offset.toInt()
} else {
draggableState.offset.toInt()
}
IntOffset(x = offset, y = 0)
}
){
selected?.content?.let { it() }
}
}
HorizontalPager(state = pagerState) { page ->
sections[page].content()
}
}
}

@ -0,0 +1,156 @@
package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.HelpOutline
import androidx.compose.material.icons.filled.*
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
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.vector.ImageVector
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.ui.theme.AllInTheme
class SelectionElement(
val text: String,
val iconVector: ImageVector
)
@Composable
fun AllInSelectionLine(
text: String,
iconVector: ImageVector,
modifier: Modifier = Modifier,
onClick: ()->Unit,
trailingIcon: ImageVector? = null,
interactionSource: MutableInteractionSource
){
Row(
modifier = modifier
.clickable(
interactionSource = interactionSource,
indication = null,
onClick = onClick
)
.padding(horizontal = 12.dp, vertical = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
Icon(
imageVector = iconVector,
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
modifier = Modifier.size(20.dp)
)
Text(
text = text,
color = AllInTheme.colors.allIn_Purple,
style = AllInTheme.typography.h2,
fontWeight = FontWeight.Bold,
modifier = Modifier.weight(1f)
)
trailingIcon?.let {
Icon(
imageVector = trailingIcon,
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
modifier = Modifier
.size(30.dp)
)
}
}
}
@Composable
fun AllInSelectionBox(
modifier: Modifier = Modifier,
isOpen: Boolean,
setIsOpen: (Boolean)->Unit,
selected: SelectionElement,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
) {
val interactionSource = remember { MutableInteractionSource() }
AllInCard(modifier){
Column(
Modifier.animateContentSize()
) {
AllInSelectionLine(
text = selected.text,
iconVector = selected.iconVector,
onClick = { setIsOpen(!isOpen) },
interactionSource = interactionSource,
trailingIcon = with(Icons.Default){
if(isOpen) ExpandLess else ExpandMore
}
)
if(isOpen){
HorizontalDivider(color = AllInTheme.themeColors.border)
elements.filter { it != selected }.forEach{
element ->
AllInSelectionLine(
text = element.text,
iconVector = element.iconVector,
interactionSource = interactionSource,
onClick = {
setSelected(element)
setIsOpen(false)
}
)
}
}
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun AllInSelectionBoxClosedPreview() {
AllInTheme {
val elements = listOf(
SelectionElement("Oui/Non", Icons.AutoMirrored.Default.HelpOutline),
SelectionElement("Sport", Icons.Default.SportsFootball),
SelectionElement("Perso", Icons.Default.PinEnd)
)
AllInSelectionBox(
isOpen = false,
selected = elements[0],
elements = elements,
setSelected = {},
setIsOpen = {},
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun AllInSelectionBoxOpenPreview() {
AllInTheme {
val elements = listOf(
SelectionElement("Oui/Non", Icons.AutoMirrored.Default.HelpOutline),
SelectionElement("Sport", Icons.Default.SportsFootball),
SelectionElement("Perso", Icons.Default.Edit)
)
AllInSelectionBox(
isOpen = true,
selected = elements[0],
elements = elements,
setSelected = {},
setIsOpen = {},
)
}
}

@ -46,7 +46,7 @@ fun RainbowButton(
style = textStyle,
fontSize = 30.sp,
modifier = Modifier
.padding(vertical = 20.dp)
.padding(vertical = 15.dp)
.fillMaxWidth(),
)
}

@ -1,6 +1,7 @@
package fr.iut.alldev.allin.ui.core.topbar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.wrapContentSize
@ -21,19 +22,22 @@ import fr.iut.alldev.allin.ui.theme.AllInTheme
@Composable
fun CoinCounter(amount:Int, modifier: Modifier = Modifier) {
Card(modifier = modifier.wrapContentSize(), shape = RoundedCornerShape(topStartPercent = 50, bottomStartPercent = 50)) {
Row(modifier = Modifier
Row(
modifier = Modifier
.background(AllInTheme.colors.white)
.padding(horizontal = 13.dp, vertical = 5.dp),
verticalAlignment = Alignment.CenterVertically) {
Icon(
painter = painterResource(R.drawable.allcoin),
tint = AllInTheme.colors.allIn_Blue,
contentDescription = null,
modifier = Modifier.padding(end = 8.dp))
horizontalArrangement = Arrangement.spacedBy(7.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = amount.toString(),
color = AllInTheme.colors.allIn_Dark,
style = AllInTheme.typography.h1,
fontSize = 20.sp)
Icon(
painter = painterResource(R.drawable.allcoin),
tint = AllInTheme.colors.allIn_Blue,
contentDescription = null,
)
}
}
}

@ -22,6 +22,7 @@ data class AllInColors(
val white: Color,
val black: Color,
val allIn_Pink: Color,
val allIn_Mint: Color,
val allIn_Purple: Color,
val allIn_LoginPurple: Color,
val allIn_Blue: Color,
@ -56,6 +57,7 @@ internal val LocalColors = staticCompositionLocalOf {
allIn_BarPurple = Color.Unspecified,
allIn_BarPink = Color.Unspecified,
allIn_Blue = Color.Unspecified,
allIn_Mint = Color.Unspecified,
allIn_DarkBlue = Color.Unspecified,
allIn_MainGradient = Brush.linearGradient(

@ -37,6 +37,7 @@ fun AllInTheme(
allIn_BarPurple = Color(0xFF846AC9),
allIn_BarPink = Color(0xFFFE2B8A),
allIn_Blue = Color(0xFF6a89fa),
allIn_Mint = Color(0xFFC4DEE9),
allIn_DarkBlue = Color(0xFF323078),
allIn_MainGradient = Brush.linearGradient(

@ -51,6 +51,9 @@
<string name="private_bottom_text_2">Seulement vos amis pourront rejoindre le bet.</string>
<string name="private_bottom_text_3">Vous pourrez inviter des amis à tout moment pendant la période dinscription.</string>
<string name="yes_no">Oui / Non</string>
<string name="sport_match">Match sportif</string>
<string name="yes_no_bottom_text_1">Les utilisateurs devront répondre au pari avec OUI ou NON.</string>
<string name="yes_no_bottom_text_2">Aucune autre réponse ne sera acceptée.</string>
<string name="custom_answers">Réponses personnalisées</string>
<!--Bet Page-->
<string name="Popular">Populaire</string>

@ -56,6 +56,9 @@
<string name="private_bottom_text_2">Only your friends will be able to join the bet.</string>
<string name="private_bottom_text_3">You can invite friends at any moment during the registration period.</string>
<string name="yes_no">Yes / No</string>
<string name="yes_no_bottom_text_1">The participants will have to respond with either YES or NO.</string>
<string name="yes_no_bottom_text_2">No other answer will be accepted.</string>
<string name="sport_match">Sport match</string>
<string name="custom_answers">Custom answers</string>
<!--Bet Page-->
<string name="Popular">Popular</string>

@ -0,0 +1,7 @@
package fr.iut.alldev.allin.data.model
enum class BetType {
YES_NO,
MATCH,
CUSTOM
}
Loading…
Cancel
Save