From 4c19c800136388782369c6cff73d5f33cd179417 Mon Sep 17 00:00:00 2001 From: Roshan Varughese <40583749+Animeboynz@users.noreply.github.com> Date: Sat, 27 Jul 2024 08:59:59 +1200 Subject: [PATCH] Adds Option to Copy Panel to Clipboard (mihonapp/mihon#1003) * Add Copy to Clipboard * Removing Unused Import * Reusing onShare function * Commit Suggestion * Early Return on null Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> --------- Co-authored-by: AntsyLich <59261191+AntsyLich@users.noreply.github.com> (cherry picked from commit 0af90999c8eed4b6c56a94418e5558833f273aa9) --- .../reader/ReaderPageActionsDialog.kt | 53 ++++++++++++++++--- .../tachiyomi/ui/reader/ReaderActivity.kt | 12 +++++ .../tachiyomi/ui/reader/ReaderViewModel.kt | 16 ++++-- .../moko-resources/base/strings.xml | 3 ++ 4 files changed, 71 insertions(+), 13 deletions(-) diff --git a/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt b/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt index 538dd01e1..a224add2c 100644 --- a/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt +++ b/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt @@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.padding import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.outlined.ContentCopy import androidx.compose.material.icons.outlined.Photo import androidx.compose.material.icons.outlined.Save import androidx.compose.material.icons.outlined.Share @@ -29,11 +30,11 @@ import tachiyomi.presentation.core.i18n.stringResource @Composable fun ReaderPageActionsDialog( onDismissRequest: () -> Unit, + onSetAsCover: (/* SY --> */useExtraPage: Boolean/* SY <-- */) -> Unit, + onShare: (copyToClipboard: Boolean, /* SY --> */useExtraPage: Boolean/* SY <-- */) -> Unit, + onSave: (/* SY --> */useExtraPage: Boolean/* SY <-- */) -> Unit, // SY --> - onSetAsCover: (useExtraPage: Boolean) -> Unit, - onShare: (useExtraPage: Boolean) -> Unit, - onSave: (useExtraPage: Boolean) -> Unit, - onShareCombined: () -> Unit, + onShareCombined: (copyToClipboard: Boolean) -> Unit, onSaveCombined: () -> Unit, hasExtraPage: Boolean, // SY <-- @@ -62,6 +63,25 @@ fun ReaderPageActionsDialog( icon = Icons.Outlined.Photo, onClick = { showSetCoverDialog = true }, ) + ActionButton( + modifier = Modifier.weight(1f), + title = stringResource( + // SY --> + if (hasExtraPage) { + SYMR.strings.action_copy_to_clipboard_first_page + } else { + MR.strings.action_copy_to_clipboard + }, + // SY <-- + ), + icon = Icons.Outlined.ContentCopy, + onClick = { + // SY --> + onShare(true, false) + // SY <-- + onDismissRequest() + }, + ) ActionButton( modifier = Modifier.weight(1f), title = stringResource( @@ -76,12 +96,11 @@ fun ReaderPageActionsDialog( icon = Icons.Outlined.Share, onClick = { // SY --> - onShare(false) + onShare(false, false) // SY <-- onDismissRequest() }, ) - ActionButton( modifier = Modifier.weight(1f), title = stringResource( @@ -114,12 +133,21 @@ fun ReaderPageActionsDialog( showSetCoverDialog = true }, ) + ActionButton( + modifier = Modifier.weight(1f), + title = stringResource(SYMR.strings.action_copy_to_clipboard_second_page), + icon = Icons.Outlined.ContentCopy, + onClick = { + onShare(true, true) + onDismissRequest() + }, + ) ActionButton( modifier = Modifier.weight(1f), title = stringResource(SYMR.strings.action_share_second_page), icon = Icons.Outlined.Share, onClick = { - onShare(true) + onShare(false, true) onDismissRequest() }, ) @@ -136,12 +164,21 @@ fun ReaderPageActionsDialog( Row( horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small), ) { + ActionButton( + modifier = Modifier.weight(1f), + title = stringResource(SYMR.strings.action_copy_to_clipboard_combined_page), + icon = Icons.Outlined.ContentCopy, + onClick = { + onShareCombined(true) + onDismissRequest() + }, + ) ActionButton( modifier = Modifier.weight(1f), title = stringResource(SYMR.strings.action_share_combined_page), icon = Icons.Outlined.Share, onClick = { - onShareCombined() + onShareCombined(false) onDismissRequest() }, ) diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt index 032233914..c3b95f3dd 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderActivity.kt @@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.ui.reader import android.annotation.SuppressLint import android.app.Activity import android.app.assist.AssistContent +import android.content.ClipData +import android.content.ClipboardManager import android.content.Context import android.content.Intent import android.content.res.Configuration @@ -38,6 +40,7 @@ import androidx.compose.ui.Alignment import androidx.compose.ui.graphics.toArgb import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.unit.dp +import androidx.core.content.getSystemService import androidx.core.graphics.ColorUtils import androidx.core.net.toUri import androidx.core.transition.doOnEnd @@ -285,6 +288,9 @@ class ReaderActivity : BaseActivity() { is ReaderViewModel.Event.ShareImage -> { onShareImageResult(event.uri, event.page /* SY --> */, event.secondPage /* SY <-- */) } + is ReaderViewModel.Event.CopyImage -> { + onCopyImageResult(event.uri) + } is ReaderViewModel.Event.SetCoverResult -> { onSetAsCoverResult(event.result) } @@ -1186,6 +1192,12 @@ class ReaderActivity : BaseActivity() { startActivity(Intent.createChooser(intent, stringResource(MR.strings.action_share))) } + private fun onCopyImageResult(uri: Uri) { + val clipboardManager = applicationContext.getSystemService() ?: return + val clipData = ClipData.newUri(applicationContext.contentResolver, "", uri) + clipboardManager.setPrimaryClip(clipData) + } + /** * Called from the presenter when a page is saved or fails. It shows a message or logs the * event depending on the [result]. diff --git a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt index e799afe58..bc3e21ed5 100644 --- a/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt +++ b/app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt @@ -701,7 +701,7 @@ class ReaderViewModel @JvmOverloads constructor( // SY --> if (readerChapter.chapter.chapter_number > 0 && readerPreferences.markReadDupe().get()) { getChaptersByMangaId.await(manga!!.id).sortedByDescending { it.sourceOrder } - .filter { + .filter { it.id != readerChapter.chapter.id && !it.read && it.chapterNumber.toFloat() == readerChapter.chapter.chapter_number @@ -1156,7 +1156,12 @@ class ReaderViewModel @JvmOverloads constructor( * get a path to the file and it has to be decompressed somewhere first. Only the last shared * image will be kept so it won't be taking lots of internal disk space. */ - fun shareImage(useExtraPage: Boolean) { + fun shareImage( + copyToClipboard: Boolean, + // SY --> + useExtraPage: Boolean, + // SY <-- + ) { // SY --> val page = if (useExtraPage) { (state.value.dialog as? Dialog.PageActions)?.extraPage @@ -1182,7 +1187,7 @@ class ReaderViewModel @JvmOverloads constructor( location = Location.Cache, ), ) - eventChannel.send(Event.ShareImage(uri, page)) + eventChannel.send(if (copyToClipboard) Event.CopyImage(uri) else Event.ShareImage(uri, page)) } } catch (e: Throwable) { logcat(LogPriority.ERROR, e) @@ -1190,7 +1195,7 @@ class ReaderViewModel @JvmOverloads constructor( } // SY --> - fun shareImages() { + fun shareImages(copyToClipboard: Boolean) { val (firstPage, secondPage) = (state.value.dialog as? Dialog.PageActions ?: return) val viewer = state.value.viewer as? PagerViewer ?: return val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages) @@ -1214,7 +1219,7 @@ class ReaderViewModel @JvmOverloads constructor( location = Location.Cache, manga = manga, ) - eventChannel.send(Event.ShareImage(uri, firstPage, secondPage)) + eventChannel.send(if (copyToClipboard) Event.CopyImage(uri) else Event.ShareImage(uri, firstPage, secondPage)) } } catch (e: Throwable) { logcat(LogPriority.ERROR, e) @@ -1382,5 +1387,6 @@ class ReaderViewModel @JvmOverloads constructor( val page: ReaderPage/* SY --> */, val secondPage: ReaderPage? = null, /* SY <-- */ ) : Event + data class CopyImage(val uri: Uri) : Event } } diff --git a/i18n-sy/src/commonMain/moko-resources/base/strings.xml b/i18n-sy/src/commonMain/moko-resources/base/strings.xml index 435149755..fa5d010ff 100644 --- a/i18n-sy/src/commonMain/moko-resources/base/strings.xml +++ b/i18n-sy/src/commonMain/moko-resources/base/strings.xml @@ -346,8 +346,11 @@ Save second page Share first page Share second page + Copy first page to clipboard + Copy second page to clipboard Save combined page Share combined page + Copy combined page to clipboard %1$s: %2$s, pages %3$s