Fix events
continuous-integration/drone/push Build is passing
Details
continuous-integration/drone/push Build is passing
Details
parent
58d788f58f
commit
53b6eacfff
@ -0,0 +1,30 @@
|
||||
package fr.iut.alldev.allin.ui.betHistory
|
||||
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.collectAsState
|
||||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.ui.res.stringResource
|
||||
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.ui.betHistory.components.GenericHistory
|
||||
|
||||
@Composable
|
||||
fun BetCurrentScreen(
|
||||
viewModel: BetCurrentViewModel = hiltViewModel()
|
||||
) {
|
||||
val bets by viewModel.bets.collectAsState()
|
||||
GenericHistory(
|
||||
title = stringResource(id = R.string.bet_history_current_title),
|
||||
bets = bets,
|
||||
getTitle = { it.bet.phrase },
|
||||
getCreator = { it.bet.creator },
|
||||
getCategory = { it.bet.theme },
|
||||
getEndRegisterDate = { it.bet.endRegisterDate.formatToMediumDateNoYear() },
|
||||
getEndBetTime = { it.bet.endBetDate.formatToTime() },
|
||||
getStatus = { it.bet.betStatus },
|
||||
getNbCoins = { it.userParticipation?.stake ?: 0 },
|
||||
getWon = { true }
|
||||
)
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package fr.iut.alldev.allin.ui.betHistory
|
||||
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
import dagger.hilt.android.lifecycle.HiltViewModel
|
||||
import fr.iut.alldev.allin.data.model.bet.vo.BetDetail
|
||||
import fr.iut.alldev.allin.data.repository.BetRepository
|
||||
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class BetCurrentViewModel @Inject constructor(
|
||||
private val betRepository: BetRepository,
|
||||
private val keystoreManager: AllInKeystoreManager
|
||||
) : ViewModel() {
|
||||
private val _bets: MutableStateFlow<List<BetDetail>> by lazy {
|
||||
MutableStateFlow(emptyList())
|
||||
}
|
||||
|
||||
val bets: StateFlow<List<BetDetail>> by lazy {
|
||||
_bets.asStateFlow()
|
||||
.filterNotNull()
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(5_000L),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
_bets.emit(
|
||||
betRepository.getToConfirm(keystoreManager.getTokenOrEmpty())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -1,65 +1,30 @@
|
||||
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
|
||||
import fr.iut.alldev.allin.ui.betHistory.components.GenericHistory
|
||||
|
||||
@Composable
|
||||
fun BetHistoryScreen(
|
||||
isCurrent: Boolean,
|
||||
viewModel: BetHistoryViewModel = hiltViewModel(),
|
||||
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 = it.creator,
|
||||
category = it.theme,
|
||||
date = it.endRegisterDate.formatToMediumDateNoYear(),
|
||||
time = it.endRegisterDate.formatToTime(),
|
||||
status = it.betStatus,
|
||||
nbCoins = 230
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
GenericHistory(
|
||||
title = stringResource(id = R.string.bet_history_title),
|
||||
bets = bets,
|
||||
getTitle = { it.bet.phrase },
|
||||
getCreator = { it.bet.creator },
|
||||
getCategory = { it.bet.theme },
|
||||
getEndRegisterDate = { it.bet.endRegisterDate.formatToMediumDateNoYear() },
|
||||
getEndBetTime = { it.bet.endBetDate.formatToTime() },
|
||||
getStatus = { it.bet.betStatus },
|
||||
getNbCoins = { it.amount },
|
||||
getWon = { it.won }
|
||||
)
|
||||
}
|
@ -1,35 +1,44 @@
|
||||
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.model.bet.BetResultDetail
|
||||
import fr.iut.alldev.allin.data.repository.BetRepository
|
||||
import fr.iut.alldev.allin.ui.navigation.NavArguments
|
||||
import fr.iut.alldev.allin.keystore.AllInKeystoreManager
|
||||
import kotlinx.coroutines.flow.MutableStateFlow
|
||||
import kotlinx.coroutines.flow.SharingStarted
|
||||
import kotlinx.coroutines.flow.StateFlow
|
||||
import kotlinx.coroutines.flow.asStateFlow
|
||||
import kotlinx.coroutines.flow.filterNotNull
|
||||
import kotlinx.coroutines.flow.flatMapConcat
|
||||
import kotlinx.coroutines.flow.flowOf
|
||||
import kotlinx.coroutines.flow.stateIn
|
||||
import kotlinx.coroutines.launch
|
||||
import javax.inject.Inject
|
||||
|
||||
@HiltViewModel
|
||||
class BetHistoryViewModel @Inject constructor(
|
||||
savedStateHandle: SavedStateHandle,
|
||||
private val betRepository: BetRepository,
|
||||
private val keystoreManager: AllInKeystoreManager
|
||||
) : ViewModel() {
|
||||
private val isCurrent: Boolean? = savedStateHandle[NavArguments.ARG_BET_HISTORY_IS_CURRENT]
|
||||
private val _bets: MutableStateFlow<List<BetResultDetail>> by lazy {
|
||||
MutableStateFlow(emptyList())
|
||||
}
|
||||
|
||||
val bets: StateFlow<List<BetResultDetail>> by lazy {
|
||||
_bets.asStateFlow()
|
||||
.filterNotNull()
|
||||
.stateIn(
|
||||
viewModelScope,
|
||||
SharingStarted.WhileSubscribed(5_000L),
|
||||
emptyList()
|
||||
)
|
||||
}
|
||||
|
||||
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
|
||||
)
|
||||
init {
|
||||
viewModelScope.launch {
|
||||
_bets.emit(
|
||||
betRepository.getHistory(keystoreManager.getTokenOrEmpty())
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,60 @@
|
||||
package fr.iut.alldev.allin.ui.betHistory.components
|
||||
|
||||
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.ui.Modifier
|
||||
import androidx.compose.ui.text.style.TextAlign
|
||||
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.theme.AllInTheme
|
||||
|
||||
@Composable
|
||||
fun <T> GenericHistory(
|
||||
title: String,
|
||||
bets: List<T>,
|
||||
getTitle: (T) -> String,
|
||||
getCreator: (T) -> String,
|
||||
getCategory: (T) -> String,
|
||||
getEndRegisterDate: (T) -> String,
|
||||
getEndBetTime: (T) -> String,
|
||||
getStatus: (T) -> BetStatus,
|
||||
getNbCoins: (T) -> Int,
|
||||
getWon: (T) -> Boolean,
|
||||
) {
|
||||
LazyColumn(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
contentPadding = PaddingValues(horizontal = 24.dp, vertical = 18.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(18.dp),
|
||||
) {
|
||||
item {
|
||||
Text(
|
||||
text = title,
|
||||
style = AllInTheme.typography.h1,
|
||||
color = AllInTheme.colors.allInGrey,
|
||||
fontSize = 24.sp,
|
||||
textAlign = TextAlign.Center,
|
||||
modifier = Modifier.fillMaxWidth()
|
||||
)
|
||||
}
|
||||
|
||||
items(bets) {
|
||||
BetHistoryScreenCard(
|
||||
title = getTitle(it),
|
||||
creator = getCreator(it),
|
||||
category = getCategory(it),
|
||||
date = getEndRegisterDate(it),
|
||||
time = getEndBetTime(it),
|
||||
status = getStatus(it),
|
||||
nbCoins = getNbCoins(it),
|
||||
won = getWon(it)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,12 @@
|
||||
package fr.iut.alldev.allin.ui.main.event
|
||||
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
|
||||
sealed class AllInEvent {
|
||||
@Composable
|
||||
abstract fun Display(
|
||||
sheetState: SheetState,
|
||||
onDismiss: () -> Unit
|
||||
)
|
||||
}
|
@ -0,0 +1,39 @@
|
||||
package fr.iut.alldev.allin.ui.main.event
|
||||
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import fr.iut.alldev.allin.data.model.bet.vo.BetDetail
|
||||
import fr.iut.alldev.allin.ui.betConfirmation.BetConfirmationBottomSheet
|
||||
|
||||
data class ToConfirmBet(
|
||||
private val betDetail: BetDetail,
|
||||
private val onConfirm: (String) -> Unit
|
||||
) : AllInEvent() {
|
||||
@Composable
|
||||
override fun Display(
|
||||
sheetState: SheetState,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
BetConfirmationBottomSheet(
|
||||
state = sheetState,
|
||||
sheetVisibility = true,
|
||||
betDetail = betDetail,
|
||||
onDismiss = onDismiss,
|
||||
onConfirm = onConfirm
|
||||
)
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
return betDetail.hashCode()
|
||||
}
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as ToConfirmBet
|
||||
|
||||
return betDetail == other.betDetail
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
package fr.iut.alldev.allin.ui.main.event
|
||||
|
||||
import androidx.compose.material3.SheetState
|
||||
import androidx.compose.runtime.Composable
|
||||
import fr.iut.alldev.allin.data.model.User
|
||||
import fr.iut.alldev.allin.data.model.bet.BetResultDetail
|
||||
import fr.iut.alldev.allin.ui.betResult.BetResultBottomSheet
|
||||
|
||||
data class WonBet(
|
||||
private val user: User,
|
||||
private val betResult: BetResultDetail,
|
||||
) : AllInEvent() {
|
||||
@Composable
|
||||
override fun Display(
|
||||
sheetState: SheetState,
|
||||
onDismiss: () -> Unit
|
||||
) {
|
||||
BetResultBottomSheet(
|
||||
state = sheetState,
|
||||
sheetVisibility = true,
|
||||
onDismiss = onDismiss,
|
||||
bet = betResult.bet,
|
||||
username = user.username,
|
||||
coinAmount = betResult.amount,
|
||||
stake = betResult.participation.stake,
|
||||
winnings = betResult.amount,
|
||||
odds = 1f
|
||||
)
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
package fr.iut.alldev.allin.data.model.bet
|
||||
|
||||
data class BetResult(
|
||||
val betId: String,
|
||||
val result: String
|
||||
)
|
||||
|
||||
data class BetResultDetail(
|
||||
val betResult: BetResult,
|
||||
val bet: Bet,
|
||||
val participation: Participation,
|
||||
val amount: Int,
|
||||
val won: Boolean
|
||||
)
|
@ -1,19 +1,9 @@
|
||||
package fr.iut.alldev.allin.data.model.bet
|
||||
|
||||
sealed class BetStatus {
|
||||
data class Finished(val status: BetFinishedStatus) : BetStatus()
|
||||
|
||||
data object InProgress : BetStatus()
|
||||
|
||||
data object Waiting : BetStatus()
|
||||
|
||||
companion object {
|
||||
val entries = sequenceOf(
|
||||
InProgress,
|
||||
Waiting,
|
||||
Finished(BetFinishedStatus.WON),
|
||||
Finished(BetFinishedStatus.LOST)
|
||||
)
|
||||
}
|
||||
|
||||
enum class BetStatus {
|
||||
IN_PROGRESS,
|
||||
WAITING,
|
||||
CLOSING,
|
||||
FINISHED,
|
||||
CANCELLED
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package fr.iut.alldev.allin.data.model.bet
|
||||
|
||||
enum class BetType {
|
||||
YES_NO,
|
||||
BINARY,
|
||||
MATCH,
|
||||
CUSTOM
|
||||
}
|
||||
|
@ -1,10 +1,6 @@
|
||||
package fr.iut.alldev.allin.data.model.bet.vo
|
||||
|
||||
import fr.iut.alldev.allin.data.model.bet.Bet
|
||||
import fr.iut.alldev.allin.data.model.bet.Participation
|
||||
|
||||
data class BetResult(
|
||||
val bet: Bet,
|
||||
val participations: List<Participation>,
|
||||
val answerDetail: BetAnswerDetail
|
||||
val betId: String,
|
||||
val result: String
|
||||
)
|
@ -1,15 +1,18 @@
|
||||
package fr.iut.alldev.allin.data.repository
|
||||
|
||||
import fr.iut.alldev.allin.data.model.bet.Bet
|
||||
import fr.iut.alldev.allin.data.model.bet.BetResultDetail
|
||||
import fr.iut.alldev.allin.data.model.bet.Participation
|
||||
import fr.iut.alldev.allin.data.model.bet.vo.BetDetail
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
|
||||
abstract class BetRepository {
|
||||
abstract suspend fun createBet(bet: Bet, token: String)
|
||||
abstract suspend fun getHistory(): Flow<List<Bet>>
|
||||
abstract suspend fun getCurrentBets(): Flow<List<Bet>>
|
||||
abstract suspend fun getHistory(token: String): List<BetResultDetail>
|
||||
abstract suspend fun getCurrentBets(token: String): List<BetDetail>
|
||||
abstract suspend fun getBet(id: String, token: String): BetDetail
|
||||
abstract suspend fun participateToBet(participation: Participation, token: String)
|
||||
abstract suspend fun getAllBets(): List<Bet>
|
||||
abstract suspend fun getAllBets(token: String): List<Bet>
|
||||
abstract suspend fun confirmBet(token: String, id: String, response: String)
|
||||
abstract suspend fun getToConfirm(token: String): List<BetDetail>
|
||||
abstract suspend fun getWon(token: String): List<BetResultDetail>
|
||||
}
|
Loading…
Reference in new issue