package ru.omni_devel.cards import android.app.Activity import android.content.Intent import android.os.Bundle import androidx.activity.ComponentActivity import androidx.activity.compose.LocalActivity import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.setContent import androidx.activity.enableEdgeToEdge import androidx.activity.result.contract.ActivityResultContracts 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.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 import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.res.stringResource import androidx.compose.ui.unit.dp import io.ktor.client.HttpClient import io.ktor.client.engine.cio.CIO import io.ktor.client.request.get import io.ktor.client.statement.HttpResponse import io.ktor.client.statement.bodyAsText import kotlinx.serialization.json.Json import ru.omni_devel.cards.ui.theme.OmniCardsTheme class SelectTemplateActivity : ComponentActivity() { override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) enableEdgeToEdge() setContent { OmniCardsTheme { Scaffold(modifier = Modifier.fillMaxSize()) { innerPadding -> SelectTemplatePage(innerPadding) } } } } } @Composable fun SelectTemplatePage(innerPadding: PaddingValues) { val activityContext = LocalActivity.current val context = LocalContext.current val language = getLanguage(context) var searchQuery by rememberSaveable { mutableStateOf("") } var templates by remember { mutableStateOf?>(null) } var loadingError by remember { mutableStateOf(null) } LaunchedEffect(Unit) { try { val client = HttpClient(CIO) val response: HttpResponse = client.get("$REPO_BASE_URL/$TEMPLATES_REPO_FILE") templates = Template.parseTemplatesFromJson(response.bodyAsText()) } catch (e: Exception) { loadingError = e.toString() } } val fillTemplateLauncher = rememberLauncherForActivityResult( contract = ActivityResultContracts.StartActivityForResult() ) { result -> if (result.resultCode == Activity.RESULT_OK) { val codeValue = result.data?.getStringExtra("codeValue") val resultIntent = Intent() resultIntent.putExtra("codeValue", codeValue) activityContext!!.setResult(Activity.RESULT_OK, resultIntent) activityContext.finish() } } Page( stringResource(R.string.choosing_template), innerPadding ) { OutlinedTextField( value = searchQuery, onValueChange = { newValue -> searchQuery = newValue }, modifier = Modifier.fillMaxWidth(), label = { Text(stringResource(R.string.search)) } ) LazyColumn( horizontalAlignment = Alignment.CenterHorizontally ) { val currentTemplates = templates if (loadingError != null) { item { Text(loadingError!!) } } else if (currentTemplates == null) { item { Column( modifier = Modifier.fillMaxWidth(), horizontalAlignment = Alignment.CenterHorizontally ) { CircularProgressIndicator( modifier = Modifier.size(48.dp), color = MaterialTheme.colorScheme.primary ) } } } else { 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 ((from, to) in SEARCH_REPLACE_SYMBOLS) { nameCleaned = nameCleaned.replace(from, to) queryCleaned = queryCleaned.replace(from, to) } if (nameCleaned.contains(queryCleaned)) { return@filter true } } return@filter false } if (searchResults.isEmpty()) { item { 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)) fillTemplateLauncher.launch(intent) } ) { Text(selectItemNameViaLanguage(template.names, language)) } } } } } } } }