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>
(cherry picked from commit 0af90999c8eed4b6c56a94418e5558833f273aa9)

# Conflicts:
#	app/src/main/java/eu/kanade/presentation/reader/ReaderPageActionsDialog.kt
#	app/src/main/java/eu/kanade/tachiyomi/ui/reader/ReaderViewModel.kt
This commit is contained in:
Roshan Varughese 2024-07-27 08:59:59 +12:00 committed by Jobobby04
parent 04580ce357
commit a0786d9b09
4 changed files with 63 additions and 9 deletions

View File

@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material.icons.Icons 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.Photo
import androidx.compose.material.icons.outlined.Save import androidx.compose.material.icons.outlined.Save
import androidx.compose.material.icons.outlined.Share import androidx.compose.material.icons.outlined.Share
@ -31,9 +32,9 @@ fun ReaderPageActionsDialog(
onDismissRequest: () -> Unit, onDismissRequest: () -> Unit,
// SY --> // SY -->
onSetAsCover: (useExtraPage: Boolean) -> Unit, onSetAsCover: (useExtraPage: Boolean) -> Unit,
onShare: (useExtraPage: Boolean) -> Unit, onShare: (copy: Boolean, useExtraPage: Boolean) -> Unit,
onSave: (useExtraPage: Boolean) -> Unit, onSave: (useExtraPage: Boolean) -> Unit,
onShareCombined: () -> Unit, onShareCombined: (copy: Boolean) -> Unit,
onSaveCombined: () -> Unit, onSaveCombined: () -> Unit,
hasExtraPage: Boolean, hasExtraPage: Boolean,
// SY <-- // SY <--
@ -62,6 +63,25 @@ fun ReaderPageActionsDialog(
icon = Icons.Outlined.Photo, icon = Icons.Outlined.Photo,
onClick = { showSetCoverDialog = true }, onClick = { showSetCoverDialog = true },
) )
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(
// SY -->
if (hasExtraPage) {
SYMR.strings.action_copy_first_page
} else {
MR.strings.action_copy_to_clipboard
},
// SY <--
),
icon = Icons.Outlined.ContentCopy,
onClick = {
// SY -->
onShare(true, false)
// SY <--
onDismissRequest()
},
)
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource( title = stringResource(
@ -76,7 +96,7 @@ fun ReaderPageActionsDialog(
icon = Icons.Outlined.Share, icon = Icons.Outlined.Share,
onClick = { onClick = {
// SY --> // SY -->
onShare(false) onShare(false, false)
// SY <-- // SY <--
onDismissRequest() onDismissRequest()
}, },
@ -114,12 +134,21 @@ fun ReaderPageActionsDialog(
showSetCoverDialog = true showSetCoverDialog = true
}, },
) )
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_copy_second_page),
icon = Icons.Outlined.ContentCopy,
onClick = {
onShare(true, true)
onDismissRequest()
},
)
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_share_second_page), title = stringResource(SYMR.strings.action_share_second_page),
icon = Icons.Outlined.Share, icon = Icons.Outlined.Share,
onClick = { onClick = {
onShare(true) onShare(false, true)
onDismissRequest() onDismissRequest()
}, },
) )
@ -136,12 +165,21 @@ fun ReaderPageActionsDialog(
Row( Row(
horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small), horizontalArrangement = Arrangement.spacedBy(MaterialTheme.padding.small),
) { ) {
ActionButton(
modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_copy_combined_page),
icon = Icons.Outlined.ContentCopy,
onClick = {
onShareCombined(true)
onDismissRequest()
},
)
ActionButton( ActionButton(
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
title = stringResource(SYMR.strings.action_share_combined_page), title = stringResource(SYMR.strings.action_share_combined_page),
icon = Icons.Outlined.Share, icon = Icons.Outlined.Share,
onClick = { onClick = {
onShareCombined() onShareCombined(false)
onDismissRequest() onDismissRequest()
}, },
) )

View File

@ -3,6 +3,8 @@ package eu.kanade.tachiyomi.ui.reader
import android.annotation.SuppressLint import android.annotation.SuppressLint
import android.app.Activity import android.app.Activity
import android.app.assist.AssistContent import android.app.assist.AssistContent
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context import android.content.Context
import android.content.Intent import android.content.Intent
import android.content.res.Configuration import android.content.res.Configuration
@ -35,6 +37,7 @@ import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.platform.LocalConfiguration import androidx.compose.ui.platform.LocalConfiguration
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.core.content.getSystemService
import androidx.core.graphics.ColorUtils import androidx.core.graphics.ColorUtils
import androidx.core.net.toUri import androidx.core.net.toUri
import androidx.core.transition.doOnEnd import androidx.core.transition.doOnEnd
@ -269,6 +272,9 @@ class ReaderActivity : BaseActivity() {
is ReaderViewModel.Event.ShareImage -> { is ReaderViewModel.Event.ShareImage -> {
onShareImageResult(event.uri, event.page /* SY --> */, event.secondPage /* SY <-- */) onShareImageResult(event.uri, event.page /* SY --> */, event.secondPage /* SY <-- */)
} }
is ReaderViewModel.Event.CopyImage -> {
onCopyImageResult(event.uri)
}
is ReaderViewModel.Event.SetCoverResult -> { is ReaderViewModel.Event.SetCoverResult -> {
onSetAsCoverResult(event.result) onSetAsCoverResult(event.result)
} }
@ -1100,6 +1106,12 @@ class ReaderActivity : BaseActivity() {
startActivity(Intent.createChooser(intent, stringResource(MR.strings.action_share))) 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 * Called from the presenter when a page is saved or fails. It shows a message or logs the
* event depending on the [result]. * event depending on the [result].

View File

@ -1156,7 +1156,7 @@ class ReaderViewModel @JvmOverloads constructor(
* get a path to the file and it has to be decompressed somewhere first. Only the last shared * 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. * image will be kept so it won't be taking lots of internal disk space.
*/ */
fun shareImage(useExtraPage: Boolean) { fun shareImage(copyToClipboard: Boolean, useExtraPage: Boolean) {
// SY --> // SY -->
val page = if (useExtraPage) { val page = if (useExtraPage) {
(state.value.dialog as? Dialog.PageActions)?.extraPage (state.value.dialog as? Dialog.PageActions)?.extraPage
@ -1182,7 +1182,7 @@ class ReaderViewModel @JvmOverloads constructor(
location = Location.Cache, location = Location.Cache,
), ),
) )
eventChannel.send(Event.ShareImage(uri, page)) eventChannel.send(if (copyToClipboard) Event.CopyImage(uri) else Event.ShareImage(uri, page))
} }
} catch (e: Throwable) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) logcat(LogPriority.ERROR, e)
@ -1190,7 +1190,7 @@ class ReaderViewModel @JvmOverloads constructor(
} }
// SY --> // SY -->
fun shareImages() { fun shareImages(copyToClipboard: Boolean) {
val (firstPage, secondPage) = (state.value.dialog as? Dialog.PageActions ?: return) val (firstPage, secondPage) = (state.value.dialog as? Dialog.PageActions ?: return)
val viewer = state.value.viewer as? PagerViewer ?: return val viewer = state.value.viewer as? PagerViewer ?: return
val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages) val isLTR = (viewer !is R2LPagerViewer) xor (viewer.config.invertDoublePages)
@ -1214,7 +1214,7 @@ class ReaderViewModel @JvmOverloads constructor(
location = Location.Cache, location = Location.Cache,
manga = manga, 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) { } catch (e: Throwable) {
logcat(LogPriority.ERROR, e) logcat(LogPriority.ERROR, e)
@ -1382,5 +1382,6 @@ class ReaderViewModel @JvmOverloads constructor(
val page: ReaderPage/* SY --> */, val page: ReaderPage/* SY --> */,
val secondPage: ReaderPage? = null, /* SY <-- */ val secondPage: ReaderPage? = null, /* SY <-- */
) : Event ) : Event
data class CopyImage(val uri: Uri) : Event
} }
} }

View File

@ -348,6 +348,9 @@
<string name="action_share_second_page">Share second page</string> <string name="action_share_second_page">Share second page</string>
<string name="action_save_combined_page">Save combined page</string> <string name="action_save_combined_page">Save combined page</string>
<string name="action_share_combined_page">Share combined page</string> <string name="action_share_combined_page">Share combined page</string>
<string name="action_copy_first_page">Copy first page</string>
<string name="action_copy_second_page">Copy second page</string>
<string name="action_copy_combined_page">Copy combined page</string>
<!-- Reader Sharing --> <!-- Reader Sharing -->
<string name="share_pages_info">%1$s: %2$s, pages %3$s</string> <string name="share_pages_info">%1$s: %2$s, pages %3$s</string>