[track-search] Added context menu for copy and open-in-web (#10352)

This commit is contained in:
Caleb Morris 2024-01-07 20:49:51 -07:00 committed by GitHub
parent f60782f11f
commit a8040cb21a
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -7,6 +7,7 @@ import androidx.compose.animation.slideInVertically
import androidx.compose.animation.slideOutVertically import androidx.compose.animation.slideOutVertically
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.border import androidx.compose.foundation.border
import androidx.compose.foundation.combinedClickable
import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
@ -22,7 +23,6 @@ import androidx.compose.foundation.layout.paddingFromBaseline
import androidx.compose.foundation.layout.width import androidx.compose.foundation.layout.width
import androidx.compose.foundation.layout.windowInsetsPadding import androidx.compose.foundation.layout.windowInsetsPadding
import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.items
import androidx.compose.foundation.selection.selectable
import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.foundation.text.BasicTextField import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions import androidx.compose.foundation.text.KeyboardActions
@ -33,6 +33,7 @@ import androidx.compose.material.icons.filled.CheckCircle
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.Button import androidx.compose.material3.Button
import androidx.compose.material3.ButtonDefaults import androidx.compose.material3.ButtonDefaults
import androidx.compose.material3.DropdownMenuItem
import androidx.compose.material3.HorizontalDivider import androidx.compose.material3.HorizontalDivider
import androidx.compose.material3.Icon import androidx.compose.material3.Icon
import androidx.compose.material3.IconButton import androidx.compose.material3.IconButton
@ -40,7 +41,10 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.TopAppBar import androidx.compose.material3.TopAppBar
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -48,7 +52,11 @@ import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalFocusManager import androidx.compose.ui.platform.LocalFocusManager
import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.capitalize import androidx.compose.ui.text.capitalize
import androidx.compose.ui.text.input.ImeAction import androidx.compose.ui.text.input.ImeAction
import androidx.compose.ui.text.input.TextFieldValue import androidx.compose.ui.text.input.TextFieldValue
@ -58,9 +66,11 @@ import androidx.compose.ui.text.toLowerCase
import androidx.compose.ui.tooling.preview.PreviewLightDark import androidx.compose.ui.tooling.preview.PreviewLightDark
import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.tooling.preview.PreviewParameter
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import eu.kanade.presentation.components.DropdownMenu
import eu.kanade.presentation.manga.components.MangaCover import eu.kanade.presentation.manga.components.MangaCover
import eu.kanade.presentation.theme.TachiyomiTheme import eu.kanade.presentation.theme.TachiyomiTheme
import eu.kanade.tachiyomi.data.track.model.TrackSearch import eu.kanade.tachiyomi.data.track.model.TrackSearch
import eu.kanade.tachiyomi.util.system.openInBrowser
import tachiyomi.i18n.MR import tachiyomi.i18n.MR
import tachiyomi.presentation.core.components.ScrollbarLazyColumn import tachiyomi.presentation.core.components.ScrollbarLazyColumn
import tachiyomi.presentation.core.components.material.Scaffold import tachiyomi.presentation.core.components.material.Scaffold
@ -188,13 +198,7 @@ fun TrackerSearch(
key = { it.hashCode() }, key = { it.hashCode() },
) { ) {
SearchResultItem( SearchResultItem(
title = it.title, trackSearch = it,
coverUrl = it.cover_url,
type = it.publishing_type.toLowerCase(Locale.current).capitalize(Locale.current),
startDate = it.start_date,
status = it.publishing_status.toLowerCase(Locale.current).capitalize(Locale.current),
score = it.score,
description = it.summary.trim(),
selected = it == selected, selected = it == selected,
onClick = { onSelectedChange(it) }, onClick = { onSelectedChange(it) },
) )
@ -214,18 +218,18 @@ fun TrackerSearch(
@Composable @Composable
private fun SearchResultItem( private fun SearchResultItem(
title: String, trackSearch: TrackSearch,
coverUrl: String,
type: String,
startDate: String,
status: String,
score: Float,
description: String,
selected: Boolean, selected: Boolean,
onClick: () -> Unit, onClick: () -> Unit,
) { ) {
val context = LocalContext.current
val clipboardManager: ClipboardManager = LocalClipboardManager.current
val type = trackSearch.publishing_type.toLowerCase(Locale.current).capitalize(Locale.current)
val status = trackSearch.publishing_status.toLowerCase(Locale.current).capitalize(Locale.current)
val description = trackSearch.summary.trim()
val shape = RoundedCornerShape(16.dp) val shape = RoundedCornerShape(16.dp)
val borderColor = if (selected) MaterialTheme.colorScheme.outline else Color.Transparent val borderColor = if (selected) MaterialTheme.colorScheme.outline else Color.Transparent
var dropDownMenuExpanded by remember { mutableStateOf(false) }
Box( Box(
modifier = Modifier modifier = Modifier
.fillMaxWidth() .fillMaxWidth()
@ -237,7 +241,10 @@ private fun SearchResultItem(
color = borderColor, color = borderColor,
shape = shape, shape = shape,
) )
.selectable(selected = selected, onClick = onClick) .combinedClickable(
onLongClick = { dropDownMenuExpanded = true },
onClick = onClick,
)
.padding(12.dp), .padding(12.dp),
) { ) {
if (selected) { if (selected) {
@ -251,28 +258,41 @@ private fun SearchResultItem(
Column { Column {
Row { Row {
MangaCover.Book( MangaCover.Book(
data = coverUrl, data = trackSearch.cover_url,
modifier = Modifier.height(96.dp), modifier = Modifier.height(96.dp),
) )
Spacer(modifier = Modifier.width(12.dp)) Spacer(modifier = Modifier.width(12.dp))
Column { Column {
Text( Text(
text = title, text = trackSearch.title,
modifier = Modifier.padding(end = 28.dp), modifier = Modifier.padding(end = 28.dp),
maxLines = 2, maxLines = 2,
overflow = TextOverflow.Ellipsis, overflow = TextOverflow.Ellipsis,
style = MaterialTheme.typography.titleMedium, style = MaterialTheme.typography.titleMedium,
) )
SearchResultItemDropDownMenu(
expanded = dropDownMenuExpanded,
onCollapseMenu = { dropDownMenuExpanded = false },
onCopyName = {
clipboardManager.setText(AnnotatedString(trackSearch.title))
},
onOpenInBrowser = {
val url = trackSearch.tracking_url
if (url.isNotBlank()) {
context.openInBrowser(url)
}
},
)
if (type.isNotBlank()) { if (type.isNotBlank()) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(MR.strings.track_type), title = stringResource(MR.strings.track_type),
text = type, text = type,
) )
} }
if (startDate.isNotBlank()) { if (trackSearch.start_date.isNotBlank()) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(MR.strings.label_started), title = stringResource(MR.strings.label_started),
text = startDate, text = trackSearch.start_date,
) )
} }
if (status.isNotBlank()) { if (status.isNotBlank()) {
@ -281,10 +301,10 @@ private fun SearchResultItem(
text = status, text = status,
) )
} }
if (score != -1f) { if (trackSearch.score != -1f) {
SearchResultItemDetails( SearchResultItemDetails(
title = stringResource(MR.strings.score), title = stringResource(MR.strings.score),
text = score.toString(), text = trackSearch.score.toString(),
) )
} }
} }
@ -304,6 +324,33 @@ private fun SearchResultItem(
} }
} }
@Composable
private fun SearchResultItemDropDownMenu(
expanded: Boolean,
onCollapseMenu: () -> Unit,
onCopyName: () -> Unit,
onOpenInBrowser: () -> Unit,
) {
DropdownMenu(
expanded = expanded,
onDismissRequest = onCollapseMenu,
) {
DropdownMenuItem(
text = { Text(stringResource(MR.strings.action_copy_to_clipboard)) },
onClick = {
onCopyName()
onCollapseMenu()
},
)
DropdownMenuItem(
text = { Text(stringResource(MR.strings.action_open_in_browser)) },
onClick = {
onOpenInBrowser()
},
)
}
}
@Composable @Composable
private fun SearchResultItemDetails( private fun SearchResultItemDetails(
title: String, title: String,