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 // Keystore
val keystorePropertiesFile = rootProject.file("app/keys/keystore.properties") val keystorePropertiesFile = rootProject.file("keys/keystore.properties")
val keystoreProperties = Properties() val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile)) keystoreProperties.load(FileInputStream(keystorePropertiesFile))
@ -33,11 +33,16 @@ android {
} }
} }
signingConfigs { signingConfigs {
named(BuildType.DEBUG.name) {
storeFile = file(keystoreProperties["debugStoreFile"].toString())
}
register(BuildType.RELEASE.name) { register(BuildType.RELEASE.name) {
storeFile = file(keystoreProperties["store"].toString()) storeFile = file(keystoreProperties["releaseStoreFile"].toString())
storePassword = keystoreProperties["password"].toString() storePassword = keystoreProperties["passwordRelease"].toString()
keyPassword = keystoreProperties["password"].toString() keyAlias = keystoreProperties["aliasRelease"].toString()
keyPassword = keystoreProperties["passwordRelease"].toString()
} }
} }
@ -102,5 +107,6 @@ dependencies {
androidTestImplementation(libs.test.androidx.junit) androidTestImplementation(libs.test.androidx.junit)
androidTestImplementation(libs.hilt.androidTesting) androidTestImplementation(libs.hilt.androidTesting)
kaptAndroidTest(libs.hilt.androidCompiler) 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 # If you keep the line number information, uncomment this to
# hide the original source file name. # 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 package fr.iut.alldev.allin.test.mock
import fr.iut.alldev.allin.data.model.bet.BetStatus 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.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet import fr.iut.alldev.allin.data.model.bet.YesNoBet
import java.time.ZonedDateTime import java.time.ZonedDateTime
@ -14,7 +15,8 @@ object Bets {
endRegisterDate = ZonedDateTime.now(), endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(), endBetDate = ZonedDateTime.now(),
isPublic = true, isPublic = true,
betStatus = BetStatus.InProgress betStatus = BetStatus.InProgress,
creator = "creator",
), ),
MatchBet( MatchBet(
theme = "Theme", theme = "Theme",
@ -24,7 +26,23 @@ object Bets {
isPublic = true, isPublic = true,
betStatus = BetStatus.InProgress, betStatus = BetStatus.InProgress,
nameTeam1 = "Team_1", 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.test.mock.Bets
import fr.iut.alldev.allin.ui.MainActivity import fr.iut.alldev.allin.ui.MainActivity
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.vo.bet.factory.toBetVO import fr.iut.alldev.allin.vo.bet.displayer.BetTestDisplayer
import fr.iut.alldev.allin.vo.bet.visitor.BetTestVisitor
import org.junit.Before import org.junit.Before
import org.junit.Rule import org.junit.Rule
import org.junit.Test import org.junit.Test
@ -30,37 +29,55 @@ class BetVOTest {
} }
companion object { companion object {
val visitor = BetTestVisitor() val displayer = BetTestDisplayer()
} }
@Test @Test
fun testVisitor_shouldDisplayYesNoBetUI(){ fun testDisplayer_shouldDisplayYesNoBetUI(){
//Given //Given
//When //When
composeTestRule.activity.setContent { composeTestRule.activity.setContent {
AllInTheme{ AllInTheme{
Bets.bets[0].toBetVO()?.Accept(v = visitor) displayer.DisplayBet(Bets.bets[0])
} }
} }
//Expect //Expect
composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertExists() composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertExists()
composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertDoesNotExist() composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertDoesNotExist()
composeTestRule.onNodeWithTag(TestTags.CUSTOM_BET.tag).assertDoesNotExist()
} }
@Test @Test
fun testVisitor_shouldDisplayMatchUI(){ fun testDisplayer_shouldDisplayMatchUI(){
//Given //Given
//When //When
composeTestRule.activity.setContent { composeTestRule.activity.setContent {
AllInTheme{ AllInTheme{
Bets.bets[1].toBetVO()?.Accept(v = visitor) displayer.DisplayBet(Bets.bets[1])
} }
} }
//Expect //Expect
composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertExists() composeTestRule.onNodeWithTag(TestTags.MATCH_BET.tag).assertExists()
composeTestRule.onNodeWithTag(TestTags.YES_NO_BET.tag).assertDoesNotExist() 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.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.testTag 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.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.test.TestTags import fr.iut.alldev.allin.test.TestTags
import fr.iut.alldev.allin.vo.bet.BetDisplayer
class BetTestVisitor : DisplayBetVisitor { class BetTestDisplayer : BetDisplayer {
@Composable @Composable
override fun VisitYesNoBet(b: YesNoBet) { override fun DisplayYesNoBet(b: YesNoBet) {
Text("This is a YesNo Bet", Modifier.testTag(TestTags.YES_NO_BET.tag)) Text("This is a YesNo Bet", Modifier.testTag(TestTags.YES_NO_BET.tag))
} }
@Composable @Composable
override fun VisitMatchBet(b: MatchBet) { override fun DisplayMatchBet(b: MatchBet) {
Text("This is a Match Bet", Modifier.testTag(TestTags.MATCH_BET.tag)) 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 package fr.iut.alldev.allin.keystore
import androidx.security.crypto.MasterKeys import androidx.security.crypto.MasterKey
abstract class AllInKeystoreManager { abstract class AllInKeystoreManager {
val masterKeyAlias = MasterKeys.getOrCreate(MasterKeys.AES256_GCM_SPEC) protected abstract val masterKey: MasterKey
abstract fun createKeystore() abstract fun createKeystore()
abstract fun putToken(token: String) abstract fun putToken(token: String)
abstract fun getToken(): String? abstract fun getToken(): String?

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

@ -2,5 +2,6 @@ package fr.iut.alldev.allin.test
enum class TestTags(val tag: String) { enum class TestTags(val tag: String) {
YES_NO_BET("YES_NO"), 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 allInBetInProgressText: Color,
val allInBetWaitingText: Color, val allInBetWaitingText: Color,
val allInMainGradient: Brush, val allInMainGradient: Brush,
val allInMainGradientReverse: Brush,
val allInBar1stGradient: Brush, val allInBar1stGradient: Brush,
val allInBar2ndGradient: Brush, val allInBar2ndGradient: Brush,
val allInTextGradient: Brush, val allInTextGradient: Brush,
@ -73,6 +74,7 @@ internal val LocalColors = staticCompositionLocalOf {
allInBetInProgressText = Color.Unspecified, allInBetInProgressText = Color.Unspecified,
allInBetWaitingText = Color.Unspecified, allInBetWaitingText = Color.Unspecified,
allInMainGradient = SolidColor(Color.Unspecified), allInMainGradient = SolidColor(Color.Unspecified),
allInMainGradientReverse = SolidColor(Color.Unspecified),
allInBar1stGradient = SolidColor(Color.Unspecified), allInBar1stGradient = SolidColor(Color.Unspecified),
allInBar2ndGradient = SolidColor(Color.Unspecified), allInBar2ndGradient = SolidColor(Color.Unspecified),
allInTextGradient = SolidColor(Color.Unspecified), allInTextGradient = SolidColor(Color.Unspecified),

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

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

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

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

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

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

@ -1,24 +1,13 @@
package fr.iut.alldev.allin.ui.betHistory.components package fr.iut.alldev.allin.ui.betHistory.components
import android.content.res.Configuration 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.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.model.bet.BetStatus 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.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard import fr.iut.alldev.allin.ui.core.bet.BetCard
import fr.iut.alldev.allin.ui.core.bet.BetDateTimeRow
import fr.iut.alldev.allin.ui.core.bet.BetTitleHeader
import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider
@Composable @Composable
@ -32,30 +21,15 @@ fun BetHistoryScreenCard(
status: BetStatus, status: BetStatus,
nbCoins: Int, nbCoins: Int,
) { ) {
AllInCard( BetCard(
modifier = modifier.fillMaxWidth(), title = title,
radius = 16.dp 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( BetHistoryBetStatus(
status = status, status = status,
nbCoins = nbCoins 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 androidx.compose.ui.graphics.Color
import fr.iut.alldev.allin.data.model.bet.Bet 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.components.BetStatusBottomSheetBack
import fr.iut.alldev.allin.ui.betStatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.core.AllInBottomSheet import fr.iut.alldev.allin.ui.core.AllInBottomSheet
import fr.iut.alldev.allin.vo.bet.BetVO
internal const val SHEET_HEIGHT = .85f internal const val SHEET_HEIGHT = .85f
@ -22,9 +20,9 @@ fun BetStatusBottomSheet(
state: SheetState, state: SheetState,
sheetVisibility: Boolean, sheetVisibility: Boolean,
sheetBackVisibility: Boolean, sheetBackVisibility: Boolean,
bet: BetVO<Bet>?, bet: Bet?,
onDismiss: ()->Unit, onDismiss: ()->Unit,
visitor: BetStatusBottomSheetDisplayBetVisitor displayBet: @Composable (Bet) -> Unit
) { ) {
AnimatedVisibility( AnimatedVisibility(
visible = sheetBackVisibility, visible = sheetBackVisibility,
@ -37,7 +35,7 @@ fun BetStatusBottomSheet(
) { ) {
bet?.let { bet?.let {
BetStatusBottomSheetBack( BetStatusBottomSheetBack(
status = it.bet.betStatus status = it.betStatus
) )
} }
} }
@ -51,7 +49,9 @@ fun BetStatusBottomSheet(
Column( Column(
Modifier.fillMaxHeight(SHEET_HEIGHT) Modifier.fillMaxHeight(SHEET_HEIGHT)
) { ) {
bet?.Accept(visitor) bet?.let {
displayBet(it)
}
} }
} }
} }

@ -1,6 +1,5 @@
package fr.iut.alldev.allin.ui.betStatus.components package fr.iut.alldev.allin.ui.betStatus.components
import android.content.res.Configuration
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.material3.* import androidx.compose.material3.*
@ -9,7 +8,6 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.Dp import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp import androidx.compose.ui.unit.sp
@ -31,6 +29,7 @@ fun BetStatusParticipationBottomSheet(
onDismiss: () -> Unit, onDismiss: () -> Unit,
state: SheetState, state: SheetState,
onParticipate: () -> Unit, onParticipate: () -> Unit,
content: @Composable () -> Unit
) { ) {
val scope = rememberCoroutineScope() val scope = rememberCoroutineScope()
AllInBottomSheet( AllInBottomSheet(
@ -61,7 +60,7 @@ fun BetStatusParticipationBottomSheet(
Spacer(modifier = Modifier.height(30.dp)) Spacer(modifier = Modifier.height(30.dp))
Text( Text(
text = betPhrase, text = betPhrase,
style = AllInTheme.typography.s, style = AllInTheme.typography.p2,
color = AllInTheme.themeColors.onMainSurface, color = AllInTheme.themeColors.onMainSurface,
modifier = Modifier.padding(horizontal = 18.dp) modifier = Modifier.padding(horizontal = 18.dp)
) )
@ -81,7 +80,7 @@ fun BetStatusParticipationBottomSheet(
) { ) {
Text( Text(
text = stringResource(id = R.string.Possible_winnings), text = stringResource(id = R.string.Possible_winnings),
style = AllInTheme.typography.r, style = AllInTheme.typography.p1,
color = AllInTheme.themeColors.onBackground color = AllInTheme.themeColors.onBackground
) )
AllInCoinCount( AllInCoinCount(
@ -89,6 +88,9 @@ fun BetStatusParticipationBottomSheet(
color = AllInTheme.themeColors.onBackground color = AllInTheme.themeColors.onBackground
) )
} }
Box(modifier = Modifier.fillMaxSize()) {
content()
}
AllInButton( AllInButton(
color = AllInTheme.colors.allInPurple, color = AllInTheme.colors.allInPurple,
text = stringResource(id = R.string.Participate), 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.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.rememberVectorPainter
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme import fr.iut.alldev.allin.theme.AllInTheme
@ -41,7 +42,7 @@ fun BetStatusWinner(
) { ) {
AllInTextIcon( AllInTextIcon(
text = answer, text = answer,
icon = Icons.Filled.EmojiEvents, icon = rememberVectorPainter(image = Icons.Filled.EmojiEvents),
color = color, color = color,
size = 50, size = 50,
iconSize = 60, iconSize = 60,
@ -57,13 +58,13 @@ fun BetStatusWinner(
) )
AllInTextIcon( AllInTextIcon(
text = username, text = username,
icon = Icons.Filled.People, icon = rememberVectorPainter(image = Icons.Filled.People),
color = color, color = color,
position = IconPosition.LEADING position = IconPosition.LEADING
) )
AllInTextIcon( AllInTextIcon(
text = "x" + String.format("%.1f", multiplier), text = "x" + String.format("%.1f", multiplier),
icon = Icons.Filled.EmojiEvents, icon = rememberVectorPainter(image = Icons.Filled.EmojiEvents),
color = color, color = color,
position = IconPosition.LEADING position = IconPosition.LEADING
) )

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

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

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

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

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

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

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

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

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

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

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

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

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

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

@ -31,7 +31,7 @@ fun AllInTooltip(
Text( Text(
text = text, text = text,
color = AllInTheme.colors.allInLightGrey200, color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r, style = AllInTheme.typography.p1,
fontSize = 12.sp fontSize = 12.sp
) )
} }
@ -121,7 +121,7 @@ private fun AllInTooltipPreview() {
Text( Text(
text = "Généralement une question qui sera répondu par les utilisateurs.", text = "Généralement une question qui sera répondu par les utilisateurs.",
color = AllInTheme.colors.allInLightGrey200, color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r, style = AllInTheme.typography.p1,
fontSize = 10.sp 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 = text, text = text,
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp), modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
style = AllInTheme.typography.h3, style = AllInTheme.typography.sm1,
textAlign = TextAlign.Center, textAlign = TextAlign.Center,
color = AllInTheme.colors.allInPurple color = AllInTheme.colors.allInPurple
) )

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

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

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

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

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

@ -8,12 +8,16 @@ import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel import dagger.hilt.android.lifecycle.HiltViewModel
import fr.iut.alldev.allin.data.model.User 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.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.di.AllInCurrentUser
import fr.iut.alldev.allin.keystore.AllInKeystoreManager import fr.iut.alldev.allin.keystore.AllInKeystoreManager
import fr.iut.alldev.allin.ui.core.snackbar.SnackbarType import fr.iut.alldev.allin.ui.core.snackbar.SnackbarType
import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext import kotlinx.coroutines.withContext
import java.time.ZonedDateTime
import javax.inject.Inject import javax.inject.Inject
class UserState(val user: User) { class UserState(val user: User) {
@ -30,6 +34,17 @@ class MainViewModel @Inject constructor(
val currentUserState = UserState(currentUser) val currentUserState = UserState(currentUser)
val selectedBet = mutableStateOf<Bet?>(null) 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) } val snackbarContent: MutableState<SnackbarContent?> by lazy { mutableStateOf(null) }
fun putSnackbarContent(content: SnackbarContent) { fun putSnackbarContent(content: SnackbarContent) {

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

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

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

@ -88,7 +88,7 @@ fun WelcomeScreen(
text = stringResource(id = R.string.welcome_subtitle), text = stringResource(id = R.string.welcome_subtitle),
color = AllInTheme.themeColors.onBackground, color = AllInTheme.themeColors.onBackground,
fontSize = 15.sp, fontSize = 15.sp,
style = AllInTheme.typography.r style = AllInTheme.typography.p1
) )
Spacer(modifier = Modifier.height(78.dp)) Spacer(modifier = Modifier.height(78.dp))
AllInButton( AllInButton(
@ -106,12 +106,12 @@ fun WelcomeScreen(
text = stringResource(id = R.string.already_have_account), text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.tint1, color = AllInTheme.themeColors.tint1,
fontSize = 15.sp, fontSize = 15.sp,
style = AllInTheme.typography.r, style = AllInTheme.typography.p1,
modifier = Modifier.padding(end = 5.dp) modifier = Modifier.padding(end = 5.dp)
) )
ClickableText( ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)), text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.r.copy( style = AllInTheme.typography.p1.copy(
color = AllInTheme.themeColors.tint1, color = AllInTheme.themeColors.tint1,
fontSize = 15.sp, fontSize = 15.sp,
fontWeight = FontWeight.Bold 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_won">%s [icon] gagnés !</string>
<string name="bet_history_status_lost">%s [icon] perdus !</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> </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_won">%s [icon] won !</string>
<string name="bet_history_status_lost">%s [icon] lost !</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> </resources>

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

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

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

@ -6,4 +6,14 @@ sealed class BetStatus {
data object InProgress : BetStatus() data object InProgress : BetStatus()
data object Waiting : 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() { ) : BetRepository() {
override suspend fun createBet(bet: Bet, token: String) { override suspend fun createBet(bet: Bet, token: String) {
api.createBet( api.createBet(
bet.toRequestBet().copy(createdBy = token) token = token,
body = bet.toRequestBet()
) )
} }

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

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

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