iOS and Android Updates!
This commit is contained in:
1
android/.idea/.name
generated
Normal file
1
android/.idea/.name
generated
Normal file
@@ -0,0 +1 @@
|
||||
MagicCounter
|
||||
1
android/.idea/misc.xml
generated
1
android/.idea/misc.xml
generated
@@ -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" project-jdk-name="jbr-21" project-jdk-type="JavaSDK">
|
||||
|
||||
1
android/.idea/vcs.xml
generated
1
android/.idea/vcs.xml
generated
@@ -2,5 +2,6 @@
|
||||
<project version="4">
|
||||
<component name="VcsDirectoryMappings">
|
||||
<mapping directory="" vcs="Git" />
|
||||
<mapping directory="$PROJECT_DIR$/.." vcs="Git" />
|
||||
</component>
|
||||
</project>
|
||||
@@ -15,8 +15,8 @@ android {
|
||||
applicationId = "com.atridad.magiccounter"
|
||||
minSdk = 31
|
||||
targetSdk = 36
|
||||
versionCode = 3
|
||||
versionName = "1.3.0"
|
||||
versionCode = 4
|
||||
versionName = "1.4.0"
|
||||
|
||||
testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner"
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ fun MagicCounterApp() {
|
||||
val settingsVm: AppSettingsViewModel = viewModel()
|
||||
val theme = settingsVm.themeMode.collectAsState()
|
||||
val historyState = settingsVm.matchHistory.collectAsState()
|
||||
|
||||
|
||||
|
||||
|
||||
MagicCounterTheme(themeMode = theme.value) {
|
||||
@@ -81,7 +81,7 @@ fun MagicCounterApp() {
|
||||
}
|
||||
},
|
||||
actions = {
|
||||
|
||||
|
||||
IconButton(onClick = { screenStack.add(Screen.Settings) }) {
|
||||
Icon(Icons.Default.Settings, contentDescription = "App settings")
|
||||
}
|
||||
@@ -142,7 +142,7 @@ fun MagicCounterApp() {
|
||||
screenStack.removeAt(screenStack.lastIndex)
|
||||
return@SetupScreen
|
||||
}
|
||||
|
||||
|
||||
// Create and persist a new MatchRecord
|
||||
val newId = java.util.UUID.randomUUID().toString()
|
||||
val now = System.currentTimeMillis()
|
||||
@@ -175,6 +175,8 @@ fun MagicCounterApp() {
|
||||
.padding(paddingValues)
|
||||
.fillMaxSize(),
|
||||
state = stateForGame,
|
||||
matchName = record?.name ?: "Game",
|
||||
startedAtEpochMs = record?.startedAtEpochMs ?: System.currentTimeMillis(),
|
||||
onProgress = { updated ->
|
||||
val current = historyState.value
|
||||
val idx = current.indexOfFirst { it.id == id }
|
||||
@@ -233,7 +235,7 @@ fun MagicCounterApp() {
|
||||
onSelect = { settingsVm.setTheme(it) }
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -242,7 +244,7 @@ fun MagicCounterApp() {
|
||||
@Composable
|
||||
private fun SettingsContent(modifier: Modifier, current: ThemeMode, onSelect: (ThemeMode) -> Unit) {
|
||||
Column(
|
||||
modifier = modifier.padding(24.dp),
|
||||
modifier = modifier.padding(24.dp),
|
||||
verticalArrangement = Arrangement.spacedBy(24.dp)
|
||||
) {
|
||||
Text(
|
||||
@@ -250,7 +252,7 @@ private fun SettingsContent(modifier: Modifier, current: ThemeMode, onSelect: (T
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
|
||||
|
||||
Column(verticalArrangement = Arrangement.spacedBy(16.dp)) {
|
||||
Text(
|
||||
"Theme",
|
||||
@@ -291,17 +293,17 @@ private fun HomeScreen(
|
||||
contentAlignment = Alignment.Center
|
||||
) {
|
||||
Column(
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.spacedBy(16.dp)
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.History,
|
||||
Icons.Default.History,
|
||||
contentDescription = "Empty history",
|
||||
modifier = Modifier.size(64.dp),
|
||||
tint = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
Text(
|
||||
"No games yet",
|
||||
"No games yet",
|
||||
style = MaterialTheme.typography.headlineSmall,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
@@ -332,13 +334,13 @@ private fun HomeScreen(
|
||||
onClick = { onResume(activeGame) }
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
"Active Game",
|
||||
"Active Game",
|
||||
style = MaterialTheme.typography.titleMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimary
|
||||
)
|
||||
@@ -382,23 +384,29 @@ private fun HomeScreen(
|
||||
onClick = { onResume(rec) }
|
||||
) {
|
||||
Row(
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
modifier = Modifier.fillMaxWidth().padding(16.dp),
|
||||
horizontalArrangement = Arrangement.SpaceBetween,
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
Column(modifier = Modifier.weight(1f)) {
|
||||
Text(
|
||||
rec.name,
|
||||
rec.name,
|
||||
style = MaterialTheme.typography.bodyLarge,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant
|
||||
)
|
||||
val status = if (rec.state.stopped) "Stopped" else "Finished"
|
||||
val winner = rec.winnerPlayerId?.let { " • Winner: Player ${it + 1}" } ?: ""
|
||||
val statusText = if (winner.isNotEmpty()) "$status$winner" else status
|
||||
val winnerId = rec.winnerPlayerId ?: rec.state.winnerPlayerId
|
||||
val winnerName = winnerId?.let { wId ->
|
||||
rec.state.players.find { it.id == wId }?.name
|
||||
}
|
||||
val statusText = when {
|
||||
winnerName != null -> "Winner: $winnerName"
|
||||
rec.state.stopped -> "Stopped"
|
||||
else -> "Finished"
|
||||
}
|
||||
Text(
|
||||
statusText,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f)
|
||||
color = if (winnerName != null) Color(0xFF2E7D32) else MaterialTheme.colorScheme.onSurfaceVariant.copy(alpha = 0.7f)
|
||||
)
|
||||
}
|
||||
Row(horizontalArrangement = Arrangement.spacedBy(8.dp)) {
|
||||
@@ -409,12 +417,12 @@ private fun HomeScreen(
|
||||
containerColor = MaterialTheme.colorScheme.secondary,
|
||||
contentColor = MaterialTheme.colorScheme.onSecondary
|
||||
)
|
||||
) {
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Visibility,
|
||||
Icons.Default.Visibility,
|
||||
contentDescription = "View match",
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
)
|
||||
}
|
||||
androidx.compose.material3.FilledTonalIconButton(
|
||||
onClick = { pendingDeleteId = rec.id },
|
||||
@@ -423,12 +431,12 @@ private fun HomeScreen(
|
||||
containerColor = MaterialTheme.colorScheme.error,
|
||||
contentColor = MaterialTheme.colorScheme.onError
|
||||
)
|
||||
) {
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Delete,
|
||||
Icons.Default.Delete,
|
||||
contentDescription = "Delete",
|
||||
modifier = Modifier.size(20.dp)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -461,14 +469,14 @@ private fun GameDuration(
|
||||
color: Color
|
||||
) {
|
||||
var duration by remember { mutableStateOf("") }
|
||||
|
||||
|
||||
LaunchedEffect(startTime) {
|
||||
while (true) {
|
||||
val elapsed = System.currentTimeMillis() - startTime
|
||||
val seconds = (elapsed / 1000).toInt()
|
||||
val minutes = seconds / 60
|
||||
val remainingSeconds = seconds % 60
|
||||
|
||||
|
||||
duration = when {
|
||||
minutes > 0 -> "Duration: ${minutes}m ${remainingSeconds}s"
|
||||
else -> "${remainingSeconds}s"
|
||||
@@ -476,12 +484,10 @@ private fun GameDuration(
|
||||
delay(1000)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Text(
|
||||
text = duration,
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
color = color.copy(alpha = 0.8f)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -21,9 +21,8 @@ data class GameState(
|
||||
val startingLife: Int,
|
||||
val trackPoison: Boolean,
|
||||
val trackCommanderDamage: Boolean,
|
||||
val stopped: Boolean = false
|
||||
val stopped: Boolean = false,
|
||||
val winnerPlayerId: Int? = null
|
||||
)
|
||||
|
||||
fun defaultPlayerName(index: Int): String = "Player ${index + 1}"
|
||||
|
||||
|
||||
|
||||
@@ -201,6 +201,25 @@ object CustomIcons {
|
||||
close()
|
||||
}.build()
|
||||
|
||||
fun Droplet(color: Color = Color.Black): ImageVector = ImageVector.Builder(
|
||||
name = "Droplet",
|
||||
defaultWidth = 24.dp,
|
||||
defaultHeight = 24.dp,
|
||||
viewportWidth = 24f,
|
||||
viewportHeight = 24f
|
||||
).path(
|
||||
fill = SolidColor(color)
|
||||
) {
|
||||
moveTo(12f, 2.69f)
|
||||
lineTo(17.66f, 8.35f)
|
||||
curveTo(19.1f, 9.79f, 20f, 11.79f, 20f, 14f)
|
||||
curveTo(20f, 18.42f, 16.42f, 22f, 12f, 22f)
|
||||
curveTo(7.58f, 22f, 4f, 18.42f, 4f, 14f)
|
||||
curveTo(4f, 11.79f, 4.9f, 9.79f, 6.34f, 8.35f)
|
||||
lineTo(12f, 2.69f)
|
||||
close()
|
||||
}.build()
|
||||
|
||||
fun Sword(color: Color = Color.Black): ImageVector = ImageVector.Builder(
|
||||
name = "Sword",
|
||||
defaultWidth = 24.dp,
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
[versions]
|
||||
agp = "8.12.3"
|
||||
kotlin = "2.0.21"
|
||||
coreKtx = "1.10.1"
|
||||
kotlin = "2.3.0"
|
||||
coreKtx = "1.17.0"
|
||||
junit = "4.13.2"
|
||||
junitVersion = "1.1.5"
|
||||
espressoCore = "3.5.1"
|
||||
appcompat = "1.6.1"
|
||||
material = "1.10.0"
|
||||
constraintlayout = "2.1.4"
|
||||
lifecycleLivedataKtx = "2.6.1"
|
||||
lifecycleViewmodelKtx = "2.6.1"
|
||||
navigationFragmentKtx = "2.6.0"
|
||||
navigationUiKtx = "2.6.0"
|
||||
composeBom = "2024.10.01"
|
||||
activityCompose = "1.9.2"
|
||||
lifecycleRuntimeCompose = "2.8.6"
|
||||
lifecycleViewmodelCompose = "2.8.6"
|
||||
datastore = "1.1.1"
|
||||
serialization = "1.7.3"
|
||||
junitVersion = "1.3.0"
|
||||
espressoCore = "3.7.0"
|
||||
appcompat = "1.7.1"
|
||||
material = "1.13.0"
|
||||
constraintlayout = "2.2.1"
|
||||
lifecycleLivedataKtx = "2.10.0"
|
||||
lifecycleViewmodelKtx = "2.10.0"
|
||||
navigationFragmentKtx = "2.9.6"
|
||||
navigationUiKtx = "2.9.6"
|
||||
composeBom = "2025.12.01"
|
||||
activityCompose = "1.12.2"
|
||||
lifecycleRuntimeCompose = "2.10.0"
|
||||
lifecycleViewmodelCompose = "2.10.0"
|
||||
datastore = "1.2.0"
|
||||
serialization = "1.9.0"
|
||||
|
||||
[libraries]
|
||||
androidx-core-ktx = { group = "androidx.core", name = "core-ktx", version.ref = "coreKtx" }
|
||||
|
||||
Reference in New Issue
Block a user