Add bet history and current bets

pull/3/head
Arthur VALIN 1 year ago
parent c97bf42cb6
commit 304508fa8c

@ -7,7 +7,7 @@
<option name="testRunner" value="GRADLE" />
<option name="distributionType" value="DEFAULT_WRAPPED" />
<option name="externalProjectPath" value="$PROJECT_DIR$" />
<option name="gradleJvm" value="Android Studio default JDK" />
<option name="gradleJvm" value="jbr-17" />
<option name="modules">
<set>
<option value="$PROJECT_DIR$" />

@ -1,4 +1,3 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ExternalStorageConfigurationManager" enabled="true" />
<component name="ProjectRootManager" version="2" languageLevel="JDK_17" default="true" project-jdk-name="jbr-17" project-jdk-type="JavaSDK">

@ -1,105 +0,0 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id "kotlin-kapt"
id "dagger.hilt.android.plugin"
}
def keystorePropertiesFile = rootProject.file("app/keys/keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
release {
storeFile file(keystoreProperties['store'])
storePassword keystoreProperties['password']
keyPassword keystoreProperties['password']
}
}
namespace 'fr.iut.alldev.allin'
compileSdk 34
defaultConfig {
applicationId "fr.iut.alldev.allin"
minSdk 26
targetSdk 34
versionCode 1
versionName "1.0"
testInstrumentationRunner "fr.iut.alldev.allin.TestRunner"
vectorDrawables {
useSupportLibrary true
}
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.2.0'
}
packagingOptions {
resources {
excludes += '/META-INF/{AL2.0,LGPL2.1}'
}
}
}
dependencies {
implementation project(path: ':data')
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.lifecycle:lifecycle-runtime-ktx:2.6.2'
implementation 'androidx.activity:activity-compose:1.7.2'
implementation "androidx.compose.ui:ui:$compose_version"
implementation "androidx.compose.ui:ui-tooling-preview:$compose_version"
implementation 'androidx.compose.material3:material3:1.2.0-alpha08'
implementation "androidx.compose.material:material:1.5.3"
implementation "androidx.navigation:navigation-compose:2.7.3"
implementation 'androidx.compose.material:material-icons-core'
implementation 'androidx.compose.material:material-icons-extended'
//Tests
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
androidTestImplementation "androidx.compose.ui:ui-test-junit4:$compose_version"
androidTestImplementation "com.google.dagger:hilt-android-testing:$hilt_version"
kaptAndroidTest "com.google.dagger:hilt-android-compiler:$hilt_version"
debugImplementation "androidx.compose.ui:ui-tooling:$compose_version"
debugImplementation "androidx.compose.ui:ui-test-manifest:$compose_version"
implementation("androidx.core:core-splashscreen:1.0.1")
//Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
implementation "androidx.hilt:hilt-navigation-compose:1.0.0"
// Smooth Corners
implementation 'com.github.racra:smooth-corner-rect-android-compose:v1.0.0'
//Timber
implementation 'com.jakewharton.timber:timber:5.0.1'
}

@ -0,0 +1,103 @@
import org.gradle.language.nativeplatform.internal.BuildType
import java.io.FileInputStream
import java.util.Properties
plugins {
id("com.android.application")
id("kotlin-android")
id("kotlin-kapt")
id("dagger.hilt.android.plugin")
}
// Keystore
val keystorePropertiesFile = rootProject.file("app/keys/keystore.properties")
val keystoreProperties = Properties()
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
android {
namespace = "fr.iut.alldev.allin"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
applicationId = "fr.iut.alldev.allin"
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
versionCode = 1
versionName = "1.0"
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables {
useSupportLibrary = true
}
}
signingConfigs {
register(BuildType.RELEASE.name) {
storeFile = file(keystoreProperties["store"].toString())
storePassword = keystoreProperties["password"].toString()
keyPassword = keystoreProperties["password"].toString()
}
}
buildTypes {
debug {
isMinifyEnabled = false
versionNameSuffix = "-debug"
applicationIdSuffix = ".debug"
signingConfig = signingConfigs.getByName(BuildType.DEBUG.name)
}
release {
isMinifyEnabled = true
isShrinkResources = true
signingConfig = signingConfigs.getByName(BuildType.RELEASE.name)
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
buildFeatures {
compose = true
buildConfig = true
}
composeOptions {
kotlinCompilerExtensionVersion = libs.versions.composeCompiler.get()
}
packaging {
resources {
excludes += "/META-INF/{AL2.0,LGPL2.1}"
}
}
}
dependencies {
implementation(project(":data"))
// Android
implementation(libs.bundles.android)
// Lifecycle
implementation(libs.bundles.androidx.lifecycle)
// Compose
implementation(platform(libs.compose.bom))
implementation(libs.bundles.compose)
// Hilt
implementation(libs.hilt.android)
kapt(libs.hilt.compiler)
implementation(libs.hilt.navigation.compose)
// Timber
implementation(libs.timber)
// Squircle
implementation(libs.smoothCornerRect)
// Tests
testImplementation(libs.test.junit)
androidTestImplementation(libs.test.junit)
androidTestImplementation(libs.test.espresso)
androidTestImplementation(libs.test.androidx.junit)
}

@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

@ -6,7 +6,7 @@ import fr.iut.alldev.allin.data.model.bet.YesNoBet
import java.time.ZonedDateTime
object Bets {
val bets by lazy{
val bets by lazy {
listOf(
YesNoBet(
theme = "Theme",
@ -14,7 +14,7 @@ object Bets {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.IN_PROGRESS
betStatus = BetStatus.InProgress
),
MatchBet(
theme = "Theme",
@ -22,7 +22,7 @@ object Bets {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.IN_PROGRESS,
betStatus = BetStatus.InProgress,
nameTeam1 = "Team_1",
nameTeam2 = "Team_2"
),

@ -1,29 +1,37 @@
package fr.iut.alldev.allin.ext
import androidx.annotation.StringRes
import androidx.compose.runtime.Composable
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus.LOST
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus.WON
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.theme.AllInTheme
fun BetStatus.getTitle(): Int {
@StringRes
fun BetStatus.getTitleId(): Int {
return when (this) {
BetStatus.FINISHED -> R.string.bet_status_finished
BetStatus.IN_PROGRESS -> R.string.bet_status_in_progress
BetStatus.WAITING -> R.string.bet_status_waiting
is BetStatus.Finished -> R.string.bet_status_finished
BetStatus.InProgress -> R.string.bet_status_in_progress
BetStatus.Waiting -> R.string.bet_status_waiting
}
}
fun BetStatus.getDateStartLabel(): Int {
@StringRes
fun BetStatus.getDateStartLabelId(): Int {
return when (this) {
BetStatus.FINISHED -> R.string.Started
is BetStatus.Finished -> R.string.Started
else -> R.string.Starting
}
}
fun BetStatus.getDateEndLabel(): Int {
@StringRes
fun BetStatus.getDateEndLabelId(): Int {
return when (this) {
BetStatus.FINISHED -> R.string.Ended
is BetStatus.Finished -> R.string.Ended
else -> R.string.Ends
}
}
@ -31,17 +39,41 @@ fun BetStatus.getDateEndLabel(): Int {
@Composable
fun BetStatus.getColor(): Color {
return when (this) {
BetStatus.FINISHED -> AllInTheme.colors.allIn_BetFinish
BetStatus.IN_PROGRESS -> AllInTheme.colors.allIn_BetInProgress
BetStatus.WAITING -> AllInTheme.colors.allIn_BetWaiting
is BetStatus.Finished -> AllInTheme.colors.allInBetFinish
BetStatus.InProgress -> AllInTheme.colors.allInBetInProgress
BetStatus.Waiting -> AllInTheme.colors.allInBetWaiting
}
}
@Composable
fun BetStatus.getTextColor(): Color {
return when (this) {
BetStatus.FINISHED -> AllInTheme.colors.allIn_BetFinishText
BetStatus.IN_PROGRESS -> AllInTheme.colors.allIn_BetInProgressText
BetStatus.WAITING -> AllInTheme.colors.allIn_BetWaitingText
is BetStatus.Finished -> AllInTheme.colors.allInBetFinishText
BetStatus.InProgress -> AllInTheme.colors.allInBetInProgressText
BetStatus.Waiting -> AllInTheme.colors.allInBetWaitingText
}
}
@StringRes
fun BetStatus.getBetHistoryPhrase(): Int {
return when (this) {
is BetStatus.Finished -> when (this.status) {
WON -> R.string.bet_history_status_won
LOST -> R.string.bet_history_status_lost
}
else -> R.string.bet_history_status_in_progress
}
}
@Composable
fun BetStatus.getBetHistoryStatusColor(): Brush {
return when (this) {
is BetStatus.Finished -> when (this.status) {
WON -> AllInTheme.colors.allInMainGradient
LOST -> AllInTheme.colors.allInDarkGradient
}
else -> SolidColor(AllInTheme.colors.allInDarkGrey100)
}
}

@ -1,5 +1,6 @@
package fr.iut.alldev.allin.ext
import androidx.annotation.StringRes
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.HelpOutline
import androidx.compose.material.icons.filled.Edit
@ -8,7 +9,8 @@ import androidx.compose.ui.graphics.vector.ImageVector
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetType
fun BetType.getTitle(): Int {
@StringRes
fun BetType.getTitleId(): Int {
return when (this) {
BetType.YES_NO -> R.string.yes_no
BetType.MATCH -> R.string.sport_match

@ -10,33 +10,33 @@ const val ALLOWED_SYMBOLS = "~`!@#\$%^&*()_-+={[}]|\\:;\"'<,>.?/"
sealed class FieldErrorState(
private val messageId: Int? = null,
private val messageArgs:Array<out Any> = emptyArray()
){
object NoError: FieldErrorState()
private vararg val messageArgs: Any,
) {
data object NoError : FieldErrorState()
data class TooShort(val fieldName: String, val minChar: Int)
: FieldErrorState(R.string.FieldError_TooShort, arrayOf(fieldName, minChar))
data class TooShort(val fieldName: String, val minChar: Int) :
FieldErrorState(R.string.FieldError_TooShort, fieldName, minChar)
data class BadFormat(val fieldName: String, val format: String)
: FieldErrorState(R.string.FieldError_BadFormat, arrayOf(fieldName, format))
data class BadFormat(val fieldName: String, val format: String) :
FieldErrorState(R.string.FieldError_BadFormat, fieldName, format)
object NotIdentical: FieldErrorState(R.string.FieldError_NotIdentical)
data object NotIdentical : FieldErrorState(R.string.FieldError_NotIdentical)
data class NoSpecialCharacter(val fieldName: String, val characters: String = ALLOWED_SYMBOLS) :
FieldErrorState(R.string.FieldError_NoSpecialCharacter, arrayOf(fieldName, characters))
FieldErrorState(R.string.FieldError_NoSpecialCharacter, fieldName, characters)
data class AlreadyUsed(val value: String) :
FieldErrorState(R.string.FieldError_AlreadyUsed, arrayOf(value))
FieldErrorState(R.string.FieldError_AlreadyUsed, value)
data class PastDate(val fieldName: String)
: FieldErrorState(R.string.FieldError_PastDate, arrayOf(fieldName))
data class DateOrder(val fieldName1: String, val fieldName2: String)
: FieldErrorState(R.string.FieldError_DateOrder, arrayOf(fieldName1, fieldName2))
data class PastDate(val fieldName: String) :
FieldErrorState(R.string.FieldError_PastDate, fieldName)
data class DateOrder(val fieldName1: String, val fieldName2: String) :
FieldErrorState(R.string.FieldError_DateOrder, fieldName1, fieldName2)
@Composable
fun errorResource() = stringResourceOrNull(id = messageId, messageArgs)
fun errorResource() = stringResourceOrNull(id = messageId, *messageArgs)
}
fun String.isEmail() = Patterns.EMAIL_ADDRESS.matcher(this).matches()
@ -44,7 +44,7 @@ fun String.isEmail() = Patterns.EMAIL_ADDRESS.matcher(this).matches()
fun String.containsCharacter(characters: CharSequence): Boolean {
var contains = false
characters.forEach {
if(this.contains(it)){
if (this.contains(it)) {
contains = true
return@forEach
}
@ -54,7 +54,7 @@ fun String.containsCharacter(characters: CharSequence): Boolean {
@Composable
fun stringResourceOrNull(@StringRes id: Int?, args: Array<out Any>) = id?.let {
fun stringResourceOrNull(@StringRes id: Int?, vararg args: Any) = id?.let {
stringResource(id = id, *args)
}

@ -2,128 +2,110 @@ package fr.iut.alldev.allin.theme
import androidx.compose.runtime.Immutable
import androidx.compose.runtime.staticCompositionLocalOf
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
@Immutable
data class AllInColors(
val allIn_Dark: Color,
val allIn_DarkGrey300: Color,
val allIn_DarkGrey200: Color,
val allIn_DarkGrey100: Color,
val allIn_DarkGrey50: Color,
val allIn_Grey: Color,
val allIn_LightGrey300: Color,
val allIn_LightGrey200: Color,
val allIn_LightGrey100: Color,
val allIn_LightGrey50: Color,
val allIn_White: Color,
val allInDark: Color,
val allInDarkGrey300: Color,
val allInDarkGrey200: Color,
val allInDarkGrey100: Color,
val allInDarkGrey50: Color,
val allInGrey: Color,
val allInLightGrey300: Color,
val allInLightGrey200: Color,
val allInLightGrey100: Color,
val allInLightGrey50: Color,
val allInWhite: Color,
val white: Color,
val black: Color,
val allIn_Pink: Color,
val allIn_Mint: Color,
val allIn_Purple: Color,
val allIn_LoginPurple: Color,
val allIn_Blue: Color,
val allIn_DarkBlue: Color,
val allIn_BarPurple: Color,
val allIn_BarPink: Color,
val allIn_BetFinish: Color,
val allIn_BetInProgress: Color,
val allIn_BetWaiting: Color,
val allIn_BetFinishText: Color,
val allIn_BetInProgressText: Color,
val allIn_BetWaitingText: Color,
val allIn_MainGradient: Brush,
val allIn_Bar1stGradient: Brush,
val allIn_Bar2ndGradient: Brush,
val allIn_TextGradient: Brush,
val allIn_LoginGradient: Brush
val allInPink: Color,
val allInMint: Color,
val allInPurple: Color,
val allInLoginPurple: Color,
val allInBlue: Color,
val allInDarkBlue: Color,
val allInBarPurple: Color,
val allInBarPink: Color,
val allInBetFinish: Color,
val allInBetInProgress: Color,
val allInBetWaiting: Color,
val allInBetFinishText: Color,
val allInBetInProgressText: Color,
val allInBetWaitingText: Color,
val allInMainGradient: Brush,
val allInBar1stGradient: Brush,
val allInBar2ndGradient: Brush,
val allInTextGradient: Brush,
val allInLoginGradient: Brush,
val allInDarkGradient: Brush,
)
internal val LocalColors = staticCompositionLocalOf {
AllInColors(
allIn_Dark = Color.Unspecified,
allIn_DarkGrey300 = Color.Unspecified,
allIn_DarkGrey200 = Color.Unspecified,
allIn_DarkGrey100 = Color.Unspecified,
allIn_DarkGrey50 = Color.Unspecified,
allIn_Grey = Color.Unspecified,
allIn_LightGrey300 = Color.Unspecified,
allIn_LightGrey200 = Color.Unspecified,
allIn_LightGrey100 = Color.Unspecified,
allIn_LightGrey50 = Color.Unspecified,
allIn_White = Color.Unspecified,
allInDark = Color.Unspecified,
allInDarkGrey300 = Color.Unspecified,
allInDarkGrey200 = Color.Unspecified,
allInDarkGrey100 = Color.Unspecified,
allInDarkGrey50 = Color.Unspecified,
allInGrey = Color.Unspecified,
allInLightGrey300 = Color.Unspecified,
allInLightGrey200 = Color.Unspecified,
allInLightGrey100 = Color.Unspecified,
allInLightGrey50 = Color.Unspecified,
allInWhite = Color.Unspecified,
white = Color.Unspecified,
black = Color.Unspecified,
allIn_Pink = Color.Unspecified,
allIn_Purple = Color.Unspecified,
allIn_LoginPurple = Color.Unspecified,
allIn_BarPurple = Color.Unspecified,
allIn_BarPink = Color.Unspecified,
allIn_Blue = Color.Unspecified,
allIn_Mint = Color.Unspecified,
allIn_DarkBlue = Color.Unspecified,
allIn_BetFinish = Color.Unspecified,
allIn_BetInProgress = Color.Unspecified,
allIn_BetWaiting = Color.Unspecified,
allIn_BetFinishText = Color.Unspecified,
allIn_BetInProgressText = Color.Unspecified,
allIn_BetWaitingText = Color.Unspecified,
allIn_MainGradient = Brush.linearGradient(
0.0f to Color(0xFFf951a8),
0.5f to Color(0xFFaa7ef3),
1.0f to Color(0xFF199fee),
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
),
allIn_Bar1stGradient = Brush.horizontalGradient(
0.0f to Color(0xFF2599F8),
1.0f to Color(0xFF846AC9)
),
allIn_Bar2ndGradient = Brush.horizontalGradient(
0.0f to Color(0xFFFE2B8A),
1.0f to Color(0xFFC249A8)
),
allIn_TextGradient = Brush.horizontalGradient(
0.0f to Color(0xFFF876C1),
1.0f to Color(0xFF2399F8)
),
allIn_LoginGradient = Brush.linearGradient(
0.0f to Color(0xFFEC1794),
0.5f to Color(0xFFaa7ef3),
1.0f to Color(0xFF00EEEE),
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
)
allInPink = Color.Unspecified,
allInPurple = Color.Unspecified,
allInLoginPurple = Color.Unspecified,
allInBarPurple = Color.Unspecified,
allInBarPink = Color.Unspecified,
allInBlue = Color.Unspecified,
allInMint = Color.Unspecified,
allInDarkBlue = Color.Unspecified,
allInBetFinish = Color.Unspecified,
allInBetInProgress = Color.Unspecified,
allInBetWaiting = Color.Unspecified,
allInBetFinishText = Color.Unspecified,
allInBetInProgressText = Color.Unspecified,
allInBetWaitingText = Color.Unspecified,
allInMainGradient = SolidColor(Color.Unspecified),
allInBar1stGradient = SolidColor(Color.Unspecified),
allInBar2ndGradient = SolidColor(Color.Unspecified),
allInTextGradient = SolidColor(Color.Unspecified),
allInLoginGradient = SolidColor(Color.Unspecified),
allInDarkGradient = SolidColor(Color.Unspecified)
)
}
@Immutable
data class AllInThemeColors(
val main_surface: Color,
val on_main_surface: Color,
val mainSurface: Color,
val onMainSurface: Color,
val background: Color,
val on_background: Color,
val tint_1: Color,
val background_2: Color,
val on_background_2: Color,
val onBackground: Color,
val tint1: Color,
val background2: Color,
val onBackground2: Color,
val border: Color,
val disabled: Color,
val disabled_border: Color
val disabledBorder: Color,
)
internal val LocalThemeColors = staticCompositionLocalOf {
AllInThemeColors(
main_surface = Color.Unspecified,
on_main_surface = Color.Unspecified,
mainSurface = Color.Unspecified,
onMainSurface = Color.Unspecified,
background = Color.Unspecified,
on_background = Color.Unspecified,
tint_1 = Color.Unspecified,
background_2 = Color.Unspecified,
on_background_2 = Color.Unspecified,
onBackground = Color.Unspecified,
tint1 = Color.Unspecified,
background2 = Color.Unspecified,
onBackground2 = Color.Unspecified,
border = Color.Unspecified,
disabled = Color.Unspecified,
disabled_border = Color.Unspecified
disabledBorder = Color.Unspecified
)
}

@ -17,62 +17,66 @@ import fr.iut.alldev.allin.R
@Composable
fun AllInTheme(
content: @Composable () -> Unit
) {
content: @Composable () -> Unit,
) {
val customColors = AllInColors(
allIn_Dark = Color(0xFF2A2A2A),
allIn_DarkGrey300 = Color(0xFF1c1c1c),
allIn_DarkGrey200 = Color(0xFF262626),
allIn_DarkGrey100 = Color(0xFF393939),
allIn_DarkGrey50 = Color(0xFF454545),
allIn_Grey = Color(0xFF525252),
allIn_LightGrey300 = Color(0XFFAAAAAA),
allIn_LightGrey200 = Color(0XFFC5C5C5),
allIn_LightGrey100 = Color(0XFFEBEBEB),
allIn_LightGrey50 = Color(0XFFF7F7F7),
allIn_White = Color(0xFFEBEBF6),
allInDark = Color(0xFF2A2A2A),
allInDarkGrey300 = Color(0xFF1c1c1c),
allInDarkGrey200 = Color(0xFF262626),
allInDarkGrey100 = Color(0xFF393939),
allInDarkGrey50 = Color(0xFF454545),
allInGrey = Color(0xFF525252),
allInLightGrey300 = Color(0XFFAAAAAA),
allInLightGrey200 = Color(0XFFC5C5C5),
allInLightGrey100 = Color(0XFFEBEBEB),
allInLightGrey50 = Color(0XFFF7F7F7),
allInWhite = Color(0xFFEBEBF6),
white = Color(0xFFFFFFFF),
black = Color(0xFF000000),
allIn_Pink = Color(0xFFFF2A89),
allIn_Purple = Color(0xFF7D79FF),
allIn_LoginPurple = Color(0xFF7F7BFB),
allIn_BarPurple = Color(0xFF846AC9),
allIn_BarPink = Color(0xFFFE2B8A),
allIn_Blue = Color(0xFF6a89fa),
allIn_Mint = Color(0xFFC4DEE9),
allIn_DarkBlue = Color(0xFF323078),
allIn_BetFinish = Color(0xFF353535),
allIn_BetInProgress = Color(0xFF604BDB),
allIn_BetWaiting = Color(0xFFDF3B9A),
allIn_BetFinishText = Color(0xFFA7A7A7),
allIn_BetInProgressText = Color(0xFF4636A3),
allIn_BetWaitingText = Color(0xFF852E6C),
allIn_MainGradient = Brush.linearGradient(
allInPink = Color(0xFFFF2A89),
allInPurple = Color(0xFF7D79FF),
allInLoginPurple = Color(0xFF7F7BFB),
allInBarPurple = Color(0xFF846AC9),
allInBarPink = Color(0xFFFE2B8A),
allInBlue = Color(0xFF6a89fa),
allInMint = Color(0xFFC4DEE9),
allInDarkBlue = Color(0xFF323078),
allInBetFinish = Color(0xFF353535),
allInBetInProgress = Color(0xFF604BDB),
allInBetWaiting = Color(0xFFDF3B9A),
allInBetFinishText = Color(0xFFA7A7A7),
allInBetInProgressText = Color(0xFF4636A3),
allInBetWaitingText = Color(0xFF852E6C),
allInMainGradient = Brush.linearGradient(
0.0f to Color(0xFFf951a8),
0.5f to Color(0xFFaa7ef3),
1.0f to Color(0xFF199fee),
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
),
allIn_Bar1stGradient = Brush.horizontalGradient(
allInBar1stGradient = Brush.horizontalGradient(
0.0f to Color(0xFF2599F8),
1.0f to Color(0xFF846AC9)
),
allIn_Bar2ndGradient = Brush.horizontalGradient(
allInBar2ndGradient = Brush.horizontalGradient(
0.0f to Color(0xFFFE2B8A),
1.0f to Color(0xFFC249A8)
),
allIn_TextGradient = Brush.horizontalGradient(
allInTextGradient = Brush.horizontalGradient(
0.0f to Color(0xFFF876C1),
1.0f to Color(0xFF2399F8)
),
allIn_LoginGradient = Brush.linearGradient(
allInLoginGradient = Brush.linearGradient(
0.0f to Color(0xFFEC1794),
0.5f to Color(0xFFaa7ef3),
1.0f to Color(0xFF00EEEE),
start = Offset(0f, Float.POSITIVE_INFINITY),
end = Offset(Float.POSITIVE_INFINITY, 0f)
),
allInDarkGradient = Brush.horizontalGradient(
0.0f to Color(0xFF595959),
1.0f to Color(0xFF000000)
)
)
@ -107,31 +111,31 @@ fun AllInTheme(
)
)
val customTheme = if(isSystemInDarkTheme()){
val customTheme = if (isSystemInDarkTheme()) {
AllInThemeColors(
main_surface = customColors.allIn_DarkGrey300,
on_main_surface = customColors.allIn_White,
background = customColors.allIn_DarkGrey200,
on_background = customColors.white,
tint_1 = customColors.white,
background_2 = customColors.allIn_Dark,
on_background_2 = customColors.allIn_LightGrey200,
border = customColors.allIn_DarkGrey100,
disabled = customColors.allIn_DarkGrey200,
disabled_border = customColors.allIn_DarkGrey100
mainSurface = customColors.allInDarkGrey300,
onMainSurface = customColors.allInWhite,
background = customColors.allInDarkGrey200,
onBackground = customColors.white,
tint1 = customColors.white,
background2 = customColors.allInDark,
onBackground2 = customColors.allInLightGrey200,
border = customColors.allInDarkGrey100,
disabled = customColors.allInDarkGrey200,
disabledBorder = customColors.allInDarkGrey100
)
}else{
} else {
AllInThemeColors(
main_surface = customColors.allIn_White,
on_main_surface = customColors.allIn_Dark,
mainSurface = customColors.allInWhite,
onMainSurface = customColors.allInDark,
background = customColors.white,
on_background = customColors.allIn_DarkBlue,
tint_1 = customColors.allIn_LoginPurple,
background_2 = customColors.allIn_LightGrey50,
on_background_2 = customColors.allIn_LightGrey300,
border = customColors.allIn_LightGrey100,
disabled = customColors.allIn_LightGrey100,
disabled_border = customColors.allIn_LightGrey200
onBackground = customColors.allInDarkBlue,
tint1 = customColors.allInLoginPurple,
background2 = customColors.allInLightGrey50,
onBackground2 = customColors.allInLightGrey300,
border = customColors.allInLightGrey100,
disabled = customColors.allInLightGrey100,
disabledBorder = customColors.allInLightGrey200
)
}
@ -145,7 +149,7 @@ fun AllInTheme(
LocalIcons provides customIcons,
LocalTypography provides customTypography,
LocalThemeColors provides customTheme
){
) {
content()
}
}

@ -3,7 +3,13 @@ package fr.iut.alldev.allin.ui.bet
import androidx.compose.animation.core.animateFloatAsState
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.LazyRow
import androidx.compose.foundation.lazy.items
@ -11,7 +17,12 @@ import androidx.compose.material.ExperimentalMaterialApi
import androidx.compose.material.pullrefresh.PullRefreshIndicator
import androidx.compose.material.pullrefresh.pullRefresh
import androidx.compose.material.pullrefresh.rememberPullRefreshState
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Brush
@ -22,13 +33,14 @@ import androidx.compose.ui.unit.dp
import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R
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.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.bet.components.BetScreenCard
import fr.iut.alldev.allin.ui.bet.components.BetScreenPopularCard
import fr.iut.alldev.allin.ui.core.AllInChip
import fr.iut.alldev.allin.theme.AllInTheme
import java.time.ZonedDateTime
private val bets = listOf(
@ -38,7 +50,7 @@ private val bets = listOf(
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.WAITING
betStatus = BetStatus.Waiting
),
YesNoBet(
theme = "Études",
@ -46,7 +58,7 @@ private val bets = listOf(
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.IN_PROGRESS
betStatus = BetStatus.InProgress
),
YesNoBet(
theme = "Études",
@ -54,7 +66,7 @@ private val bets = listOf(
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.FINISHED
betStatus = BetStatus.Finished(BetFinishedStatus.WON)
),
MatchBet(
theme = "Études",
@ -62,7 +74,7 @@ private val bets = listOf(
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.WAITING,
betStatus = BetStatus.Waiting,
nameTeam1 = "Team 1",
nameTeam2 = "Team 2"
),
@ -72,17 +84,15 @@ private val bets = listOf(
@Composable
fun BetScreen(
viewModel: BetViewModel = hiltViewModel(),
selectBet: (Bet, Boolean)->Unit
){
selectBet: (Bet, Boolean) -> Unit,
) {
val horizontalPadding = 23.dp
val refreshing by viewModel.isRefreshing.collectAsState()
val pullRefreshState = rememberPullRefreshState(refreshing, { viewModel.refresh() })
val progressAnimation by animateFloatAsState(
pullRefreshState.progress*15
)
val progressAnimation by animateFloatAsState(pullRefreshState.progress * 15, label = "")
LazyColumn(
Modifier
@ -90,7 +100,7 @@ fun BetScreen(
.padding(top = with(LocalDensity.current) {
progressAnimation.toDp()
})
){
) {
item {
Box(
Modifier.fillMaxWidth()
@ -113,42 +123,42 @@ fun BetScreen(
}
}
stickyHeader {
LazyRow(
modifier = Modifier
.background(
Brush.verticalGradient(
0.5f to AllInTheme.themeColors.main_surface,
1f to Color.Transparent
)
LazyRow(
modifier = Modifier
.background(
Brush.verticalGradient(
0.5f to AllInTheme.themeColors.mainSurface,
1f to Color.Transparent
)
.padding(top = 5.dp, bottom = 19.dp),
horizontalArrangement = Arrangement.spacedBy(9.dp)
) {
item {
Spacer(modifier = Modifier.width(horizontalPadding))
}
items(items) {
var isSelected by remember { mutableStateOf(false) }
AllInChip(
text = stringResource(id = it),
isSelected = isSelected,
onClick = {
isSelected = !isSelected
})
}
item {
Spacer(modifier = Modifier.width(horizontalPadding))
}
)
.padding(top = 5.dp, bottom = 19.dp),
horizontalArrangement = Arrangement.spacedBy(9.dp)
) {
item {
Spacer(modifier = Modifier.width(horizontalPadding))
}
items(items) {
var isSelected by remember { mutableStateOf(false) }
AllInChip(
text = stringResource(id = it),
isSelected = isSelected,
onClick = {
isSelected = !isSelected
})
}
item {
Spacer(modifier = Modifier.width(horizontalPadding))
}
}
}
items(bets){
items(bets) {
BetScreenCard(
creator = "Lucas",
category = "Études",
title = "Emre va réussir son TP de CI/CD mercredi?",
date = "11 Sept.",
time = "13:00",
players = List(3){ null },
players = List(3) { null },
onClickParticipate = { selectBet(it, true) },
onClickCard = { selectBet(it, false) },
modifier = Modifier.padding(horizontal = horizontalPadding)

@ -1,15 +1,19 @@
package fr.iut.alldev.allin.ui.bet.components
import android.content.res.Configuration
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.foundation.layout.width
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Alignment.Companion.CenterHorizontally
import androidx.compose.ui.ExperimentalComposeUiApi
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.res.pluralStringResource
@ -17,14 +21,13 @@ 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.AllInBouncyCard
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.BetProfilePictureRow
import fr.iut.alldev.allin.ui.core.bet.BetTitleHeader
import fr.iut.alldev.allin.theme.AllInTheme
@OptIn(ExperimentalComposeUiApi::class, ExperimentalFoundationApi::class)
@Composable
fun BetScreenCard(
creator: String,
@ -34,14 +37,14 @@ fun BetScreenCard(
time: String,
players: List<Painter?>,
modifier: Modifier = Modifier,
onClickParticipate: ()->Unit,
onClickCard: ()->Unit
onClickParticipate: () -> Unit,
onClickCard: () -> Unit,
) {
AllInBouncyCard(
modifier = modifier.fillMaxWidth(),
radius = 16.dp,
onClick = onClickCard
){
) {
Column(
Modifier.padding(horizontal = 19.dp, vertical = 11.dp)
) {
@ -60,14 +63,14 @@ fun BetScreenCard(
)
Column(
Modifier
.background(AllInTheme.themeColors.background_2)
.background(AllInTheme.themeColors.background2)
) {
Row(
modifier = Modifier
.align(CenterHorizontally)
.padding(7.dp),
verticalAlignment = Alignment.CenterVertically
){
) {
BetProfilePictureRow(pictures = players)
Spacer(modifier = Modifier.width(12.dp))
Text(
@ -77,7 +80,7 @@ fun BetScreenCard(
players.size
),
style = AllInTheme.typography.m,
color = AllInTheme.themeColors.on_background_2
color = AllInTheme.themeColors.onBackground2
)
}
RainbowButton(
@ -100,7 +103,7 @@ private fun BetScreenCardPreview() {
title = "Emre va réussir son TP de CI/CD mercredi?",
date = "12 Sept.",
time = "13:00",
players = List(3){ null },
players = List(3) { null },
onClickParticipate = {},
onClickCard = {}
)

@ -1,7 +1,13 @@
package fr.iut.alldev.allin.ui.bet.components
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@ -18,9 +24,9 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ext.shadow
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.HighlightedText
import fr.iut.alldev.allin.theme.AllInTheme
import kotlin.math.ceil
@Composable
@ -29,22 +35,22 @@ fun BetScreenPopularCard(
points: Float,
pointUnit: String,
title: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
AllInCard(
modifier = modifier
.let {
if(isSystemInDarkTheme()){
if (isSystemInDarkTheme()) {
it.shadow(
colors = listOf(
AllInTheme.colors.allIn_Pink,
AllInTheme.colors.allIn_Blue
AllInTheme.colors.allInPink,
AllInTheme.colors.allInBlue
),
blurRadius = 10.dp,
alpha = .5f,
cornerRadius = 15.dp
)
}else{
} else {
it.shadow(
color = Color.Black,
blurRadius = 10.dp,
@ -53,11 +59,10 @@ fun BetScreenPopularCard(
)
}
}
.fillMaxWidth()
,
backgroundColor = AllInTheme.colors.allIn_Dark,
.fillMaxWidth(),
backgroundColor = AllInTheme.colors.allInDark,
borderWidth = 2.dp,
borderBrush = AllInTheme.colors.allIn_MainGradient
borderBrush = AllInTheme.colors.allInMainGradient
) {
Column(modifier = Modifier.padding(13.dp)) {
Row(verticalAlignment = Alignment.CenterVertically) {
@ -65,12 +70,12 @@ fun BetScreenPopularCard(
painter = painterResource(id = R.drawable.allin_fire),
modifier = Modifier.size(15.dp),
contentDescription = null,
tint = AllInTheme.colors.allIn_Pink
tint = AllInTheme.colors.allInPink
)
Spacer(modifier = Modifier.width(3.dp))
Text(
text = stringResource(id = R.string.Popular),
color = AllInTheme.colors.allIn_Pink,
color = AllInTheme.colors.allInPink,
fontSize = 17.sp,
style = AllInTheme.typography.h2
)
@ -92,7 +97,7 @@ fun BetScreenPopularCard(
query = nbPlayers.toString(),
highlightStyle = SpanStyle(
fontWeight = FontWeight.Bold,
color = AllInTheme.colors.allIn_Pink
color = AllInTheme.colors.allInPink
),
color = AllInTheme.colors.white,
style = AllInTheme.typography.r,
@ -104,21 +109,21 @@ fun BetScreenPopularCard(
style = AllInTheme.typography.r,
fontSize = 15.sp
)
val pointsText = if (points % 1 == 0f){
val pointsText = if (points % 1 == 0f) {
stringResource(id = R.string.int_and_unit, points.toInt(), pointUnit)
}else{
} else {
stringResource(id = R.string.float_and_unit, points, pointUnit)
}
HighlightedText(
text = pluralStringResource(
id = R.plurals.n_points_at_stake,
if(pointUnit.isEmpty()) ceil(points).toInt() else 2,
if (pointUnit.isEmpty()) ceil(points).toInt() else 2,
pointsText
),
query = pointsText,
highlightStyle = SpanStyle(
fontWeight = FontWeight.Bold,
color = AllInTheme.colors.allIn_Pink
color = AllInTheme.colors.allInPink
),
color = AllInTheme.colors.white,
style = AllInTheme.typography.r,

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation
package fr.iut.alldev.allin.ui.betCreation
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Box
@ -6,7 +6,12 @@ import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.verticalScroll
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalFocusManager
@ -16,10 +21,15 @@ import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.ext.getIcon
import fr.iut.alldev.allin.ext.getTitle
import fr.iut.alldev.allin.ui.betcreation.tabs.BetCreationScreenAnswerTab
import fr.iut.alldev.allin.ui.betcreation.tabs.BetCreationScreenQuestionTab
import fr.iut.alldev.allin.ui.core.*
import fr.iut.alldev.allin.ext.getTitleId
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenAnswerTab
import fr.iut.alldev.allin.ui.betCreation.tabs.BetCreationScreenQuestionTab
import fr.iut.alldev.allin.ui.core.AllInDatePicker
import fr.iut.alldev.allin.ui.core.AllInSections
import fr.iut.alldev.allin.ui.core.AllInTimePicker
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.SectionElement
import fr.iut.alldev.allin.ui.core.SelectionElement
import fr.iut.alldev.allin.ui.main.MainViewModel
import java.time.Instant
import java.time.ZoneId
@ -33,21 +43,21 @@ fun BetCreationScreen(
val interactionSource = remember { MutableInteractionSource() }
val betTypes = remember { BetType.values().toList() }
var theme by remember{ viewModel.theme }
var phrase by remember{ viewModel.phrase }
val (registerDate, setRegisterDate) = remember { viewModel.registerDate }
var theme by remember { viewModel.theme }
var phrase by remember { viewModel.phrase }
val (registerDate, setRegisterDate) = remember { viewModel.registerDate }
val (betDate, setBetDate) = remember { viewModel.betDate }
var isPublic by remember{ viewModel.isPublic }
var selectedBetType by remember{ viewModel.selectedBetType }
var isPublic by remember { viewModel.isPublic }
var selectedBetType by remember { viewModel.selectedBetType }
val themeError by remember{ viewModel.themeError }
val phraseError by remember{ viewModel.phraseError }
val registerDateError by remember{ viewModel.registerDateError }
val betDateError by remember{ viewModel.betDateError }
val themeError by remember { viewModel.themeError }
val phraseError by remember { viewModel.phraseError }
val registerDateError by remember { viewModel.registerDateError }
val betDateError by remember { viewModel.betDateError }
val selectedFriends = remember { mutableListOf<Int>() }
var selectionElements by remember { mutableStateOf(listOf<SelectionElement>()) }
var selectedBetTypeElement by remember { mutableStateOf<SelectionElement?>(null)}
var selectedBetTypeElement by remember { mutableStateOf<SelectionElement?>(null) }
val focus = LocalFocusManager.current
val themeFieldName = stringResource(id = R.string.Theme)
@ -58,14 +68,14 @@ fun BetCreationScreen(
LaunchedEffect(key1 = betTypes) {
selectionElements = betTypes.map {
SelectionElement(
textId = it.getTitle(),
textId = it.getTitleId(),
imageVector = it.getIcon()
)
}
selectedBetTypeElement = selectionElements.getOrNull(0)
}
LaunchedEffect(key1 = selectedBetTypeElement){
LaunchedEffect(key1 = selectedBetTypeElement) {
selectedBetType = betTypes[selectionElements.indexOf(selectedBetTypeElement)]
}
@ -89,7 +99,7 @@ fun BetCreationScreen(
.fillMaxSize()
.padding(bottom = 90.dp),
sections = listOf(
SectionElement(stringResource(id = R.string.Question)){
SectionElement(stringResource(id = R.string.Question)) {
BetCreationScreenQuestionTab(
isPublic = isPublic,
setIsPublic = { isPublic = it },
@ -116,7 +126,7 @@ fun BetCreationScreen(
.padding(vertical = 12.dp, horizontal = 20.dp)
)
},
SectionElement(stringResource(id = R.string.Answer)){
SectionElement(stringResource(id = R.string.Answer)) {
BetCreationScreenAnswerTab(
selectedBetType = selectedBetType,
selected = selectedBetTypeElement,
@ -142,22 +152,23 @@ fun BetCreationScreen(
phraseFieldName = phraseFieldName,
registerDateFieldName = registerDateFieldName,
betDateFieldName = betDateFieldName
){ mainViewModel.loading.value = it }
) { mainViewModel.loading.value = it }
}
)
}
if (showRegisterDatePicker || showEndDatePicker) {
val dateToEdit = if(showRegisterDatePicker) registerDate else betDate
val dateToEdit = if (showRegisterDatePicker) registerDate else betDate
AllInDatePicker(
currentDate = if(showRegisterDatePicker) registerDate else betDate,
currentDate = if (showRegisterDatePicker) registerDate else betDate,
onSelectDate = { date ->
val selectedDate = ZonedDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.systemDefault())
val selectedDate =
ZonedDateTime.ofInstant(Instant.ofEpochMilli(date), ZoneId.systemDefault())
val newDate = dateToEdit
.withYear(selectedDate.year)
.withMonth(selectedDate.month.value)
.withDayOfMonth(selectedDate.dayOfMonth)
.withDayOfYear(selectedDate.dayOfYear)
if(showRegisterDatePicker) {
if (showRegisterDatePicker) {
setRegisterDate(newDate)
} else {
setBetDate(newDate)
@ -172,7 +183,7 @@ fun BetCreationScreen(
)
}
if (showRegisterTimePicker || showEndTimePicker) {
val timeToEdit = if(showRegisterTimePicker) registerDate else betDate
val timeToEdit = if (showRegisterTimePicker) registerDate else betDate
AllInTimePicker(
hour = timeToEdit.hour,
minutes = timeToEdit.minute,
@ -180,7 +191,7 @@ fun BetCreationScreen(
val time = (timeToEdit)
.withHour(hour)
.withMinute(min)
if(showRegisterTimePicker) {
if (showRegisterTimePicker) {
setRegisterDate(time)
} else {
setBetDate(time)

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation
package fr.iut.alldev.allin.ui.betCreation
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.ViewModel

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.components
package fr.iut.alldev.allin.ui.betCreation.components
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.material3.Text
@ -13,15 +13,17 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun BetCreationScreenBottomText(
text: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Text(
text = text,
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
fontWeight = FontWeight.Bold,
textAlign = TextAlign.Center,
style = AllInTheme.typography.h2,
modifier = modifier.fillMaxWidth().alpha(.5f)
modifier = modifier
.fillMaxWidth()
.alpha(.5f)
)
}

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.components
package fr.iut.alldev.allin.ui.betCreation.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.padding
@ -8,14 +8,14 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
@Composable
fun BetCreationScreenDateTimeButton(
modifier: Modifier = Modifier,
text: String,
onClick: ()->Unit
onClick: () -> Unit,
) {
AllInCard(
modifier = modifier,
@ -24,7 +24,7 @@ fun BetCreationScreenDateTimeButton(
) {
Text(
text = text,
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
style = AllInTheme.typography.h2,
fontSize = 16.sp,
modifier = Modifier.padding(horizontal = 23.dp, vertical = 9.dp)

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.components
package fr.iut.alldev.allin.ui.betCreation.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.Arrangement

@ -1,9 +1,13 @@
package fr.iut.alldev.allin.ui.betcreation.components
package fr.iut.alldev.allin.ui.betCreation.components
import android.content.res.Configuration
import androidx.compose.foundation.background
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -12,24 +16,24 @@ import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.AllInRadioButton
import fr.iut.alldev.allin.ui.core.ProfilePicture
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun BetCreationScreenFriendLine(
username: String,
allCoinsAmount: Int,
isSelected: Boolean,
onClick: ()->Unit
onClick: () -> Unit,
) {
Row(
modifier = Modifier
.fillMaxWidth()
.clickable(onClick = onClick)
.background(
if (isSelected) AllInTheme.colors.allIn_Purple.copy(alpha = .13f)
if (isSelected) AllInTheme.colors.allInPurple.copy(alpha = .13f)
else AllInTheme.themeColors.background
)
.padding(15.dp),
@ -45,14 +49,14 @@ fun BetCreationScreenFriendLine(
text = username,
fontWeight = FontWeight.Bold,
style = AllInTheme.typography.h2,
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
maxLines = 1,
overflow = TextOverflow.Ellipsis,
modifier = Modifier.weight(1f)
)
AllInCoinCount(
amount = allCoinsAmount,
color = AllInTheme.colors.allIn_Purple
color = AllInTheme.colors.allInPurple
)
}
}
@ -65,7 +69,8 @@ private fun BetCreationScreenFriendLinePreview() {
BetCreationScreenFriendLine(
username = "David",
allCoinsAmount = 542,
isSelected = false) {
isSelected = false
) {
}
}
@ -79,7 +84,8 @@ private fun BetCreationScreenFriendLineSelectedPreview() {
BetCreationScreenFriendLine(
username = "David",
allCoinsAmount = 542,
isSelected = true) {
isSelected = true
) {
}
}

@ -1,14 +1,22 @@
package fr.iut.alldev.allin.ui.betcreation.tabs
package fr.iut.alldev.allin.ui.betCreation.tabs
import androidx.compose.foundation.layout.*
import androidx.compose.runtime.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetType
import fr.iut.alldev.allin.ext.getTitle
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ext.getTitleId
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.core.AllInSelectionBox
import fr.iut.alldev.allin.ui.core.SelectionElement
@ -17,10 +25,10 @@ fun BetCreationScreenAnswerTab(
modifier: Modifier = Modifier,
selected: SelectionElement?,
selectedBetType: BetType,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
setSelected: (SelectionElement) -> Unit,
elements: List<SelectionElement>,
) {
var isOpen by remember{
var isOpen by remember {
mutableStateOf(false)
}
@ -34,7 +42,7 @@ fun BetCreationScreenAnswerTab(
elements = elements
)
Spacer(modifier = Modifier.height(26.dp))
when(selectedBetType){
when (selectedBetType) {
BetType.YES_NO -> {
Column(
modifier = Modifier.padding(vertical = 20.dp),
@ -44,14 +52,16 @@ fun BetCreationScreenAnswerTab(
BetCreationScreenBottomText(text = stringResource(id = R.string.yes_no_bottom_text_2))
}
}
BetType.MATCH -> {
BetCreationScreenBottomText(
text = stringResource(selectedBetType.getTitle())
text = stringResource(selectedBetType.getTitleId())
)
}
BetType.CUSTOM -> {
BetCreationScreenBottomText(
text = stringResource(selectedBetType.getTitle())
text = stringResource(selectedBetType.getTitleId())
)
}
}

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.tabs
package fr.iut.alldev.allin.ui.betCreation.tabs
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.interaction.MutableInteractionSource
@ -9,9 +9,9 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.ext.formatToMediumDate
import fr.iut.alldev.allin.data.ext.formatToTime
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabDateTimeSection
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabPrivacySection
import fr.iut.alldev.allin.ui.betcreation.tabs.sections.QuestionTabThemePhraseSection
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabDateTimeSection
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabPrivacySection
import fr.iut.alldev.allin.ui.betCreation.tabs.sections.QuestionTabThemePhraseSection
import java.time.ZonedDateTime
@OptIn(ExperimentalFoundationApi::class)

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
package fr.iut.alldev.allin.ui.betCreation.tabs.sections
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.Spacer
@ -11,7 +11,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenDateTimeRow
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenDateTimeRow
import fr.iut.alldev.allin.ui.core.AllInErrorLine
import fr.iut.alldev.allin.ui.core.AllInTitleInfo

@ -1,32 +1,40 @@
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
package fr.iut.alldev.allin.ui.betCreation.tabs.sections
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material.icons.filled.Lock
import androidx.compose.material.icons.filled.Public
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.betcreation.components.BetCreationScreenFriendLine
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenBottomText
import fr.iut.alldev.allin.ui.betCreation.components.BetCreationScreenFriendLine
import fr.iut.alldev.allin.ui.core.AllInIconChip
import fr.iut.alldev.allin.ui.core.AllInRetractableCard
import fr.iut.alldev.allin.ui.core.AllInTitleInfo
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun QuestionTabPrivacySection(
isPublic: Boolean,
setIsPublic: (Boolean)->Unit,
setIsPublic: (Boolean) -> Unit,
nbFriends: Int,
selectedFriends: MutableList<Int>,
interactionSource: MutableInteractionSource
interactionSource: MutableInteractionSource,
) {
AllInTitleInfo(
text = stringResource(id = R.string.Bet_privacy),
@ -38,7 +46,7 @@ fun QuestionTabPrivacySection(
Row(
modifier = Modifier.padding(bottom = 10.dp),
horizontalArrangement = Arrangement.spacedBy(8.dp)
){
) {
AllInIconChip(
text = stringResource(id = R.string.Public),
leadingIcon = Icons.Default.Public,
@ -60,11 +68,11 @@ fun QuestionTabPrivacySection(
Column(
verticalArrangement = Arrangement.spacedBy(17.dp)
) {
var isOpen by remember{
var isOpen by remember {
mutableStateOf(false)
}
if(isPublic){
if (isPublic) {
Column(
modifier = Modifier.padding(vertical = 20.dp),
verticalArrangement = Arrangement.spacedBy(17.dp)
@ -72,7 +80,7 @@ fun QuestionTabPrivacySection(
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_1))
BetCreationScreenBottomText(text = stringResource(id = R.string.public_bottom_text_2))
}
}else{
} else {
AllInRetractableCard(
text = stringResource(
id = R.string.n_friends_available,
@ -86,13 +94,13 @@ fun QuestionTabPrivacySection(
) {
LazyColumn(
modifier = Modifier.height(165.dp)
){
items(nbFriends){
var isSelected by remember{
) {
items(nbFriends) {
var isSelected by remember {
mutableStateOf(selectedFriends.contains(it))
}
if(it!=0){
if (it != 0) {
HorizontalDivider(color = AllInTheme.themeColors.border)
}
BetCreationScreenFriendLine(
@ -105,7 +113,7 @@ fun QuestionTabPrivacySection(
} else {
selectedFriends.add(it)
}
isSelected = ! isSelected
isSelected = !isSelected
}
}
}

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betcreation.tabs.sections
package fr.iut.alldev.allin.ui.betCreation.tabs.sections
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.interaction.MutableInteractionSource

@ -0,0 +1,65 @@
package fr.iut.alldev.allin.ui.betHistory
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
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.theme.AllInTheme
import fr.iut.alldev.allin.ui.betHistory.components.BetHistoryScreenCard
@Composable
fun BetHistoryScreen(
isCurrent: Boolean,
viewModel: BetHistoryViewModel = hiltViewModel(),
) {
val bets by viewModel.bets.collectAsState()
LazyColumn(
modifier = Modifier.fillMaxSize(),
contentPadding = PaddingValues(horizontal = 24.dp, vertical = 18.dp),
verticalArrangement = Arrangement.spacedBy(18.dp),
) {
item {
Text(
text = stringResource(
id = if (isCurrent) R.string.bet_history_current_title
else R.string.bet_history_title
),
style = AllInTheme.typography.h1,
color = AllInTheme.colors.allInGrey,
fontSize = 24.sp,
textAlign = TextAlign.Center,
modifier = Modifier.fillMaxWidth()
)
}
bets?.let { bets ->
items(bets) {
BetHistoryScreenCard(
title = it.phrase,
creator = "creator",
category = it.theme,
date = it.endBetDate.formatToMediumDateNoYear(),
time = it.endBetDate.formatToTime(),
status = it.betStatus,
nbCoins = 230
)
}
}
}
}

@ -0,0 +1,35 @@
package fr.iut.alldev.allin.ui.betHistory
import androidx.lifecycle.SavedStateHandle
import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope
import dagger.hilt.android.lifecycle.HiltViewModel
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.data.repository.BetRepository
import fr.iut.alldev.allin.ui.navigation.NavArguments
import kotlinx.coroutines.flow.SharingStarted
import kotlinx.coroutines.flow.StateFlow
import kotlinx.coroutines.flow.filterNotNull
import kotlinx.coroutines.flow.flatMapConcat
import kotlinx.coroutines.flow.flowOf
import kotlinx.coroutines.flow.stateIn
import javax.inject.Inject
@HiltViewModel
class BetHistoryViewModel @Inject constructor(
savedStateHandle: SavedStateHandle,
private val betRepository: BetRepository,
) : ViewModel() {
private val isCurrent: Boolean? = savedStateHandle[NavArguments.ARG_BET_HISTORY_IS_CURRENT]
val bets: StateFlow<List<Bet>?> by lazy {
flowOf(isCurrent).filterNotNull().flatMapConcat {
if (it) betRepository.getCurrentBets()
else betRepository.getHistory()
}.stateIn(
viewModelScope,
SharingStarted.WhileSubscribed(5_000L),
null
)
}
}

@ -0,0 +1,91 @@
package fr.iut.alldev.allin.ui.betHistory.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.text.InlineTextContent
import androidx.compose.foundation.text.appendInlineContent
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.Placeholder
import androidx.compose.ui.text.PlaceholderVerticalAlign
import androidx.compose.ui.text.buildAnnotatedString
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.sp
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.ext.getBetHistoryPhrase
import fr.iut.alldev.allin.ext.getBetHistoryStatusColor
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider
const val betHistoryStatusModId = "allCoinsIcon"
val betHistoryStatusInlineContent = mapOf(
Pair(
betHistoryStatusModId,
InlineTextContent(
Placeholder(
width = 24.sp,
height = 24.sp,
placeholderVerticalAlign = PlaceholderVerticalAlign.Center
)
) {
Icon(
painter = AllInTheme.icons.allCoins(),
tint = AllInTheme.colors.white,
contentDescription = null,
modifier = Modifier.size(24.dp)
)
}
)
)
@Composable
fun BetHistoryBetStatus(
status: BetStatus,
nbCoins: Int,
) {
val betHistoryPhrase = stringResource(id = status.getBetHistoryPhrase(), nbCoins)
Row(
modifier = Modifier
.fillMaxWidth()
.background(status.getBetHistoryStatusColor())
.padding(16.dp),
horizontalArrangement = Arrangement.Center,
verticalAlignment = Alignment.CenterVertically
) {
Text(
text = buildAnnotatedString {
append(betHistoryPhrase.substringBefore("[icon]"))
appendInlineContent(betHistoryStatusModId, "[icon]")
append(betHistoryPhrase.substringAfter("[icon]"))
},
color = AllInTheme.colors.white,
inlineContent = betHistoryStatusInlineContent,
style = AllInTheme.typography.h1,
fontSize = 24.sp
)
}
}
@Preview
@Composable
private fun BetHistoryBetStatusPreview(
@PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus,
) {
AllInTheme {
BetHistoryBetStatus(
status = betStatus,
nbCoins = 230
)
}
}

@ -0,0 +1,83 @@
package fr.iut.alldev.allin.ui.betHistory.components
import android.content.res.Configuration
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.HorizontalDivider
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.ext.getDateStartLabelId
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCard
import fr.iut.alldev.allin.ui.core.bet.BetDateTimeRow
import fr.iut.alldev.allin.ui.core.bet.BetTitleHeader
import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider
@Composable
fun BetHistoryScreenCard(
modifier: Modifier = Modifier,
title: String,
creator: String,
category: String,
date: String,
time: String,
status: BetStatus,
nbCoins: Int,
) {
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
)
BetHistoryBetStatus(
status = status,
nbCoins = nbCoins
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetHistoryScreenCardPreview(
@PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus
) {
AllInTheme {
BetHistoryScreenCard(
creator = "Creator",
category = "Category",
title = "Title",
date = "Date",
time = "Time",
status = betStatus,
nbCoins = 123
)
}
}

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betstatus
package fr.iut.alldev.allin.ui.betStatus
import androidx.compose.animation.*
import androidx.compose.foundation.layout.*
@ -7,8 +7,8 @@ import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.ui.betstatus.components.BetStatusBottomSheetBack
import fr.iut.alldev.allin.ui.betstatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.betStatus.components.BetStatusBottomSheetBack
import fr.iut.alldev.allin.ui.betStatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.core.AllInBottomSheet
import fr.iut.alldev.allin.vo.bet.BetVO

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betstatus.components
package fr.iut.alldev.allin.ui.betStatus.components
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
@ -12,21 +12,21 @@ import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontStyle
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.ext.getColor
import fr.iut.alldev.allin.ext.getTextColor
import fr.iut.alldev.allin.ext.getTitle
import fr.iut.alldev.allin.ui.betstatus.SHEET_HEIGHT
import fr.iut.alldev.allin.ext.getTitleId
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betStatus.SHEET_HEIGHT
import fr.iut.alldev.allin.ui.preview.BetStatusPreviewProvider
@Composable
fun BetStatusBottomSheetBack(
status: BetStatus,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Box(
@ -37,10 +37,10 @@ fun BetStatusBottomSheetBack(
) {
Row(
verticalAlignment = Alignment.CenterVertically,
modifier = Modifier.fillMaxHeight(1-SHEET_HEIGHT)
modifier = Modifier.fillMaxHeight(1 - SHEET_HEIGHT)
) {
Text(
text = stringResource(id = status.getTitle()),
text = stringResource(id = status.getTitleId()),
color = status.getTextColor(),
style = AllInTheme.typography.h2.copy(
fontStyle = FontStyle.Italic
@ -57,14 +57,10 @@ fun BetStatusBottomSheetBack(
}
}
private class BetStatusPreviewProvider: PreviewParameterProvider<BetStatus> {
override val values = BetStatus.values().asSequence()
}
@Preview
@Composable
private fun BackStatusScreenBackPreview(
@PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus
@PreviewParameter(BetStatusPreviewProvider::class) betStatus: BetStatus,
) {
AllInTheme {
BetStatusBottomSheetBack(status = betStatus)

@ -1,4 +1,4 @@
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
@ -14,11 +14,11 @@ import androidx.compose.ui.unit.Dp
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.AllInBottomSheet
import fr.iut.alldev.allin.ui.core.AllInButton
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.topbar.AllInTopBarCoinCounter
import fr.iut.alldev.allin.theme.AllInTheme
import kotlinx.coroutines.launch
@OptIn(ExperimentalMaterial3Api::class)
@ -28,16 +28,16 @@ fun BetStatusParticipationBottomSheet(
safeBottomPadding: Dp,
betPhrase: String,
coinAmount: Int,
onDismiss: ()->Unit,
onDismiss: () -> Unit,
state: SheetState,
onParticipate: ()->Unit
onParticipate: () -> Unit,
) {
val scope = rememberCoroutineScope()
AllInBottomSheet(
sheetVisibility = sheetVisibility,
onDismiss = onDismiss,
state = state,
containerColor = AllInTheme.themeColors.background_2
containerColor = AllInTheme.themeColors.background2
) {
Row(
modifier = Modifier.fillMaxWidth(),
@ -47,13 +47,13 @@ fun BetStatusParticipationBottomSheet(
Text(
text = stringResource(id = R.string.place_your_bets),
style = AllInTheme.typography.h2,
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontSize = 20.sp,
modifier = Modifier.padding(start = 18.dp)
)
AllInTopBarCoinCounter(
amount = coinAmount,
backgroundColor = AllInTheme.colors.allIn_Blue,
backgroundColor = AllInTheme.colors.allInBlue,
textColor = AllInTheme.colors.white,
iconColor = AllInTheme.colors.white,
)
@ -62,7 +62,7 @@ fun BetStatusParticipationBottomSheet(
Text(
text = betPhrase,
style = AllInTheme.typography.s,
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
modifier = Modifier.padding(horizontal = 18.dp)
)
Spacer(modifier = Modifier.height(100.dp))
@ -78,24 +78,24 @@ fun BetStatusParticipationBottomSheet(
modifier = Modifier.fillMaxWidth(),
horizontalArrangement = Arrangement.SpaceBetween,
verticalAlignment = Alignment.CenterVertically
){
) {
Text(
text = stringResource(id = R.string.Possible_winnings),
style = AllInTheme.typography.r,
color = AllInTheme.themeColors.on_background
color = AllInTheme.themeColors.onBackground
)
AllInCoinCount(
amount = 121,
color = AllInTheme.themeColors.on_background
color = AllInTheme.themeColors.onBackground
)
}
AllInButton(
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
text = stringResource(id = R.string.Participate),
textColor = AllInTheme.colors.white,
radius = 5.dp
){
scope.launch{
) {
scope.launch {
onParticipate()
state.hide()
onDismiss()
@ -106,7 +106,6 @@ fun BetStatusParticipationBottomSheet(
}
@OptIn(ExperimentalMaterial3Api::class)
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)

@ -1,8 +1,12 @@
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.layout.*
import androidx.compose.foundation.layout.Arrangement
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.material.icons.Icons
import androidx.compose.material.icons.filled.EmojiEvents
import androidx.compose.material.icons.filled.People
@ -13,10 +17,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInCoinCount
import fr.iut.alldev.allin.ui.core.AllInTextIcon
import fr.iut.alldev.allin.ui.core.IconPosition
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun BetStatusWinner(
@ -24,7 +28,7 @@ fun BetStatusWinner(
coinAmount: Int,
username: String,
multiplier: Float,
color: Color = AllInTheme.themeColors.on_main_surface
color: Color = AllInTheme.themeColors.onMainSurface,
) {
Column {
HorizontalDivider(color = color.copy(alpha = .4f))

@ -1,4 +1,4 @@
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.layout.Arrangement
@ -9,15 +9,15 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.tooling.preview.Preview
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInTextIcon
import fr.iut.alldev.allin.ui.core.IconPosition
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun YesNoDetailsLine(
icon: ImageVector,
yesText: String,
noText: String
noText: String,
) {
Row(
modifier = Modifier.fillMaxWidth(),
@ -25,7 +25,7 @@ fun YesNoDetailsLine(
) {
AllInTextIcon(
text = yesText,
color = AllInTheme.colors.allIn_Blue,
color = AllInTheme.colors.allInBlue,
icon = icon,
position = IconPosition.LEADING,
size = 10,
@ -33,7 +33,7 @@ fun YesNoDetailsLine(
)
AllInTextIcon(
text = noText,
color = AllInTheme.colors.allIn_BarPink,
color = AllInTheme.colors.allInBarPink,
icon = icon,
position = IconPosition.TRAILING,
size = 10,
@ -46,7 +46,7 @@ fun YesNoDetailsLine(
fun YesNoDetailsLine(
icon: Painter,
yesText: String,
noText: String
noText: String,
) {
Row(
modifier = Modifier.fillMaxWidth(),
@ -54,7 +54,7 @@ fun YesNoDetailsLine(
) {
AllInTextIcon(
text = yesText,
color = AllInTheme.colors.allIn_Blue,
color = AllInTheme.colors.allInBlue,
icon = icon,
position = IconPosition.LEADING,
size = 10,
@ -62,7 +62,7 @@ fun YesNoDetailsLine(
)
AllInTextIcon(
text = noText,
color = AllInTheme.colors.allIn_BarPink,
color = AllInTheme.colors.allInBarPink,
icon = icon,
position = IconPosition.TRAILING,
size = 10,

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betstatus.components
package fr.iut.alldev.allin.ui.betStatus.components
import androidx.compose.foundation.layout.*
import androidx.compose.material3.Text
@ -12,20 +12,20 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.ext.toPercentageString
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.PercentagePositionnedElement
import fr.iut.alldev.allin.ui.core.StatBar
import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun YesNoStatBar(
yesPercentage: Float,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Column(modifier){
Row{
Column(modifier) {
Row {
Text(
text = stringResource(id = R.string.Yes).uppercase(),
color = AllInTheme.colors.allIn_Blue,
color = AllInTheme.colors.allInBlue,
style = AllInTheme.typography.h1,
fontStyle = FontStyle.Italic,
fontSize = 30.sp,
@ -36,24 +36,24 @@ fun YesNoStatBar(
style = AllInTheme.typography.h1,
fontStyle = FontStyle.Italic,
fontSize = 30.sp,
color = AllInTheme.colors.allIn_BarPink
color = AllInTheme.colors.allInBarPink
)
}
StatBar(percentage = yesPercentage)
PercentagePositionnedElement(
percentage = yesPercentage
){
) {
Text(
text = yesPercentage.toPercentageString(),
style = AllInTheme.typography.h3,
color = AllInTheme.colors.allIn_BarPurple
color = AllInTheme.colors.allInBarPurple
)
}
}
}
private class YesNoStatBarPreviewProvider: PreviewParameterProvider<Float> {
private class YesNoStatBarPreviewProvider : PreviewParameterProvider<Float> {
override val values = sequenceOf(0f, .33f, .5f, .66f, 1f)
}
@ -61,7 +61,7 @@ private class YesNoStatBarPreviewProvider: PreviewParameterProvider<Float> {
@Preview
@Composable
private fun YesNoStatBarPreview(
@PreviewParameter(YesNoStatBarPreviewProvider::class) percentage: Float
@PreviewParameter(YesNoStatBarPreviewProvider::class) percentage: Float,
) {
AllInTheme {
YesNoStatBar(percentage)

@ -1,4 +1,4 @@
package fr.iut.alldev.allin.ui.betstatus.visitor
package fr.iut.alldev.allin.ui.betStatus.visitor
import android.content.res.Configuration
import androidx.compose.foundation.background
@ -20,16 +20,17 @@ import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.data.ext.formatToMediumDateNoYear
import fr.iut.alldev.allin.data.ext.formatToTime
import fr.iut.alldev.allin.data.model.bet.BetFinishedStatus
import fr.iut.alldev.allin.data.model.bet.BetStatus
import fr.iut.alldev.allin.data.model.bet.MatchBet
import fr.iut.alldev.allin.data.model.bet.YesNoBet
import fr.iut.alldev.allin.ext.getDateEndLabel
import fr.iut.alldev.allin.ext.getDateStartLabel
import fr.iut.alldev.allin.ext.getDateEndLabelId
import fr.iut.alldev.allin.ext.getDateStartLabelId
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betstatus.components.BetStatusParticipationBottomSheet
import fr.iut.alldev.allin.ui.betstatus.components.BetStatusWinner
import fr.iut.alldev.allin.ui.betstatus.components.YesNoDetailsLine
import fr.iut.alldev.allin.ui.betstatus.components.YesNoStatBar
import fr.iut.alldev.allin.ui.betStatus.components.BetStatusParticipationBottomSheet
import fr.iut.alldev.allin.ui.betStatus.components.BetStatusWinner
import fr.iut.alldev.allin.ui.betStatus.components.YesNoDetailsLine
import fr.iut.alldev.allin.ui.betStatus.components.YesNoStatBar
import fr.iut.alldev.allin.ui.core.AllInDetailsDrawer
import fr.iut.alldev.allin.ui.core.RainbowButton
import fr.iut.alldev.allin.ui.core.bet.BetDateTimeRow
@ -40,7 +41,7 @@ import java.time.ZonedDateTime
class BetStatusBottomSheetDisplayBetVisitor(
val userCoinAmount: MutableIntState,
val onParticipate: (Int)->Unit
val onParticipate: (Int) -> Unit,
) : DisplayBetVisitor {
val participateBottomSheetVisibility = mutableStateOf(false)
@ -50,7 +51,7 @@ class BetStatusBottomSheetDisplayBetVisitor(
@Composable
override fun VisitYesNoBet(b: YesNoBet) {
val (participateSheetVisibility, setParticipateSheetVisibility) = remember{
val (participateSheetVisibility, setParticipateSheetVisibility) = remember {
this.participateBottomSheetVisibility
}
@ -60,10 +61,8 @@ class BetStatusBottomSheetDisplayBetVisitor(
Modifier
.padding(bottom = safeBottomPadding)
) {
Column{
Column(
Modifier.padding(horizontal = 20.dp)
) {
Column {
Column(Modifier.padding(horizontal = 20.dp)) {
BetTitleHeader(
title = b.phrase,
category = b.theme,
@ -75,14 +74,14 @@ class BetStatusBottomSheetDisplayBetVisitor(
horizontalAlignment = Alignment.End
) {
BetDateTimeRow(
label = stringResource(id = b.betStatus.getDateStartLabel()),
label = stringResource(id = b.betStatus.getDateStartLabelId()),
date = b.endRegisterDate.formatToMediumDateNoYear(),
time = b.endRegisterDate.formatToTime(),
modifier = Modifier.width(IntrinsicSize.Max)
)
Spacer(modifier = Modifier.height(15.dp))
BetDateTimeRow(
label = stringResource(id = b.betStatus.getDateEndLabel()),
label = stringResource(id = b.betStatus.getDateEndLabelId()),
date = b.endBetDate.formatToMediumDateNoYear(),
time = b.endBetDate.formatToTime(),
modifier = Modifier.width(IntrinsicSize.Max)
@ -90,10 +89,10 @@ class BetStatusBottomSheetDisplayBetVisitor(
}
Spacer(modifier = Modifier.height(20.dp))
}
if (b.betStatus == BetStatus.FINISHED) {
if (b.betStatus is BetStatus.Finished) {
BetStatusWinner(
answer = stringResource(id = R.string.Yes),
color = AllInTheme.colors.allIn_Blue,
color = AllInTheme.colors.allInBlue,
coinAmount = 442,
username = "Imri",
multiplier = 1.2f
@ -104,7 +103,7 @@ class BetStatusBottomSheetDisplayBetVisitor(
Column(
Modifier
.fillMaxHeight()
.background(AllInTheme.themeColors.background_2)
.background(AllInTheme.themeColors.background2)
.padding(horizontal = 20.dp)
) {
Spacer(modifier = Modifier.height(20.dp))
@ -133,13 +132,13 @@ class BetStatusBottomSheetDisplayBetVisitor(
}
}
}
if(b.betStatus != BetStatus.FINISHED) {
if (b.betStatus !is BetStatus.Finished) {
RainbowButton(
modifier = Modifier
.align(Alignment.BottomCenter)
.padding(horizontal = 7.dp),
text = stringResource(id = R.string.Participate),
enabled = b.betStatus == BetStatus.WAITING,
enabled = b.betStatus == BetStatus.Waiting,
onClick = {
setParticipateSheetVisibility(true)
}
@ -148,16 +147,17 @@ class BetStatusBottomSheetDisplayBetVisitor(
}
BetStatusParticipationBottomSheet(
sheetVisibility = participateSheetVisibility && b.betStatus == BetStatus.WAITING,
sheetVisibility = participateSheetVisibility && b.betStatus == BetStatus.Waiting,
safeBottomPadding = safeBottomPadding,
betPhrase = b.phrase,
coinAmount = userCoinAmount.intValue,
onDismiss = { setParticipateSheetVisibility(false) },
state = rememberModalBottomSheetState()
){
) {
onParticipate(100)
}
}
@Composable
override fun VisitMatchBet(b: MatchBet) {
Text("This is a MATCH BET")
@ -176,7 +176,7 @@ private fun YesNoBetPreview() {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.IN_PROGRESS
betStatus = BetStatus.InProgress
).toBetVO()?.Accept(
BetStatusBottomSheetDisplayBetVisitor(
userCoinAmount = coins,
@ -185,6 +185,7 @@ private fun YesNoBetPreview() {
)
}
}
@Preview
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
@ -197,7 +198,7 @@ private fun YesNoBetFinishedPreview() {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.FINISHED
betStatus = BetStatus.Finished(BetFinishedStatus.WON)
).toBetVO()?.Accept(
BetStatusBottomSheetDisplayBetVisitor(
userCoinAmount = coins,
@ -219,7 +220,7 @@ private fun MatchBetPreview() {
endRegisterDate = ZonedDateTime.now(),
endBetDate = ZonedDateTime.now(),
isPublic = true,
betStatus = BetStatus.IN_PROGRESS,
betStatus = BetStatus.InProgress,
nameTeam1 = "Team 1",
nameTeam2 = "Team 2"
).toBetVO()?.Accept(

@ -17,10 +17,10 @@ fun AllInAlertDialog(
title: String,
text: String,
confirmText: String = stringResource(id = R.string.Ok),
onDismiss: ()->Unit,
onConfirm: ()->Unit = onDismiss
onDismiss: () -> Unit,
onConfirm: () -> Unit = onDismiss,
) {
if(enabled) {
if (enabled) {
AlertDialog(
title = {
Text(
@ -43,16 +43,16 @@ fun AllInAlertDialog(
text = confirmText,
fontSize = 15.sp,
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allIn_MainGradient
brush = AllInTheme.colors.allInMainGradient
)
)
}
},
onDismissRequest = onDismiss,
containerColor = AllInTheme.themeColors.main_surface,
titleContentColor = AllInTheme.themeColors.on_main_surface,
textContentColor = AllInTheme.themeColors.on_background_2,
containerColor = AllInTheme.themeColors.mainSurface,
titleContentColor = AllInTheme.themeColors.onMainSurface,
textContentColor = AllInTheme.themeColors.onBackground2,
)
}
}

@ -18,9 +18,9 @@ fun AllInButton(
color: Color,
text: String,
textColor: Color,
radius: Dp = 15.dp,
modifier: Modifier = Modifier,
onClick: ()->Unit
radius: Dp = 15.dp,
onClick: () -> Unit,
) {
AllInCard(
onClick = onClick,
@ -46,7 +46,7 @@ fun AllInButton(
private fun AllInButtonPreview() {
AllInTheme {
AllInButton(
color = AllInTheme.colors.allIn_LoginPurple,
color = AllInTheme.colors.allInLoginPurple,
text = "Connexion",
textColor = Color.White
) {

@ -29,7 +29,7 @@ import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@Composable
fun AllInCard(
modifier: Modifier = Modifier,
onClick: (()->Unit)? = null,
onClick: (() -> Unit)? = null,
radius: Dp = 15.dp,
enabled: Boolean = true,
backgroundColor: Color = AllInTheme.themeColors.background,
@ -37,24 +37,26 @@ fun AllInCard(
backgroundBrush: Brush? = null,
borderWidth: Dp? = null,
borderColor: Color = AllInTheme.themeColors.border,
disabledBorderColor: Color = AllInTheme.themeColors.disabled_border,
disabledBorderColor: Color = AllInTheme.themeColors.disabledBorder,
borderBrush: Brush? = null,
content: @Composable ()->Unit
content: @Composable () -> Unit,
) {
val cardShape = AbsoluteSmoothCornerShape(radius, smoothnessAsPercent = 100)
val cardModifier = modifier
.run {
backgroundBrush?.let{
this.clip(cardShape).background(it)
} ?: this
}
val cardBorders = borderWidth?.let{
width -> borderBrush?.let{BorderStroke(width, it)}
?: BorderStroke(width, if(enabled) borderColor else disabledBorderColor)
backgroundBrush?.let {
this
.clip(cardShape)
.background(it)
} ?: this
}
val cardBorders = borderWidth?.let { width ->
borderBrush?.let { BorderStroke(width, it) }
?: BorderStroke(width, if (enabled) borderColor else disabledBorderColor)
}
val cardColors = CardDefaults.cardColors(
containerColor = if(backgroundBrush!=null) Color.Transparent else backgroundColor,
containerColor = if (backgroundBrush != null) Color.Transparent else backgroundColor,
disabledContainerColor = disabledBackgroundColor
)
onClick?.let {
@ -84,7 +86,7 @@ fun AllInCard(
@Composable
fun AllInBouncyCard(
modifier: Modifier = Modifier,
onClick: (()->Unit)? = null,
onClick: (() -> Unit)? = null,
radius: Dp = 15.dp,
enabled: Boolean = true,
backgroundColor: Color = AllInTheme.themeColors.background,
@ -92,15 +94,15 @@ fun AllInBouncyCard(
backgroundBrush: Brush? = null,
borderWidth: Dp? = null,
borderColor: Color = AllInTheme.themeColors.border,
disabledBorderColor: Color = AllInTheme.themeColors.disabled_border,
disabledBorderColor: Color = AllInTheme.themeColors.disabledBorder,
borderBrush: Brush? = null,
content: @Composable ()->Unit
){
content: @Composable () -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
val isPressed by interactionSource.collectIsPressedAsState()
val scale by animateFloatAsState(
targetValue = if(isPressed) .95f else 1f,
targetValue = if (isPressed) .95f else 1f,
animationSpec = spring(
Spring.DampingRatioHighBouncy,
Spring.StiffnessMediumLow
@ -109,10 +111,10 @@ fun AllInBouncyCard(
AllInCard(
modifier = modifier
.combinedClickable(
interactionSource = interactionSource,
indication = null,
onClick = { onClick?.let { it() } }
)
interactionSource = interactionSource,
indication = null,
onClick = { onClick?.let { it() } }
)
.scale(scale),
onClick = null,
radius = radius,

@ -20,20 +20,20 @@ import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@Composable
fun AllInChip(
text: String,
isSelected: Boolean = false,
onClick: ()->Unit = {},
modifier: Modifier = Modifier,
isSelected: Boolean = false,
onClick: () -> Unit = {},
radius: Dp = 50.dp,
selectedColor: Color = AllInTheme.colors.allIn_Purple,
selectedColor: Color = AllInTheme.colors.allInPurple,
unselectedColor: Color = AllInTheme.themeColors.background,
) {
Card(
modifier = modifier,
shape = AbsoluteSmoothCornerShape(radius, 100),
onClick = onClick,
border = if(!isSelected) BorderStroke(1.dp, AllInTheme.themeColors.border) else null,
border = if (!isSelected) BorderStroke(1.dp, AllInTheme.themeColors.border) else null,
colors = CardDefaults.cardColors(
containerColor = if(isSelected) selectedColor else unselectedColor
containerColor = if (isSelected) selectedColor else unselectedColor
)
) {
Box {
@ -45,7 +45,7 @@ fun AllInChip(
.alpha(if (isSelected) 0f else 1f),
textAlign = TextAlign.Center,
style = AllInTheme.typography.r,
color = AllInTheme.themeColors.on_background_2
color = AllInTheme.themeColors.onBackground2
)
if (isSelected) {
Text(
@ -66,7 +66,7 @@ fun AllInChip(
@Composable
private fun AllInChipPreviewUnselected() {
AllInTheme {
AllInChip("Public", false)
AllInChip("Public", isSelected = false)
}
}
@ -74,6 +74,6 @@ private fun AllInChipPreviewUnselected() {
@Composable
private fun AllInChipPreviewSelected() {
AllInTheme {
AllInChip("Public", true)
AllInChip("Public", isSelected = true)
}
}

@ -12,7 +12,7 @@ fun AllInCoinCount(
modifier: Modifier = Modifier,
amount: Int,
color: Color,
position: IconPosition = IconPosition.TRAILING
position: IconPosition = IconPosition.TRAILING,
) {
AllInTextIcon(
text = amount.toString(),
@ -28,6 +28,6 @@ fun AllInCoinCount(
@Composable
private fun AllInCoinCountPreview() {
AllInTheme {
AllInCoinCount(amount = 542, color = AllInTheme.colors.allIn_Purple)
AllInCoinCount(amount = 542, color = AllInTheme.colors.allInPurple)
}
}

@ -15,7 +15,7 @@ import java.util.*
fun AllInDatePicker(
currentDate: ZonedDateTime?,
onSelectDate: (Long) -> Unit,
onDismiss: () -> Unit
onDismiss: () -> Unit,
) {
val calendar = Calendar.getInstance()
val realDate = currentDate?.toEpochSecond()?.let {
@ -41,7 +41,7 @@ fun AllInDatePicker(
Text(
text = stringResource(id = R.string.Validate),
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allIn_MainGradient
brush = AllInTheme.colors.allInMainGradient
)
)
}
@ -50,36 +50,36 @@ fun AllInDatePicker(
TextButton(onClick = onDismiss) {
Text(
text = stringResource(id = R.string.Cancel),
color = AllInTheme.themeColors.on_background_2,
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.h3
)
}
},
colors = DatePickerDefaults.colors(
containerColor = AllInTheme.themeColors.main_surface
containerColor = AllInTheme.themeColors.mainSurface
)
){
) {
DatePicker(
state = datePickerState,
colors = DatePickerDefaults.colors(
todayDateBorderColor = AllInTheme.colors.allIn_Blue,
selectedDayContainerColor = AllInTheme.colors.allIn_Blue,
todayContentColor = AllInTheme.colors.allIn_Blue,
dayContentColor = AllInTheme.colors.allIn_Blue,
todayDateBorderColor = AllInTheme.colors.allInBlue,
selectedDayContainerColor = AllInTheme.colors.allInBlue,
todayContentColor = AllInTheme.colors.allInBlue,
dayContentColor = AllInTheme.colors.allInBlue,
dividerColor = AllInTheme.themeColors.border,
containerColor = AllInTheme.themeColors.background,
titleContentColor = AllInTheme.themeColors.on_main_surface,
headlineContentColor = AllInTheme.themeColors.on_main_surface,
subheadContentColor = AllInTheme.themeColors.on_background_2,
titleContentColor = AllInTheme.themeColors.onMainSurface,
headlineContentColor = AllInTheme.themeColors.onMainSurface,
subheadContentColor = AllInTheme.themeColors.onBackground2,
dateTextFieldColors = OutlinedTextFieldDefaults.colors(
focusedContainerColor = AllInTheme.themeColors.main_surface,
unfocusedContainerColor = AllInTheme.themeColors.main_surface,
focusedBorderColor = AllInTheme.colors.allIn_Purple,
focusedContainerColor = AllInTheme.themeColors.mainSurface,
unfocusedContainerColor = AllInTheme.themeColors.mainSurface,
focusedBorderColor = AllInTheme.colors.allInPurple,
unfocusedBorderColor = AllInTheme.themeColors.border,
focusedTextColor = AllInTheme.themeColors.on_main_surface,
unfocusedTextColor = AllInTheme.themeColors.on_main_surface,
focusedLabelColor = AllInTheme.colors.allIn_Purple,
unfocusedLabelColor = AllInTheme.themeColors.on_main_surface,
focusedTextColor = AllInTheme.themeColors.onMainSurface,
unfocusedTextColor = AllInTheme.themeColors.onMainSurface,
focusedLabelColor = AllInTheme.colors.allInPurple,
unfocusedLabelColor = AllInTheme.themeColors.onMainSurface,
)
)
)

@ -5,13 +5,21 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@ -25,9 +33,9 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun AllInDetailsDrawer(
text: String = stringResource(id = R.string.Details),
textColor: Color = AllInTheme.themeColors.on_background_2,
content: @Composable ColumnScope.()->Unit
){
textColor: Color = AllInTheme.themeColors.onBackground2,
content: @Composable ColumnScope.() -> Unit,
) {
val interactionSource = remember { MutableInteractionSource() }
var isOpen by remember { mutableStateOf(false) }
@ -47,7 +55,7 @@ fun AllInDetailsDrawer(
isOpen = !isOpen
}
)
){
) {
Text(
text = text,
style = AllInTheme.typography.s,
@ -55,15 +63,15 @@ fun AllInDetailsDrawer(
fontSize = 15.sp
)
Icon(
imageVector = with(Icons.Default){
if(isOpen) ExpandLess else ExpandMore
imageVector = with(Icons.Default) {
if (isOpen) ExpandLess else ExpandMore
},
contentDescription = null,
tint = textColor,
modifier = Modifier.size(15.dp)
)
}
AnimatedVisibility(visible = isOpen){
AnimatedVisibility(visible = isOpen) {
Column {
content()
}
@ -76,6 +84,6 @@ fun AllInDetailsDrawer(
@Composable
private fun AllInDetailsDrawerPreview() {
AllInTheme {
AllInDetailsDrawer{}
AllInDetailsDrawer {}
}
}

@ -16,15 +16,15 @@ import fr.iut.alldev.allin.theme.AllInTheme
fun AllInGradientButton(
text: String,
modifier: Modifier = Modifier,
onClick: ()->Unit
onClick: () -> Unit,
) {
AllInCard(
onClick = onClick,
modifier = modifier
.shadow(
colors = listOf(
AllInTheme.colors.allIn_Pink,
AllInTheme.colors.allIn_Blue
AllInTheme.colors.allInPink,
AllInTheme.colors.allInBlue
),
blurRadius = 20.dp,
alpha = .5f,
@ -32,7 +32,7 @@ fun AllInGradientButton(
)
.fillMaxWidth(),
radius = 10.dp,
backgroundBrush = AllInTheme.colors.allIn_MainGradient
backgroundBrush = AllInTheme.colors.allInMainGradient
) {
Text(
text = text,

@ -25,22 +25,22 @@ import racra.compose.smooth_corner_rect_library.AbsoluteSmoothCornerShape
@Composable
fun AllInIconChip(
text: String,
isSelected: Boolean = false,
onClick: ()->Unit = {},
modifier: Modifier = Modifier,
isSelected: Boolean = false,
onClick: () -> Unit = {},
radius: Dp = 15.dp,
selectedColor: Color = AllInTheme.colors.allIn_Purple,
selectedColor: Color = AllInTheme.colors.allInPurple,
unselectedColor: Color = AllInTheme.themeColors.background,
leadingIcon: ImageVector
leadingIcon: ImageVector,
) {
val contentColor = if(isSelected) AllInTheme.colors.white else selectedColor
val contentColor = if (isSelected) AllInTheme.colors.white else selectedColor
Card(
modifier = modifier,
shape = AbsoluteSmoothCornerShape(radius, 100),
onClick = onClick,
border = if(!isSelected) BorderStroke(1.dp, AllInTheme.themeColors.border) else null,
border = if (!isSelected) BorderStroke(1.dp, AllInTheme.themeColors.border) else null,
colors = CardDefaults.cardColors(
containerColor = if(isSelected) selectedColor else unselectedColor
containerColor = if (isSelected) selectedColor else unselectedColor
)
) {
Row(

@ -2,7 +2,15 @@ package fr.iut.alldev.allin.ui.core
import android.content.res.Configuration
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.*
import androidx.compose.animation.core.CubicBezierEasing
import androidx.compose.animation.core.LinearEasing
import androidx.compose.animation.core.VectorConverter
import androidx.compose.animation.core.animateFloat
import androidx.compose.animation.core.animateValue
import androidx.compose.animation.core.infiniteRepeatable
import androidx.compose.animation.core.keyframes
import androidx.compose.animation.core.rememberInfiniteTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.foundation.Canvas
@ -42,7 +50,7 @@ import kotlin.math.max
fun AllInLoading(
modifier: Modifier = Modifier,
visible: Boolean,
brush: Brush = AllInTheme.colors.allIn_MainGradient
brush: Brush = AllInTheme.colors.allInMainGradient,
) {
val interactionSource = remember { MutableInteractionSource() }
AnimatedVisibility(
@ -68,7 +76,7 @@ fun AllInLoading(
indication = null,
onClick = {}
)
.background(AllInTheme.themeColors.main_surface.copy(alpha = .4f))
.background(AllInTheme.themeColors.mainSurface.copy(alpha = .4f))
) {
AllInCircularProgressIndicator(
modifier = Modifier
@ -85,7 +93,7 @@ fun AllInLoading(
@Composable
fun AllInCircularProgressIndicator(
modifier: Modifier = Modifier,
brush: Brush = AllInTheme.colors.allIn_MainGradient,
brush: Brush = AllInTheme.colors.allInMainGradient,
strokeWidth: Dp = ProgressIndicatorDefaults.CircularStrokeWidth,
strokeCap: StrokeCap = ProgressIndicatorDefaults.CircularIndeterminateStrokeCap,
) {
@ -93,7 +101,7 @@ fun AllInCircularProgressIndicator(
Stroke(width = strokeWidth.toPx(), cap = strokeCap)
}
val transition = rememberInfiniteTransition()
val transition = rememberInfiniteTransition(label = "")
val currentRotation = transition.animateValue(
0,
RotationsPerCycle,
@ -113,7 +121,7 @@ fun AllInCircularProgressIndicator(
durationMillis = RotationDuration,
easing = LinearEasing
)
)
), label = ""
)
val endAngle = transition.animateFloat(
0f,
@ -121,10 +129,10 @@ fun AllInCircularProgressIndicator(
infiniteRepeatable(
animation = keyframes {
durationMillis = HeadAndTailAnimationDuration + HeadAndTailDelayDuration
0f at 0 with CircularEasing
0f at 0 using CircularEasing
JumpRotationAngle at HeadAndTailAnimationDuration
}
)
), label = ""
)
val startAngle = transition.animateFloat(
0f,
@ -132,10 +140,10 @@ fun AllInCircularProgressIndicator(
infiniteRepeatable(
animation = keyframes {
durationMillis = HeadAndTailAnimationDuration + HeadAndTailDelayDuration
0f at HeadAndTailDelayDuration with CircularEasing
0f at HeadAndTailDelayDuration using CircularEasing
JumpRotationAngle at durationMillis
}
)
), label = ""
)
Canvas(
modifier
@ -162,7 +170,7 @@ private fun DrawScope.drawCircularIndicator(
startAngle: Float,
sweep: Float,
color: Color,
stroke: Stroke
stroke: Stroke,
) {
val diameterOffset = stroke.width / 2
val arcDimen = size.width - 2 * diameterOffset
@ -181,7 +189,7 @@ private fun DrawScope.drawCircularIndicator(
startAngle: Float,
sweep: Float,
brush: Brush,
stroke: Stroke
stroke: Stroke,
) {
val diameterOffset = stroke.width / 2
val arcDimen = size.width - 2 * diameterOffset
@ -201,7 +209,7 @@ private fun DrawScope.drawIndeterminateCircularIndicator(
strokeWidth: Dp,
sweep: Float,
brush: Brush,
stroke: Stroke
stroke: Stroke,
) {
val strokeCapOffset = if (stroke.cap == StrokeCap.Butt) {
0f

@ -12,15 +12,15 @@ import fr.iut.alldev.allin.theme.AllInTheme
fun AllInRadioButton(
modifier: Modifier = Modifier,
checked: Boolean,
unCheckedColor: Color = Color.Transparent
unCheckedColor: Color = Color.Transparent,
) {
AllInCard(
radius = 100.dp,
borderColor = AllInTheme.colors.allIn_Mint,
borderWidth = if(!checked) 1.dp else null,
backgroundColor = if (checked) AllInTheme.colors.allIn_Purple else unCheckedColor,
borderColor = AllInTheme.colors.allInMint,
borderWidth = if (!checked) 1.dp else null,
backgroundColor = if (checked) AllInTheme.colors.allInPurple else unCheckedColor,
modifier = modifier.size(12.dp)
){}
) {}
}
@Preview
@ -35,7 +35,7 @@ private fun AllInRadioButtonNotCheckedPreview() {
@Composable
private fun AllInRadioButtonNotCheckedFilledPreview() {
AllInTheme {
AllInRadioButton(checked = false, unCheckedColor = AllInTheme.colors.allIn_Mint)
AllInRadioButton(checked = false, unCheckedColor = AllInTheme.colors.allInMint)
}
}

@ -4,7 +4,12 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
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.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
@ -26,16 +31,16 @@ fun AllInRetractableCard(
text: String,
boldText: String = "",
isOpen: Boolean,
setIsOpen: (Boolean)->Unit,
setIsOpen: (Boolean) -> Unit,
borderWidth: Dp? = null,
interactionSource: MutableInteractionSource = MutableInteractionSource(),
content: @Composable ()->Unit
content: @Composable () -> Unit,
) {
AllInCard(
modifier = modifier.fillMaxWidth(),
borderWidth = borderWidth,
borderColor = AllInTheme.colors.allIn_Purple.copy(.5f)
){
borderColor = AllInTheme.colors.allInPurple.copy(.5f)
) {
Column(
Modifier.animateContentSize()
) {
@ -55,25 +60,25 @@ fun AllInRetractableCard(
query = boldText,
highlightStyle = SpanStyle(
fontWeight = FontWeight.Bold,
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontStyle = AllInTheme.typography.h2.fontStyle
),
color = AllInTheme.themeColors.on_background_2,
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.r,
fontSize = 16.sp,
modifier = Modifier.weight(1f)
)
Icon(
imageVector = with(Icons.Default){
if(isOpen) ExpandLess else ExpandMore
imageVector = with(Icons.Default) {
if (isOpen) ExpandLess else ExpandMore
},
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
tint = AllInTheme.colors.allInPurple,
modifier = Modifier.size(30.dp)
)
}
AnimatedVisibility(isOpen){
Column{
AnimatedVisibility(isOpen) {
Column {
HorizontalDivider(color = AllInTheme.themeColors.border)
content()
}

@ -17,18 +17,18 @@ import fr.iut.alldev.allin.theme.AllInTheme
fun AllInSectionButton(
text: String,
isSelected: Boolean,
onClick: (Int)->Unit
onClick: (Int) -> Unit,
) {
val style = if(isSelected){
val style = if (isSelected) {
AllInTheme.typography.h3.copy(
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.ExtraBold
)
}else{
} else {
AllInTheme.typography.h3.copy(
color = AllInTheme.themeColors.on_background_2,
color = AllInTheme.themeColors.onBackground2,
fontSize = 15.sp,
textAlign = TextAlign.Center,
fontWeight = FontWeight.SemiBold

@ -5,10 +5,19 @@ import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.animateContentSize
import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
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.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.filled.HelpOutline
import androidx.compose.material.icons.filled.*
import androidx.compose.material.icons.filled.Edit
import androidx.compose.material.icons.filled.ExpandLess
import androidx.compose.material.icons.filled.ExpandMore
import androidx.compose.material.icons.filled.PinEnd
import androidx.compose.material.icons.filled.SportsFootball
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
@ -27,7 +36,7 @@ import fr.iut.alldev.allin.theme.AllInTheme
class SelectionElement(
val textId: Int,
val imageVector: ImageVector
val imageVector: ImageVector,
)
@Composable
@ -35,10 +44,10 @@ fun AllInSelectionLine(
text: String,
iconVector: ImageVector?,
modifier: Modifier = Modifier,
onClick: ()->Unit,
onClick: () -> Unit,
trailingIcon: ImageVector? = null,
interactionSource: MutableInteractionSource
){
interactionSource: MutableInteractionSource,
) {
Row(
modifier = modifier
.clickable(
@ -54,13 +63,13 @@ fun AllInSelectionLine(
Icon(
imageVector = it,
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
tint = AllInTheme.colors.allInPurple,
modifier = Modifier.size(20.dp)
)
}
Text(
text = text,
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
style = AllInTheme.typography.h2,
fontWeight = FontWeight.Bold,
modifier = Modifier.weight(1f)
@ -69,7 +78,7 @@ fun AllInSelectionLine(
Icon(
imageVector = trailingIcon,
contentDescription = null,
tint = AllInTheme.colors.allIn_Purple,
tint = AllInTheme.colors.allInPurple,
modifier = Modifier
.size(30.dp)
)
@ -82,30 +91,30 @@ fun AllInSelectionLine(
fun AllInSelectionBox(
modifier: Modifier = Modifier,
isOpen: Boolean,
setIsOpen: (Boolean)->Unit,
setIsOpen: (Boolean) -> Unit,
selected: SelectionElement?,
setSelected: (SelectionElement)->Unit,
elements: List<SelectionElement>
setSelected: (SelectionElement) -> Unit,
elements: List<SelectionElement>,
) {
val interactionSource = remember { MutableInteractionSource() }
AllInCard(modifier.fillMaxWidth()){
AllInCard(modifier.fillMaxWidth()) {
Column(
Modifier.animateContentSize()
) {
AllInSelectionLine(
text = selected?.let{
text = selected?.let {
stringResource(id = it.textId)
} ?: "",
iconVector = selected?.let{
iconVector = selected?.let {
selected.imageVector
},
onClick = { setIsOpen(!isOpen) },
interactionSource = interactionSource,
trailingIcon = with(Icons.Default){
if(isOpen) ExpandLess else ExpandMore
trailingIcon = with(Icons.Default) {
if (isOpen) ExpandLess else ExpandMore
}
)
AnimatedVisibility(isOpen){
AnimatedVisibility(isOpen) {
Column {
HorizontalDivider(color = AllInTheme.themeColors.border)
elements.filter { it != selected }.forEach { element ->

@ -37,17 +37,17 @@ fun AllInTextField(
trailingContent: @Composable (() -> Unit)? = null,
placeholderFontSize: TextUnit = 18.sp,
multiLine: Boolean = false,
onValueChange: (String)->Unit,
onValueChange: (String) -> Unit,
errorText: String? = null,
bringIntoViewRequester: BringIntoViewRequester,
visualTransformation: VisualTransformation = VisualTransformation.None,
keyboardType: KeyboardType = KeyboardType.Text,
imeAction: ImeAction = ImeAction.Default,
keyboardActions: KeyboardActions = KeyboardActions.Default,
borderColor: Color = AllInTheme.themeColors.on_background_2,
borderColor: Color = AllInTheme.themeColors.onBackground2,
containerColor: Color = AllInTheme.themeColors.background,
textColor: Color = AllInTheme.themeColors.on_main_surface,
placeholderColor: Color = AllInTheme.themeColors.on_background_2
textColor: Color = AllInTheme.themeColors.onMainSurface,
placeholderColor: Color = AllInTheme.themeColors.onBackground2,
) {
val scope = rememberCoroutineScope()
var hasFocus by remember { mutableStateOf(false) }
@ -65,24 +65,23 @@ fun AllInTextField(
OutlinedTextField(
value = textFieldValue,
isError = errorText!=null,
isError = errorText != null,
modifier = modifier
.onFocusChanged {
hasFocus = it.hasFocus
if (it.isFocused) {
scope.launch {
bringIntoViewRequester.bringIntoView()
hasFocus = it.hasFocus
if (it.isFocused) {
scope.launch {
bringIntoViewRequester.bringIntoView()
}
}
}
}
,
},
supportingText = errorText?.let {
{ AllInErrorLine(text = it) }
},
visualTransformation = visualTransformation,
singleLine = !multiLine,
onValueChange = {
if(maxChar==null || it.text.length<=maxChar) {
if (maxChar == null || it.text.length <= maxChar) {
textFieldValue = it
onValueChange(it.text)
}
@ -93,16 +92,16 @@ fun AllInTextField(
fontSize = placeholderFontSize,
style = AllInTheme.typography.r,
color = placeholderColor,
maxLines = if(multiLine) 3 else 1,
maxLines = if (multiLine) 3 else 1,
overflow = TextOverflow.Ellipsis
)
},
trailingIcon = trailingContent ?: trailingIcon?.let{
trailingIcon = trailingContent ?: trailingIcon?.let {
@Composable {
Icon(
imageVector = it,
contentDescription = null,
tint = AllInTheme.colors.allIn_LightGrey300
tint = AllInTheme.colors.allInLightGrey300
)
}
},
@ -111,7 +110,7 @@ fun AllInTextField(
keyboardOptions = KeyboardOptions(keyboardType = keyboardType, imeAction = imeAction),
keyboardActions = keyboardActions,
shape = AbsoluteSmoothCornerShape(10.dp, 100),
colors = OutlinedTextFieldDefaults.colors(
colors = OutlinedTextFieldDefaults.colors(
cursorColor = textColor,
focusedBorderColor = borderColor,
unfocusedBorderColor = borderColor,
@ -135,36 +134,36 @@ fun AllInPasswordField(
keyboardType: KeyboardType = KeyboardType.Password,
keyboardActions: KeyboardActions = KeyboardActions.Default,
errorText: String? = null,
onValueChange: (String)->Unit,
onValueChange: (String) -> Unit,
bringIntoViewRequester: BringIntoViewRequester,
isHiddenByDefault: Boolean = true
){
var hidden by remember{
isHiddenByDefault: Boolean = true,
) {
var hidden by remember {
mutableStateOf(isHiddenByDefault)
}
AllInTextField(
modifier = modifier,
errorText = errorText,
placeholder = placeholder,
imeAction = imeAction,
keyboardActions = keyboardActions,
visualTransformation = if (hidden) PasswordVisualTransformation() else VisualTransformation.None,
value = value,
onValueChange = onValueChange,
bringIntoViewRequester = bringIntoViewRequester,
trailingContent = {
IconButton(
onClick = { hidden = !hidden }
) {
Icon(
imageVector = if (hidden) Icons.Default.VisibilityOff else Icons.Default.Visibility,
contentDescription = null,
tint = AllInTheme.colors.allIn_LightGrey300
)
}
},
keyboardType = keyboardType
)
AllInTextField(
modifier = modifier,
errorText = errorText,
placeholder = placeholder,
imeAction = imeAction,
keyboardActions = keyboardActions,
visualTransformation = if (hidden) PasswordVisualTransformation() else VisualTransformation.None,
value = value,
onValueChange = onValueChange,
bringIntoViewRequester = bringIntoViewRequester,
trailingContent = {
IconButton(
onClick = { hidden = !hidden }
) {
Icon(
imageVector = if (hidden) Icons.Default.VisibilityOff else Icons.Default.Visibility,
contentDescription = null,
tint = AllInTheme.colors.allInLightGrey300
)
}
},
keyboardType = keyboardType
)
}
@OptIn(ExperimentalFoundationApi::class)

@ -23,7 +23,7 @@ import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.theme.AllInTheme
enum class IconPosition{
enum class IconPosition {
LEADING,
TRAILING
}
@ -36,10 +36,10 @@ fun AllInTextIcon(
color: Color,
position: IconPosition = IconPosition.TRAILING,
size: Int = 15,
iconSize: Int = size
iconSize: Int = size,
) {
val direction =
if(position==IconPosition.LEADING) LayoutDirection.Rtl
if (position == IconPosition.LEADING) LayoutDirection.Rtl
else LayoutDirection.Ltr
Box(modifier) {
CompositionLocalProvider(
@ -75,10 +75,10 @@ fun AllInTextIcon(
color: Color,
position: IconPosition = IconPosition.TRAILING,
size: Int = 15,
iconSize: Int = size
iconSize: Int = size,
) {
val direction =
if(position==IconPosition.LEADING) LayoutDirection.Rtl
if (position == IconPosition.LEADING) LayoutDirection.Rtl
else LayoutDirection.Ltr
Box(modifier) {
CompositionLocalProvider(
@ -113,7 +113,7 @@ private fun AllInTextIconPreview() {
AllInTextIcon(
text = "value",
icon = Icons.Default.Fireplace,
color = AllInTheme.colors.allIn_Blue
color = AllInTheme.colors.allInBlue
)
}
}
@ -125,7 +125,7 @@ private fun AllInTextIconReversePreview() {
AllInTextIcon(
text = "value",
icon = AllInTheme.icons.allCoins(),
color = AllInTheme.colors.allIn_Blue,
color = AllInTheme.colors.allInBlue,
position = IconPosition.LEADING
)
}

@ -15,7 +15,7 @@ fun AllInTimePicker(
hour: Int?,
minutes: Int?,
onSelectHour: (Int, Int) -> Unit,
onDismiss: () -> Unit
onDismiss: () -> Unit,
) {
val calendar = Calendar.getInstance()
val timePickerState = rememberTimePickerState(
@ -36,7 +36,7 @@ fun AllInTimePicker(
Text(
text = stringResource(id = R.string.Validate),
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allIn_MainGradient
brush = AllInTheme.colors.allInMainGradient
)
)
}
@ -45,7 +45,7 @@ fun AllInTimePicker(
TextButton(onClick = onDismiss) {
Text(
text = stringResource(id = R.string.Cancel),
color = AllInTheme.themeColors.on_background_2,
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.h3
)
}
@ -54,16 +54,16 @@ fun AllInTimePicker(
TimePicker(
state = timePickerState,
colors = TimePickerDefaults.colors(
selectorColor = AllInTheme.colors.allIn_Purple,
selectorColor = AllInTheme.colors.allInPurple,
containerColor = AllInTheme.themeColors.background,
clockDialColor = AllInTheme.themeColors.background_2,
clockDialUnselectedContentColor = AllInTheme.themeColors.on_main_surface,
clockDialSelectedContentColor = AllInTheme.themeColors.background_2,
clockDialColor = AllInTheme.themeColors.background2,
clockDialUnselectedContentColor = AllInTheme.themeColors.onMainSurface,
clockDialSelectedContentColor = AllInTheme.themeColors.background2,
)
)
)
},
containerColor = AllInTheme.themeColors.main_surface
containerColor = AllInTheme.themeColors.mainSurface
)
}

@ -10,7 +10,11 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
import androidx.compose.material3.*
import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.Icon
import androidx.compose.material3.Text
import androidx.compose.material3.TooltipState
import androidx.compose.material3.rememberTooltipState
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
@ -28,8 +32,8 @@ import kotlinx.coroutines.launch
private fun launchTooltip(
scope: CoroutineScope,
tooltipState: TooltipState
){
tooltipState: TooltipState,
) {
scope.launch {
tooltipState.show()
}
@ -38,12 +42,12 @@ private fun launchTooltip(
@OptIn(ExperimentalMaterial3Api::class, ExperimentalFoundationApi::class)
@Composable
fun AllInTitleInfo(
modifier: Modifier = Modifier,
text: String,
tooltipText: String,
icon: ImageVector,
tooltipState: TooltipState = rememberTooltipState(isPersistent = true),
modifier: Modifier = Modifier,
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }
tooltipState: TooltipState = rememberTooltipState(isPersistent = true),
interactionSource: MutableInteractionSource = remember { MutableInteractionSource() },
) {
val scope = rememberCoroutineScope()
Row(
@ -62,14 +66,14 @@ fun AllInTitleInfo(
style = AllInTheme.typography.h2,
fontWeight = FontWeight.Bold,
fontSize = 15.sp,
color = AllInTheme.themeColors.on_main_surface
color = AllInTheme.themeColors.onMainSurface
)
Spacer(modifier = Modifier.width(5.dp))
AllInTooltip(text = tooltipText, state = tooltipState) {
Icon(
imageVector = icon,
contentDescription = null,
tint = AllInTheme.themeColors.on_main_surface,
tint = AllInTheme.themeColors.onMainSurface,
modifier = Modifier
.size(15.dp)
.alpha(.8f)

@ -27,14 +27,14 @@ fun AllInTooltip(
TooltipBox(
positionProvider = TooltipDefaults.rememberPlainTooltipPositionProvider(),
tooltip = {
AllInPlainTooltip{
AllInPlainTooltip {
Text(
text = text,
color = AllInTheme.colors.allIn_LightGrey200,
color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r,
fontSize = 10.sp
fontSize = 12.sp
)
}
}
},
state = state
) {
@ -60,15 +60,15 @@ private val AllInPlainTooltipContentPadding =
@Composable
fun AllInPlainTooltip(
modifier: Modifier = Modifier,
containerColor: Color = AllInTheme.colors.allIn_Dark,
containerColor: Color = AllInTheme.colors.allInDark,
borderWidth: Dp = 1.dp,
borderColor: Color = AllInTheme.colors.allIn_DarkGrey100,
borderColor: Color = AllInTheme.colors.allInDarkGrey100,
shape: Shape = AbsoluteSmoothCornerShape(10.dp, 100),
content: @Composable () -> Unit
content: @Composable () -> Unit,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
){
) {
Surface(
shape = shape,
border = BorderStroke(borderWidth, borderColor),
@ -107,8 +107,8 @@ class AllInArrowShape : Shape {
) =
Outline.Generic(
Path().apply {
lineTo(size.width /2 , size.height)
lineTo(size.width , 0f)
lineTo(size.width / 2, size.height)
lineTo(size.width, 0f)
}
)
}
@ -120,7 +120,7 @@ private fun AllInTooltipPreview() {
AllInPlainTooltip(content = {
Text(
text = "Généralement une question qui sera répondu par les utilisateurs.",
color = AllInTheme.colors.allIn_LightGrey200,
color = AllInTheme.colors.allInLightGrey200,
style = AllInTheme.typography.r,
fontSize = 10.sp
)

@ -25,17 +25,17 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun ProfilePicture(
modifier: Modifier = Modifier,
image: Painter? = null,
borderWidth: Dp? = null,
size: Dp = 80.dp,
modifier: Modifier = Modifier
) {
val shape = RoundedCornerShape(100)
Card(
modifier = modifier.size(size),
shape = shape,
colors = CardDefaults.cardColors(containerColor = AllInTheme.colors.allIn_DarkGrey100),
border = borderWidth?.let{BorderStroke(it, AllInTheme.colors.allIn_DarkGrey50)}
colors = CardDefaults.cardColors(containerColor = AllInTheme.colors.allInDarkGrey100),
border = borderWidth?.let { BorderStroke(it, AllInTheme.colors.allInDarkGrey50) }
) {
Box(Modifier.fillMaxSize()) {
image?.let {
@ -47,7 +47,7 @@ fun ProfilePicture(
.fillMaxSize()
.clip(shape)
)
} ?: run{
} ?: run {
Icon(
imageVector = Icons.Default.PhotoCamera,
tint = AllInTheme.colors.white,
@ -76,7 +76,7 @@ private fun ProfilePictureDefaultPreview() {
private fun ProfilePicturePreview() {
AllInTheme {
ProfilePicture(
painterResource(id = R.drawable.money_with_wings)
image = painterResource(id = R.drawable.money_with_wings)
)
}
}

@ -15,11 +15,11 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun RainbowButton(
modifier: Modifier = Modifier,
text: String,
onClick: ()->Unit,
onClick: () -> Unit,
enabled: Boolean = true,
rippleColor: Color = AllInTheme.colors.allIn_Blue,
modifier: Modifier = Modifier
rippleColor: Color = AllInTheme.colors.allInBlue,
) {
AllInRipple(rippleColor) {
AllInCard(
@ -32,11 +32,11 @@ fun RainbowButton(
with(AllInTheme.typography.h2) {
if (enabled) {
copy(
brush = AllInTheme.colors.allIn_TextGradient
brush = AllInTheme.colors.allInTextGradient
)
} else {
copy(
color = AllInTheme.themeColors.disabled_border
color = AllInTheme.themeColors.disabledBorder
)
}
}

@ -2,7 +2,13 @@ package fr.iut.alldev.allin.ui.core
import androidx.compose.foundation.Image
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.size
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.shape.AbsoluteRoundedCornerShape
import androidx.compose.material3.Icon
import androidx.compose.runtime.Composable
@ -17,14 +23,14 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun StatBar(
percentage: Float
percentage: Float,
) {
val radius100percent = if(percentage==1f) 50 else 0
val radius0percent = if(percentage==0f) 50 else 0
Box{
val radius100percent = if (percentage == 1f) 50 else 0
val radius0percent = if (percentage == 0f) 50 else 0
Box {
Row(
Modifier.align(Alignment.Center)
){
) {
Box(
modifier = Modifier
.height(20.dp)
@ -37,10 +43,10 @@ fun StatBar(
bottomRightPercent = radius100percent
)
)
.background(AllInTheme.colors.allIn_Bar1stGradient)
.background(AllInTheme.colors.allInBar1stGradient)
)
if(percentage!=0f && percentage!=1f) {
if (percentage != 0f && percentage != 1f) {
Spacer(modifier = Modifier.width(15.dp))
}
Box(
@ -55,23 +61,25 @@ fun StatBar(
bottomRightPercent = 50
)
)
.background(AllInTheme.colors.allIn_Bar2ndGradient)
.background(AllInTheme.colors.allInBar2ndGradient)
)
}
PercentagePositionnedElement(percentage = percentage) {
when(percentage){
when (percentage) {
0f -> Icon(
painter = painterResource(id = R.drawable.fire_solid),
tint = AllInTheme.colors.allIn_BarPink,
tint = AllInTheme.colors.allInBarPink,
contentDescription = null,
modifier = Modifier.size(32.dp)
)
)
1f -> Icon(
painter = painterResource(id = R.drawable.fire_solid),
tint = AllInTheme.colors.allIn_BarPurple,
tint = AllInTheme.colors.allInBarPurple,
contentDescription = null,
modifier = Modifier.size(32.dp)
)
else -> Image(
painter = painterResource(id = R.drawable.bar_flame),
contentDescription = null,

@ -18,7 +18,7 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun BetDateTimeChip(
text: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Card(
modifier = modifier.wrapContentSize(),
@ -31,7 +31,7 @@ fun BetDateTimeChip(
modifier = Modifier.padding(vertical = 8.dp, horizontal = 16.dp),
style = AllInTheme.typography.h3,
textAlign = TextAlign.Center,
color = AllInTheme.colors.allIn_Purple
color = AllInTheme.colors.allInPurple
)
}
}

@ -17,7 +17,7 @@ fun BetDateTimeRow(
label: String,
date: String,
time: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Row(
verticalAlignment = Alignment.CenterVertically,
@ -28,7 +28,7 @@ fun BetDateTimeRow(
text = label,
fontSize = 15.sp,
style = AllInTheme.typography.m,
color = AllInTheme.themeColors.on_background_2
color = AllInTheme.themeColors.onBackground2
)
BetDateTimeChip(date)
BetDateTimeChip(time)
@ -39,7 +39,7 @@ fun BetDateTimeRow(
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun BetDateTimeRowPreview() {
AllInTheme{
AllInTheme {
BetDateTimeRow(label = "Commence le", date = "11 Sept.", time = "13:00")
}
}

@ -1,7 +1,10 @@
package fr.iut.alldev.allin.ui.core.bet
import android.content.res.Configuration
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.height
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -13,15 +16,15 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.core.HighlightedText
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.HighlightedText
@Composable
fun BetTitleHeader(
title: String,
category: String,
creator: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Column(modifier) {
Row(
@ -32,24 +35,24 @@ fun BetTitleHeader(
query = creator,
highlightStyle = SpanStyle(
fontWeight = FontWeight.Bold,
color = AllInTheme.themeColors.on_main_surface
color = AllInTheme.themeColors.onMainSurface
),
fontSize = 12.sp,
style = AllInTheme.typography.s,
color = AllInTheme.themeColors.on_background_2
color = AllInTheme.themeColors.onBackground2
)
}
Spacer(modifier = Modifier.height(11.dp))
Text(
text = category,
fontSize = 15.sp,
color = AllInTheme.themeColors.on_background_2,
color = AllInTheme.themeColors.onBackground2,
style = AllInTheme.typography.m
)
Text(
text = title,
fontSize = 20.sp,
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h1
)
}
@ -60,6 +63,10 @@ fun BetTitleHeader(
@Composable
private fun BetTitleHeaderPreview() {
AllInTheme {
BetTitleHeader(title = "Emre va réussir son TP de CI/CD mercredi?", category = "Études", creator = "Lucas")
BetTitleHeader(
title = "Emre va réussir son TP de CI/CD mercredi?",
category = "Études",
creator = "Lucas"
)
}
}

@ -20,24 +20,29 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun AllInTopBarCoinCounter(
amount:Int,
amount: Int,
modifier: Modifier = Modifier,
backgroundColor: Color = AllInTheme.colors.white,
textColor: Color = AllInTheme.colors.allIn_Dark,
iconColor: Color = AllInTheme.colors.allIn_Blue,
modifier: Modifier = Modifier
textColor: Color = AllInTheme.colors.allInDark,
iconColor: Color = AllInTheme.colors.allInBlue,
) {
Card(modifier = modifier.wrapContentSize(), shape = RoundedCornerShape(topStartPercent = 50, bottomStartPercent = 50)) {
Card(
modifier = modifier.wrapContentSize(),
shape = RoundedCornerShape(topStartPercent = 50, bottomStartPercent = 50)
) {
Row(
modifier = Modifier
.background(backgroundColor)
.padding(horizontal = 13.dp, vertical = 5.dp),
.background(backgroundColor)
.padding(horizontal = 13.dp, vertical = 5.dp),
horizontalArrangement = Arrangement.spacedBy(7.dp),
verticalAlignment = Alignment.CenterVertically
) {
Text(text = amount.toString(),
Text(
text = amount.toString(),
color = textColor,
style = AllInTheme.typography.h1,
fontSize = 20.sp)
fontSize = 20.sp
)
Icon(
painter = AllInTheme.icons.allCoins(),
tint = iconColor,

@ -1,7 +1,11 @@
package fr.iut.alldev.allin.ui.core.topbar
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.runtime.Composable
@ -16,14 +20,14 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun AllInTopBar(
onMenuClicked: ()->Unit,
coinAmount: Int
onMenuClicked: () -> Unit,
coinAmount: Int,
) {
Box(
modifier = Modifier
.height(86.dp)
.fillMaxWidth()
.background(brush = AllInTheme.colors.allIn_MainGradient)
.background(brush = AllInTheme.colors.allInMainGradient)
) {
IconButton(
onClick = onMenuClicked,
@ -35,7 +39,8 @@ fun AllInTopBar(
painterResource(id = R.drawable.allin_menu),
modifier = Modifier.size(30.dp),
contentDescription = null,
tint = Color.White)
tint = Color.White
)
}
Icon(
painter = painterResource(R.drawable.allin),
@ -55,7 +60,7 @@ fun AllInTopBar(
@Preview
@Composable
private fun AllInTopBarPreview(){
private fun AllInTopBarPreview() {
AllInTheme {
AllInTopBar(onMenuClicked = { }, coinAmount = 541)
}

@ -2,7 +2,15 @@ package fr.iut.alldev.allin.ui.login
import androidx.compose.foundation.ExperimentalFoundationApi
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.relocation.BringIntoViewRequester
import androidx.compose.foundation.rememberScrollState
import androidx.compose.foundation.text.ClickableText
@ -27,24 +35,28 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.core.*
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInAlertDialog
import fr.iut.alldev.allin.ui.core.AllInGradientButton
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.core.AllInPasswordField
import fr.iut.alldev.allin.ui.core.AllInTextField
@OptIn(ExperimentalFoundationApi::class, ExperimentalMaterial3Api::class)
@Composable
fun LoginScreen(
navigateToDashboard: ()->Unit,
navigateToRegister: ()->Unit,
loginViewModel: LoginViewModel = hiltViewModel()
navigateToDashboard: () -> Unit,
navigateToRegister: () -> Unit,
loginViewModel: LoginViewModel = hiltViewModel(),
) {
val focusManager = LocalFocusManager.current
val bringIntoViewRequester = BringIntoViewRequester()
val loading by remember{ loginViewModel.loading }
var hasLoginError by remember{ loginViewModel.hasError }
val loading by remember { loginViewModel.loading }
var hasLoginError by remember { loginViewModel.hasError }
val (username, setUsername) = remember{ loginViewModel.username }
val (password, setPassword) = remember{ loginViewModel.password }
val (username, setUsername) = remember { loginViewModel.username }
val (password, setPassword) = remember { loginViewModel.password }
val keyboardActions = remember {
KeyboardActions(
@ -61,7 +73,7 @@ fun LoginScreen(
Box(
Modifier
.fillMaxSize()
.background(AllInTheme.themeColors.main_surface)
.background(AllInTheme.themeColors.mainSurface)
.padding(horizontal = 44.dp)
.verticalScroll(rememberScrollState())
) {
@ -71,7 +83,7 @@ fun LoginScreen(
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Login_title),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
textAlign = TextAlign.Center,
fontSize = 40.sp
@ -80,7 +92,7 @@ fun LoginScreen(
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Login_subtitle),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.r,
textAlign = TextAlign.Center,
fontSize = 23.sp
@ -111,13 +123,13 @@ fun LoginScreen(
ClickableText(
text = AnnotatedString(stringResource(id = R.string.forgot_password)),
style = AllInTheme.typography.m.copy(
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
),
modifier = Modifier
.align(Alignment.End)
.padding(top = 15.dp)
){
) {
// TODO : Forgot password
}
Spacer(modifier = Modifier.height(67.dp))
@ -142,7 +154,7 @@ fun LoginScreen(
) {
Text(
text = stringResource(id = R.string.no_account),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
style = AllInTheme.typography.r,
modifier = Modifier.padding(end = 5.dp)
@ -150,7 +162,7 @@ fun LoginScreen(
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Register)),
style = AllInTheme.typography.r.copy(
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
)

@ -10,8 +10,9 @@ import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavHostController
import androidx.navigation.compose.rememberNavController
import fr.iut.alldev.allin.ui.betstatus.BetStatusBottomSheet
import fr.iut.alldev.allin.ui.betstatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.betStatus.BetStatusBottomSheet
import fr.iut.alldev.allin.ui.betStatus.visitor.BetStatusBottomSheetDisplayBetVisitor
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.main.components.AllInScaffold
import fr.iut.alldev.allin.ui.navigation.AllInDrawerNavHost
@ -19,7 +20,6 @@ import fr.iut.alldev.allin.ui.navigation.Routes
import fr.iut.alldev.allin.ui.navigation.TopLevelDestination
import fr.iut.alldev.allin.ui.navigation.drawer.AllInDrawer
import fr.iut.alldev.allin.ui.navigation.popUpTo
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.vo.bet.factory.toBetVO
import kotlinx.coroutines.launch
@ -33,7 +33,7 @@ private val topLevelDestinations = listOf(
@Composable
private fun rememberBetStatusVisibilities()
: Triple<MutableState<Boolean>, MutableState<Boolean>, (Boolean) -> Unit> {
: Triple<MutableState<Boolean>, MutableState<Boolean>, (Boolean) -> Unit> {
val statusVisibility = remember {
mutableStateOf(false)
}
@ -42,10 +42,9 @@ private fun rememberBetStatusVisibilities()
mutableStateOf(false)
}
val setStatusVisibility = {
it: Boolean ->
val setStatusVisibility = { it: Boolean ->
statusVisibility.value = it
if(it) sheetBackVisibility.value = true
if (it) sheetBackVisibility.value = true
}
return Triple(
statusVisibility,
@ -60,15 +59,15 @@ fun MainScreen(
navController: NavHostController = rememberNavController(),
drawerState: DrawerState = rememberDrawerState(initialValue = DrawerValue.Closed),
startDestination: String = Routes.PUBLIC_BETS,
mainViewModel: MainViewModel = hiltViewModel()
mainViewModel: MainViewModel = hiltViewModel(),
) {
val loading by remember{ mainViewModel.loading }
val loading by remember { mainViewModel.loading }
val currentUser = remember{
val currentUser = remember {
mainViewModel.currentUserState
}
val (selectedBet, setSelectedBet) = remember{
val (selectedBet, setSelectedBet) = remember {
mainViewModel.selectedBet
}
@ -84,12 +83,12 @@ fun MainScreen(
val scope = rememberCoroutineScope()
val (statusVisibility, sheetBackVisibility, setStatusVisibility)
= rememberBetStatusVisibilities()
= rememberBetStatusVisibilities()
val bottomSheetState = rememberModalBottomSheetState(
skipPartiallyExpanded = true,
confirmValueChange = {
if(it == SheetValue.Hidden){
if (it == SheetValue.Hidden) {
sheetBackVisibility.value = false
}
true
@ -104,23 +103,23 @@ fun MainScreen(
nbFriends = 5,
nbBets = 35,
bestWin = 362,
navigateTo = {route ->
navigateTo = { route ->
navController.popUpTo(route, startDestination)
}
){
) {
AllInScaffold(
onMenuClicked = { scope.launch { drawerState.open() } },
onMenuClicked = { scope.launch { drawerState.open() } },
coinAmount = currentUser.userCoins.value,
drawerState = drawerState
) {
LaunchedEffect(key1 = it){
LaunchedEffect(key1 = it) {
betStatusDisplayVisitor.paddingValues.value = it
}
Column(
modifier = Modifier
.padding(top = it.calculateTopPadding())
.fillMaxSize()
.background(AllInTheme.themeColors.main_surface),
.background(AllInTheme.themeColors.mainSurface),
horizontalAlignment = Alignment.CenterHorizontally
) {
AllInDrawerNavHost(

@ -4,7 +4,13 @@ import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.offset
import androidx.compose.material3.DrawerState
import androidx.compose.material3.Scaffold
import androidx.compose.runtime.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.derivedStateOf
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.unit.dp
@ -13,25 +19,24 @@ import kotlin.math.abs
@Composable
fun AllInScaffold(
onMenuClicked: ()->Unit,
onMenuClicked: () -> Unit,
coinAmount: Int,
drawerState: DrawerState,
content: @Composable (PaddingValues)->Unit
content: @Composable (PaddingValues) -> Unit,
) {
val drawerOffset = derivedStateOf { drawerState.offset.value }
var drawerWidth by remember {
mutableStateOf(drawerState.offset.value)
mutableStateOf(drawerState.currentOffset)
}
LaunchedEffect(drawerWidth == 0f) {
drawerWidth = drawerState.offset.value
LaunchedEffect(drawerState.currentOffset.isNaN()) {
drawerWidth = drawerState.currentOffset
}
val localDensity = LocalDensity.current
val contentOffset by derivedStateOf {
if (drawerWidth == 0f) 0.dp
if (drawerWidth.isNaN() || drawerWidth == 0f) 0.dp
else with(localDensity) {
(abs(drawerWidth) + drawerOffset.value).toDp()
(abs(drawerWidth) + drawerState.currentOffset).toDp()
}
}

@ -1,20 +1,29 @@
package fr.iut.alldev.allin.ui.navigation
import androidx.compose.animation.*
import androidx.compose.animation.EnterTransition
import androidx.compose.animation.ExitTransition
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
import androidx.compose.animation.fadeOut
import androidx.compose.animation.slideInHorizontally
import androidx.compose.animation.slideOutHorizontally
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.hilt.navigation.compose.hiltViewModel
import androidx.navigation.NavGraphBuilder
import androidx.navigation.NavHostController
import androidx.navigation.NavType
import androidx.navigation.compose.NavHost
import androidx.navigation.compose.composable
import androidx.navigation.compose.rememberNavController
import androidx.navigation.navArgument
import fr.iut.alldev.allin.data.model.bet.Bet
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.bet.BetScreen
import fr.iut.alldev.allin.ui.betcreation.BetCreationScreen
import fr.iut.alldev.allin.ui.betCreation.BetCreationScreen
import fr.iut.alldev.allin.ui.betHistory.BetHistoryScreen
import fr.iut.alldev.allin.ui.login.LoginScreen
import fr.iut.alldev.allin.ui.main.MainScreen
import fr.iut.alldev.allin.ui.main.MainViewModel
@ -30,11 +39,15 @@ object Routes {
const val BET_CREATION = "BET_CREATION"
const val BET_HISTORY = "BET_HISTORY"
const val FRIENDS = "FRIENDS"
const val CURRENT_BETS = "CURRENT_BETS"
}
internal fun NavHostController.popUpTo(route: String, baseRoute: String){
object NavArguments {
const val ARG_BET_HISTORY_IS_CURRENT = "ARG_BET_HISTORY_IS_CURRENT"
}
internal fun NavHostController.popUpTo(route: String, baseRoute: String) {
this.navigate(route) {
launchSingleTop = true
popUpTo(baseRoute) {
@ -46,30 +59,33 @@ internal fun NavHostController.popUpTo(route: String, baseRoute: String){
}
@Composable
fun AllInNavHost(modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: String = Routes.WELCOME
fun AllInNavHost(
modifier: Modifier = Modifier,
navController: NavHostController = rememberNavController(),
startDestination: String = Routes.WELCOME,
) {
NavHost(
navController = navController,
startDestination = startDestination,
enterTransition =
{
if(navController.currentDestination?.route != Routes.DASHBOARD)
if (navController.currentDestination?.route != Routes.DASHBOARD)
slideInHorizontally(initialOffsetX = { it })
else
fadeIn(animationSpec = tween(1500))
},
exitTransition =
{
if(navController.currentDestination?.route != Routes.DASHBOARD)
slideOutHorizontally(targetOffsetX = { -it/2 })
if (navController.currentDestination?.route != Routes.DASHBOARD)
slideOutHorizontally(targetOffsetX = { -it / 2 })
else
fadeOut(
animationSpec = tween(1500)
)
},
modifier = modifier.fillMaxSize().background(AllInTheme.themeColors.main_surface),
modifier = modifier
.fillMaxSize()
.background(AllInTheme.themeColors.mainSurface),
) {
allInWelcomeScreen(navController)
allInRegisterScreen(navController)
@ -84,7 +100,7 @@ internal fun AllInDrawerNavHost(
navController: NavHostController,
mainViewModel: MainViewModel,
selectBet: (Bet, Boolean) -> Unit,
startDestination: String = Routes.PUBLIC_BETS
startDestination: String = Routes.PUBLIC_BETS,
) {
NavHost(
navController = navController,
@ -103,12 +119,30 @@ internal fun AllInDrawerNavHost(
mainViewModel = mainViewModel
)
}
composable(
route = "${Routes.BET_HISTORY}/{${NavArguments.ARG_BET_HISTORY_IS_CURRENT}}",
arguments = listOf(
navArgument(NavArguments.ARG_BET_HISTORY_IS_CURRENT) {
type = NavType.BoolType
}
)
) {
val isCurrent =
it.arguments?.getBoolean(NavArguments.ARG_BET_HISTORY_IS_CURRENT) ?: false
BetHistoryScreen(
isCurrent = isCurrent,
viewModel = hiltViewModel(it, isCurrent.toString())
)
}
}
}
private fun NavGraphBuilder.allInWelcomeScreen(
navController: NavHostController
){
composable(route = Routes.WELCOME){
navController: NavHostController,
) {
composable(route = Routes.WELCOME) {
WelcomeScreen(
navigateToRegister = {
navController.popUpTo(Routes.REGISTER, Routes.WELCOME)
@ -121,9 +155,9 @@ private fun NavGraphBuilder.allInWelcomeScreen(
}
private fun NavGraphBuilder.allInRegisterScreen(
navController: NavHostController
){
composable(route = Routes.REGISTER){
navController: NavHostController,
) {
composable(route = Routes.REGISTER) {
RegisterScreen(
navigateToDashboard = {
navController.popUpTo(Routes.DASHBOARD, Routes.REGISTER)
@ -136,9 +170,9 @@ private fun NavGraphBuilder.allInRegisterScreen(
}
private fun NavGraphBuilder.allInLoginScreen(
navController: NavHostController
){
composable(route = Routes.LOGIN){
navController: NavHostController,
) {
composable(route = Routes.LOGIN) {
LoginScreen(
navigateToRegister = {
navController.popUpTo(Routes.REGISTER, Routes.LOGIN)
@ -153,7 +187,7 @@ private fun NavGraphBuilder.allInLoginScreen(
private fun NavGraphBuilder.allInDashboard() {
composable(
route = Routes.DASHBOARD,
){
) {
MainScreen()
}
}

@ -6,34 +6,38 @@ sealed class TopLevelDestination(
val route: String,
val title: Int,
val subtitle: Int,
val emoji: Int
val emoji: Int,
) {
object PublicBets : TopLevelDestination(
data object PublicBets : TopLevelDestination(
route = Routes.PUBLIC_BETS,
title = R.string.public_bets,
subtitle = R.string.public_bets_subtitle,
emoji = R.drawable.globe
)
object BetCreation : TopLevelDestination(
data object BetCreation : TopLevelDestination(
route = Routes.BET_CREATION,
title = R.string.create_a_bet,
subtitle = R.string.create_a_bet_subtitle,
emoji = R.drawable.video_game
)
object BetHistory : TopLevelDestination(
route = Routes.BET_HISTORY,
data object BetHistory : TopLevelDestination(
route = "${Routes.BET_HISTORY}/false",
title = R.string.bet_history,
subtitle = R.string.bet_history_subtitle,
emoji = R.drawable.eyes
)
object Friends : TopLevelDestination(
data object Friends : TopLevelDestination(
route = Routes.FRIENDS,
title = R.string.friends,
subtitle = R.string.friends_subtitle,
emoji = R.drawable.holding_hands
)
object CurrentBets : TopLevelDestination(
route = Routes.CURRENT_BETS,
data object CurrentBets : TopLevelDestination(
route = "${Routes.BET_HISTORY}/true",
title = R.string.current_bets,
subtitle = R.string.current_bets_subtitle,
emoji = R.drawable.money_with_wings

@ -6,7 +6,11 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Settings
import androidx.compose.material3.*
import androidx.compose.material3.DrawerState
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ModalDrawerSheet
import androidx.compose.material3.ModalNavigationDrawer
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
@ -14,10 +18,10 @@ import androidx.compose.ui.graphics.RectangleShape
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.navigation.TopLevelDestination
import fr.iut.alldev.allin.ui.navigation.drawer.components.DrawerCell
import fr.iut.alldev.allin.ui.navigation.drawer.components.DrawerHeader
import fr.iut.alldev.allin.theme.AllInTheme
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
@ -30,15 +34,15 @@ fun AllInDrawer(
nbBets: Int,
bestWin: Int,
nbFriends: Int,
navigateTo: (String)->Unit,
content: @Composable ()->Unit
navigateTo: (String) -> Unit,
content: @Composable () -> Unit,
) {
ModalNavigationDrawer(
drawerState = drawerState,
drawerContent = {
ModalDrawerSheet(
drawerShape = RectangleShape,
drawerContainerColor = AllInTheme.colors.allIn_Dark
drawerContainerColor = AllInTheme.colors.allInDark
) {
DrawerHeader(
nbBets = nbBets,
@ -71,7 +75,7 @@ fun AllInDrawer(
Icon(
imageVector = Icons.Filled.Settings,
modifier = Modifier.size(40.dp),
tint = AllInTheme.colors.allIn_DarkGrey50,
tint = AllInTheme.colors.allInDarkGrey50,
contentDescription = null
)
}

@ -25,14 +25,16 @@ fun DrawerCell(
title: String,
subtitle: String,
emoji: Painter,
onClick: ()->Unit,
modifier: Modifier = Modifier
onClick: () -> Unit,
modifier: Modifier = Modifier,
) {
Card(onClick = onClick,
Card(
onClick = onClick,
modifier = modifier,
border = BorderStroke(width = 1.dp, color = AllInTheme.colors.allIn_DarkGrey50),
border = BorderStroke(width = 1.dp, color = AllInTheme.colors.allInDarkGrey50),
shape = RoundedCornerShape(20),
colors = CardDefaults.cardColors(containerColor = AllInTheme.colors.allIn_DarkGrey100)) {
colors = CardDefaults.cardColors(containerColor = AllInTheme.colors.allInDarkGrey100)
) {
Row(
modifier = Modifier.padding(horizontal = 10.dp, vertical = 17.dp),
verticalAlignment = Alignment.CenterVertically
@ -56,12 +58,12 @@ fun DrawerCell(
text = subtitle,
style = AllInTheme.typography.r,
fontSize = 9.sp,
color = AllInTheme.colors.allIn_LightGrey300,
color = AllInTheme.colors.allInLightGrey300,
)
}
Icon(
imageVector = Icons.Default.ChevronRight,
tint = AllInTheme.colors.allIn_DarkGrey50,
tint = AllInTheme.colors.allInDarkGrey50,
contentDescription = null
)

@ -1,6 +1,12 @@
package fr.iut.alldev.allin.ui.navigation.drawer.components
import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row
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.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment
@ -11,8 +17,8 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.core.ProfilePicture
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.ProfilePicture
@Composable
fun DrawerHeader(
@ -20,7 +26,7 @@ fun DrawerHeader(
bestWin: Int,
nbFriends: Int,
username: String,
modifier: Modifier = Modifier
modifier: Modifier = Modifier,
) {
Column(
modifier = modifier.fillMaxWidth(),
@ -33,7 +39,7 @@ fun DrawerHeader(
Text(
text = username,
fontSize = 20.sp,
color = AllInTheme.colors.allIn_LightGrey200,
color = AllInTheme.colors.allInLightGrey200,
textAlign = TextAlign.Center,
style = AllInTheme.typography.h2,
)
@ -55,7 +61,7 @@ fun DrawerHeader(
@Preview
@Composable
private fun DrawerHeaderPreview() {
AllInTheme{
AllInTheme {
DrawerHeader(
nbBets = 114,
bestWin = 360,

@ -10,7 +10,7 @@ import fr.iut.alldev.allin.theme.AllInTheme
@Composable
fun DrawerHeaderStat(
label: String,
value: Int
value: Int,
) {
Column(
horizontalAlignment = Alignment.CenterHorizontally
@ -22,7 +22,7 @@ fun DrawerHeaderStat(
)
Text(
text = label,
color = AllInTheme.colors.allIn_LightGrey300,
color = AllInTheme.colors.allInLightGrey300,
style = AllInTheme.typography.r
)
}

@ -0,0 +1,14 @@
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)
)
}

@ -21,11 +21,11 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.hilt.navigation.compose.hiltViewModel
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInGradientButton
import fr.iut.alldev.allin.ui.core.AllInLoading
import fr.iut.alldev.allin.ui.core.AllInPasswordField
import fr.iut.alldev.allin.ui.core.AllInTextField
import fr.iut.alldev.allin.theme.AllInTheme
@OptIn(ExperimentalFoundationApi::class)
@Composable
@ -37,17 +37,17 @@ fun RegisterScreen(
val focusManager = LocalFocusManager.current
val loading by remember{ registerViewModel.loading }
val loading by remember { registerViewModel.loading }
val usernameError by remember{ registerViewModel.usernameError }
val emailError by remember{ registerViewModel.emailError }
val passwordError by remember{ registerViewModel.passwordError }
val passwordValidationError by remember{ registerViewModel.passwordValidationError }
val usernameError by remember { registerViewModel.usernameError }
val emailError by remember { registerViewModel.emailError }
val passwordError by remember { registerViewModel.passwordError }
val passwordValidationError by remember { registerViewModel.passwordValidationError }
val (username, setUsername) = remember{ registerViewModel.username }
val (email, setEmail) = remember{ registerViewModel.email }
val (password, setPassword) = remember{ registerViewModel.password }
val (passwordValidation, setPasswordValidation) = remember{ registerViewModel.passwordValidation }
val (username, setUsername) = remember { registerViewModel.username }
val (email, setEmail) = remember { registerViewModel.email }
val (password, setPassword) = remember { registerViewModel.password }
val (passwordValidation, setPasswordValidation) = remember { registerViewModel.passwordValidation }
val bringIntoViewRequester = remember { BringIntoViewRequester() }
val scrollState = rememberScrollState()
@ -76,7 +76,7 @@ fun RegisterScreen(
Column(
Modifier
.fillMaxSize()
.background(AllInTheme.themeColors.main_surface)
.background(AllInTheme.themeColors.mainSurface)
.padding(horizontal = 44.dp)
) {
Column(
@ -88,7 +88,7 @@ fun RegisterScreen(
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Hello_x, username),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
textAlign = TextAlign.Center,
fontSize = 40.sp,
@ -98,7 +98,7 @@ fun RegisterScreen(
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_title),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.h3,
textAlign = TextAlign.Center,
fontSize = 40.sp
@ -107,7 +107,7 @@ fun RegisterScreen(
Text(
modifier = Modifier.fillMaxWidth(),
text = stringResource(id = R.string.Register_subtitle),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
style = AllInTheme.typography.r,
textAlign = TextAlign.Center,
fontSize = 23.sp
@ -182,7 +182,7 @@ fun RegisterScreen(
) {
Text(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.on_main_surface,
color = AllInTheme.themeColors.onMainSurface,
fontSize = 15.sp,
style = AllInTheme.typography.r,
modifier = Modifier.padding(end = 5.dp)
@ -190,7 +190,7 @@ fun RegisterScreen(
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.r.copy(
color = AllInTheme.colors.allIn_Purple,
color = AllInTheme.colors.allInPurple,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
)

@ -18,20 +18,20 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import fr.iut.alldev.allin.R
import fr.iut.alldev.allin.ui.core.AllInButton
import fr.iut.alldev.allin.theme.AllInTheme
import fr.iut.alldev.allin.ui.core.AllInButton
@OptIn(ExperimentalFoundationApi::class)
@Composable
fun WelcomeScreen(
navigateToRegister: ()->Unit,
navigateToLogin: ()->Unit
navigateToRegister: () -> Unit,
navigateToLogin: () -> Unit,
) {
Box(
Modifier
.fillMaxWidth()
.fillMaxHeight(.5f)
.background(AllInTheme.colors.allIn_LoginGradient)
.background(AllInTheme.colors.allInLoginGradient)
)
Box(
Modifier
@ -42,17 +42,17 @@ fun WelcomeScreen(
.5f to AllInTheme.themeColors.background
)
)
){
) {
Column(
Modifier
.align(Alignment.BottomCenter)
.fillMaxWidth()
.fillMaxHeight(.5f)
.padding(horizontal = 45.dp)
){
) {
Text(
text = stringResource(id = R.string.welcome_title),
color = AllInTheme.themeColors.on_background,
color = AllInTheme.themeColors.onBackground,
fontSize = 30.sp,
style = AllInTheme.typography.h1
)
@ -60,19 +60,19 @@ fun WelcomeScreen(
text = stringResource(id = R.string.welcome_appname),
fontSize = 60.sp,
style = AllInTheme.typography.h1.copy(
brush = AllInTheme.colors.allIn_MainGradient
brush = AllInTheme.colors.allInMainGradient
)
)
Spacer(modifier = Modifier.height(43.dp))
Text(
text = stringResource(id = R.string.welcome_subtitle),
color = AllInTheme.themeColors.on_background,
color = AllInTheme.themeColors.onBackground,
fontSize = 15.sp,
style = AllInTheme.typography.r
)
Spacer(modifier = Modifier.height(78.dp))
AllInButton(
color = AllInTheme.themeColors.tint_1,
color = AllInTheme.themeColors.tint1,
text = stringResource(id = R.string.join),
textColor = AllInTheme.themeColors.background,
onClick = navigateToRegister,
@ -84,7 +84,7 @@ fun WelcomeScreen(
) {
Text(
text = stringResource(id = R.string.already_have_account),
color = AllInTheme.themeColors.tint_1,
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
style = AllInTheme.typography.r,
modifier = Modifier.padding(end = 5.dp)
@ -92,11 +92,11 @@ fun WelcomeScreen(
ClickableText(
text = AnnotatedString(stringResource(id = R.string.Login)),
style = AllInTheme.typography.r.copy(
color = AllInTheme.themeColors.tint_1,
color = AllInTheme.themeColors.tint1,
fontSize = 15.sp,
fontWeight = FontWeight.Bold
)
){
) {
navigateToLogin()
}
}
@ -108,7 +108,7 @@ fun WelcomeScreen(
@Preview(uiMode = Configuration.UI_MODE_NIGHT_YES)
@Composable
private fun WelcomeScreenPreview() {
AllInTheme{
AllInTheme {
WelcomeScreen(navigateToRegister = {}, navigateToLogin = {})
}
}

@ -114,4 +114,11 @@
<string name="bet_status_waiting">En attente…</string>
<string name="place_your_bets">Faites vos paris</string>
<!--Bet history-->
<string name="bet_history_current_title">En cours</string>
<string name="bet_history_title">Historique</string>
<string name="bet_history_status_in_progress">%s [icon] pariés</string>
<string name="bet_history_status_won">%s [icon] gagnés !</string>
<string name="bet_history_status_lost">%s [icon] perdus !</string>
</resources>

@ -112,4 +112,12 @@
<string name="bet_status_in_progress">In progress…</string>
<string name="bet_status_waiting">Waiting…</string>
<string name="place_your_bets">Place your bets</string>
<!--Bet history-->
<string name="bet_history_current_title">Current</string>
<string name="bet_history_title">History</string>
<string name="bet_history_status_in_progress">%s [icon] bet</string>
<string name="bet_history_status_won">%s [icon] won !</string>
<string name="bet_history_status_lost">%s [icon] lost !</string>
</resources>

@ -1,16 +0,0 @@
buildscript {
ext {
compose_version = '1.2.0'
accompanist_version = '0.25.1'
hilt_version = "2.45"
}
}// Top-level build file where you can add configuration options common to all sub-projects/modules.
plugins {
id 'com.android.application' version '7.4.2' apply false
id 'com.android.library' version '7.4.2' apply false
id 'org.jetbrains.kotlin.android' version '1.7.0' apply false
id 'com.google.dagger.hilt.android' version "$hilt_version" apply false
id 'org.jetbrains.kotlin.plugin.serialization' version '1.7.0' apply false
}

@ -0,0 +1,57 @@
buildscript {
repositories {
google()
mavenCentral()
gradlePluginPortal()
maven { url = uri("https://www.jitpack.io") }
maven { url = uri("https://maven.openium.fr/") }
}
dependencies {
// Gradle
classpath(libs.plugin.gradle)
// Kotlin
classpath(libs.plugin.kotlin)
// Kotlin Serialization
classpath(libs.plugin.kotlinSerialization)
// Hilt
classpath(libs.plugin.hilt)
}
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}
subprojects {
tasks {
withType(JavaCompile::class.java).configureEach {
sourceCompatibility = JavaVersion.VERSION_1_8.name
targetCompatibility = JavaVersion.VERSION_1_8.name
}
withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile::class.java).configureEach {
kotlinOptions {
jvmTarget = JavaVersion.VERSION_1_8.toString()
freeCompilerArgs += listOf(
"-Xallow-result-return-type",
"-opt-in=kotlin.RequiresOptIn",
"-opt-in=kotlin.ExperimentalStdlibApi",
"-opt-in=androidx.compose.foundation.ExperimentalFoundationApi",
"-opt-in=androidx.compose.ui.ExperimentalComposeUiApi",
"-opt-in=androidx.compose.foundation.layout.ExperimentalLayoutApi",
"-opt-in=androidx.compose.material.ExperimentalMaterialApi",
"-opt-in=androidx.compose.material3.ExperimentalMaterial3Api",
"-opt-in=androidx.compose.animation.ExperimentalAnimationApi",
"-opt-in=kotlinx.coroutines.ExperimentalCoroutinesApi",
"-opt-in=kotlin.time.ExperimentalTime",
"-opt-in=kotlinx.coroutines.FlowPreview"
)
}
}
}
}

@ -1,77 +0,0 @@
plugins {
id 'com.android.library'
id 'org.jetbrains.kotlin.android'
id "kotlin-kapt"
id "kotlinx-serialization"
}
def keystorePropertiesFile = rootProject.file("app/keys/keystore.properties")
def keystoreProperties = new Properties()
keystoreProperties.load(new FileInputStream(keystorePropertiesFile))
android {
signingConfigs {
release {
storeFile file(keystoreProperties['store'])
storePassword keystoreProperties['password']
keyPassword keystoreProperties['password']
}
}
namespace 'fr.iut.alldev.allin.data'
compileSdk 34
defaultConfig {
minSdk 26
targetSdk 34
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
}
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
debug {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
signingConfig signingConfigs.debug
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = '1.8'
}
}
dependencies {
implementation 'androidx.core:core-ktx:1.12.0'
implementation 'androidx.appcompat:appcompat:1.6.1'
// implementation 'com.google.android.material:material:1.9.0'
//Tests
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.5'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.5.1'
//Hilt
implementation "com.google.dagger:hilt-android:$hilt_version"
kapt "com.google.dagger:hilt-android-compiler:$hilt_version"
// Retrofit
api "com.squareup.retrofit2:retrofit:2.9.0"
implementation "com.squareup.okhttp3:okhttp:4.11.0"
debugImplementation "com.squareup.okhttp3:logging-interceptor:4.11.0"
api "org.jetbrains.kotlinx:kotlinx-serialization-json:1.5.1"
implementation "com.jakewharton.retrofit:retrofit2-kotlinx-serialization-converter:0.8.0"
//Timber
implementation 'com.jakewharton.timber:timber:5.0.1'
}

@ -0,0 +1,67 @@
plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-kapt")
id("com.google.dagger.hilt.android")
id("kotlinx-serialization")
}
android {
namespace = "fr.iut.alldev.allin.data"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
targetSdk = libs.versions.targetSdk.get().toInt()
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles("consumer-rules.pro")
}
buildTypes {
debug {
isMinifyEnabled = false
}
release {
isMinifyEnabled = true
proguardFiles(
getDefaultProguardFile("proguard-android-optimize.txt"),
"proguard-rules.pro"
)
}
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_1_8
targetCompatibility = JavaVersion.VERSION_1_8
}
kotlinOptions {
jvmTarget = "1.8"
}
}
dependencies {
// Androidx
implementation(libs.androidx.core)
// Hilt
implementation(libs.hilt.android)
kapt(libs.hilt.compiler)
// Timber
implementation(libs.timber)
// Retrofit
api(libs.retrofit)
implementation(libs.okhttp)
debugImplementation(libs.okhttpLogging.interceptor)
// Serialization
implementation(libs.kotlinSerialization.json)
implementation(libs.kotlinSerialization.retrofit)
// Tests
testImplementation(libs.test.junit)
androidTestImplementation(libs.test.androidx.junit)
androidTestImplementation(libs.test.espresso)
}

@ -1,6 +1,6 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
# proguardFiles setting in build.gradle.kts.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html

@ -3,7 +3,7 @@ package fr.iut.alldev.allin.data.model.bet
import java.time.ZonedDateTime
class BetFactory {
companion object{
companion object {
fun createBet(
betType: BetType,
theme: String,
@ -13,10 +13,10 @@ class BetFactory {
isPublic: Boolean,
nameTeam1: String = "",
nameTeam2: String = "",
possibleAnswers: Set<String> = emptySet()
possibleAnswers: Set<String> = emptySet(),
): Bet =
when(betType){
): Bet =
when (betType) {
BetType.YES_NO -> {
YesNoBet(
theme = theme,
@ -24,30 +24,32 @@ class BetFactory {
endRegisterDate = endRegisterDate,
endBetDate = endBetDate,
isPublic = isPublic,
betStatus = BetStatus.WAITING
betStatus = BetStatus.Waiting
)
}
BetType.MATCH -> {
BetType.MATCH -> {
MatchBet(
theme = theme,
phrase = phrase,
endRegisterDate = endRegisterDate,
endBetDate = endBetDate,
isPublic = isPublic,
betStatus = BetStatus.WAITING,
betStatus = BetStatus.Waiting,
nameTeam1 = nameTeam1,
nameTeam2 = nameTeam2
)
}
BetType.CUSTOM -> {
BetType.CUSTOM -> {
CustomBet(
theme = theme,
phrase = phrase,
endRegisterDate = endRegisterDate,
endBetDate = endBetDate,
isPublic = isPublic,
betStatus = BetStatus.WAITING,
betStatus = BetStatus.Waiting,
possibleAnswers = possibleAnswers
)
}

@ -0,0 +1,6 @@
package fr.iut.alldev.allin.data.model.bet
enum class BetFinishedStatus {
WON,
LOST
}

@ -1,7 +1,9 @@
package fr.iut.alldev.allin.data.model.bet
enum class BetStatus {
FINISHED,
IN_PROGRESS,
WAITING
sealed class BetStatus {
data class Finished(val status: BetFinishedStatus) : BetStatus()
data object InProgress : BetStatus()
data object Waiting : BetStatus()
}

@ -1,9 +1,13 @@
package fr.iut.alldev.allin.data.repository
import fr.iut.alldev.allin.data.model.bet.Bet
import kotlinx.coroutines.flow.Flow
abstract class BetRepository {
abstract suspend fun createBet(
bet: Bet,
)
abstract suspend fun getHistory(): Flow<List<Bet>>
abstract suspend fun getCurrentBets(): Flow<List<Bet>>
}

@ -2,8 +2,14 @@ package fr.iut.alldev.allin.data.repository.impl
import fr.iut.alldev.allin.data.api.AllInApi
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.data.repository.BetRepository
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flowOf
import timber.log.Timber
import java.time.ZonedDateTime
import javax.inject.Inject
class BetRepositoryImpl @Inject constructor(
@ -13,4 +19,70 @@ class BetRepositoryImpl @Inject constructor(
// TODO
Timber.d("$bet")
}
override suspend fun getHistory(): Flow<List<Bet>> {
// TODO
return flowOf(
listOf(
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 1",
endRegisterDate = ZonedDateTime.now().minusDays(4),
endBetDate = ZonedDateTime.now().minusDays(2),
isPublic = false,
betStatus = BetStatus.Finished(BetFinishedStatus.WON)
),
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 2",
endRegisterDate = ZonedDateTime.now().minusDays(3),
endBetDate = ZonedDateTime.now().minusDays(1),
isPublic = true,
betStatus = BetStatus.Finished(BetFinishedStatus.LOST)
),
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 3",
endRegisterDate = ZonedDateTime.now().minusDays(15),
endBetDate = ZonedDateTime.now().minusDays(7),
isPublic = false,
betStatus = BetStatus.Finished(BetFinishedStatus.LOST)
)
)
)
}
override suspend fun getCurrentBets(): Flow<List<Bet>> {
// TODO
return flowOf(
listOf(
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 1",
endRegisterDate = ZonedDateTime.now().plusDays(5),
endBetDate = ZonedDateTime.now().plusDays(7),
isPublic = false,
betStatus = BetStatus.InProgress
),
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 2",
endRegisterDate = ZonedDateTime.now().plusDays(1),
endBetDate = ZonedDateTime.now().plusDays(2),
isPublic = true,
betStatus = BetStatus.InProgress
),
YesNoBet(
theme = "Theme",
phrase = "Bet phrase 3",
endRegisterDate = ZonedDateTime.now().plusDays(3),
endBetDate = ZonedDateTime.now().plusDays(4),
isPublic = false,
betStatus = BetStatus.InProgress
)
)
)
}
}

@ -20,4 +20,5 @@ kotlin.code.style=official
# Enables namespacing of each library's R class so that its R class includes only the
# resources declared in the library itself and none from the library's dependencies,
# thereby reducing the size of the R class for that library
android.nonTransitiveRClass=true
android.nonTransitiveRClass=true
android.enableR8.fullMode=false

@ -0,0 +1,100 @@
[versions]
# Android
compileSdk = "34"
targetSdk = "34"
minSdk = "26"
# Libraries
kotlin = "1.9.20"
androidxCore = "1.12.0"
androidxActivity = "1.8.2"
composeBom = "2023.10.01"
composePreview = "1.6.0-beta03"
composeCompiler = "1.5.5"
composeNavigation = "2.7.6"
hilt = "2.48"
hiltNavigation = "1.1.0"
timber = "5.0.1"
lifecycle = "2.6.2"
junit = "4.13.2"
androidxTestExtJunit = "1.1.5"
espressoCore = "3.5.1"
room = "2.6.1"
okHttp = "4.11.0"
# Plugins
gradlePlugin = "8.1.2"
publishPlugin = "1.1"
resgenPlugin = "2.5"
[libraries]
# Android
androidx-core = { module = "androidx.core:core-ktx", version.ref = "androidxCore" }
androidx-activity = { module = "androidx.activity:activity-compose", version.ref = "androidxActivity" }
# Lifecycle
androidx-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
androidx-lifecycle-viewmodel = { module = "androidx.lifecycle:lifecycle-viewmodel-ktx", version.ref = "lifecycle" }
androidx-lifecycle-process = { module = "androidx.lifecycle:lifecycle-process", version.ref = "lifecycle" }
androidx-lifecycle-runtime-compose = { module = "androidx.lifecycle:lifecycle-runtime-compose", version.ref = "lifecycle" }
# Tests
test-junit = { group = "junit", name = "junit", version.ref = "junit" }
test-androidx-junit = { group = "androidx.test.ext", name = "junit-ktx", version.ref = "androidxTestExtJunit" }
test-espresso = { group = "androidx.test.espresso", name = "espresso-core", version.ref = "espressoCore" }
# Compose
compose-bom = { module = "androidx.compose:compose-bom", version.ref = "composeBom" }
compose-ui = { module = "androidx.compose.ui:ui" }
compose-ui-graphics = { module = "androidx.compose.ui:ui-graphics" }
compose-foundation = { module = "androidx.compose.foundation:foundation", version = "1.6.0-beta03" }
compose-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "composePreview" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling" }
compose-ui-googlefonts = { group = "androidx.compose.ui", name = "ui-text-google-fonts" }
compose-material = { module = "androidx.compose.material:material" }
compose-material3 = { group = "androidx.compose.material3", name = "material3", version = "1.2.0-beta01" }
compose-material-icons = { group = "androidx.compose.material", name = "material-icons-core" }
compose-material-icons-extended = { group = "androidx.compose.material", name = "material-icons-extended" }
compose-navigation = { module = "androidx.navigation:navigation-compose", version.ref = "composeNavigation" }
# Hilt
hilt-android = { module = "com.google.dagger:hilt-android", version.ref = "hilt" }
hilt-compiler = { module = "com.google.dagger:hilt-compiler", version.ref = "hilt" }
hilt-navigation-compose = { module = "androidx.hilt:hilt-navigation-compose", version.ref = "hiltNavigation" }
# Timber
timber = { module = "com.jakewharton.timber:timber", version.ref = "timber" }
# Retrofit
retrofit = { group = "com.squareup.retrofit2", name = "retrofit", version = "2.9.0" }
okhttp = { group = "com.squareup.okhttp3", name = "okhttp", version.ref = "okHttp" }
okhttpLogging-interceptor = { group = "com.squareup.okhttp3", name = "logging-interceptor", version.ref = "okHttp" }
# Serialization
kotlinSerialization-json = { group = "org.jetbrains.kotlinx", name = "kotlinx-serialization-json", version = "1.6.2" }
kotlinSerialization-retrofit = { group = "com.jakewharton.retrofit", name = "retrofit2-kotlinx-serialization-converter", version = "0.8.0" }
# Squicle
smoothCornerRect = { module = "com.github.racra:smooth-corner-rect-android-compose", version = "v1.0.0" }
# Plugins
plugin-gradle = { module = "com.android.tools.build:gradle", version.ref = "gradlePlugin" }
plugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", 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" }
[bundles]
android = ["androidx-core", "androidx-activity"]
androidx-lifecycle = ["androidx-lifecycle-runtime", "androidx-lifecycle-viewmodel", "androidx-lifecycle-process", "androidx-lifecycle-runtime-compose"]
compose = ["compose-ui", "compose-ui-graphics", "compose-tooling-preview", "compose-ui-tooling", "compose-foundation", "compose-material", "compose-material3", "compose-material-icons", "compose-material-icons-extended", "compose-navigation", "compose-ui-googlefonts"]

@ -1,6 +1,7 @@
#Mon Sep 25 00:27:11 CEST 2023
distributionBase=GRADLE_USER_HOME
distributionUrl=https\://services.gradle.org/distributions/gradle-8.3-bin.zip
distributionPath=wrapper/dists
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.4-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists

@ -10,9 +10,10 @@ dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven { url 'https://jitpack.io' }
maven { url = uri("https://www.jitpack.io") }
}
}
rootProject.name = "allin"
include ':app'
include ':data'
include(":app")
include(":data")
Loading…
Cancel
Save