From d02b0ca2db744b0eca48dfca86811d653fd3bdaf Mon Sep 17 00:00:00 2001 From: 0x7673 <123292609+0x7673@users.noreply.github.com> Date: Tue, 14 Feb 2023 09:22:10 +0530 Subject: [PATCH] Add copy tags to clipboard feature (#9063) --- .../kanade/presentation/manga/MangaScreen.kt | 37 +++++++++++++++---- .../manga/components/MangaInfoHeader.kt | 36 ++++++++++++++++-- .../kanade/tachiyomi/ui/manga/MangaScreen.kt | 2 +- i18n/src/main/res/values/strings.xml | 1 + 4 files changed, 65 insertions(+), 11 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt index e9bee59c9..ffb33420a 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/MangaScreen.kt @@ -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, ) } }, diff --git a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt index 7bc36cd91..e2a90de36 100644 --- a/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt +++ b/app/src/main/java/eu/kanade/presentation/manga/components/MangaInfoHeader.kt @@ -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?, - 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 + }, ) } } diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt index 2ae74a509..e3380ea5c 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/manga/MangaScreen.kt @@ -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()) }, diff --git a/i18n/src/main/res/values/strings.xml b/i18n/src/main/res/values/strings.xml index ebb9ad96c..c018161d6 100644 --- a/i18n/src/main/res/values/strings.xml +++ b/i18n/src/main/res/values/strings.xml @@ -96,6 +96,7 @@ Resume Open in browser Show entry + Copy to clipboard Open in WebView WebView