mirror of
https://github.com/ReVanced/revanced-manager.git
synced 2024-11-10 01:01:56 +01:00
fix: automatically focus search views
This commit is contained in:
parent
6bfd9098d6
commit
1f671aba33
4 changed files with 118 additions and 90 deletions
|
@ -0,0 +1,59 @@
|
|||
package app.revanced.manager.ui.component
|
||||
|
||||
import androidx.compose.foundation.layout.ColumnScope
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.IconButton
|
||||
import androidx.compose.material3.SearchBar
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.LaunchedEffect
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.focus.FocusRequester
|
||||
import androidx.compose.ui.focus.focusRequester
|
||||
import androidx.compose.ui.platform.LocalSoftwareKeyboardController
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import app.revanced.manager.R
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun SearchView(
|
||||
query: String,
|
||||
onQueryChange: (String) -> Unit,
|
||||
onActiveChange: (Boolean) -> Unit,
|
||||
placeholder: (@Composable () -> Unit)? = null,
|
||||
content: @Composable ColumnScope.() -> Unit
|
||||
) {
|
||||
val focusRequester = remember { FocusRequester() }
|
||||
val keyboardController = LocalSoftwareKeyboardController.current
|
||||
|
||||
SearchBar(
|
||||
query = query,
|
||||
onQueryChange = onQueryChange,
|
||||
onSearch = {
|
||||
keyboardController?.hide()
|
||||
},
|
||||
active = true,
|
||||
onActiveChange = onActiveChange,
|
||||
modifier = Modifier
|
||||
.fillMaxSize()
|
||||
.focusRequester(focusRequester),
|
||||
placeholder = placeholder,
|
||||
leadingIcon = {
|
||||
IconButton({ onActiveChange(false) }) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
stringResource(R.string.back)
|
||||
)
|
||||
}
|
||||
},
|
||||
content = content
|
||||
)
|
||||
|
||||
LaunchedEffect(Unit) {
|
||||
focusRequester.requestFocus()
|
||||
}
|
||||
}
|
|
@ -6,7 +6,6 @@ import androidx.compose.foundation.clickable
|
|||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.lazy.items
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.filled.Storage
|
||||
import androidx.compose.material.icons.outlined.Search
|
||||
import androidx.compose.material3.*
|
||||
|
@ -30,6 +29,7 @@ import app.revanced.manager.ui.component.AppTopBar
|
|||
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
||||
import app.revanced.manager.ui.component.LoadingIndicator
|
||||
import app.revanced.manager.ui.component.NonSuggestedVersionDialog
|
||||
import app.revanced.manager.ui.component.SearchView
|
||||
import app.revanced.manager.ui.model.SelectedApp
|
||||
import app.revanced.manager.ui.viewmodel.AppSelectorViewModel
|
||||
import app.revanced.manager.util.APK_MIMETYPE
|
||||
|
@ -75,79 +75,66 @@ fun AppSelectorScreen(
|
|||
)
|
||||
}
|
||||
|
||||
// TODO: find something better for this
|
||||
if (search) {
|
||||
SearchBar(
|
||||
SearchView(
|
||||
query = filterText,
|
||||
onQueryChange = { filterText = it },
|
||||
onSearch = { },
|
||||
active = true,
|
||||
onActiveChange = { search = it },
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
placeholder = { Text(stringResource(R.string.search_apps)) },
|
||||
leadingIcon = {
|
||||
IconButton({ search = false }) {
|
||||
placeholder = { Text(stringResource(R.string.search_apps)) }
|
||||
) {
|
||||
if (appList.isNotEmpty() && filterText.isNotEmpty()) {
|
||||
LazyColumnWithScrollbar(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(
|
||||
items = filteredAppList,
|
||||
key = { it.packageName }
|
||||
) { app ->
|
||||
ListItem(
|
||||
modifier = Modifier.clickable { onAppClick(app.packageName) },
|
||||
leadingContent = {
|
||||
AppIcon(
|
||||
app.packageInfo,
|
||||
null,
|
||||
Modifier.size(36.dp)
|
||||
)
|
||||
},
|
||||
headlineContent = { AppLabel(app.packageInfo) },
|
||||
supportingContent = { Text(app.packageName) },
|
||||
trailingContent = app.patches?.let {
|
||||
{
|
||||
Text(
|
||||
pluralStringResource(
|
||||
R.plurals.patch_count,
|
||||
it,
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
stringResource(R.string.back)
|
||||
imageVector = Icons.Outlined.Search,
|
||||
contentDescription = stringResource(R.string.search),
|
||||
modifier = Modifier.size(64.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.type_anything),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
},
|
||||
content = {
|
||||
if (appList.isNotEmpty() && filterText.isNotEmpty()) {
|
||||
LazyColumnWithScrollbar(
|
||||
modifier = Modifier.fillMaxSize()
|
||||
) {
|
||||
items(
|
||||
items = filteredAppList,
|
||||
key = { it.packageName }
|
||||
) { app ->
|
||||
ListItem(
|
||||
modifier = Modifier.clickable { onAppClick(app.packageName) },
|
||||
leadingContent = {
|
||||
AppIcon(
|
||||
app.packageInfo,
|
||||
null,
|
||||
Modifier.size(36.dp)
|
||||
)
|
||||
},
|
||||
headlineContent = { AppLabel(app.packageInfo) },
|
||||
supportingContent = { Text(app.packageName) },
|
||||
trailingContent = app.patches?.let {
|
||||
{
|
||||
Text(
|
||||
pluralStringResource(
|
||||
R.plurals.patch_count,
|
||||
it,
|
||||
it
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
modifier = Modifier.fillMaxSize(),
|
||||
verticalArrangement = Arrangement.Center,
|
||||
horizontalAlignment = Alignment.CenterHorizontally
|
||||
) {
|
||||
Icon(
|
||||
imageVector = Icons.Outlined.Search,
|
||||
contentDescription = stringResource(R.string.search),
|
||||
modifier = Modifier.size(64.dp)
|
||||
)
|
||||
|
||||
Text(
|
||||
text = stringResource(R.string.type_anything),
|
||||
style = MaterialTheme.typography.bodyLarge
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
Scaffold(
|
||||
|
|
|
@ -14,7 +14,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState
|
|||
import androidx.compose.foundation.pager.HorizontalPager
|
||||
import androidx.compose.foundation.pager.rememberPagerState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.automirrored.filled.ArrowBack
|
||||
import androidx.compose.material.icons.automirrored.outlined.HelpOutline
|
||||
import androidx.compose.material.icons.outlined.FilterList
|
||||
import androidx.compose.material.icons.outlined.Restore
|
||||
|
@ -33,7 +32,6 @@ import androidx.compose.material3.MaterialTheme
|
|||
import androidx.compose.material3.ModalBottomSheet
|
||||
import androidx.compose.material3.Scaffold
|
||||
import androidx.compose.material3.ScrollableTabRow
|
||||
import androidx.compose.material3.SearchBar
|
||||
import androidx.compose.material3.Tab
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextButton
|
||||
|
@ -61,6 +59,7 @@ import app.revanced.manager.ui.component.AppTopBar
|
|||
import app.revanced.manager.ui.component.Countdown
|
||||
import app.revanced.manager.ui.component.DangerousActionDialogBase
|
||||
import app.revanced.manager.ui.component.LazyColumnWithScrollbar
|
||||
import app.revanced.manager.ui.component.SearchView
|
||||
import app.revanced.manager.ui.component.patches.OptionItem
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel
|
||||
import app.revanced.manager.ui.viewmodel.PatchesSelectorViewModel.Companion.SHOW_SUPPORTED
|
||||
|
@ -208,28 +207,11 @@ fun PatchesSelectorScreen(
|
|||
}
|
||||
|
||||
search?.let { query ->
|
||||
SearchBar(
|
||||
SearchView(
|
||||
query = query,
|
||||
onQueryChange = { new ->
|
||||
search = new
|
||||
},
|
||||
onSearch = {},
|
||||
active = true,
|
||||
onActiveChange = { new ->
|
||||
if (new) return@SearchBar
|
||||
search = null
|
||||
},
|
||||
placeholder = {
|
||||
Text(stringResource(R.string.search_patches))
|
||||
},
|
||||
leadingIcon = {
|
||||
IconButton(onClick = { search = null }) {
|
||||
Icon(
|
||||
Icons.AutoMirrored.Filled.ArrowBack,
|
||||
stringResource(R.string.back)
|
||||
)
|
||||
}
|
||||
}
|
||||
onQueryChange = { search = it },
|
||||
onActiveChange = { if (!it) search = null },
|
||||
placeholder = { Text(stringResource(R.string.search_patches)) }
|
||||
) {
|
||||
val bundle = bundles[pagerState.currentPage]
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@
|
|||
<string name="select_from_storage_description">Select an APK file from storage using file picker</string>
|
||||
<string name="suggested_version_info">Suggested version: %s</string>
|
||||
<string name="type_anything">Type anything to continue</string>
|
||||
<string name="search">Search</string>
|
||||
<string name="search">Search patches…</string>
|
||||
<string name="apply">Apply</string>
|
||||
<string name="help">Help</string>
|
||||
<string name="back">Back</string>
|
||||
|
|
Loading…
Reference in a new issue