Add copy tags to clipboard feature (#9063)
Cette révision appartient à :
Parent
4d607c4aed
révision
d02b0ca2db
4 fichiers modifiés avec 65 ajouts et 11 suppressions
|
@ -72,6 +72,7 @@ import eu.kanade.tachiyomi.ui.manga.ChapterItem
|
|||
import eu.kanade.tachiyomi.ui.manga.MangaScreenState
|
||||
import eu.kanade.tachiyomi.ui.manga.chapterDecimalFormat
|
||||
import eu.kanade.tachiyomi.util.lang.toRelativeString
|
||||
import eu.kanade.tachiyomi.util.system.copyToClipboard
|
||||
import tachiyomi.domain.chapter.model.Chapter
|
||||
import tachiyomi.domain.manga.model.Manga
|
||||
import java.text.DateFormat
|
||||
|
@ -91,7 +92,10 @@ fun MangaScreen(
|
|||
onWebViewClicked: (() -> Unit)?,
|
||||
onWebViewLongClicked: (() -> Unit)?,
|
||||
onTrackingClicked: (() -> Unit)?,
|
||||
onTagClicked: (String) -> Unit,
|
||||
|
||||
// For tags menu
|
||||
onTagSearch: (String) -> Unit,
|
||||
|
||||
onFilterButtonClicked: () -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onContinueReading: () -> Unit,
|
||||
|
@ -117,6 +121,13 @@ fun MangaScreen(
|
|||
onAllChapterSelected: (Boolean) -> Unit,
|
||||
onInvertSelection: () -> Unit,
|
||||
) {
|
||||
val context = LocalContext.current
|
||||
val onCopyTagToClipboard: (tag: String) -> Unit = {
|
||||
if (it.isNotEmpty()) {
|
||||
context.copyToClipboard(it, it)
|
||||
}
|
||||
}
|
||||
|
||||
if (!isTabletUi) {
|
||||
MangaScreenSmallImpl(
|
||||
state = state,
|
||||
|
@ -130,7 +141,8 @@ fun MangaScreen(
|
|||
onWebViewClicked = onWebViewClicked,
|
||||
onWebViewLongClicked = onWebViewLongClicked,
|
||||
onTrackingClicked = onTrackingClicked,
|
||||
onTagClicked = onTagClicked,
|
||||
onTagSearch = onTagSearch,
|
||||
onCopyTagToClipboard = onCopyTagToClipboard,
|
||||
onFilterClicked = onFilterButtonClicked,
|
||||
onRefresh = onRefresh,
|
||||
onContinueReading = onContinueReading,
|
||||
|
@ -161,7 +173,8 @@ fun MangaScreen(
|
|||
onWebViewClicked = onWebViewClicked,
|
||||
onWebViewLongClicked = onWebViewLongClicked,
|
||||
onTrackingClicked = onTrackingClicked,
|
||||
onTagClicked = onTagClicked,
|
||||
onTagSearch = onTagSearch,
|
||||
onCopyTagToClipboard = onCopyTagToClipboard,
|
||||
onFilterButtonClicked = onFilterButtonClicked,
|
||||
onRefresh = onRefresh,
|
||||
onContinueReading = onContinueReading,
|
||||
|
@ -195,7 +208,11 @@ private fun MangaScreenSmallImpl(
|
|||
onWebViewClicked: (() -> Unit)?,
|
||||
onWebViewLongClicked: (() -> Unit)?,
|
||||
onTrackingClicked: (() -> Unit)?,
|
||||
onTagClicked: (String) -> Unit,
|
||||
|
||||
// For tags menu
|
||||
onTagSearch: (String) -> Unit,
|
||||
onCopyTagToClipboard: (tag: String) -> Unit,
|
||||
|
||||
onFilterClicked: () -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onContinueReading: () -> Unit,
|
||||
|
@ -363,7 +380,8 @@ private fun MangaScreenSmallImpl(
|
|||
defaultExpandState = state.isFromSource,
|
||||
description = state.manga.description,
|
||||
tagsProvider = { state.manga.genre },
|
||||
onTagClicked = onTagClicked,
|
||||
onTagSearch = onTagSearch,
|
||||
onCopyTagToClipboard = onCopyTagToClipboard,
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -406,7 +424,11 @@ fun MangaScreenLargeImpl(
|
|||
onWebViewClicked: (() -> Unit)?,
|
||||
onWebViewLongClicked: (() -> Unit)?,
|
||||
onTrackingClicked: (() -> Unit)?,
|
||||
onTagClicked: (String) -> Unit,
|
||||
|
||||
// For tags menu
|
||||
onTagSearch: (String) -> Unit,
|
||||
onCopyTagToClipboard: (tag: String) -> Unit,
|
||||
|
||||
onFilterButtonClicked: () -> Unit,
|
||||
onRefresh: () -> Unit,
|
||||
onContinueReading: () -> Unit,
|
||||
|
@ -555,7 +577,8 @@ fun MangaScreenLargeImpl(
|
|||
defaultExpandState = true,
|
||||
description = state.manga.description,
|
||||
tagsProvider = { state.manga.genre },
|
||||
onTagClicked = onTagClicked,
|
||||
onTagSearch = onTagSearch,
|
||||
onCopyTagToClipboard = onCopyTagToClipboard,
|
||||
)
|
||||
}
|
||||
},
|
||||
|
|
|
@ -35,6 +35,7 @@ import androidx.compose.material.icons.outlined.Pause
|
|||
import androidx.compose.material.icons.outlined.Public
|
||||
import androidx.compose.material.icons.outlined.Schedule
|
||||
import androidx.compose.material.icons.outlined.Sync
|
||||
import androidx.compose.material3.DropdownMenuItem
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.LocalMinimumTouchTargetEnforcement
|
||||
|
@ -72,6 +73,7 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import coil.compose.AsyncImage
|
||||
import com.google.accompanist.flowlayout.FlowRow
|
||||
import eu.kanade.presentation.components.DropdownMenu
|
||||
import eu.kanade.presentation.components.MangaCover
|
||||
import eu.kanade.presentation.components.TextButton
|
||||
import eu.kanade.presentation.util.clickableNoIndication
|
||||
|
@ -210,7 +212,8 @@ fun ExpandableMangaDescription(
|
|||
defaultExpandState: Boolean,
|
||||
description: String?,
|
||||
tagsProvider: () -> List<String>?,
|
||||
onTagClicked: (String) -> Unit,
|
||||
onTagSearch: (String) -> Unit,
|
||||
onCopyTagToClipboard: (tag: String) -> Unit,
|
||||
) {
|
||||
Column(modifier = modifier) {
|
||||
val (expanded, onExpanded) = rememberSaveable {
|
||||
|
@ -240,6 +243,27 @@ fun ExpandableMangaDescription(
|
|||
.padding(vertical = 12.dp)
|
||||
.animateContentSize(),
|
||||
) {
|
||||
var showMenu by remember { mutableStateOf(false) }
|
||||
var tagSelected by remember { mutableStateOf("") }
|
||||
DropdownMenu(
|
||||
expanded = showMenu,
|
||||
onDismissRequest = { showMenu = false },
|
||||
) {
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = stringResource(R.string.action_search)) },
|
||||
onClick = {
|
||||
onTagSearch(tagSelected)
|
||||
showMenu = false
|
||||
},
|
||||
)
|
||||
DropdownMenuItem(
|
||||
text = { Text(text = stringResource(R.string.action_copy_to_clipboard)) },
|
||||
onClick = {
|
||||
onCopyTagToClipboard(tagSelected)
|
||||
showMenu = false
|
||||
},
|
||||
)
|
||||
}
|
||||
if (expanded) {
|
||||
FlowRow(
|
||||
modifier = Modifier.padding(horizontal = 16.dp),
|
||||
|
@ -249,7 +273,10 @@ fun ExpandableMangaDescription(
|
|||
tags.forEach {
|
||||
TagsChip(
|
||||
text = it,
|
||||
onClick = { onTagClicked(it) },
|
||||
onClick = {
|
||||
tagSelected = it
|
||||
showMenu = true
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -261,7 +288,10 @@ fun ExpandableMangaDescription(
|
|||
items(items = tags) {
|
||||
TagsChip(
|
||||
text = it,
|
||||
onClick = { onTagClicked(it) },
|
||||
onClick = {
|
||||
tagSelected = it
|
||||
showMenu = true
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,7 @@ class MangaScreen(
|
|||
onWebViewClicked = { openMangaInWebView(navigator, screenModel.manga, screenModel.source) }.takeIf { isHttpSource },
|
||||
onWebViewLongClicked = { copyMangaUrl(context, screenModel.manga, screenModel.source) }.takeIf { isHttpSource },
|
||||
onTrackingClicked = screenModel::showTrackDialog.takeIf { successState.trackingAvailable },
|
||||
onTagClicked = { scope.launch { performGenreSearch(navigator, it, screenModel.source!!) } },
|
||||
onTagSearch = { scope.launch { performGenreSearch(navigator, it, screenModel.source!!) } },
|
||||
onFilterButtonClicked = screenModel::showSettingsDialog,
|
||||
onRefresh = screenModel::fetchAllFromSource,
|
||||
onContinueReading = { continueReading(context, screenModel.getNextUnreadChapter()) },
|
||||
|
|
|
@ -96,6 +96,7 @@
|
|||
<string name="action_resume">Resume</string>
|
||||
<string name="action_open_in_browser">Open in browser</string>
|
||||
<string name="action_show_manga">Show entry</string>
|
||||
<string name="action_copy_to_clipboard">Copy to clipboard</string>
|
||||
<!-- Do not translate "WebView" -->
|
||||
<string name="action_open_in_web_view">Open in WebView</string>
|
||||
<string name="action_web_view" translatable="false">WebView</string>
|
||||
|
|
Référencer dans un nouveau ticket