diff --git a/README.md b/README.md
index e1ccf2a07..f321f85d4 100644
--- a/README.md
+++ b/README.md
@@ -11,9 +11,9 @@ passkeys, and credit card information encrypted entirely on your local device.
### Driven by a modern & intuitive design
## Features
@@ -22,17 +22,17 @@ passkeys, and credit card information encrypted entirely on your local device.
* **Local-Only Storage:** Your data will never leave your device.
* **Comprehensive Management:** Store passwords, passkeys, and credit cards.
* **MFA Support:** Built-in authenticator for TOTP tokens.
-* **Advanced Security:** Per-item, industry-standard encryption.
+* **Advanced Security:** Per-item, industry-standard encryption & password health scanning.
* **Seamless Integration:** System-wide autofill service for all your credentials.
## Download
Get the latest version of KeyGo directly from the Play Store or GitHub:
-|Platform|Status|
-|:------:|:----:|
-| Google Play
-Store | [
](https://play.google.com/store/apps/details?id=de.davis.passwordmanager) |
-|GitHub. | [](https://github.com/OffRange/KeyGo/releases/)|
+
+| Platform | Status |
+|:-----------------:|:-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------:|
+| Google Play Store | [
](https://play.google.com/store/apps/details?id=de.davis.passwordmanager) |
+| GitHub | [](https://github.com/OffRange/KeyGo/releases/) |
## Build it Yourself
diff --git a/app/build.gradle.kts b/app/build.gradle.kts
index 376955630..c6012031b 100644
--- a/app/build.gradle.kts
+++ b/app/build.gradle.kts
@@ -15,7 +15,7 @@ plugins {
}
versioning {
- minVersion = Version(major = 2, minor = 1)
+ minVersion = Version(major = 2, minor = 2)
}
android versionedBy versioning
diff --git a/core/ui/src/main/kotlin/de/davis/keygo/core/ui/components/KeyGoMenuDefaults.kt b/core/ui/src/main/kotlin/de/davis/keygo/core/ui/components/KeyGoMenuDefaults.kt
new file mode 100644
index 000000000..2fe0cdb05
--- /dev/null
+++ b/core/ui/src/main/kotlin/de/davis/keygo/core/ui/components/KeyGoMenuDefaults.kt
@@ -0,0 +1,18 @@
+package de.davis.keygo.core.ui.components
+
+import androidx.compose.material3.MaterialTheme
+import androidx.compose.material3.MenuDefaults
+import androidx.compose.material3.SelectableMenuItemColors
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.graphics.Color
+
+object KeyGoMenuDefaults {
+
+ val containerColor: Color
+ @Composable get() = MaterialTheme.colorScheme.surfaceContainerHighest
+
+ /** Item colors matching [containerColor]; the M3 defaults paint items `surfaceContainerLow`. */
+ val selectableItemColors: SelectableMenuItemColors
+ @Composable
+ get() = MenuDefaults.selectableItemColors(containerColor = containerColor)
+}
diff --git a/docs/assets/desktop.png b/docs/assets/desktop.png
deleted file mode 100644
index 544af986b..000000000
Binary files a/docs/assets/desktop.png and /dev/null differ
diff --git a/docs/assets/feature-graphic.png b/docs/assets/feature-graphic.png
index 9153f8637..3486feeec 100644
Binary files a/docs/assets/feature-graphic.png and b/docs/assets/feature-graphic.png differ
diff --git a/docs/assets/phone-1.png b/docs/assets/phone-1.png
deleted file mode 100644
index 0fdeb88ad..000000000
Binary files a/docs/assets/phone-1.png and /dev/null differ
diff --git a/docs/assets/phone-2.png b/docs/assets/phone-2.png
deleted file mode 100644
index 0b44581bb..000000000
Binary files a/docs/assets/phone-2.png and /dev/null differ
diff --git a/docs/assets/phone-3.png b/docs/assets/phone-3.png
deleted file mode 100644
index e41ba5f35..000000000
Binary files a/docs/assets/phone-3.png and /dev/null differ
diff --git a/docs/assets/phone-4.png b/docs/assets/phone-4.png
deleted file mode 100644
index fb336730b..000000000
Binary files a/docs/assets/phone-4.png and /dev/null differ
diff --git a/docs/assets/phone-5.png b/docs/assets/phone-5.png
deleted file mode 100644
index cd013daca..000000000
Binary files a/docs/assets/phone-5.png and /dev/null differ
diff --git a/docs/assets/phone-6.png b/docs/assets/phone-6.png
deleted file mode 100644
index 4127f62ec..000000000
Binary files a/docs/assets/phone-6.png and /dev/null differ
diff --git a/docs/assets/phone/01_hero.png b/docs/assets/phone/01_hero.png
new file mode 100644
index 000000000..a399a7c48
Binary files /dev/null and b/docs/assets/phone/01_hero.png differ
diff --git a/docs/assets/phone/02_password_health.png b/docs/assets/phone/02_password_health.png
new file mode 100644
index 000000000..135688405
Binary files /dev/null and b/docs/assets/phone/02_password_health.png differ
diff --git a/docs/assets/phone/03_2fa.png b/docs/assets/phone/03_2fa.png
new file mode 100644
index 000000000..5f0e048bb
Binary files /dev/null and b/docs/assets/phone/03_2fa.png differ
diff --git a/docs/assets/phone/04_generator.png b/docs/assets/phone/04_generator.png
new file mode 100644
index 000000000..b500e3dbb
Binary files /dev/null and b/docs/assets/phone/04_generator.png differ
diff --git a/docs/assets/phone/05_vaults.png b/docs/assets/phone/05_vaults.png
new file mode 100644
index 000000000..ee8f61683
Binary files /dev/null and b/docs/assets/phone/05_vaults.png differ
diff --git a/docs/assets/phone/06_privacy.png b/docs/assets/phone/06_privacy.png
new file mode 100644
index 000000000..e2b12fd93
Binary files /dev/null and b/docs/assets/phone/06_privacy.png differ
diff --git a/docs/assets/tablet-1.png b/docs/assets/tablet-1.png
deleted file mode 100644
index fb8dc022a..000000000
Binary files a/docs/assets/tablet-1.png and /dev/null differ
diff --git a/docs/assets/tablet-10in/01_hero.png b/docs/assets/tablet-10in/01_hero.png
new file mode 100644
index 000000000..9d1ac193c
Binary files /dev/null and b/docs/assets/tablet-10in/01_hero.png differ
diff --git a/docs/assets/tablet-10in/02_password_health.png b/docs/assets/tablet-10in/02_password_health.png
new file mode 100644
index 000000000..cd4bfecd5
Binary files /dev/null and b/docs/assets/tablet-10in/02_password_health.png differ
diff --git a/docs/assets/tablet-10in/03_2fa_generator.png b/docs/assets/tablet-10in/03_2fa_generator.png
new file mode 100644
index 000000000..01d3d8133
Binary files /dev/null and b/docs/assets/tablet-10in/03_2fa_generator.png differ
diff --git a/docs/assets/tablet-10in/04_privacy.png b/docs/assets/tablet-10in/04_privacy.png
new file mode 100644
index 000000000..d2af625a7
Binary files /dev/null and b/docs/assets/tablet-10in/04_privacy.png differ
diff --git a/docs/assets/tablet-2.png b/docs/assets/tablet-2.png
deleted file mode 100644
index 9d1c0234a..000000000
Binary files a/docs/assets/tablet-2.png and /dev/null differ
diff --git a/docs/assets/tablet-7in/01_hero.png b/docs/assets/tablet-7in/01_hero.png
new file mode 100644
index 000000000..682c247b1
Binary files /dev/null and b/docs/assets/tablet-7in/01_hero.png differ
diff --git a/docs/assets/tablet-7in/02_password_health.png b/docs/assets/tablet-7in/02_password_health.png
new file mode 100644
index 000000000..bb7e4a56a
Binary files /dev/null and b/docs/assets/tablet-7in/02_password_health.png differ
diff --git a/docs/assets/tablet-7in/03_2fa_generator.png b/docs/assets/tablet-7in/03_2fa_generator.png
new file mode 100644
index 000000000..a3988f2ce
Binary files /dev/null and b/docs/assets/tablet-7in/03_2fa_generator.png differ
diff --git a/docs/assets/tablet-7in/04_privacy.png b/docs/assets/tablet-7in/04_privacy.png
new file mode 100644
index 000000000..668fc86a5
Binary files /dev/null and b/docs/assets/tablet-7in/04_privacy.png differ
diff --git a/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/export/ScheduleComponents.kt b/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/export/ScheduleComponents.kt
index 3201ff540..c86d3389c 100644
--- a/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/export/ScheduleComponents.kt
+++ b/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/export/ScheduleComponents.kt
@@ -10,7 +10,6 @@ import androidx.compose.foundation.interaction.collectIsPressedAsState
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.ColumnScope
-import androidx.compose.foundation.layout.ExperimentalLayoutApi
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.WindowInsets
import androidx.compose.foundation.layout.fillMaxWidth
@@ -31,7 +30,6 @@ import androidx.compose.material.icons.filled.DeleteSweep
import androidx.compose.material.icons.filled.Remove
import androidx.compose.material.icons.filled.Schedule
import androidx.compose.material3.ButtonGroupDefaults
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon
@@ -78,7 +76,6 @@ import de.davis.keygo.feature.backup.presentation.label
import kotlinx.coroutines.delay
import kotlin.time.Duration.Companion.milliseconds
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
internal fun IntervalPicker(
interval: BackupInterval,
@@ -115,7 +112,7 @@ internal fun IntervalPicker(
0 -> ButtonGroupDefaults.connectedLeadingButtonShapes()
else -> ButtonGroupDefaults.connectedTrailingButtonShapes()
},
- colors = OutlinedToggleButtonDefaults.outlinedToggleButtonColors(
+ colors = OutlinedToggleButtonDefaults.colors(
checkedContainerColor = MaterialTheme.colorScheme.primaryContainer,
checkedContentColor = MaterialTheme.colorScheme.onPrimaryContainer,
)
@@ -127,7 +124,6 @@ internal fun IntervalPicker(
}
}
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
internal fun RetentionPicker(
keepCount: Int,
@@ -314,7 +310,6 @@ private fun StepperButton(
}
}
-@OptIn(ExperimentalLayoutApi::class)
@Composable
private fun StepperValueField(
value: Int,
diff --git a/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/import/MapColumnsContent.kt b/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/import/MapColumnsContent.kt
index 99c1c1879..31b61ae03 100644
--- a/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/import/MapColumnsContent.kt
+++ b/feature/backup/src/main/kotlin/de/davis/keygo/feature/backup/presentation/import/MapColumnsContent.kt
@@ -6,13 +6,12 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.foundation.layout.padding
+import androidx.compose.foundation.layout.size
import androidx.compose.foundation.lazy.LazyColumn
import androidx.compose.foundation.lazy.items
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
import androidx.compose.material.icons.filled.TableChart
-import androidx.compose.material3.DropdownMenuItem
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.ExposedDropdownMenu
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
@@ -22,6 +21,7 @@ import androidx.compose.material3.ListItemDefaults
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.SegmentedListItem
+import androidx.compose.material3.SelectableDropdownMenuItem
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -193,7 +193,6 @@ private fun SourceSegment(columnIndex: Int, header: String) {
* since all three segments carry the same weight of leading icon. This is the only segment of the
* three that is genuinely interactive.
*/
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun TypeSegment(
selectedType: CsvColumnType?,
@@ -254,7 +253,7 @@ private fun TypeSegment(
shape = MenuDefaults.standaloneGroupShape,
) {
TYPE_OPTIONS.forEachIndexed { index, option ->
- DropdownMenuItem(
+ SelectableDropdownMenuItem(
selected = selectedType == option,
onClick = {
onTypeChange(option)
@@ -262,10 +261,18 @@ private fun TypeSegment(
},
text = { Text(text = option.displayName) },
leadingIcon = {
- Icon(imageVector = option.icon, contentDescription = null)
+ Icon(
+ imageVector = option.icon,
+ modifier = Modifier.size(MenuDefaults.LeadingIconSize),
+ contentDescription = null,
+ )
},
selectedLeadingIcon = {
- Icon(imageVector = Icons.Default.Check, contentDescription = null)
+ Icon(
+ imageVector = Icons.Default.Check,
+ modifier = Modifier.size(MenuDefaults.LeadingIconSize),
+ contentDescription = null,
+ )
},
shapes = MenuDefaults.itemShape(index, TYPE_OPTIONS.size)
)
diff --git a/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/KeyGoFormSuggestionField.kt b/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/KeyGoFormSuggestionField.kt
index 693d25a00..d6423f9c9 100644
--- a/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/KeyGoFormSuggestionField.kt
+++ b/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/KeyGoFormSuggestionField.kt
@@ -8,8 +8,6 @@ import androidx.compose.foundation.text.input.TextFieldLineLimits
import androidx.compose.foundation.text.input.TextFieldState
import androidx.compose.foundation.text.input.clearText
import androidx.compose.material3.DropdownMenuItem
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.ExposedDropdownMenu
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
@@ -23,8 +21,8 @@ import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.input.ImeAction
+import de.davis.keygo.core.ui.components.KeyGoMenuDefaults
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun KeyGoFormSuggestionField(
suggestions: Set,
@@ -70,7 +68,9 @@ fun KeyGoFormSuggestionField(
ExposedDropdownMenu(
expanded = expanded,
- onDismissRequest = { setExpanded(false) }
+ onDismissRequest = { setExpanded(false) },
+ containerColor = KeyGoMenuDefaults.containerColor,
+ shape = MenuDefaults.standaloneGroupShape,
) {
suggestions.forEachIndexed { index, suggestion ->
DropdownMenuItem(
diff --git a/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/MenuChip.kt b/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/MenuChip.kt
index 36fb61fd0..5b15d9199 100644
--- a/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/MenuChip.kt
+++ b/feature/item/core/src/main/kotlin/de/davis/keygo/feature/item/core/presentation/component/MenuChip.kt
@@ -10,10 +10,8 @@ import androidx.compose.material.icons.filled.Edit
import androidx.compose.material3.DropdownMenuGroup
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.DropdownMenuPopup
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.InputChip
-import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
@@ -25,9 +23,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
+import de.davis.keygo.core.ui.components.KeyGoMenuDefaults
import de.davis.keygo.feature.item.core.R
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun MenuChip(
chipText: String,
@@ -56,7 +54,7 @@ fun MenuChip(
) {
DropdownMenuGroup(
shapes = MenuDefaults.groupShape(0, 1),
- containerColor = MaterialTheme.colorScheme.surfaceContainerHigh,
+ containerColor = KeyGoMenuDefaults.containerColor,
) {
onModifyClick?.let { onModify ->
DropdownMenuItem(
diff --git a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/component/VaultDropDownMenu.kt b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/component/VaultDropDownMenu.kt
index 93bb1c1e6..84395bbcb 100644
--- a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/component/VaultDropDownMenu.kt
+++ b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/component/VaultDropDownMenu.kt
@@ -4,9 +4,6 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.size
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Check
-import androidx.compose.material3.DropdownMenuItem
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.ExposedDropdownMenu
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
@@ -15,6 +12,7 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.OutlinedTextField
+import androidx.compose.material3.SelectableDropdownMenuItem
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
@@ -25,10 +23,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import de.davis.keygo.core.item.domain.alias.VaultId
import de.davis.keygo.core.item.presentation.toImageVector
+import de.davis.keygo.core.ui.components.KeyGoMenuDefaults
import de.davis.keygo.feature.item.create.R
import de.davis.keygo.feature.item.create.presentation.model.VaultsState
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
fun VaultDropDownMenu(
vaultsState: VaultsState,
@@ -68,15 +66,14 @@ fun VaultDropDownMenu(
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
- containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
+ containerColor = KeyGoMenuDefaults.containerColor,
+ shape = MenuDefaults.standaloneGroupShape,
) {
val optionCount = vaultsState.vaults.size
vaultsState.vaults.forEachIndexed { index, metadata ->
- DropdownMenuItem(
+ SelectableDropdownMenuItem(
shapes = MenuDefaults.itemShape(index, optionCount),
- colors = MenuDefaults.selectableItemColors(
- containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
- ),
+ colors = KeyGoMenuDefaults.selectableItemColors,
text = {
Text(
metadata.name,
diff --git a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordContent.kt b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordContent.kt
index 1b68c36a2..5c8109fee 100644
--- a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordContent.kt
+++ b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordContent.kt
@@ -141,7 +141,10 @@ fun GeneratePasswordContent(
.fillMaxWidth(),
properties = cardProp,
) {
- Slider(state = viewModel.sliderState)
+ Slider(
+ state = viewModel.sliderState,
+ onValueChange = { viewModel.sliderState.value = it },
+ )
}
}
diff --git a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordViewModel.kt b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordViewModel.kt
index 04e0aae25..83613e8de 100644
--- a/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordViewModel.kt
+++ b/feature/item/create/src/main/kotlin/de/davis/keygo/feature/item/create/presentation/password/GeneratePasswordViewModel.kt
@@ -1,6 +1,5 @@
package de.davis.keygo.feature.item.create.presentation.password
-import androidx.compose.material3.ExperimentalMaterial3Api
import androidx.compose.material3.SliderState
import androidx.compose.runtime.snapshotFlow
import androidx.lifecycle.ViewModel
@@ -28,14 +27,13 @@ import org.koin.core.annotation.KoinViewModel
import kotlin.time.Duration.Companion.milliseconds
@KoinViewModel
-@OptIn(ExperimentalMaterial3Api::class, FlowPreview::class)
+@OptIn(FlowPreview::class)
internal class GeneratePasswordViewModel(
private val passwordGenerator: PasswordGenerator,
private val passwordStrengthEstimator: PasswordStrengthEstimator,
) : ViewModel() {
- @OptIn(ExperimentalMaterial3Api::class)
- val sliderState = SliderState(value = 10f, valueRange = 8f..100f)
+ val sliderState = SliderState(value = 10f, trackRange = 8f..100f)
private val finalPasswordChannel = Channel()
val finalPassword = finalPasswordChannel.receiveAsFlow()
@@ -73,7 +71,6 @@ internal class GeneratePasswordViewModel(
initialValue = GeneratePasswordUiState(),
)
- @OptIn(ExperimentalMaterial3Api::class)
fun onEvent(event: GeneratePasswordUiEvent) {
when (event) {
is GeneratePasswordUiEvent.OnCharacterSetClick -> {
diff --git a/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/MoveVaultDialog.kt b/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/MoveVaultDialog.kt
index adc6a0fa7..4d7a8a621 100644
--- a/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/MoveVaultDialog.kt
+++ b/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/MoveVaultDialog.kt
@@ -13,9 +13,6 @@ import androidx.compose.material.icons.filled.Check
import androidx.compose.material3.AlertDialog
import androidx.compose.material3.AlertDialogDefaults
import androidx.compose.material3.Button
-import androidx.compose.material3.DropdownMenuItem
-import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.ExposedDropdownMenu
import androidx.compose.material3.ExposedDropdownMenuAnchorType
import androidx.compose.material3.ExposedDropdownMenuBox
@@ -28,6 +25,7 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.ProgressIndicatorDefaults
+import androidx.compose.material3.SelectableDropdownMenuItem
import androidx.compose.material3.Surface
import androidx.compose.material3.Text
import androidx.compose.material3.TextButton
@@ -47,13 +45,13 @@ import de.davis.keygo.core.item.domain.alias.newVaultId
import de.davis.keygo.core.item.domain.model.Vault
import de.davis.keygo.core.item.domain.model.VaultMetadata
import de.davis.keygo.core.item.presentation.toImageVector
+import de.davis.keygo.core.ui.components.KeyGoMenuDefaults
import de.davis.keygo.core.ui.components.KeyGoSwitch
import de.davis.keygo.core.ui.theme.KeyGoTheme
import de.davis.keygo.feature.vault.R
import de.davis.keygo.feature.vault.domain.model.MoveItemsProgress
import de.davis.keygo.feature.vault.presentation.model.VaultState
-@OptIn(ExperimentalMaterial3Api::class)
@Composable
fun MoveVaultDialog(
vaultState: VaultState.Move,
@@ -105,7 +103,6 @@ fun MoveVaultDialog(
)
}
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
private fun MoveVaultProgressContent(progress: MoveItemsProgress) {
val animatedFraction by animateFloatAsState(
@@ -134,7 +131,6 @@ private fun MoveVaultProgressContent(progress: MoveItemsProgress) {
}
}
-@OptIn(ExperimentalMaterial3ExpressiveApi::class)
@Composable
private fun MoveVaultDialogContent(
vaultState: VaultState.Move,
@@ -193,7 +189,6 @@ private fun SrcVaultRow(srcVault: VaultMetadata) {
)
}
-@OptIn(ExperimentalMaterial3Api::class, ExperimentalMaterial3ExpressiveApi::class)
@Composable
private fun DstVaultDropdown(
dstVaults: List,
@@ -231,15 +226,14 @@ private fun DstVaultDropdown(
ExposedDropdownMenu(
expanded = expanded,
onDismissRequest = { expanded = false },
- containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
+ containerColor = KeyGoMenuDefaults.containerColor,
+ shape = MenuDefaults.standaloneGroupShape,
) {
val optionCount = dstVaults.size
dstVaults.forEachIndexed { index, vault ->
- DropdownMenuItem(
+ SelectableDropdownMenuItem(
shapes = MenuDefaults.itemShape(index, optionCount),
- colors = MenuDefaults.selectableItemColors(
- containerColor = MaterialTheme.colorScheme.surfaceContainerHighest,
- ),
+ colors = KeyGoMenuDefaults.selectableItemColors,
selected = vault.vaultId == selectedDstVault?.vaultId,
text = {
Text(
diff --git a/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/VaultSelectionSheet.kt b/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/VaultSelectionSheet.kt
index dd236b028..a576b95bc 100644
--- a/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/VaultSelectionSheet.kt
+++ b/feature/vault/src/main/kotlin/de/davis/keygo/feature/vault/presentation/components/VaultSelectionSheet.kt
@@ -21,7 +21,6 @@ import androidx.compose.material3.DropdownMenuGroup
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.DropdownMenuPopup
import androidx.compose.material3.ExperimentalMaterial3Api
-import androidx.compose.material3.ExperimentalMaterial3ExpressiveApi
import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton
import androidx.compose.material3.ListItemDefaults
@@ -95,7 +94,7 @@ fun VaultSelectionSheet(
}
}
-@OptIn(ExperimentalMaterial3ExpressiveApi::class, ExperimentalMaterial3Api::class)
+@OptIn(ExperimentalMaterial3Api::class)
@Composable
private fun VaultSelectionSheetContent(
vaultState: VaultState.Select,
@@ -232,6 +231,7 @@ private fun VaultSelectionSheetContent(
leadingIcon = {
Icon(
imageVector = Icons.Default.Edit,
+ modifier = Modifier.size(MenuDefaults.LeadingIconSize),
contentDescription = stringResource(R.string.edit)
)
}
@@ -250,6 +250,7 @@ private fun VaultSelectionSheetContent(
leadingIcon = {
Icon(
imageVector = Icons.AutoMirrored.Default.DriveFileMove,
+ modifier = Modifier.size(MenuDefaults.LeadingIconSize),
contentDescription = stringResource(R.string.move_to)
)
}
@@ -272,12 +273,13 @@ private fun VaultSelectionSheetContent(
onDeleteRequest(metadata)
},
shape = MenuDefaults.trailingItemShape,
- colors = MenuDefaults.selectableItemColors(
+ colors = MenuDefaults.itemColors().copy(
containerColor = MaterialTheme.colorScheme.errorContainer,
),
leadingIcon = {
Icon(
imageVector = Icons.Default.DeleteForever,
+ modifier = Modifier.size(MenuDefaults.LeadingIconSize),
contentDescription = stringResource(R.string.delete)
)
}
diff --git a/gradle.properties b/gradle.properties
index 4c51ec73c..2abf2e0f6 100644
--- a/gradle.properties
+++ b/gradle.properties
@@ -6,7 +6,10 @@
# http://www.gradle.org/docs/current/userguide/build_environment.html
# Specifies the JVM arguments used for the daemon process.
# The setting is particularly useful for tweaking memory settings.
-org.gradle.jvmargs=-Xmx3g -XX:+UseParallelGC -Dfile.encoding=UTF-8
+org.gradle.jvmargs=-Xmx4g -XX:+UseParallelGC -Dfile.encoding=UTF-8
+# JVM arguments for the Kotlin daemon, which runs the Kotlin compiler. Without this it inherits
+# the Gradle daemon's heap, which is not enough for the larger Compose modules.
+kotlin.daemon.jvmargs=-Xmx4g -XX:+UseParallelGC
# When configured, Gradle will run in incubating parallel mode.
# This option should only be used with decoupled projects. For more details, visit
# https://developer.android.com/r/tools/gradle-multi-project-decoupled-projects
diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml
index 280e2c0cc..78d29ed35 100644
--- a/gradle/libs.versions.toml
+++ b/gradle/libs.versions.toml
@@ -2,47 +2,47 @@
compileSdk = "37"
minSdk = "26"
-agp = "9.3.2"
+agp = "9.4.1"
autofill = "1.3.0"
accompanist = "0.37.3"
-camera = "1.6.1"
+camera = "1.6.2"
credentials = "1.6.0"
gmsAuthApiPhone = "18.3.1"
gmsMlkitBarcodeScanning = "18.3.1"
okhttp = "5.5.0"
zxingBarcodeScanning = "3.5.4"
-kotlin = "2.4.10"
+kotlin = "2.4.20"
kotlinSerializationJson = "1.11.0"
-collectionsImmutable = "0.5.1"
-coreKtx = "1.19.0"
+collectionsImmutable = "0.5.2"
+coreKtx = "1.19.1"
junitVersion = "1.3.0"
espressoCore = "3.7.0"
lifecycleRuntimeKtx = "2.11.0"
activityCompose = "1.13.0"
-composeBom = "2026.08.00"
+composeBom = "2026.09.00"
mockk = "1.14.11"
semver = "0.2.6"
koinBOM = "4.2.2"
-koin-plugin = "1.1.0"
-room3 = "3.0.1"
-sqlite = "2.7.0"
+koin-plugin = "1.2.1"
+room3 = "3.0.3"
+sqlite = "2.7.1"
ksp = "2.3.11"
datastore = "1.2.1"
protobuf = "0.10.0"
-protoc = "4.36.0"
+protoc = "4.36.2"
coroutines = "1.11.0"
bcrypt = "0.10.2"
biometric = "1.4.0-alpha07"
-nav3 = "1.2.0-beta01"
+nav3 = "1.2.0"
lifecycleViewmodelNav3 = "2.11.0"
-kotlinpoet = "2.3.0"
+kotlinpoet = "2.4.0"
jna = "5.19.1"
nbvcxz = "1.5.1"
passGen = "0.1.0-beta"
-robolectric = "4.16.1"
-emvnfccard = "3.1.0"
-aboutlibraries = "15.1.1"
-work = "2.11.2"
+robolectric = "4.17"
+emvnfccard = "3.2.0"
+aboutlibraries = "15.2.0"
+work = "2.12.0"
splashscreen = "1.2.0"
[libraries]
@@ -70,7 +70,7 @@ androidx-ui-tooling = { group = "androidx.compose.ui", name = "ui-tooling" }
androidx-ui-tooling-preview = { group = "androidx.compose.ui", name = "ui-tooling-preview" }
androidx-ui-test-manifest = { group = "androidx.compose.ui", name = "ui-test-manifest" }
androidx-ui-test-junit4 = { group = "androidx.compose.ui", name = "ui-test-junit4" }
-androidx-material3 = { group = "androidx.compose.material3", name = "material3", version = "1.5.0-alpha26" }
+androidx-material3 = { group = "androidx.compose.material3", name = "material3", version = "1.5.0-alpha29" }
androidx-material3-adaptive-layout = { group = "androidx.compose.material3.adaptive", name = "adaptive-layout" }
androidx-material3-adaptive-navigation-suite = { group = "androidx.compose.material3", name = "material3-adaptive-navigation-suite" }