Tweak categories view

- Remove Compose top app bar behaviour since it's kind of jank -- we'll probably just remove the scrolling behaviour everywhere
- Tap title to rename
- Focus in textfield when opening dialogs
This commit is contained in:
arkon 2022-07-16 17:28:12 -04:00
parent 46ac9fe970
commit 0b78028cf6
8 changed files with 48 additions and 27 deletions

View File

@ -3,13 +3,9 @@ package eu.kanade.presentation.category
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
import androidx.compose.foundation.layout.statusBarsPadding import androidx.compose.foundation.layout.statusBarsPadding
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.material3.TopAppBarDefaults
import androidx.compose.material3.rememberTopAppBarScrollState
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.getValue
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.input.nestedscroll.nestedScroll
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import eu.kanade.presentation.category.components.CategoryContent import eu.kanade.presentation.category.components.CategoryContent
import eu.kanade.presentation.category.components.CategoryCreateDialog import eu.kanade.presentation.category.components.CategoryCreateDialog
@ -35,15 +31,10 @@ fun CategoryScreen(
navigateUp: () -> Unit, navigateUp: () -> Unit,
) { ) {
val lazyListState = rememberLazyListState() val lazyListState = rememberLazyListState()
val topAppBarScrollState = rememberTopAppBarScrollState()
val topAppBarScrollBehavior = TopAppBarDefaults.enterAlwaysScrollBehavior(topAppBarScrollState)
Scaffold( Scaffold(
modifier = Modifier modifier = Modifier.statusBarsPadding(),
.statusBarsPadding()
.nestedScroll(topAppBarScrollBehavior.nestedScrollConnection),
topBar = { topBar = {
CategoryTopAppBar( CategoryTopAppBar(
topAppBarScrollBehavior = topAppBarScrollBehavior,
navigateUp = navigateUp, navigateUp = navigateUp,
) )
}, },

View File

@ -4,12 +4,17 @@ import androidx.compose.material3.AlertDialog
import androidx.compose.material3.OutlinedTextField import androidx.compose.material3.OutlinedTextField
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.LaunchedEffect
import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember 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.res.stringResource import androidx.compose.ui.res.stringResource
import eu.kanade.domain.category.model.Category import eu.kanade.domain.category.model.Category
import eu.kanade.presentation.components.TextButton import eu.kanade.presentation.components.TextButton
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
import kotlinx.coroutines.delay
@Composable @Composable
fun CategoryCreateDialog( fun CategoryCreateDialog(
@ -17,6 +22,8 @@ fun CategoryCreateDialog(
onCreate: (String) -> Unit, onCreate: (String) -> Unit,
) { ) {
val (name, onNameChange) = remember { mutableStateOf("") } val (name, onNameChange) = remember { mutableStateOf("") }
val focusRequester = remember { FocusRequester() }
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
confirmButton = { confirmButton = {
@ -24,27 +31,35 @@ fun CategoryCreateDialog(
onCreate(name) onCreate(name)
onDismissRequest() onDismissRequest()
},) { },) {
Text(text = stringResource(id = R.string.action_add)) Text(text = stringResource(R.string.action_add))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = R.string.action_cancel)) Text(text = stringResource(R.string.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(id = R.string.action_add_category)) Text(text = stringResource(R.string.action_add_category))
}, },
text = { text = {
OutlinedTextField( OutlinedTextField(
modifier = Modifier
.focusRequester(focusRequester),
value = name, value = name,
onValueChange = onNameChange, onValueChange = onNameChange,
label = { label = {
Text(text = stringResource(id = R.string.name)) Text(text = stringResource(R.string.name))
}, },
) )
}, },
) )
LaunchedEffect(focusRequester) {
// TODO: https://issuetracker.google.com/issues/204502668
delay(100)
focusRequester.requestFocus()
}
} }
@Composable @Composable
@ -54,6 +69,8 @@ fun CategoryRenameDialog(
category: Category, category: Category,
) { ) {
val (name, onNameChange) = remember { mutableStateOf(category.name) } val (name, onNameChange) = remember { mutableStateOf(category.name) }
val focusRequester = remember { FocusRequester.Default }
AlertDialog( AlertDialog(
onDismissRequest = onDismissRequest, onDismissRequest = onDismissRequest,
confirmButton = { confirmButton = {
@ -61,27 +78,35 @@ fun CategoryRenameDialog(
onRename(name) onRename(name)
onDismissRequest() onDismissRequest()
},) { },) {
Text(text = stringResource(id = android.R.string.ok)) Text(text = stringResource(android.R.string.ok))
} }
}, },
dismissButton = { dismissButton = {
TextButton(onClick = onDismissRequest) { TextButton(onClick = onDismissRequest) {
Text(text = stringResource(id = R.string.action_cancel)) Text(text = stringResource(R.string.action_cancel))
} }
}, },
title = { title = {
Text(text = stringResource(id = R.string.action_rename_category)) Text(text = stringResource(R.string.action_rename_category))
}, },
text = { text = {
OutlinedTextField( OutlinedTextField(
modifier = Modifier
.focusRequester(focusRequester),
value = name, value = name,
onValueChange = onNameChange, onValueChange = onNameChange,
label = { label = {
Text(text = stringResource(id = R.string.name)) Text(text = stringResource(R.string.name))
}, },
) )
}, },
) )
LaunchedEffect(focusRequester) {
// TODO: https://issuetracker.google.com/issues/204502668
delay(100)
focusRequester.requestFocus()
}
} }
@Composable @Composable

View File

@ -20,7 +20,7 @@ fun CategoryFloatingActionButton(
onCreate: () -> Unit, onCreate: () -> Unit,
) { ) {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
text = { Text(text = stringResource(id = R.string.action_add)) }, text = { Text(text = stringResource(R.string.action_add)) },
icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = "") }, icon = { Icon(imageVector = Icons.Outlined.Add, contentDescription = "") },
onClick = onCreate, onClick = onCreate,
modifier = Modifier modifier = Modifier

View File

@ -1,7 +1,9 @@
package eu.kanade.presentation.category.components package eu.kanade.presentation.category.components
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.ArrowDropDown import androidx.compose.material.icons.outlined.ArrowDropDown
@ -35,11 +37,17 @@ fun CategoryListItem(
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth()
.clickable { onRename() }
.padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding), .padding(start = horizontalPadding, top = horizontalPadding, end = horizontalPadding),
verticalAlignment = Alignment.CenterVertically, verticalAlignment = Alignment.CenterVertically,
) { ) {
Icon(imageVector = Icons.Outlined.Label, contentDescription = "") Icon(imageVector = Icons.Outlined.Label, contentDescription = "")
Text(text = category.name, modifier = Modifier.padding(start = horizontalPadding)) Text(
text = category.name,
modifier = Modifier
.padding(start = horizontalPadding),
)
} }
Row { Row {
IconButton( IconButton(

View File

@ -6,14 +6,12 @@ import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
import androidx.compose.material3.SmallTopAppBar import androidx.compose.material3.SmallTopAppBar
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBarScrollBehavior
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import eu.kanade.tachiyomi.R import eu.kanade.tachiyomi.R
@Composable @Composable
fun CategoryTopAppBar( fun CategoryTopAppBar(
topAppBarScrollBehavior: TopAppBarScrollBehavior,
navigateUp: () -> Unit, navigateUp: () -> Unit,
) { ) {
SmallTopAppBar( SmallTopAppBar(
@ -26,8 +24,7 @@ fun CategoryTopAppBar(
} }
}, },
title = { title = {
Text(text = stringResource(id = R.string.action_edit_categories)) Text(text = stringResource(R.string.action_edit_categories))
}, },
scrollBehavior = topAppBarScrollBehavior,
) )
} }

View File

@ -57,7 +57,7 @@ fun LibraryGridCover(
) { ) {
if (isLocal) { if (isLocal) {
Badge( Badge(
text = stringResource(id = R.string.local_source_badge), text = stringResource(R.string.local_source_badge),
color = MaterialTheme.colorScheme.tertiary, color = MaterialTheme.colorScheme.tertiary,
textColor = MaterialTheme.colorScheme.onTertiary, textColor = MaterialTheme.colorScheme.onTertiary,
) )

View File

@ -103,7 +103,7 @@ fun LibraryListItem(
} }
if (item.isLocal) { if (item.isLocal) {
Badge( Badge(
text = stringResource(id = R.string.local_source_badge), text = stringResource(R.string.local_source_badge),
color = MaterialTheme.colorScheme.tertiary, color = MaterialTheme.colorScheme.tertiary,
textColor = MaterialTheme.colorScheme.onTertiary, textColor = MaterialTheme.colorScheme.onTertiary,
) )

View File

@ -215,7 +215,7 @@ fun ExpandableMangaDescription(
mutableStateOf(defaultExpandState) mutableStateOf(defaultExpandState)
} }
val desc = val desc =
description.takeIf { !it.isNullOrBlank() } ?: stringResource(id = R.string.description_placeholder) description.takeIf { !it.isNullOrBlank() } ?: stringResource(R.string.description_placeholder)
val trimmedDescription = remember(desc) { val trimmedDescription = remember(desc) {
desc desc
.replace(whitespaceLineRegex, "\n") .replace(whitespaceLineRegex, "\n")