Рефакторинг, платный боевой пропуск и задания вызова
This commit is contained in:
		
							
								
								
									
										2
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/misc.xml
									
									
									
										generated
									
									
									
								
							| @ -4,7 +4,7 @@ | ||||
|   <component name="FrameworkDetectionExcludesConfiguration"> | ||||
|     <file type="web" url="file://$PROJECT_DIR$" /> | ||||
|   </component> | ||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_21" default="true" project-jdk-name="21" project-jdk-type="JavaSDK"> | ||||
|   <component name="ProjectRootManager" version="2" languageLevel="JDK_23" project-jdk-name="24" project-jdk-type="JavaSDK"> | ||||
|     <output url="file://$PROJECT_DIR$/out" /> | ||||
|   </component> | ||||
| </project> | ||||
							
								
								
									
										2
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										2
									
								
								.idea/vcs.xml
									
									
									
										generated
									
									
									
								
							| @ -1,6 +1,6 @@ | ||||
| <?xml version="1.0" encoding="UTF-8"?> | ||||
| <project version="4"> | ||||
|   <component name="VcsDirectoryMappings"> | ||||
|     <mapping directory="$PROJECT_DIR$" vcs="Git" /> | ||||
|     <mapping directory="" vcs="Git" /> | ||||
|   </component> | ||||
| </project> | ||||
| @ -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() | ||||
|                             }, | ||||
|                         ) | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | ||||
| @ -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( | ||||
|  | ||||
		Reference in New Issue
	
	Block a user