Bet result page
continuous-integration/drone/push Build is passing Details

pull/3/head
Arthur VALIN 1 year ago
parent e554c57ef9
commit 3c5545bdb6

@ -10,7 +10,7 @@ plugins {
}
// Keystore
val keystorePropertiesFile = rootProject.file("app/keys/keystore.properties")
val keystorePropertiesFile = rootProject.file("keys/keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
@ -33,11 +33,16 @@ android {
}
}
signingConfigs {
named(BuildType.DEBUG.name) {
storeFile = file(keystoreProperties["debugStoreFile"].toString())
}
register(BuildType.RELEASE.name) {
storeFile = file(keystoreProperties["store"].toString())
storePassword = keystoreProperties["password"].toString()
keyPassword = keystoreProperties["password"].toString()
storeFile = file(keystoreProperties["releaseStoreFile"].toString())
storePassword = keystoreProperties["passwordRelease"].toString()
keyAlias = keystoreProperties["aliasRelease"].toString()
keyPassword = keystoreProperties["passwordRelease"].toString()
}
}
@ -102,5 +107,6 @@ dependencies {
androidTestImplementation(libs.test.androidx.junit)
androidTestImplementation(libs.hilt.androidTesting)
kaptAndroidTest(libs.hilt.androidCompiler)
androidTestImplementation(libs.ui.test.junit)
debugImplementation(libs.ui.test.manifest)
}

Binary file not shown.

@ -1,2 +0,0 @@
store=keys/keystore.jks
password=placeYourBets

Binary file not shown.

@ -18,4 +18,19 @@
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
#-renamesourcefileattribute SourceFile
# Android.Security.Crypto
-dontwarn com.google.api.client.http.**
-dontwarn com.google.errorprone.**
-dontwarn org.joda.time.**
-keep,allowoptimization class com.google.crypto.tink.** { *; }
-keep,allowoptimization class com.google.errorprone.** { *; }
-keep,allowoptimization class com.google.api.client.http.** { *; }
-keep,allowobfuscation,allowshrinking interface retrofit2.Call
-keep,allowobfuscation,allowshrinking class retrofit2.Response
-keep,allowobfuscation,allowshrinking class kotlin.coroutines.Continuation

@ -1,6 +1,7 @@
package fr.iut.alldev.allin.test.mock
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import java.time.ZonedDateTime
@ -14,7 +15,8 @@ object Bets {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.InProgress
betStatus = BetStatus.InProgress,
creator = "creator",
),
MatchBet(
theme = "Theme",
@ -24,7 +26,23 @@ object Bets {
isPublic = true,
betStatus = BetStatus.InProgress,
nameTeam1 = "Team_1",
nameTeam2 = "Team_2"
nameTeam2 = "Team_2",
creator = "creator"
),
CustomBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.InProgress,
creator = "creator",
possibleAnswers = setOf(
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
)
),
)
}

@ -9,8 +9,7 @@ import fr.iut.alldev.allin.test.TestTags
import fr.iut.alldev.allin.test.mock.Bets
import fr.iut.alldev.allin.ui.MainActivity
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.vo.bet.factory.toBetVO
import fr.iut.alldev.allin.vo.bet.visitor.BetTestVisitor
import fr.iut.alldev.allin.vo.bet.displayer.BetTestDisplayer
import org.junit.Before
import org.junit.Rule
import org.junit.Test
@ -30,37 +29,55 @@ class BetVOTest {
}
companion object {
val visitor = BetTestVisitor()
val displayer = BetTestDisplayer()
}
@Test
fun testVisitor_shouldDisplayYesNoBetUI(){
fun testDisplayer_shouldDisplayYesNoBetUI(){
//Given
//When
composeTestRule.activity.setContent {
AllInTheme{
Bets.bets[0].toBetVO()?.Accept(v = visitor)
displayer.DisplayBet(Bets.bets[0])
}
}
//Expect
composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertExists()
composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertDoesNotExist()
composeTestRule.onNodeWithTag(TestTags.CUSTOM_BET.tag).assertDoesNotExist()
}
@Test
fun testVisitor_shouldDisplayMatchUI(){
fun testDisplayer_shouldDisplayMatchUI(){
//Given
//When
composeTestRule.activity.setContent {
AllInTheme{
Bets.bets[1].toBetVO()?.Accept(v = visitor)
displayer.DisplayBet(Bets.bets[1])
}
}
//Expect
composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertExists()
composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertDoesNotExist()
composeTestRule.onNodeWithTag(TestTags.CUSTOM_BET.tag).assertDoesNotExist()
}
@Test
fun testDisplayer_shouldDisplayCustomBetUI(){
//Given
//When
composeTestRule.activity.setContent {
AllInTheme{
displayer.DisplayBet(Bets.bets[2])
}
}
//Expect
composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertDoesNotExist()
composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertDoesNotExist()
composeTestRule.onNodeWithTag(TestTags.CUSTOM_BET.tag).assertExists()
}
}

@ -1,21 +1,28 @@
package fr.iut.alldev.allin.vo.bet.visitor
package fr.iut.alldev.allin.vo.bet.displayer
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.test.TestTags
import fr.iut.alldev.allin.vo.bet.BetDisplayer
class BetTestVisitor : DisplayBetVisitor {
class BetTestDisplayer : BetDisplayer {
@Composable
override fun VisitYesNoBet(b: YesNoBet) {
override fun DisplayYesNoBet(b: YesNoBet) {
Text("This is a YesNo Bet", Modifier.testTag(TestTags.YES_NO_BET.tag))
}
@Composable
override fun VisitMatchBet(b: MatchBet) {
override fun DisplayMatchBet(b: MatchBet) {
Text("This is a Match Bet", Modifier.testTag(TestTags.MATCH_BET.tag))
}
@Composable
override fun DisplayCustomBet(b: CustomBet) {
Text("This is a Custom Bet", Modifier.testTag(TestTags.CUSTOM_BET.tag))
}
}

@ -1,10 +1,9 @@
package fr.iut.alldev.allin.keystore
import androidx.security.crypto.MasterKeys
import androidx.security.crypto.MasterKey
abstract class AllInKeystoreManager {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC)
protected abstract val masterKey: MasterKey
abstract fun createKeystore()
abstract fun putToken(token: String)
abstract fun getToken(): String?

@ -3,10 +3,12 @@ package fr.iut.alldev.allin.keystore.impl
import android.content.Context
import android.content.SharedPreferences
import androidx.security.crypto.EncryptedSharedPreferences
import androidx.security.crypto.MasterKey
import dagger.hilt.android.qualifiers.ApplicationContext
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
import javax.inject.Inject
private const val AUTH_TOKEN_KEY = "auth_token"
private const val PREFS_FILE_NAME = "secured_shared_prefs"
@ -14,13 +16,18 @@ class AllInKeystoreManagerImpl @Inject constructor(
@ApplicationContext private val context: Context,
) : AllInKeystoreManager() {
override val masterKey = MasterKey
.Builder(context, MasterKey.DEFAULT_MASTER_KEY_ALIAS)
.setKeyScheme(MasterKey.KeyScheme.AES256_GCM)
.build()
private var sharedPreferences: SharedPreferences? = null
override fun createKeystore() {
if (sharedPreferences == null) {
sharedPreferences = EncryptedSharedPreferences.create(
PREFS_FILE_NAME,
masterKeyAlias,
context,
PREFS_FILE_NAME,
masterKey,
EncryptedSharedPreferences.PrefKeyEncryptionScheme.AES256_SIV,
EncryptedSharedPreferences.PrefValueEncryptionScheme.AES256_GCM
)

@ -2,5 +2,6 @@ package fr.iut.alldev.allin.test
enum class TestTags(val tag: String) {
YES_NO_BET("YES_NO"),
MATCH_BET("MATCH_BET")
MATCH_BET("MATCH_BET"),
CUSTOM_BET("CUSTOM_BET")
}

@ -36,6 +36,7 @@ data class AllInColors(
val allInBetInProgressText: Color,
val allInBetWaitingText: Color,
val allInMainGradient: Brush,
val allInMainGradientReverse: Brush,
val allInBar1stGradient: Brush,
val allInBar2ndGradient: Brush,
val allInTextGradient: Brush,
@ -73,6 +74,7 @@ internal val LocalColors = staticCompositionLocalOf {
allInBetInProgressText = Color.Unspecified,
allInBetWaitingText = Color.Unspecified,
allInMainGradient = SolidColor(Color.Unspecified),
allInMainGradientReverse = SolidColor(Color.Unspecified),
allInBar1stGradient = SolidColor(Color.Unspecified),
allInBar2ndGradient = SolidColor(Color.Unspecified),
allInTextGradient = SolidColor(Color.Unspecified),

@ -55,6 +55,13 @@ fun AllInTheme(
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
),
allInMainGradientReverse = Brush.linearGradient(
0.0f to Color(0xFF199fee),
0.5f to Color(0xFFaa7ef3),
1.0f to Color(0xFFf951a8),
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
),
allInBar1stGradient = Brush.horizontalGradient(
0.0f to Color(0xFF2599F8),
1.0f to Color(0xFF846AC9)
@ -82,32 +89,32 @@ fun AllInTheme(
val customTypography = AllInTypography(
h1 = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.ExtraBold,
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.ExtraBold
),
h2 = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.Bold,
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.Bold
),
h3 = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.SemiBold,
sm1 = TextStyle(
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.SemiBold
),
m = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.Medium,
sm2 = TextStyle(
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.Medium
),
r = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.Normal,
p1 = TextStyle(
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.Normal
),
s = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.Light,
p2 = TextStyle(
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.Light
),
xs = TextStyle(
fontFamily = PlusJakartaSans,
fontWeight = FontWeight.ExtraLight,
l1 = TextStyle(
fontFamily = fontFamilyPlusJakartaSans,
fontWeight = FontWeight.ExtraLight
)
)

@ -3,40 +3,50 @@ package fr.iut.alldev.allin.theme
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.text.font.Font
import androidx.compose.ui.text.font.FontFamily
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.googlefonts.Font
import androidx.compose.ui.text.googlefonts.GoogleFont
import fr.iut.alldev.allin.R
val PlusJakartaSans = FontFamily(
Font(R.font.plusjakartasans_extralight, weight = FontWeight.ExtraLight),
Font(R.font.plusjakartasans_light, weight = FontWeight.Light),
Font(R.font.plusjakartasans_regular, weight = FontWeight.Normal),
Font(R.font.plusjakartasans_medium, weight = FontWeight.Medium),
Font(R.font.plusjakartasans_semibold, weight = FontWeight.SemiBold),
Font(R.font.plusjakartasans_bold, weight = FontWeight.Bold),
Font(R.font.plusjakartasans_extrabold, weight = FontWeight.ExtraBold)
)
private val provider = GoogleFont.Provider(
providerAuthority = "com.google.android.gms.fonts",
providerPackage = "com.google.android.gms",
certificates = R.array.com_google_android_gms_fonts_certs
)
private val fontNamePlusJakartaSans = GoogleFont(name = "Plus Jakarta Sans")
val fontFamilyPlusJakartaSans = FontFamily(
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.ExtraLight),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.Light),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.Normal),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.Medium),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.SemiBold),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.Bold),
Font(googleFont = fontNamePlusJakartaSans, fontProvider = provider, weight = FontWeight.ExtraBold),
)
@Immutable
data class AllInTypography(
val h1: TextStyle,
val h2: TextStyle,
val h3: TextStyle,
val m: TextStyle,
val r: TextStyle,
val s: TextStyle,
val xs: TextStyle
val sm1: TextStyle,
val sm2: TextStyle,
val p1: TextStyle,
val p2: TextStyle,
val l1: TextStyle
)
internal val LocalTypography = staticCompositionLocalOf {
AllInTypography(
h1 = TextStyle.Default,
h2 = TextStyle.Default,
h3 = TextStyle.Default,
m = TextStyle.Default,
r = TextStyle.Default,
s = TextStyle.Default,
xs = TextStyle.Default
sm1 = TextStyle.Default,
sm2 = TextStyle.Default,
p1 = TextStyle.Default,
p2 = TextStyle.Default,
l1 = TextStyle.Default
)
}

@ -118,8 +118,8 @@ fun BetScreen(
creator = it.creator,
category = it.theme,
title = it.phrase,
date = it.endBetDate.formatToMediumDateNoYear(),
time = it.endBetDate.formatToTime(),
date = it.endRegisterDate.formatToMediumDateNoYear(),
time = it.endRegisterDate.formatToTime(),
players = List(3) { null },
onClickParticipate = { selectBet(it, true) },
onClickCard = { selectBet(it, false) },

@ -79,7 +79,7 @@ fun BetScreenCard(
players.size,
players.size
),
style = AllInTheme.typography.m,
style = AllInTheme.typography.sm2,
color = AllInTheme.themeColors.onBackground2
)
}

@ -100,13 +100,13 @@ fun BetScreenPopularCard(
color = AllInTheme.colors.allInPink
),
color = AllInTheme.colors.white,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 15.sp
)
Text(
text = " - ",
color = AllInTheme.colors.white,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 15.sp
)
val pointsText = if (points % 1 == 0f) {
@ -126,7 +126,7 @@ fun BetScreenPopularCard(
color = AllInTheme.colors.allInPink
),
color = AllInTheme.colors.white,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 15.sp
)
}

@ -54,8 +54,8 @@ fun BetHistoryScreen(
title = it.phrase,
creator = it.creator,
category = it.theme,
date = it.endBetDate.formatToMediumDateNoYear(),
time = it.endBetDate.formatToTime(),
date = it.endRegisterDate.formatToMediumDateNoYear(),
time = it.endRegisterDate.formatToTime(),
status = it.betStatus,
nbCoins = 230
)

@ -1,24 +1,13 @@
package fr.iut.alldev.allin.ui.betHistory.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.ext.getDateStartLabelId
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.bet.BetDateTimeRow
import fr.iut.alldev.allin.ui.core.bet.BetTitleHeader
import fr.iut.alldev.allin.ui.core.bet.BetCard
import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider
@Composable
@ -32,30 +21,15 @@ fun BetHistoryScreenCard(
status: BetStatus,
nbCoins: Int,
) {
AllInCard(
modifier = modifier.fillMaxWidth(),
radius = 16.dp
BetCard(
title = title,
creator = creator,
category = category,
date = date,
time = time,
status = status,
modifier = modifier
) {
Column(
Modifier.padding(horizontal = 19.dp, vertical = 11.dp)
) {
BetTitleHeader(
title = title,
category = category,
creator = creator,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(11.dp))
BetDateTimeRow(
label = stringResource(id = status.getDateStartLabelId()),
date = date,
time = time
)
}
HorizontalDivider(
thickness = 1.dp,
color = AllInTheme.themeColors.border
)
BetHistoryBetStatus(
status = status,
nbCoins = nbCoins

@ -0,0 +1,172 @@
package fr.iut.alldev.allin.ui.betResult
import androidx.compose.foundation.MarqueeSpacing
import androidx.compose.foundation.background
import androidx.compose.foundation.basicMarquee
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.SheetState
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.scale
import androidx.compose.ui.res.painterResource
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.ext.formatToMediumDateNoYear
import fr.iut.alldev.allin.data.ext.formatToTime
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betResult.components.BetResultBottomSheetBetCard
import fr.iut.alldev.allin.ui.betResult.components.BetResultBottomSheetContentCoinAmount
import fr.iut.alldev.allin.ui.betResult.components.BetResultBottomSheetContentCongratulations
import fr.iut.alldev.allin.ui.core.AllInBottomSheet
import java.time.ZonedDateTime
@Composable
fun BetResultBottomSheet(
state: SheetState,
sheetVisibility: Boolean,
username: String,
coinAmount: Int,
bet: Bet,
stake: Int,
winnings: Int,
odds: Float,
onDismiss: () -> Unit
) {
AllInBottomSheet(
sheetVisibility = sheetVisibility,
onDismiss = onDismiss,
state = state,
dragHandle = null
) {
BetResultBottomSheetContent(
username = username,
coinAmount = coinAmount,
bet = bet,
stake = stake,
winnings = winnings,
odds = odds,
onClose = onDismiss
)
}
}
@Composable
fun BetResultBottomSheetContent(
username: String,
coinAmount: Int,
bet: Bet,
stake: Int,
winnings: Int,
odds: Float,
onClose: () -> Unit
) {
Box(
modifier = Modifier
.fillMaxSize()
.background(AllInTheme.colors.allInMainGradientReverse),
) {
Icon(
painter = painterResource(id = R.drawable.allin_marquee),
contentDescription = null,
modifier = Modifier
.fillMaxSize()
.rotate(11f)
.scale(1.2f)
.offset(x = (-24).dp)
.basicMarquee(spacing = MarqueeSpacing(0.dp)),
tint = AllInTheme.colors.white.copy(alpha = .05f)
)
Box(
modifier = Modifier
.fillMaxSize()
.padding(16.dp)
) {
IconButton(
onClick = onClose,
modifier = Modifier
.size(24.dp)
.align(Alignment.TopStart)
) {
Icon(
imageVector = Icons.Default.Close,
tint = AllInTheme.colors.white,
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
Icon(
painter = painterResource(R.drawable.allin),
contentDescription = null,
tint = AllInTheme.colors.white,
modifier = Modifier
.size(40.dp)
.align(Alignment.TopCenter)
)
Column(
modifier = Modifier.align(Alignment.Center),
verticalArrangement = Arrangement.spacedBy(48.dp),
horizontalAlignment = Alignment.CenterHorizontally
) {
BetResultBottomSheetContentCongratulations(username = username)
BetResultBottomSheetContentCoinAmount(amount = coinAmount)
BetResultBottomSheetBetCard(
title = bet.phrase,
creator = bet.creator,
category = bet.theme,
date = bet.endBetDate.formatToMediumDateNoYear(),
time = bet.endBetDate.formatToTime(),
status = bet.betStatus,
stake = stake,
winnings = winnings,
odds = odds
)
}
}
}
}
@Preview
@Preview(widthDp = 800, heightDp = 1280)
@Composable
private fun BetResultBottomSheetContentPreview() {
AllInTheme {
BetResultBottomSheetContent(
username = "Pseudo",
coinAmount = 3976,
bet = YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.InProgress,
creator = "creator",
),
stake = 4175,
winnings = 2600,
odds = 6.7f
) {
}
}
}

@ -0,0 +1,60 @@
package fr.iut.alldev.allin.ui.betResult.components
import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.bet.BetCard
@Composable
fun BetResultBottomSheetBetCard(
modifier: Modifier = Modifier,
title: String,
creator: String,
category: String,
date: String,
time: String,
status: BetStatus,
stake: Int,
winnings: Int,
odds: Float
) {
BetCard(
title = title,
creator = creator,
category = category,
date = date,
time = time,
status = status,
modifier = modifier
) {
BetResultBottomSheetBetCardStats(
stake = stake,
winnings = winnings,
odds = odds
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetResultBottomSheetBetCardPreview() {
AllInTheme {
BetResultBottomSheetBetCard(
creator = "Creator",
category = "Category",
title = "Title",
date = "Date",
time = "Time",
status = BetStatus.Finished(BetFinishedStatus.WON),
stake = 2446,
winnings = 6930,
odds = 2.3f
)
}
}

@ -0,0 +1,111 @@
package fr.iut.alldev.allin.ui.betResult.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.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.IconPosition
@Composable
fun BetResultBottomSheetBetCardStats(
stake: Int,
winnings: Int,
odds: Float
) {
Column(
Modifier
.fillMaxWidth()
.background(AllInTheme.themeColors.background2)
.padding(horizontal = 19.dp, vertical = 11.dp),
verticalArrangement = Arrangement.spacedBy(12.dp)
) {
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = stringResource(id = R.string.bet_result_stake),
style = AllInTheme.typography.sm2,
color = AllInTheme.themeColors.onMainSurface
)
AllInCoinCount(
amount = stake,
color = AllInTheme.colors.allInPurple,
textStyle = AllInTheme.typography.sm1,
position = IconPosition.TRAILING
)
}
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = stringResource(id = R.string.bet_result_winnings),
style = AllInTheme.typography.sm2,
color = AllInTheme.colors.allInPurple
)
AllInCoinCount(
amount = winnings,
textStyle = AllInTheme.typography.sm1,
brush = AllInTheme.colors.allInMainGradient,
position = IconPosition.TRAILING
)
}
Row(
modifier = Modifier.fillMaxWidth(),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.SpaceBetween
) {
Text(
text = stringResource(id = R.string.bet_result_odds),
style = AllInTheme.typography.sm2,
color = AllInTheme.themeColors.onBackground2
)
AllInCard(
radius = 8.dp,
backgroundBrush = AllInTheme.colors.allInMainGradient
) {
Box(Modifier.padding(vertical = 4.dp, horizontal = 8.dp)) {
Text(
text = "$odds",
style = AllInTheme.typography.sm1,
color = AllInTheme.colors.white
)
}
}
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetResultBottomSheetBetCardStatsPreview() {
AllInTheme {
BetResultBottomSheetBetCardStats(
stake = 2446,
winnings = 6930,
odds = 2.3f
)
}
}

@ -0,0 +1,71 @@
package fr.iut.alldev.allin.ui.betResult.components
import androidx.compose.animation.core.RepeatMode
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.rotate
import androidx.compose.ui.draw.scale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
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
@Composable
fun BetResultBottomSheetContentCongratulations(
modifier: Modifier = Modifier,
username: String
) {
val infiniteTransition = rememberInfiniteTransition(label = "")
val rotation by infiniteTransition.animateFloat(
initialValue = -11f,
targetValue = -5f,
animationSpec = infiniteRepeatable(
animation = tween(900),
repeatMode = RepeatMode.Reverse
), label = ""
)
val scale by infiniteTransition.animateFloat(
initialValue = 1f,
targetValue = .9f,
animationSpec = infiniteRepeatable(
animation = tween(900),
repeatMode = RepeatMode.Reverse
), label = ""
)
Row(
modifier = modifier
.rotate(rotation)
.scale(scale),
verticalAlignment = Alignment.Top,
horizontalArrangement = Arrangement.spacedBy(8.dp)
) {
Text(
text= stringResource(id = R.string.bet_result_congratulations),
style = AllInTheme.typography.h1,
fontSize = 25.sp,
fontStyle = FontStyle.Italic,
color = AllInTheme.colors.white
)
Text(
text = "${username.uppercase()} !",
style = AllInTheme.typography.h1,
fontSize = 30.sp,
fontStyle = FontStyle.Italic,
color = AllInTheme.colors.white
)
}
}

@ -0,0 +1,79 @@
package fr.iut.alldev.allin.ui.betResult.components
import android.content.res.Configuration
import androidx.compose.foundation.border
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.offset
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.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.AllInCoinCount
import fr.iut.alldev.allin.ui.core.IconPosition
@Composable
fun BetResultBottomSheetContentCoinAmount(
modifier: Modifier = Modifier,
amount: Int
) {
Column(
verticalArrangement = Arrangement.spacedBy(14.dp),
horizontalAlignment = Alignment.CenterHorizontally,
) {
Text(
text = stringResource(id = R.string.bet_result_you_win),
style = AllInTheme.typography.sm2,
color = AllInTheme.colors.white,
fontSize = 20.sp
)
Box(
modifier
.border(
width = 2.dp,
shape = RoundedCornerShape(100.dp),
color = AllInTheme.colors.white
)
.padding(vertical = 22.dp, horizontal = 33.dp)
) {
AllInCoinCount(
amount = amount,
textStyle = AllInTheme.typography.h1,
position = IconPosition.TRAILING,
color = AllInTheme.colors.white,
size = 60,
modifier = Modifier
.align(Alignment.Center)
.offset(y = (-6).dp)
)
AllInCoinCount(
amount = amount,
textStyle = AllInTheme.typography.h1,
position = IconPosition.TRAILING,
color = AllInTheme.colors.white.copy(alpha = .32f),
size = 60,
modifier = Modifier.align(Alignment.Center)
)
}
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetResultBottomSheetContentCoinAmountPreview() {
AllInTheme {
BetResultBottomSheetContentCoinAmount(amount = 1572)
}
}

@ -8,9 +8,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.ui.betStatus.components.BetStatusBottomSheetBack
import fr.iut.alldev.allin.ui.betStatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.core.AllInBottomSheet
import fr.iut.alldev.allin.vo.bet.BetVO
internal const val SHEET_HEIGHT = .85f
@ -22,9 +20,9 @@ fun BetStatusBottomSheet(
state: SheetState,
sheetVisibility: Boolean,
sheetBackVisibility: Boolean,
bet: BetVO<Bet>?,
bet: Bet?,
onDismiss: ()->Unit,
visitor: BetStatusBottomSheetDisplayBetVisitor
displayBet: @Composable (Bet) -> Unit
) {
AnimatedVisibility(
visible = sheetBackVisibility,
@ -37,7 +35,7 @@ fun BetStatusBottomSheet(
) {
bet?.let {
BetStatusBottomSheetBack(
status = it.bet.betStatus
status = it.betStatus
)
}
}
@ -51,7 +49,9 @@ fun BetStatusBottomSheet(
Column(
Modifier.fillMaxHeight(SHEET_HEIGHT)
) {
bet?.Accept(visitor)
bet?.let {
displayBet(it)
}
}
}
}

@ -1,6 +1,5 @@
package fr.iut.alldev.allin.ui.betStatus.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material3.*
@ -9,7 +8,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
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 androidx.compose.ui.unit.sp
@ -31,6 +29,7 @@ fun BetStatusParticipationBottomSheet(
onDismiss: () -> Unit,
state: SheetState,
onParticipate: () -> Unit,
content: @Composable () -> Unit
) {
val scope = rememberCoroutineScope()
AllInBottomSheet(
@ -61,7 +60,7 @@ fun BetStatusParticipationBottomSheet(
Spacer(modifier = Modifier.height(30.dp))
Text(
text = betPhrase,
style = AllInTheme.typography.s,
style = AllInTheme.typography.p2,
color = AllInTheme.themeColors.onMainSurface,
modifier = Modifier.padding(horizontal = 18.dp)
)
@ -81,7 +80,7 @@ fun BetStatusParticipationBottomSheet(
) {
Text(
text = stringResource(id = R.string.Possible_winnings),
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
color = AllInTheme.themeColors.onBackground
)
AllInCoinCount(
@ -89,6 +88,9 @@ fun BetStatusParticipationBottomSheet(
color = AllInTheme.themeColors.onBackground
)
}
Box(modifier = Modifier.fillMaxSize()) {
content()
}
AllInButton(
color = AllInTheme.colors.allInPurple,
text = stringResource(id = R.string.Participate),
@ -103,23 +105,4 @@ fun BetStatusParticipationBottomSheet(
}
}
}
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetStatusParticipationBottomSheetPreview() {
AllInTheme {
BetStatusParticipationBottomSheet(
sheetVisibility = true,
safeBottomPadding = 5.dp,
betPhrase = "Lorem Ipsum",
coinAmount = 125,
onDismiss = {},
state = rememberModalBottomSheetState(),
onParticipate = {}
)
}
}

@ -15,6 +15,7 @@ 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.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme
@ -41,7 +42,7 @@ fun BetStatusWinner(
) {
AllInTextIcon(
text = answer,
icon = Icons.Filled.EmojiEvents,
icon = rememberVectorPainter(image = Icons.Filled.EmojiEvents),
color = color,
size = 50,
iconSize = 60,
@ -57,13 +58,13 @@ fun BetStatusWinner(
)
AllInTextIcon(
text = username,
icon = Icons.Filled.People,
icon = rememberVectorPainter(image = Icons.Filled.People),
color = color,
position = IconPosition.LEADING
)
AllInTextIcon(
text = "x" + String.format("%.1f", multiplier),
icon = Icons.Filled.EmojiEvents,
icon = rememberVectorPainter(image = Icons.Filled.EmojiEvents),
color = color,
position = IconPosition.LEADING
)

@ -8,6 +8,7 @@ import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInTextIcon
@ -26,7 +27,7 @@ fun YesNoDetailsLine(
AllInTextIcon(
text = yesText,
color = AllInTheme.colors.allInBlue,
icon = icon,
icon = rememberVectorPainter(image = icon),
position = IconPosition.LEADING,
size = 10,
iconSize = 15
@ -34,7 +35,7 @@ fun YesNoDetailsLine(
AllInTextIcon(
text = noText,
color = AllInTheme.colors.allInBarPink,
icon = icon,
icon = rememberVectorPainter(image = icon),
position = IconPosition.TRAILING,
size = 10,
iconSize = 15

@ -45,7 +45,7 @@ fun YesNoStatBar(
) {
Text(
text = yesPercentage.toPercentageString(),
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
color = AllInTheme.colors.allInBarPurple
)
}

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betStatus.visitor
package fr.iut.alldev.allin.ui.betStatus.vo
import android.content.res.Configuration
import androidx.compose.foundation.background
@ -16,12 +16,14 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.ext.formatToMediumDateNoYear
import fr.iut.alldev.allin.data.ext.formatToTime
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.ext.getDateEndLabelId
@ -35,38 +37,32 @@ import fr.iut.alldev.allin.ui.core.AllInDetailsDrawer
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.bet.BetDateTimeRow
import fr.iut.alldev.allin.ui.core.bet.BetTitleHeader
import fr.iut.alldev.allin.vo.bet.factory.toBetVO
import fr.iut.alldev.allin.vo.bet.visitor.DisplayBetVisitor
import java.time.ZonedDateTime
import fr.iut.alldev.allin.ui.preview.BetWithStatusPreviewProvider
import fr.iut.alldev.allin.vo.bet.BetDisplayer
class BetStatusBottomSheetDisplayBetVisitor(
class BetStatusBottomSheetBetDisplayer(
val userCoinAmount: MutableIntState,
val onParticipate: (Int) -> Unit,
) : DisplayBetVisitor {
) : BetDisplayer {
val participateBottomSheetVisibility = mutableStateOf(false)
val paddingValues = mutableStateOf(PaddingValues())
@OptIn(ExperimentalMaterial3Api::class)
@Composable
override fun VisitYesNoBet(b: YesNoBet) {
override fun DisplayYesNoBet(b: YesNoBet) {
val (participateSheetVisibility, setParticipateSheetVisibility) = remember {
this.participateBottomSheetVisibility
}
val safeBottomPadding = paddingValues.value.calculateBottomPadding()
Box(
Modifier
.padding(bottom = safeBottomPadding)
) {
Box(Modifier.padding(bottom = safeBottomPadding)) {
Column {
Column(Modifier.padding(horizontal = 20.dp)) {
BetTitleHeader(
title = b.phrase,
category = b.theme,
creator = "Lucas" /*TODO : Creator*/,
creator = b.creator,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(20.dp))
@ -152,85 +148,37 @@ class BetStatusBottomSheetDisplayBetVisitor(
betPhrase = b.phrase,
coinAmount = userCoinAmount.intValue,
onDismiss = { setParticipateSheetVisibility(false) },
state = rememberModalBottomSheetState()
state = rememberModalBottomSheetState(),
onParticipate = {
onParticipate(100)
}
) {
onParticipate(100)
}
}
@Composable
override fun VisitMatchBet(b: MatchBet) {
override fun DisplayMatchBet(b: MatchBet) {
Text("This is a MATCH BET")
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun YesNoBetPreview() {
AllInTheme {
val coins = remember { mutableIntStateOf(100) }
YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.InProgress,
creator = "creator"
).toBetVO()?.Accept(
BetStatusBottomSheetDisplayBetVisitor(
userCoinAmount = coins,
onParticipate = {}
)
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun YesNoBetFinishedPreview() {
AllInTheme {
val coins = remember { mutableIntStateOf(100) }
YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.WON),
creator = "creator"
).toBetVO()?.Accept(
BetStatusBottomSheetDisplayBetVisitor(
userCoinAmount = coins,
onParticipate = {}
)
)
@Composable
override fun DisplayCustomBet(b: CustomBet) {
Text("This is a CUSTOM BET")
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun MatchBetPreview() {
private fun BetStatusBottomSheetPreview(
@PreviewParameter(BetWithStatusPreviewProvider::class) bet: Bet
) {
AllInTheme {
val coins = remember { mutableIntStateOf(100) }
MatchBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.InProgress,
nameTeam1 = "Team 1",
nameTeam2 = "Team 2",
creator = "creator"
).toBetVO()?.Accept(
BetStatusBottomSheetDisplayBetVisitor(
userCoinAmount = coins,
onParticipate = {}
)
)
BetStatusBottomSheetBetDisplayer(
userCoinAmount = coins,
onParticipate = {}
).DisplayBet(bet)
}
}

@ -32,7 +32,7 @@ fun AllInAlertDialog(
text = {
Text(
text = text,
style = AllInTheme.typography.r
style = AllInTheme.typography.p1
)
},
confirmButton = {

@ -18,6 +18,7 @@ fun AllInBottomSheet(
state: SheetState,
scrimColor: Color = BottomSheetDefaults.ScrimColor,
containerColor: Color = AllInTheme.themeColors.background,
dragHandle: (@Composable ()->Unit)? = { BottomSheetDefaults.DragHandle() },
content: @Composable ColumnScope.()->Unit
) {
val localDensity = LocalDensity.current
@ -38,6 +39,7 @@ fun AllInBottomSheet(
bottom = 0,
)
},
dragHandle = dragHandle,
content = content
)
}

@ -44,7 +44,7 @@ fun AllInChip(
.padding(vertical = 8.dp, horizontal = 22.dp)
.alpha(if (isSelected) 0f else 1f),
textAlign = TextAlign.Center,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
color = AllInTheme.themeColors.onBackground2
)
if (isSelected) {

@ -3,7 +3,9 @@ package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.theme.AllInTheme
@ -11,14 +13,20 @@ import fr.iut.alldev.allin.theme.AllInTheme
fun AllInCoinCount(
modifier: Modifier = Modifier,
amount: Int,
color: Color,
position: IconPosition = IconPosition.TRAILING,
color: Color? = null,
brush: Brush?= null,
size: Int = 15,
textStyle: TextStyle = AllInTheme.typography.h1,
position: IconPosition = IconPosition.TRAILING
) {
AllInTextIcon(
text = amount.toString(),
icon = AllInTheme.icons.allCoins(),
color = color,
color = color ?: Color.Black,
brush = brush,
position = position,
textStyle = textStyle,
size = size,
modifier = modifier
)
}

@ -51,7 +51,7 @@ fun AllInDatePicker(
Text(
text = stringResource(id = R.string.Cancel),
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.h3
style = AllInTheme.typography.sm1
)
}
},

@ -58,7 +58,7 @@ fun AllInDetailsDrawer(
) {
Text(
text = text,
style = AllInTheme.typography.s,
style = AllInTheme.typography.p2,
color = textColor,
fontSize = 15.sp
)

@ -12,7 +12,7 @@ import fr.iut.alldev.allin.theme.AllInTheme
fun AllInErrorLine(text: String) {
Text(
text = text,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
color = Color.Red,
fontSize = 10.sp,
overflow = TextOverflow.Ellipsis

@ -64,7 +64,7 @@ fun AllInRetractableCard(
fontStyle = AllInTheme.typography.h2.fontStyle
),
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 16.sp,
modifier = Modifier.weight(1f)
)

@ -20,14 +20,14 @@ fun AllInSectionButton(
onClick: (Int) -> Unit,
) {
val style = if (isSelected) {
AllInTheme.typography.h3.copy(
AllInTheme.typography.sm1.copy(
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.ExtraBold
)
} else {
AllInTheme.typography.h3.copy(
AllInTheme.typography.sm1.copy(
color = AllInTheme.themeColors.onBackground2,
fontSize = 15.sp,
textAlign = TextAlign.Center,

@ -90,7 +90,7 @@ fun AllInTextField(
Text(
text = placeholder,
fontSize = placeholderFontSize,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
color = placeholderColor,
maxLines = if (multiLine) 3 else 1,
overflow = TextOverflow.Ellipsis
@ -105,7 +105,7 @@ fun AllInTextField(
)
}
},
textStyle = AllInTheme.typography.r,
textStyle = AllInTheme.typography.p1,
enabled = enabled,
keyboardOptions = KeyboardOptions(keyboardType = keyboardType, imeAction = imeAction),
keyboardActions = keyboardActions,

@ -6,16 +6,17 @@ import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Fireplace
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
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.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.text.TextStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.LayoutDirection
import androidx.compose.ui.unit.dp
@ -34,6 +35,8 @@ fun AllInTextIcon(
text: String,
icon: Painter,
color: Color,
brush: Brush? = null,
textStyle: TextStyle = AllInTheme.typography.h1,
position: IconPosition = IconPosition.TRAILING,
size: Int = 15,
iconSize: Int = size,
@ -52,54 +55,15 @@ fun AllInTextIcon(
Text(
text = text,
color = color,
style = AllInTheme.typography.h1,
style = brush?.let { textStyle.copy(brush = it) } ?: textStyle,
fontSize = size.sp
)
Icon(
painter = icon,
contentDescription = null,
modifier = Modifier.size(iconSize.dp),
tint = color
)
}
}
}
}
@Composable
fun AllInTextIcon(
modifier: Modifier = Modifier,
text: String,
icon: ImageVector,
color: Color,
position: IconPosition = IconPosition.TRAILING,
size: Int = 15,
iconSize: Int = size,
) {
val direction =
if (position == IconPosition.LEADING) LayoutDirection.Rtl
else LayoutDirection.Ltr
Box(modifier) {
CompositionLocalProvider(
LocalLayoutDirection provides direction
) {
Row(
modifier = modifier,
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.spacedBy(7.dp)
) {
Text(
text = text,
color = color,
style = AllInTheme.typography.h1,
fontSize = size.sp
)
Icon(
imageVector = icon,
contentDescription = null,
modifier = Modifier.size(iconSize.dp),
tint = color
tint = color,
brush = brush
)
}
}
@ -112,7 +76,7 @@ private fun AllInTextIconPreview() {
AllInTheme {
AllInTextIcon(
text = "value",
icon = Icons.Default.Fireplace,
icon = rememberVectorPainter(image = Icons.Default.Fireplace),
color = AllInTheme.colors.allInBlue
)
}
@ -126,6 +90,7 @@ private fun AllInTextIconReversePreview() {
text = "value",
icon = AllInTheme.icons.allCoins(),
color = AllInTheme.colors.allInBlue,
brush = AllInTheme.colors.allInMainGradient,
position = IconPosition.LEADING
)
}

@ -46,7 +46,7 @@ fun AllInTimePicker(
Text(
text = stringResource(id = R.string.Cancel),
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.h3
style = AllInTheme.typography.sm1
)
}
},

@ -31,7 +31,7 @@ fun AllInTooltip(
Text(
text = text,
color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 12.sp
)
}
@ -121,7 +121,7 @@ private fun AllInTooltipPreview() {
Text(
text = "Généralement une question qui sera répondu par les utilisateurs.",
color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 10.sp
)
})

@ -0,0 +1,38 @@
package fr.iut.alldev.allin.ui.core
import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawWithCache
import androidx.compose.ui.graphics.BlendMode
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.CompositingStrategy
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.painter.Painter
@Composable
fun Icon(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current,
brush: Brush? = null,
) {
Icon(
painter = painter,
contentDescription = contentDescription,
modifier = brush?.let {
modifier
.graphicsLayer { compositingStrategy = CompositingStrategy.Offscreen }
.drawWithCache {
onDrawWithContent {
drawContent()
drawRect(brush, blendMode = BlendMode.SrcAtop)
}
}
} ?: modifier,
tint = tint
)
}

@ -0,0 +1,76 @@
package fr.iut.alldev.allin.ui.core.bet
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.ext.getDateStartLabelId
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
@Composable
fun BetCard(
modifier: Modifier = Modifier,
title: String,
creator: String,
category: String,
date: String,
time: String,
status: BetStatus,
content: @Composable () -> Unit
) {
AllInCard(
modifier = modifier.fillMaxWidth(),
radius = 16.dp
) {
Column(
Modifier.padding(horizontal = 19.dp, vertical = 11.dp)
) {
BetTitleHeader(
title = title,
category = category,
creator = creator,
modifier = Modifier.fillMaxWidth()
)
Spacer(modifier = Modifier.height(11.dp))
BetDateTimeRow(
label = stringResource(id = status.getDateStartLabelId()),
date = date,
time = time
)
}
HorizontalDivider(
thickness = 1.dp,
color = AllInTheme.themeColors.border
)
content()
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetCardPreview() {
AllInTheme {
BetCard(
creator = "Creator",
category = "Category",
title = "Title",
date = "Date",
time = "Time",
status = BetStatus.Waiting
){
Text("Content")
}
}
}

@ -29,7 +29,7 @@ fun BetDateTimeChip(
Text(
text = text,
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
color = AllInTheme.colors.allInPurple
)

@ -27,7 +27,7 @@ fun BetDateTimeRow(
Text(
text = label,
fontSize = 15.sp,
style = AllInTheme.typography.m,
style = AllInTheme.typography.sm2,
color = AllInTheme.themeColors.onBackground2
)
BetDateTimeChip(date)

@ -38,7 +38,7 @@ fun BetTitleHeader(
color = AllInTheme.themeColors.onMainSurface
),
fontSize = 12.sp,
style = AllInTheme.typography.s,
style = AllInTheme.typography.p2,
color = AllInTheme.themeColors.onBackground2
)
}
@ -47,7 +47,7 @@ fun BetTitleHeader(
text = category,
fontSize = 15.sp,
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.m
style = AllInTheme.typography.sm2
)
Text(
text = title,

@ -105,7 +105,7 @@ fun AllInSnackbarContent(
Text(
text = text,
color = contentColor,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
overflow = TextOverflow.Ellipsis,
maxLines = 5,
modifier = Modifier.weight(1f)

@ -84,7 +84,7 @@ fun LoginScreen(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Login_title),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp
)
@ -93,7 +93,7 @@ fun LoginScreen(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Login_subtitle),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
textAlign = TextAlign.Center,
fontSize = 23.sp
)
@ -122,7 +122,7 @@ fun LoginScreen(
}
ClickableText(
text = AnnotatedString(stringResource(id = R.string.forgot_password)),
style = AllInTheme.typography.m.copy(
style = AllInTheme.typography.sm2.copy(
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
),
@ -156,12 +156,12 @@ fun LoginScreen(
text = stringResource(id = R.string.no_account),
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Register)),
style = AllInTheme.typography.r.copy(
style = AllInTheme.typography.p1.copy(
color = AllInTheme.colors.allInPurple,
fontSize = 15.sp,
fontWeight = FontWeight.Bold

@ -11,8 +11,9 @@ import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betResult.BetResultBottomSheet
import fr.iut.alldev.allin.ui.betStatus.BetStatusBottomSheet
import fr.iut.alldev.allin.ui.betStatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.betStatus.vo.BetStatusBottomSheetBetDisplayer
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.core.snackbar.AllInSnackbarVisualsImpl
import fr.iut.alldev.allin.ui.main.components.AllInScaffold
@ -21,7 +22,6 @@ import fr.iut.alldev.allin.ui.navigation.Routes
import fr.iut.alldev.allin.ui.navigation.TopLevelDestination
import fr.iut.alldev.allin.ui.navigation.drawer.AllInDrawer
import fr.iut.alldev.allin.ui.navigation.popUpTo
import fr.iut.alldev.allin.vo.bet.factory.toBetVO
import kotlinx.coroutines.launch
private val topLevelDestinations = listOf(
@ -68,10 +68,12 @@ fun MainScreen(
var loading by remember { mainViewModel.loading }
val currentUser = remember { mainViewModel.currentUserState }
val (selectedBet, setSelectedBet) = remember { mainViewModel.selectedBet }
val (wonBet, setWonBet) = remember { mainViewModel.wonBet }
val (statusVisibility, sheetBackVisibility, setStatusVisibility) = rememberBetStatusVisibilities()
val (displayResult, setDisplayResult ) = remember{ mutableStateOf(true) }
val betStatusDisplayVisitor = remember {
BetStatusBottomSheetDisplayBetVisitor(
val betStatusDisplayer = remember {
BetStatusBottomSheetBetDisplayer(
userCoinAmount = currentUser.userCoins,
onParticipate = {
mainViewModel.participateToBet(it)
@ -100,7 +102,7 @@ fun MainScreen(
}
}
val bottomSheetState = rememberModalBottomSheetState(
val statusBottomSheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true,
confirmValueChange = {
if (it == SheetValue.Hidden) {
@ -110,6 +112,10 @@ fun MainScreen(
}
)
val resultBottomSheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true
)
AllInDrawer(
drawerState = drawerState,
destinations = topLevelDestinations,
@ -133,7 +139,7 @@ fun MainScreen(
snackbarHostState = snackbarHostState
) {
LaunchedEffect(key1 = it) {
betStatusDisplayVisitor.paddingValues.value = it
betStatusDisplayer.paddingValues.value = it
}
Column(
modifier = Modifier
@ -146,7 +152,7 @@ fun MainScreen(
navController = navController,
selectBet = { bet, participate ->
setSelectedBet(bet)
betStatusDisplayVisitor.participateBottomSheetVisibility.value = participate
betStatusDisplayer.participateBottomSheetVisibility.value = participate
setStatusVisibility(true)
},
setLoading = { loading = it },
@ -156,15 +162,29 @@ fun MainScreen(
}
}
wonBet?.let {
BetResultBottomSheet(
state = resultBottomSheetState,
sheetVisibility = displayResult,
onDismiss = { setDisplayResult(false) },
bet = wonBet,
username = currentUser.user.username,
coinAmount = 1630,
stake = 1630,
winnings = 1630,
odds = 3.62f
)
}
BetStatusBottomSheet(
state = bottomSheetState,
state = statusBottomSheetState,
sheetVisibility = statusVisibility.value,
sheetBackVisibility = sheetBackVisibility.value,
onDismiss = {
setStatusVisibility(false)
},
bet = selectedBet?.toBetVO(),
visitor = betStatusDisplayVisitor
bet = selectedBet,
displayBet = { betStatusDisplayer.DisplayBet(it) }
)
AllInLoading(visible = loading)
BackHandler(

@ -8,12 +8,16 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import fr.iut.alldev.allin.data.model.User
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.di.AllInCurrentUser
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
import fr.iut.alldev.allin.ui.core.snackbar.SnackbarType
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import java.time.ZonedDateTime
import javax.inject.Inject
class UserState(val user: User) {
@ -30,6 +34,17 @@ class MainViewModel @Inject constructor(
val currentUserState = UserState(currentUser)
val selectedBet = mutableStateOf<Bet?>(null)
val wonBet = mutableStateOf<Bet?>(
YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.WON),
creator = "creator"
)
)
val snackbarContent: MutableState<SnackbarContent?> by lazy { mutableStateOf(null) }
fun putSnackbarContent(content: SnackbarContent) {

@ -74,7 +74,7 @@ fun AllInDrawer(
) {
Text(
text = stringResource(id = R.string.Logout),
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
color = AllInTheme.colors.allInDarkGrey50,
fontSize = 16.sp
)

@ -56,7 +56,7 @@ fun DrawerCell(
)
Text(
text = subtitle,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
fontSize = 9.sp,
color = AllInTheme.colors.allInLightGrey300,
)

@ -23,7 +23,7 @@ fun DrawerHeaderStat(
Text(
text = label,
color = AllInTheme.colors.allInLightGrey300,
style = AllInTheme.typography.r
style = AllInTheme.typography.p1
)
}
}

@ -0,0 +1,51 @@
package fr.iut.alldev.allin.ui.preview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import java.time.ZonedDateTime
class BetPreviewProvider: PreviewParameterProvider<Bet> {
override val values = sequenceOf(
YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.WON),
creator = "creator"
),
MatchBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.WON),
creator = "creator",
nameTeam1 = "The Monarchs",
nameTeam2 = "Climate Change"
),
CustomBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.WON),
creator = "creator",
possibleAnswers = setOf(
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
)
),
)
}

@ -1,14 +0,0 @@
package fr.iut.alldev.allin.ui.preview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.BetStatus
class BetStatusPreviewProvider: PreviewParameterProvider<BetStatus> {
override val values = sequenceOf(
BetStatus.InProgress,
BetStatus.Waiting,
BetStatus.Finished(BetFinishedStatus.WON),
BetStatus.Finished(BetFinishedStatus.LOST)
)
}

@ -0,0 +1,8 @@
package fr.iut.alldev.allin.ui.preview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import fr.iut.alldev.allin.data.model.bet.BetStatus
class BetStatusPreviewProvider : PreviewParameterProvider<BetStatus> {
override val values = BetStatus.entries
}

@ -0,0 +1,53 @@
package fr.iut.alldev.allin.ui.preview
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import java.time.ZonedDateTime
class BetWithStatusPreviewProvider : PreviewParameterProvider<Bet> {
override val values = BetStatus.entries.flatMap { status ->
sequenceOf(
YesNoBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = status,
creator = "creator"
),
MatchBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = status,
creator = "creator",
nameTeam1 = "The Monarchs",
nameTeam2 = "Climate Change"
),
CustomBet(
theme = "Theme",
phrase = "Phrase",
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = status,
creator = "creator",
possibleAnswers = setOf(
"Answer 1",
"Answer 2",
"Answer 3",
"Answer 4"
)
)
)
}
}

@ -89,7 +89,7 @@ fun RegisterScreen(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Hello_x, username),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp,
overflow = TextOverflow.Ellipsis,
@ -99,7 +99,7 @@ fun RegisterScreen(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_title),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center,
fontSize = 40.sp
)
@ -108,7 +108,7 @@ fun RegisterScreen(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_subtitle),
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
textAlign = TextAlign.Center,
fontSize = 23.sp
)
@ -184,12 +184,12 @@ fun RegisterScreen(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.r.copy(
style = AllInTheme.typography.p1.copy(
color = AllInTheme.colors.allInPurple,
fontSize = 15.sp,
fontWeight = FontWeight.Bold

@ -88,7 +88,7 @@ fun WelcomeScreen(
text = stringResource(id = R.string.welcome_subtitle),
color = AllInTheme.themeColors.onBackground,
fontSize = 15.sp,
style = AllInTheme.typography.r
style = AllInTheme.typography.p1
)
Spacer(modifier = Modifier.height(78.dp))
AllInButton(
@ -106,12 +106,12 @@ fun WelcomeScreen(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
style = AllInTheme.typography.r,
style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp)
)
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.r.copy(
style = AllInTheme.typography.p1.copy(
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
fontWeight = FontWeight.Bold

@ -1,8 +0,0 @@
package fr.iut.alldev.allin.vo
import androidx.compose.runtime.Composable
interface ViewObject<V : Visitor>{
@Composable
fun Accept(v: V)
}

@ -1,3 +0,0 @@
package fr.iut.alldev.allin.vo
interface Visitor

@ -0,0 +1,27 @@
package fr.iut.alldev.allin.vo.bet
import androidx.compose.runtime.Composable
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.CustomBet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
interface BetDisplayer {
@Composable
fun DisplayBet(bet: Bet){
when(bet){
is CustomBet -> DisplayCustomBet(bet)
is MatchBet -> DisplayMatchBet(bet)
is YesNoBet -> DisplayYesNoBet(bet)
}
}
@Composable
fun DisplayYesNoBet(b: YesNoBet)
@Composable
fun DisplayMatchBet(b: MatchBet)
@Composable
fun DisplayCustomBet(b: CustomBet)
}

@ -1,28 +0,0 @@
package fr.iut.alldev.allin.vo.bet
import androidx.compose.runtime.Composable
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.vo.ViewObject
import fr.iut.alldev.allin.vo.bet.visitor.DisplayBetVisitor
abstract class BetVO<T: Bet>(val bet: T)
: ViewObject<DisplayBetVisitor> {
@Composable
abstract override fun Accept(v: DisplayBetVisitor)
}
class YesNoBetVO(bet: YesNoBet) : BetVO<YesNoBet>(bet){
@Composable
override fun Accept(v: DisplayBetVisitor){
v.VisitYesNoBet(b = bet)
}
}
class MatchBetVO(bet: MatchBet) : BetVO<MatchBet>(bet){
@Composable
override fun Accept(v: DisplayBetVisitor){
v.VisitMatchBet(b = bet)
}
}

@ -1,30 +0,0 @@
package fr.iut.alldev.allin.vo.bet.factory
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.vo.bet.BetVO
import fr.iut.alldev.allin.vo.bet.MatchBetVO
import fr.iut.alldev.allin.vo.bet.YesNoBetVO
private val betTypeToVOMap = mapOf(
YesNoBet::class.java to YesNoBetVOFactory(),
MatchBet::class.java to MatchBetVOFactory()
)
abstract class BetVOFactory<out T : Bet> {
abstract fun create(bet: @UnsafeVariance T): BetVO<@UnsafeVariance T>
}
class YesNoBetVOFactory : BetVOFactory<YesNoBet>() {
override fun create(bet: YesNoBet) =
YesNoBetVO(bet)
}
class MatchBetVOFactory : BetVOFactory<MatchBet>() {
override fun create(bet: MatchBet) =
MatchBetVO(bet)
}
fun Bet.toBetVO() = betTypeToVOMap[this.javaClass]?.create(this)

@ -1,15 +0,0 @@
package fr.iut.alldev.allin.vo.bet.visitor
import androidx.compose.runtime.Composable
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.vo.Visitor
interface DisplayBetVisitor : Visitor {
@Composable
fun VisitYesNoBet(b: YesNoBet)
@Composable
fun VisitMatchBet(b: MatchBet)
}

File diff suppressed because it is too large Load Diff

@ -126,4 +126,10 @@
<string name="bet_history_status_won">%s [icon] gagnés !</string>
<string name="bet_history_status_lost">%s [icon] perdus !</string>
<!--Bet result-->
<string name="bet_result_congratulations">FÉLICITATIONS</string>
<string name="bet_result_you_win">Vous remportez</string>
<string name="bet_result_odds">Cote totale</string>
<string name="bet_result_stake">Mise</string>
<string name="bet_result_winnings">Gains</string>
</resources>

@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<array name="com_google_android_gms_fonts_certs">
<item>@array/com_google_android_gms_fonts_certs_dev</item>
<item>@array/com_google_android_gms_fonts_certs_prod</item>
</array>
<string-array name="com_google_android_gms_fonts_certs_dev">
<item>
MIIEqDCCA5CgAwIBAgIJANWFuGx90071MA0GCSqGSIb3DQEBBAUAMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTAeFw0wODA0MTUyMzM2NTZaFw0zNTA5MDEyMzM2NTZaMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbTCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBANbOLggKv+IxTdGNs8/TGFy0PTP6DHThvbbR24kT9ixcOd9W+EaBPWW+wPPKQmsHxajtWjmQwWfna8mZuSeJS48LIgAZlKkpFeVyxW0qMBujb8X8ETrWy550NaFtI6t9+u7hZeTfHwqNvacKhp1RbE6dBRGWynwMVX8XW8N1+UjFaq6GCJukT4qmpN2afb8sCjUigq0GuMwYXrFVee74bQgLHWGJwPmvmLHC69EH6kWr22ijx4OKXlSIx2xT1AsSHee70w5iDBiK4aph27yH3TxkXy9V89TDdexAcKk/cVHYNnDBapcavl7y0RiQ4biu8ymM8Ga/nmzhRKya6G0cGw8CAQOjgfwwgfkwHQYDVR0OBBYEFI0cxb6VTEM8YYY6FbBMvAPyT+CyMIHJBgNVHSMEgcEwgb6AFI0cxb6VTEM8YYY6FbBMvAPyT+CyoYGapIGXMIGUMQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEQMA4GA1UEChMHQW5kcm9pZDEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDEiMCAGCSqGSIb3DQEJARYTYW5kcm9pZEBhbmRyb2lkLmNvbYIJANWFuGx90071MAwGA1UdEwQFMAMBAf8wDQYJKoZIhvcNAQEEBQADggEBABnTDPEF+3iSP0wNfdIjIz1AlnrPzgAIHVvXxunW7SBrDhEglQZBbKJEk5kT0mtKoOD1JMrSu1xuTKEBahWRbqHsXclaXjoBADb0kkjVEJu/Lh5hgYZnOjvlba8Ld7HCKePCVePoTJBdI4fvugnL8TsgK05aIskyY0hKI9L8KfqfGTl1lzOv2KoWD0KWwtAWPoGChZxmQ+nBli+gwYMzM1vAkP+aayLe0a1EQimlOalO762r0GXO0ks+UeXde2Z4e+8S/pf7pITEI/tP+MxJTALw9QUWEv9lKTk+jkbqxbsh8nfBUapfKqYn0eidpwq2AzVp3juYl7//fKnaPhJD9gs=
</item>
</string-array>
<string-array name="com_google_android_gms_fonts_certs_prod">
<item>
MIIEQzCCAyugAwIBAgIJAMLgh0ZkSjCNMA0GCSqGSIb3DQEBBAUAMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDAeFw0wODA4MjEyMzEzMzRaFw0zNjAxMDcyMzEzMzRaMHQxCzAJBgNVBAYTAlVTMRMwEQYDVQQIEwpDYWxpZm9ybmlhMRYwFAYDVQQHEw1Nb3VudGFpbiBWaWV3MRQwEgYDVQQKEwtHb29nbGUgSW5jLjEQMA4GA1UECxMHQW5kcm9pZDEQMA4GA1UEAxMHQW5kcm9pZDCCASAwDQYJKoZIhvcNAQEBBQADggENADCCAQgCggEBAKtWLgDYO6IIrgqWbxJOKdoR8qtW0I9Y4sypEwPpt1TTcvZApxsdyxMJZ2JORland2qSGT2y5b+3JKkedxiLDmpHpDsz2WCbdxgxRczfey5YZnTJ4VZbH0xqWVW/8lGmPav5xVwnIiJS6HXk+BVKZF+JcWjAsb/GEuq/eFdpuzSqeYTcfi6idkyugwfYwXFU1+5fZKUaRKYCwkkFQVfcAs1fXA5V+++FGfvjJ/CxURaSxaBvGdGDhfXE28LWuT9ozCl5xw4Yq5OGazvV24mZVSoOO0yZ31j7kYvtwYK6NeADwbSxDdJEqO4k//0zOHKrUiGYXtqw/A0LFFtqoZKFjnkCAQOjgdkwgdYwHQYDVR0OBBYEFMd9jMIhF1Ylmn/Tgt9r45jk14alMIGmBgNVHSMEgZ4wgZuAFMd9jMIhF1Ylmn/Tgt9r45jk14aloXikdjB0MQswCQYDVQQGEwJVUzETMBEGA1UECBMKQ2FsaWZvcm5pYTEWMBQGA1UEBxMNTW91bnRhaW4gVmlldzEUMBIGA1UEChMLR29vZ2xlIEluYy4xEDAOBgNVBAsTB0FuZHJvaWQxEDAOBgNVBAMTB0FuZHJvaWSCCQDC4IdGZEowjTAMBgNVHRMEBTADAQH/MA0GCSqGSIb3DQEBBAUAA4IBAQBt0lLO74UwLDYKqs6Tm8/yzKkEu116FmH4rkaymUIE0P9KaMftGlMexFlaYjzmB2OxZyl6euNXEsQH8gjwyxCUKRJNexBiGcCEyj6z+a1fuHHvkiaai+KL8W1EyNmgjmyy8AW7P+LLlkR+ho5zEHatRbM/YAnqGcFh5iZBqpknHf1SKMXFh4dd239FJ1jWYfbMDMy3NS5CTMQ2XFI1MvcyUTdZPErjQfTbQe3aDQsQcafEQPD+nqActifKZ0Np0IS9L9kR/wbNvyz6ENwPiTrjV2KRkEjH78ZMcUQXg0L3BYHJ3lc69Vs5Ddf9uUGGMYldX3WfMBEmh/9iFBDAaTCK
</item>
</string-array>
</resources>

@ -126,4 +126,12 @@
<string name="bet_history_status_won">%s [icon] won !</string>
<string name="bet_history_status_lost">%s [icon] lost !</string>
<!--Bet result-->
<string name="bet_result_congratulations">CONGRATULATIONS</string>
<string name="bet_result_you_win">You win</string>
<string name="bet_result_odds">Total odds</string>
<string name="bet_result_stake">Stake</string>
<string name="bet_result_winnings">Winnings</string>
</resources>

@ -21,7 +21,7 @@ interface AllInApi {
suspend fun login(@Header("Authorization") token: String): ResponseUser
@POST("bets/add")
suspend fun createBet(@Body body: RequestBet)
suspend fun createBet(@Header("Authorization") token: String, @Body body: RequestBet)
@GET("bets/gets")
suspend fun getAllBets(): List<ResponseBet>

@ -55,6 +55,5 @@ data class RequestBet(
@Serializable(SimpleDateSerializer::class) val endRegistration: ZonedDateTime,
@Serializable(SimpleDateSerializer::class) var endBet: ZonedDateTime,
var isPrivate: Boolean,
var response: List<String>,
val createdBy: String
var response: List<String>
)

@ -3,7 +3,7 @@ package fr.iut.alldev.allin.data.model.bet
import fr.iut.alldev.allin.data.api.model.RequestBet
import java.time.ZonedDateTime
abstract class Bet(
sealed class Bet(
open val id: Int? = null,
open val creator: String,
open val theme: String,
@ -21,8 +21,7 @@ abstract class Bet(
endRegistration = endRegisterDate,
endBet = endBetDate,
isPrivate = !isPublic,
response = getResponses(),
createdBy = creator
response = getResponses()
)
}
}

@ -6,4 +6,14 @@ sealed class BetStatus {
data object InProgress : BetStatus()
data object Waiting : BetStatus()
companion object {
val entries = sequenceOf(
InProgress,
Waiting,
Finished(BetFinishedStatus.WON),
Finished(BetFinishedStatus.LOST)
)
}
}

@ -16,7 +16,8 @@ class BetRepositoryImpl @Inject constructor(
) : BetRepository() {
override suspend fun createBet(bet: Bet, token: String) {
api.createBet(
bet.toRequestBet().copy(createdBy = token)
token = token,
body = bet.toRequestBet()
)
}

@ -1,12 +1,8 @@
package fr.iut.alldev.allin.data.di
import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import javax.inject.Singleton
@Module(includes = [ReleaseNetworkModule::class])
@InstallIn(SingletonComponent::class)

@ -4,8 +4,8 @@ import dagger.Module
import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import fr.iut.alldev.allin.data.api.interceptors.ErrorInterceptor
import okhttp3.OkHttpClient
import okhttp3.logging.HttpLoggingInterceptor
import javax.inject.Singleton
@Module

@ -10,9 +10,10 @@ kotlin = "1.9.20"
androidxCore = "1.12.0"
androidxActivity = "1.8.2"
androidxSecurity = "1.0.0"
androidxSecurity = "1.1.0-alpha06"
composeBom = "2023.10.01"
compose = "1.5.4"
composePreview = "1.6.0-beta03"
composeCompiler = "1.5.5"
composeNavigation = "2.7.6"
@ -31,7 +32,7 @@ room = "2.6.1"
okHttp = "4.11.0"
# Plugins
gradlePlugin = "8.1.2"
gradlePlugin = "8.1.4"
publishPlugin = "1.1"
resgenPlugin = "2.5"
@ -54,6 +55,9 @@ test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version
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-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-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest", version.ref = "compose" }
# Compose
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
@ -95,7 +99,6 @@ plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.
plugin-kotlinSerialization = { module = "org.jetbrains.kotlin:kotlin-serialization", version.ref = "kotlin" }
plugin-hilt = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hilt" }
[bundles]
android = ["androidx-core", "androidx-activity", "androidx-security"]

Binary file not shown.

@ -0,0 +1,4 @@
debugStoreFile=../keys/debug.keystore
releaseStoreFile=../keys/release.keystore
aliasRelease=placeYourBets
passwordRelease=placeYourBets

Binary file not shown.
Loading…
Cancel
Save