diff --git a/mobile/src/main/java/ru/omni_devel/cards/Config.kt b/mobile/src/main/java/ru/omni_devel/cards/Config.kt index 40264e1..cd67f75 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/Config.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/Config.kt @@ -1,3 +1,5 @@ package ru.omni_devel.cards const val TEMPLATES_URL = "https://gitea.omni-devel.ru/omni/OmniCardsRepo/raw/branch/main/templates.json" + +val SPACE_SYMBOLS = listOf(" ", "-", "_") diff --git a/mobile/src/main/java/ru/omni_devel/cards/FillTemplateActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/FillTemplateActivity.kt index bdeb6ab..b6f7624 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/FillTemplateActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/FillTemplateActivity.kt @@ -79,8 +79,6 @@ fun FillTemplatePage(template: Template, innerPadding: PaddingValues) { selectTemplateNameViaLanguage(template.names, language), innerPadding ) { - val fieldModifier = Modifier.fillMaxWidth() - for (field in template.fields) { OutlinedTextField( value = filledFields[field.id]!!, @@ -89,7 +87,7 @@ fun FillTemplatePage(template: Template, innerPadding: PaddingValues) { this[field.id] = newValue } }, - modifier = fieldModifier, + modifier = Modifier.fillMaxWidth(), label = { Text((if (field.maybeEmpty) "" else "*") + selectTemplateNameViaLanguage(field.names, language)) } ) } diff --git a/mobile/src/main/java/ru/omni_devel/cards/SelectTemplateActivity.kt b/mobile/src/main/java/ru/omni_devel/cards/SelectTemplateActivity.kt index 1db161b..774fa93 100644 --- a/mobile/src/main/java/ru/omni_devel/cards/SelectTemplateActivity.kt +++ b/mobile/src/main/java/ru/omni_devel/cards/SelectTemplateActivity.kt @@ -9,19 +9,15 @@ import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts -import androidx.compose.foundation.background -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.size import androidx.compose.foundation.lazy.LazyColumn -import androidx.compose.foundation.rememberScrollState -import androidx.compose.foundation.verticalScroll -import androidx.compose.material3.Button import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.MaterialTheme +import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.Scaffold import androidx.compose.material3.Text import androidx.compose.runtime.Composable @@ -66,6 +62,8 @@ fun SelectTemplatePage(innerPadding: PaddingValues) { val language = getLanguage(context) + var searchQuery by rememberSaveable { mutableStateOf("") } + var templates by remember { mutableStateOf?>(null) } var loadingError by remember { mutableStateOf(null) } @@ -100,14 +98,25 @@ fun SelectTemplatePage(innerPadding: PaddingValues) { stringResource(R.string.choosing_template), innerPadding ) { + OutlinedTextField( + value = searchQuery, + onValueChange = { newValue -> + searchQuery = newValue + }, + modifier = Modifier.fillMaxWidth(), + label = { Text(stringResource(R.string.search_templates)) } + ) + LazyColumn( horizontalAlignment = Alignment.CenterHorizontally ) { + val currentTemplates = templates + if (loadingError != null) { item { Text(loadingError!!) } - } else if (templates == null) { + } else if (currentTemplates == null) { item { Column( modifier = Modifier.fillMaxWidth(), @@ -119,24 +128,49 @@ fun SelectTemplatePage(innerPadding: PaddingValues) { ) } } - } else if (templates!!.isEmpty()) { - item { - Text(stringResource(R.string.templates_not_found)) - } } else { - for (template in templates) { + val searchResults = currentTemplates.filter { template -> + var queryCleaned = searchQuery.lowercase() + + if (queryCleaned.isEmpty()) { + return@filter true + } + + for (name in template.names.values) { + var nameCleaned = name.lowercase() + + for (spaceSymbol in SPACE_SYMBOLS) { + nameCleaned = nameCleaned.replace(spaceSymbol, "") + queryCleaned = queryCleaned.replace(spaceSymbol, "") + } + + if (nameCleaned.contains(queryCleaned)) { + return@filter true + } + } + + return@filter false + } + + if (searchResults.isEmpty()) { item { - AdaptiveButton( - modifier = Modifier.fillMaxWidth(), - onClick = { - val intent = Intent(context, FillTemplateActivity::class.java) + Text(stringResource(R.string.templates_not_found)) + } + } else { + for (template in searchResults) { + item { + AdaptiveButton( + modifier = Modifier.fillMaxWidth(), + onClick = { + val intent = Intent(context, FillTemplateActivity::class.java) - intent.putExtra("templateJson", Json.encodeToString(template)) + intent.putExtra("templateJson", Json.encodeToString(template)) - fillTemplateLauncher.launch(intent) + fillTemplateLauncher.launch(intent) + } + ) { + Text(selectTemplateNameViaLanguage(template.names, language)) } - ) { - Text(selectTemplateNameViaLanguage(template.names, language)) } } } diff --git a/mobile/src/main/res/values-ru/strings.xml b/mobile/src/main/res/values-ru/strings.xml index c204dbf..0f1043a 100644 --- a/mobile/src/main/res/values-ru/strings.xml +++ b/mobile/src/main/res/values-ru/strings.xml @@ -39,6 +39,7 @@ Выбор шаблона Ошибка в данных. Пожалуйста, заполните все необходимые (*) поля Шаблоны не найдены + Поиск шаблонов Имя карты не должно быть пустым Значение карты не должно быть пустым Имя карты должно быть короче 32 символов diff --git a/mobile/src/main/res/values/strings.xml b/mobile/src/main/res/values/strings.xml index 77254b8..a11b85f 100644 --- a/mobile/src/main/res/values/strings.xml +++ b/mobile/src/main/res/values/strings.xml @@ -44,6 +44,7 @@ Choosing template Error in data. Please, fill all required (*) fields Templates not found + Search templates Card name must not be empty Card value must not be empty Card name must be shorter than 32 characters