From 0af90999c8eed4b6c56a94418e5558833f273aa9 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 (#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>
---
 .../presentation/reader/ReaderPageActionsDialog.kt | 14 ++++++++++++--
 .../kanade/tachiyomi/ui/reader/ReaderActivity.kt   | 12 ++++++++++++
 .../kanade/tachiyomi/ui/reader/ReaderViewModel.kt  |  5 +++--
 3 files changed, 27 insertions(+), 4 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 b83e8d6ad..9e9afde8d 100644
--- a/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt
+++ b/app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.Arrangement
 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
@@ -28,7 +29,7 @@ import tachiyomi.presentation.core.i18n.stringResource
 fun ReaderPageActionsDialog(
     onDismissRequest: () -> Unit,
     onSetAsCover: () -> Unit,
-    onShare: () -> Unit,
+    onShare: (Boolean) -> Unit,
     onSave: () -> Unit,
 ) {
     var showSetCoverDialog by remember { mutableStateOf(false) }
@@ -44,12 +45,21 @@ fun ReaderPageActionsDialog(
                 icon = Icons.Outlined.Photo,
                 onClick = { showSetCoverDialog = true },
             )
+            ActionButton(
+                modifier = Modifier.weight(1f),
+                title = stringResource(MR.strings.action_copy_to_clipboard),
+                icon = Icons.Outlined.ContentCopy,
+                onClick = {
+                    onShare(true)
+                    onDismissRequest()
+                },
+            )
             ActionButton(
                 modifier = Modifier.weight(1f),
                 title = stringResource(MR.strings.action_share),
                 icon = Icons.Outlined.Share,
                 onClick = {
-                    onShare()
+                    onShare(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 ae471a025..1a177e211 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.graphics.Color
@@ -28,6 +30,7 @@ import androidx.compose.runtime.getValue
 import androidx.compose.runtime.remember
 import androidx.compose.ui.Alignment
 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
@@ -223,6 +226,9 @@ class ReaderActivity : BaseActivity() {
                     is ReaderViewModel.Event.ShareImage -> {
                         onShareImageResult(event.uri, event.page)
                     }
+                    is ReaderViewModel.Event.CopyImage -> {
+                        onCopyImageResult(event.uri)
+                    }
                     is ReaderViewModel.Event.SetCoverResult -> {
                         onSetAsCoverResult(event.result)
                     }
@@ -721,6 +727,12 @@ class ReaderActivity : BaseActivity() {
         startActivity(Intent.createChooser(intent, stringResource(MR.strings.action_share)))
     }
 
+    private fun onCopyImageResult(uri: Uri) {
+        val clipboardManager = applicationContext.getSystemService<ClipboardManager>() ?: 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 432eff749..259b45883 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
@@ -809,7 +809,7 @@ 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() {
+    fun shareImage(copyToClipboard: Boolean) {
         val page = (state.value.dialog as? Dialog.PageActions)?.page
         if (page?.status != Page.State.READY) return
         val manga = manga ?: return
@@ -829,7 +829,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)
@@ -949,5 +949,6 @@ class ReaderViewModel @JvmOverloads constructor(
 
         data class SavedImage(val result: SaveImageResult) : Event
         data class ShareImage(val uri: Uri, val page: ReaderPage) : Event
+        data class CopyImage(val uri: Uri) : Event
     }
 }