53183c79f084
fix: Match browser add-entry tag behavior (v2.3.15)
- time
- 2026-06-26 01:23 UTC · 4 months ago
- machine
- koh2
- parent
- fb79f4f138ac
↓ peach-android-53183c79.tar.gzatlas at this save
files changed3 files
app/build.gradle+2 −2app/src/main/java/com/peachpasswords/ui/vault/TagChipEditor.kt+19 −12app/src/test/java/com/peachpasswords/ui/vault/EntryEditScreenTest.kt+17 −0app/build.gradle+2 −2
@@ -16,8 +16,8 @@1616 applicationId "com.peachpasswords"1717 minSdk 261818 targetSdk 3519- versionCode 23140020- versionName "2.3.14"19+ versionCode 23150020+ versionName "2.3.15"2121 2222 testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"2323 vectorDrawables {app/src/main/java/com/peachpasswords/ui/vault/TagChipEditor.kt+19 −12
@@ -38,22 +38,34 @@3838 import com.peachpasswords.ui.theme.PeachType3939 4040 /** Max tags per entry. */41-private const val MAX_TAGS = 1041+internal const val MAX_TAGS = 104242 4343 /** Max characters per tag. */44-private const val MAX_TAG_LEN = 3244+internal const val MAX_TAG_LEN = 324545 46+/** Browser AddView shows up to five tag suggestions. */47+internal const val MAX_TAG_SUGGESTIONS = 548+4649 /** Normalise raw tag input to the canonical form (trimmed, lowercase, length-capped). */4750 internal fun normalizeTag(raw: String): String =4851 raw.trim().lowercase().take(MAX_TAG_LEN)4952 53+internal fun tagSuggestionsFor(input: String, allTags: List<String>, tags: List<String>): List<String> {54+ val needle = input.trim().lowercase()55+ return allTags.asSequence()56+ .filter { it !in tags }57+ .filter { needle.isEmpty() || (it.contains(needle) && it != needle) }58+ .take(MAX_TAG_SUGGESTIONS)59+ .toList()60+}61+5062 /**5163 * Tag chip editor for EntryEditScreen. Self-contained: owns its own draft-input5264 * state; the committed tag list and suggestion source come from the caller.5365 *54- * - Commits on space or enter (also strips spaces typed mid-word into commits).66+ * - Commits on comma or enter, matching browser AddView.5567 * - Enforces max 10 tags, 32 chars, lowercase, trimmed, de-duplicated.56- * - Shows up to 4 autocomplete suggestions drawn from [allTags] minus current tags.68+ * - Shows up to 5 autocomplete suggestions drawn from [allTags] minus current tags.5769 */5870 @OptIn(ExperimentalLayoutApi::class)5971 @Composable@@ -75,11 +87,7 @@7587 7688 val suggestions = remember(draft, allTags, tags) {7789 val needle = draft.trim().lowercase()78- allTags.asSequence()79- .filter { it !in tags }80- .filter { needle.isEmpty() || (it.contains(needle) && it != needle) }81- .take(4)82- .toList()90+ tagSuggestionsFor(needle, allTags, tags)8391 }8492 8593 Column(Modifier.fillMaxWidth().padding(bottom = 14.dp)) {@@ -108,9 +116,8 @@108116 BasicTextField(109117 value = draft,110118 onValueChange = { input ->111- // Space acts as a delimiter: commit the segment before it.112- if (input.endsWith(" ") || input.contains(' ')) {113- val parts = input.split(' ')119+ if (input.endsWith(",") || input.contains(',')) {120+ val parts = input.split(',')114121 parts.dropLast(1).forEach { commit(it) }115122 draft = normalizeTag(parts.last())116123 } else {app/src/test/java/com/peachpasswords/ui/vault/EntryEditScreenTest.kt+17 −0
@@ -92,6 +92,23 @@9292 assertEquals("hide generator", generatorToggleLabel(open = true))9393 }9494 95+ @Test fun tag_suggestions_match_browser_add_view_limit_and_filtering() {96+ val all = listOf("banking", "billing", "books", "business", "backup", "travel")97+ assertEquals(98+ listOf("banking", "billing", "books", "business", "backup"),99+ tagSuggestionsFor(input = "b", allTags = all, tags = emptyList()),100+ )101+ assertEquals(102+ listOf("billing", "books", "business", "backup"),103+ tagSuggestionsFor(input = "b", allTags = all, tags = listOf("banking")),104+ )105+ }106+107+ @Test fun tag_normalization_allows_spaces_and_caps_length_like_browser() {108+ assertEquals("shared login", normalizeTag(" Shared Login "))109+ assertEquals("a".repeat(MAX_TAG_LEN), normalizeTag("A".repeat(MAX_TAG_LEN + 8)))110+ }111+95112 // ── Card field formatting (CardFieldUtils, used live by setCardNumber etc.) ─96113 97114 @Test fun new_card_number_auto_formats() {