Workaround edit favorites create tag popup not focusable bug

This commit is contained in:
MM20 2023-04-16 20:58:55 +02:00
parent 75226fe1b1
commit 847fe08acd
No known key found for this signature in database
GPG Key ID: 0B61A8F2DEAFA389
3 changed files with 34 additions and 71 deletions

View File

@ -8,15 +8,12 @@ import androidx.activity.result.IntentSenderRequest
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.PaddingValues import androidx.compose.foundation.layout.PaddingValues
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.aspectRatio import androidx.compose.foundation.layout.aspectRatio
import androidx.compose.foundation.layout.calculateEndPadding
import androidx.compose.foundation.layout.calculateStartPadding
import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.height
import androidx.compose.foundation.layout.offset import androidx.compose.foundation.layout.offset
@ -29,13 +26,8 @@ import androidx.compose.foundation.lazy.grid.GridItemSpan
import androidx.compose.foundation.lazy.grid.rememberLazyGridState import androidx.compose.foundation.lazy.grid.rememberLazyGridState
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.lazy.rememberLazyListState
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.rounded.Add import androidx.compose.material.icons.rounded.Add
import androidx.compose.material.icons.rounded.ArrowForward
import androidx.compose.material.icons.rounded.Close
import androidx.compose.material.icons.rounded.Create
import androidx.compose.material.icons.rounded.Delete import androidx.compose.material.icons.rounded.Delete
import androidx.compose.material.icons.rounded.Settings import androidx.compose.material.icons.rounded.Settings
import androidx.compose.material.icons.rounded.Tag import androidx.compose.material.icons.rounded.Tag
@ -45,13 +37,9 @@ import androidx.compose.material3.DropdownMenu
import androidx.compose.material3.DropdownMenuItem import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.FilledTonalIconButton import androidx.compose.material3.FilledTonalIconButton
import androidx.compose.material3.FilledTonalIconToggleButton import androidx.compose.material3.FilledTonalIconToggleButton
import androidx.compose.material3.FilterChip
import androidx.compose.material3.FilterChipDefaults import androidx.compose.material3.FilterChipDefaults
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.LocalContentColor
import androidx.compose.material3.LocalTextStyle
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.MenuDefaults
import androidx.compose.material3.OutlinedButton import androidx.compose.material3.OutlinedButton
import androidx.compose.material3.OutlinedCard import androidx.compose.material3.OutlinedCard
import androidx.compose.material3.Slider import androidx.compose.material3.Slider
@ -72,12 +60,10 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.drawBehind import androidx.compose.ui.draw.drawBehind
import androidx.compose.ui.geometry.Rect import androidx.compose.ui.geometry.Rect
import androidx.compose.ui.graphics.PathEffect import androidx.compose.ui.graphics.PathEffect
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.graphics.drawOutline import androidx.compose.ui.graphics.drawOutline
import androidx.compose.ui.graphics.drawscope.Stroke import androidx.compose.ui.graphics.drawscope.Stroke
import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.input.pointer.pointerInput
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalLayoutDirection
import androidx.compose.ui.platform.LocalLifecycleOwner import androidx.compose.ui.platform.LocalLifecycleOwner
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.text.style.TextAlign
@ -90,6 +76,7 @@ import androidx.lifecycle.viewmodel.compose.viewModel
import de.mm20.launcher2.badges.Badge import de.mm20.launcher2.badges.Badge
import de.mm20.launcher2.icons.LauncherIcon import de.mm20.launcher2.icons.LauncherIcon
import de.mm20.launcher2.search.SavableSearchable import de.mm20.launcher2.search.SavableSearchable
import de.mm20.launcher2.search.data.Tag
import de.mm20.launcher2.ui.R import de.mm20.launcher2.ui.R
import de.mm20.launcher2.ui.common.TagChip import de.mm20.launcher2.ui.common.TagChip
import de.mm20.launcher2.ui.component.BottomSheetDialog import de.mm20.launcher2.ui.component.BottomSheetDialog
@ -102,6 +89,7 @@ import de.mm20.launcher2.ui.component.dragndrop.rememberLazyDragAndDropGridState
import de.mm20.launcher2.ui.component.dragndrop.rememberLazyDragAndDropListState import de.mm20.launcher2.ui.component.dragndrop.rememberLazyDragAndDropListState
import de.mm20.launcher2.ui.ktx.toPixels import de.mm20.launcher2.ui.ktx.toPixels
import de.mm20.launcher2.ui.locals.LocalGridSettings import de.mm20.launcher2.ui.locals.LocalGridSettings
import de.mm20.launcher2.ui.settings.tags.EditTagSheet
import kotlin.math.roundToInt import kotlin.math.roundToInt
@Composable @Composable
@ -172,8 +160,8 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: Padding
val items by viewModel.gridItems.observeAsState(emptyList()) val items by viewModel.gridItems.observeAsState(emptyList())
val columns = LocalGridSettings.current.columnCount val columns = LocalGridSettings.current.columnCount
val availableTags by viewModel.availableTags.observeAsState(emptyList()) val availableTags by viewModel.availableTags
val pinnedTags by viewModel.pinnedTags.observeAsState(emptyList()) val pinnedTags by viewModel.pinnedTags
var contextMenuItemKey by remember { mutableStateOf<String?>(null) } var contextMenuItemKey by remember { mutableStateOf<String?>(null) }
@ -182,6 +170,8 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: Padding
var draggedItemKey by remember { mutableStateOf<String?>(null) } var draggedItemKey by remember { mutableStateOf<String?>(null) }
var hoveredTag by remember { mutableStateOf<String?>(null) } var hoveredTag by remember { mutableStateOf<String?>(null) }
var createTag by remember { mutableStateOf(false) }
val gridState = rememberLazyGridState() val gridState = rememberLazyGridState()
val tagsListState = rememberLazyListState() val tagsListState = rememberLazyListState()
val tagsTitleSize = 48.dp.toPixels() val tagsTitleSize = 48.dp.toPixels()
@ -526,60 +516,19 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: Padding
if (availableTags.isNotEmpty()) { if (availableTags.isNotEmpty()) {
Divider() Divider()
} }
var newTag by remember { mutableStateOf("") }
DropdownMenuItem( DropdownMenuItem(
leadingIcon = { leadingIcon = {
Icon(Icons.Rounded.Create, null) Icon(Icons.Rounded.Add, null)
}, },
contentPadding = PaddingValues(
start = MenuDefaults.DropdownMenuItemContentPadding.calculateStartPadding(
LocalLayoutDirection.current
),
end = MenuDefaults.DropdownMenuItemContentPadding.calculateEndPadding(
LocalLayoutDirection.current
),
top = if (availableTags.isNotEmpty()) 8.dp else 0.dp,
),
text = { text = {
Box { Text(
if (newTag.isEmpty()) { stringResource(R.string.edit_favorites_dialog_new_tag),
Text(
stringResource(R.string.edit_favorites_dialog_new_tag),
color = LocalContentColor.current.copy(alpha = 0.5f)
)
}
BasicTextField(
value = newTag,
onValueChange = {
newTag = it.replace(",", "")
},
textStyle = LocalTextStyle.current.copy(
color = LocalContentColor.current
),
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
singleLine = true,
keyboardActions = KeyboardActions(
onDone = {
if (newTag.isBlank()) return@KeyboardActions
viewModel.createNewTag(newTag)
showAddMenu = false
}
)
)
}
},
trailingIcon = {
Icon(
modifier = Modifier.clickable {
if (newTag.isBlank()) return@clickable
viewModel.createNewTag(newTag)
showAddMenu = false
},
imageVector = Icons.Rounded.ArrowForward,
contentDescription = null
) )
}, },
onClick = { } onClick = {
createTag = true
showAddMenu = false
}
) )
} }
} }
@ -636,6 +585,17 @@ fun ReorderFavoritesGrid(viewModel: EditFavoritesSheetVM, paddingValues: Padding
} }
} }
} }
if (createTag) {
EditTagSheet(
tag = null,
onTagSaved = { tag ->
viewModel.pinTag(Tag(tag))
},
onDismiss = {
createTag = false
}
)
}
} }
@Composable @Composable

View File

@ -5,6 +5,7 @@ import android.content.Intent
import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatActivity
import androidx.compose.foundation.lazy.LazyListItemInfo import androidx.compose.foundation.lazy.LazyListItemInfo
import androidx.compose.foundation.lazy.grid.LazyGridItemInfo import androidx.compose.foundation.lazy.grid.LazyGridItemInfo
import androidx.compose.runtime.mutableStateOf
import androidx.lifecycle.MutableLiveData import androidx.lifecycle.MutableLiveData
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.asLiveData import androidx.lifecycle.asLiveData
@ -52,8 +53,8 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
private var automaticallySorted: MutableList<SavableSearchable> = mutableListOf() private var automaticallySorted: MutableList<SavableSearchable> = mutableListOf()
private var frequentlyUsed: MutableList<SavableSearchable> = mutableListOf() private var frequentlyUsed: MutableList<SavableSearchable> = mutableListOf()
val pinnedTags = MutableLiveData<List<Tag>>(emptyList()) val pinnedTags = mutableStateOf<List<Tag>>(emptyList())
val availableTags = MutableLiveData<List<Tag>>(emptyList()) val availableTags = mutableStateOf<List<Tag>>(emptyList())
suspend fun reload(showLoadingIndicator: Boolean = true) { suspend fun reload(showLoadingIndicator: Boolean = true) {
loading.value = showLoadingIndicator loading.value = showLoadingIndicator
@ -275,24 +276,24 @@ class EditFavoritesSheetVM : ViewModel(), KoinComponent {
} }
fun pinTag(tag: Tag) { fun pinTag(tag: Tag) {
val pinned = pinnedTags.value?.toMutableList() ?: mutableListOf() val pinned = pinnedTags.value.toMutableList()
pinned.add(tag) pinned.add(tag)
val available = availableTags.value ?: emptyList() val available = availableTags.value
availableTags.value = available.filter { it.tag != tag.tag } availableTags.value = available.filter { it.tag != tag.tag }
pinnedTags.value = pinned.distinctBy { it.tag } pinnedTags.value = pinned.distinctBy { it.tag }
save() save()
} }
fun unpinTag(tag: Tag) { fun unpinTag(tag: Tag) {
val pinned = pinnedTags.value?.toMutableList() ?: mutableListOf() val pinned = pinnedTags.value.toMutableList()
val available = availableTags.value ?: emptyList() val available = availableTags.value
availableTags.value = (available + tag).sorted() availableTags.value = (available + tag).sorted()
pinnedTags.value = pinned.filter { it.tag != tag.tag } pinnedTags.value = pinned.filter { it.tag != tag.tag }
save() save()
} }
fun moveTag(from: LazyListItemInfo, to: LazyListItemInfo) { fun moveTag(from: LazyListItemInfo, to: LazyListItemInfo) {
val pinned = pinnedTags.value?.toMutableList() ?: return val pinned = pinnedTags.value.toMutableList()
val tag = pinned.removeAt(from.index) val tag = pinned.removeAt(from.index)
pinned.add(to.index, tag) pinned.add(to.index, tag)
pinnedTags.value = pinned pinnedTags.value = pinned

View File

@ -55,6 +55,7 @@ import de.mm20.launcher2.ui.locals.LocalGridSettings
fun EditTagSheet( fun EditTagSheet(
tag: String?, tag: String?,
onDismiss: () -> Unit, onDismiss: () -> Unit,
onTagSaved: (String) -> Unit = {},
) { ) {
val viewModel: EditTagSheetVM = viewModel() val viewModel: EditTagSheetVM = viewModel()
@ -79,6 +80,7 @@ fun EditTagSheet(
if (viewModel.page == EditTagSheetPage.CustomizeTag) { if (viewModel.page == EditTagSheetPage.CustomizeTag) {
OutlinedButton(onClick = { OutlinedButton(onClick = {
viewModel.save() viewModel.save()
onTagSaved(viewModel.tagName)
onDismiss() onDismiss()
}) { }) {
Text(stringResource(R.string.close)) Text(stringResource(R.string.close))