diff --git a/.idea/misc.xml b/.idea/misc.xml index f16dea7..99bb29b 100644 --- a/.idea/misc.xml +++ b/.idea/misc.xml @@ -4,7 +4,7 @@ - + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml index 94a25f7..35eb1dd 100644 --- a/.idea/vcs.xml +++ b/.idea/vcs.xml @@ -1,6 +1,6 @@ - + \ No newline at end of file diff --git a/src/main/kotlin/Main.kt b/src/main/kotlin/Main.kt index 99cad9d..8afafba 100644 --- a/src/main/kotlin/Main.kt +++ b/src/main/kotlin/Main.kt @@ -4,10 +4,10 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.verticalScroll import androidx.compose.material3.MaterialTheme -import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Surface import androidx.compose.material3.Text import androidx.compose.material3.darkColorScheme @@ -17,18 +17,27 @@ import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Modifier +import androidx.compose.ui.text.SpanStyle +import androidx.compose.ui.text.buildAnnotatedString +import androidx.compose.ui.text.withStyle import androidx.compose.ui.unit.dp import androidx.compose.ui.window.Window import androidx.compose.ui.window.application +import utils.DecimalField import utils.SliderCard +import utils.SwitchCard import utils.VSpace -import utils.parseInt import kotlin.math.ceil +const val BATTLE_PASS_WEEKS = 13 +const val BATTLE_PASS_DAYS = BATTLE_PASS_WEEKS * 7 const val BATTLE_PASS_MAX_LEVEL = 115 const val DAILY_TASKS_XP = 450 const val WEEKLY_REWARD_XP = 2250 const val WEEKLY_TASKS_XP = 1550 +const val CHALLENGE_TASKS_XP = 1000 +const val CHALLENGE_TASKS_FREE_NUMBER = 20 +const val CHALLENGE_TASKS_PAID_NUMBER = 36 @Composable @Preview @@ -46,18 +55,24 @@ fun App() { var daysLeft by remember { mutableStateOf(0) } val weeksLeft = ceil(daysLeft.toFloat() / 7).toInt() var currentLevel by remember { mutableStateOf(0) } + var paidBattlePass by remember { mutableStateOf(false) } var dailyTasksDays by remember { mutableStateOf(0) } var weeklyRewardWeeks by remember { mutableStateOf(0) } var weeklyTasksWeeks by remember { mutableStateOf(0) } + var challengeTasksNumber by remember { mutableStateOf(0) } val xp = ( DAILY_TASKS_XP * dailyTasksDays + WEEKLY_REWARD_XP * weeklyRewardWeeks + WEEKLY_TASKS_XP * weeklyTasksWeeks + + challengeTasksNumber / 3 * CHALLENGE_TASKS_XP ) - Column { + Column( + modifier = Modifier + .width(384.dp), + ) { Text( text = "Исходные значения", style = MaterialTheme.typography.headlineSmall, @@ -65,32 +80,50 @@ fun App() { VSpace(16) - OutlinedTextField( - value = daysLeft.toString(), + DecimalField( + value = daysLeft, onValueChange = { - daysLeft = parseInt(it) - }, - label = { - Text("Дней до завершения события") + daysLeft = it }, + label = "Дней до завершения события", ) VSpace(8) - OutlinedTextField( - value = currentLevel.toString(), + DecimalField( + value = currentLevel, onValueChange = { - currentLevel = parseInt(it) + currentLevel = it }, - label = { - Text("Текущий уровень") + label = "Текущий уровень", + ) + + VSpace(16) + + SwitchCard( + checked = paidBattlePass, + onCheckedChange = { + paidBattlePass = it }, + label = "Платный боевой пропуск", + description = "Вычисления будут выполняться из расчета, что боевой пропуск уже приобретен", ) VSpace(32) + + Text( - text = "${currentLevel + xp.toFloat() / 1000}/$BATTLE_PASS_MAX_LEVEL", + text = buildAnnotatedString { + append((currentLevel + xp.toFloat() / 1000).toString()) + withStyle( + style = SpanStyle( + fontSize = MaterialTheme.typography.bodyLarge.fontSize, + ), + ) { + append("/$BATTLE_PASS_MAX_LEVEL") + } + }, style = MaterialTheme.typography.displaySmall, ) } @@ -143,6 +176,20 @@ fun App() { }, valueRange = 0..weeksLeft, ) + + // TODO: место для заданий недели + + SliderCard( + name = "Задания вызова", + value = challengeTasksNumber, + onValueChange = { + challengeTasksNumber = it + }, + valueRange = 0..when (paidBattlePass) { + true -> ceil(CHALLENGE_TASKS_PAID_NUMBER.toFloat() / BATTLE_PASS_DAYS * daysLeft).toInt() + false -> ceil(CHALLENGE_TASKS_FREE_NUMBER.toFloat() / BATTLE_PASS_DAYS * daysLeft).toInt() + }, + ) } } } diff --git a/src/main/kotlin/utils/Compose.kt b/src/main/kotlin/utils/Compose.kt index 1fd2a44..9e4bc3c 100644 --- a/src/main/kotlin/utils/Compose.kt +++ b/src/main/kotlin/utils/Compose.kt @@ -1,14 +1,21 @@ package utils +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.foundation.layout.width import androidx.compose.material3.MaterialTheme import androidx.compose.material3.OutlinedCard +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Slider +import androidx.compose.material3.Switch import androidx.compose.material3.Text import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.unit.dp @@ -21,9 +28,66 @@ fun VSpace( ) } -fun parseInt( - value: String, -) = value.toIntOrNull() ?: 0 +@Composable +fun DecimalField( + value: Int, + onValueChange: (Int) -> Unit, + label: String, +) { + OutlinedTextField( + value = value.toString(), + onValueChange = { + onValueChange(it.toIntOrNull() ?: 0) + }, + modifier = Modifier + .fillMaxWidth(), + label = { + Text(label) + }, + ) +} + +@Composable +fun SwitchCard( + checked: Boolean, + onCheckedChange: (Boolean) -> Unit, + label: String, + description: String? = null, +) { + OutlinedCard { + Column( + modifier = Modifier + .padding( + horizontal = 16.dp, + vertical = 12.dp, + ), + verticalArrangement = Arrangement.spacedBy(4.dp), + ) { + Row( + modifier = Modifier + .fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically, + ) { + Text( + text = label, + style = MaterialTheme.typography.titleLarge, + ) + Spacer(Modifier.width(16.dp)) + Switch( + checked = checked, + onCheckedChange = onCheckedChange, + ) + } + description?.let { + Text( + text = it, + style = MaterialTheme.typography.bodyMedium, + ) + } + } + } +} @Composable fun SliderCard(