Skip to content

Commit

Permalink
Remove deprecated ClipboardManager
Browse files Browse the repository at this point in the history
  • Loading branch information
T8RIN committed Jan 21, 2025
1 parent 3dab466 commit 06b53be
Show file tree
Hide file tree
Showing 45 changed files with 147 additions and 204 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,6 @@ import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.getValue
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.LocalUriHandler
Expand All @@ -64,7 +63,6 @@ import androidx.exifinterface.media.ExifInterface
import com.t8rin.dynamic.theme.ColorTuple
import com.t8rin.dynamic.theme.extractPrimaryColor
import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.launch
import ru.tech.imageresizershrinker.core.crash.components.CrashHandler
import ru.tech.imageresizershrinker.core.domain.ISSUE_TRACKER
import ru.tech.imageresizershrinker.core.domain.TELEGRAM_GROUP_LINK
Expand All @@ -83,14 +81,13 @@ import ru.tech.imageresizershrinker.core.ui.theme.ImageToolboxThemeSurface
import ru.tech.imageresizershrinker.core.ui.theme.White
import ru.tech.imageresizershrinker.core.ui.theme.outlineVariant
import ru.tech.imageresizershrinker.core.ui.utils.helper.AppActivityClass
import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.copyToClipboard
import ru.tech.imageresizershrinker.core.ui.utils.provider.ImageToolboxCompositionLocals
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalScreenSize
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.utils.provider.setContentWithWindowSizeClass
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedFloatingActionButton
import ru.tech.imageresizershrinker.core.ui.widget.other.ExpandableItem
import ru.tech.imageresizershrinker.core.ui.widget.other.LocalToastHostState
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastHost
import ru.tech.imageresizershrinker.core.ui.widget.text.AutoSizeText
import javax.inject.Inject
Expand Down Expand Up @@ -118,20 +115,13 @@ class CrashActivity : CrashHandler() {
onGetEmojiColorTuple = ::getColorTupleFromEmoji
)
) {
val toastHostState = LocalToastHostState.current
val scope = rememberCoroutineScope()

val essentials = rememberLocalEssentials()
val createClip: (String) -> Unit = {
copyToClipboard(
label = getString(R.string.exception),
value = it
essentials.copyToClipboard(it)
essentials.showToast(
icon = Icons.Rounded.ContentCopy,
message = getString(R.string.copied),
)
scope.launch {
toastHostState.showToast(
icon = Icons.Rounded.ContentCopy,
message = getString(R.string.copied),
)
}
}

val linkHandler = LocalUriHandler.current
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ inline fun <reified T> T?.notNullAnd(
): Boolean = if (this != null) predicate(this)
else false

fun String.isBase64() = isNotEmpty() && BASE64_PATTERN.matches(this)
fun CharSequence.isBase64() = isNotEmpty() && BASE64_PATTERN.matches(this)

fun String.trimToBase64() = filter { !it.isWhitespace() }.substringAfter(",")
fun CharSequence.trimToBase64() = toString().filter { !it.isWhitespace() }.substringAfter(",")

private val BASE64_PATTERN = Regex(
"^(?=(.{4})*\$)[A-Za-z0-9+/]*={0,2}\$"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@ internal fun OtherContent(
},
onCopy = { manager ->
component.cacheNeutralLut { uri ->
manager.setClip(
manager.copyToClipboard(
uri.asClip(context)
)
showConfetti()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,10 @@ fun List<Uri>.toClipData(
}
}

fun CharSequence.toClipData(
label: String = "plain text"
): ClipData = ClipData.newPlainText(label, this)

fun Uri.asClip(
context: Context,
label: String = "Image"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -366,11 +366,10 @@ object ContextUtils {

/** Save a text into the clipboard. */
fun Context.copyToClipboard(
label: String,
value: String,
) {
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
val clip = ClipData.newPlainText(label, value)
val clip = ClipData.newPlainText("plain text", value)
clipboard.setPrimaryClip(clip)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@

package ru.tech.imageresizershrinker.core.ui.utils.provider

import android.content.ClipData
import android.os.Build
import androidx.activity.ComponentActivity
import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.outlined.FolderOff
Expand All @@ -27,6 +29,9 @@ import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.ClipEntry
import androidx.compose.ui.platform.Clipboard
import androidx.compose.ui.platform.LocalClipboard
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.launch
import ru.tech.imageresizershrinker.core.domain.saving.model.SaveResult
Expand All @@ -37,6 +42,7 @@ import ru.tech.imageresizershrinker.core.ui.utils.helper.ContextUtils.createScre
import ru.tech.imageresizershrinker.core.ui.utils.helper.parseFileSaveResult
import ru.tech.imageresizershrinker.core.ui.utils.helper.parseSaveResult
import ru.tech.imageresizershrinker.core.ui.utils.helper.parseSaveResults
import ru.tech.imageresizershrinker.core.ui.utils.helper.toClipData
import ru.tech.imageresizershrinker.core.ui.utils.navigation.Screen
import ru.tech.imageresizershrinker.core.ui.widget.other.LocalToastHostState
import ru.tech.imageresizershrinker.core.ui.widget.other.ToastDuration
Expand All @@ -49,29 +55,34 @@ fun rememberLocalEssentials(): LocalEssentials {
val confettiHostState = LocalConfettiHostState.current
val context = LocalComponentActivity.current
val coroutineScope = rememberCoroutineScope()
val clipboard = LocalClipboard.current

return remember(
toastHostState,
coroutineScope,
confettiHostState,
context
context,
clipboard
) {
LocalEssentials(
toastHostState = toastHostState,
confettiHostState = confettiHostState,
coroutineScope = coroutineScope,
context = context
context = context,
clipboard = clipboard
)
}
}

@ConsistentCopyVisibility
@Stable
@Immutable
data class LocalEssentials internal constructor(
val toastHostState: ToastHostState,
val confettiHostState: ConfettiHostState,
val coroutineScope: CoroutineScope,
val context: ComponentActivity,
val clipboard: Clipboard
) {
fun showToast(
message: String,
Expand Down Expand Up @@ -147,4 +158,46 @@ data class LocalEssentials internal constructor(
)
}
}

fun copyToClipboard(clipEntry: ClipEntry?) {
coroutineScope.launch {
clipboard.setClipEntry(clipEntry)
}
}

fun copyToClipboard(text: CharSequence) {
copyToClipboard(ClipEntry(text.toClipData()))
}

fun getTextFromClipboard(
onSuccess: (CharSequence) -> Unit
) {
coroutineScope.launch {
clipboard.getClipEntry()
?.clipData?.let { primaryClip ->
if (primaryClip.itemCount > 0) {
primaryClip.getItemAt(0)?.text
} else {
null
}
}?.takeIf { it.isNotEmpty() }?.let(onSuccess)
}
}

fun clearClipboard() {
val clipboardManager = clipboard.nativeClipboard
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.P) {
runCatching {
clipboardManager.clearPrimaryClip()
}.onFailure {
clipboardManager.setPrimaryClip(
ClipData.newPlainText(null, "")
)
}
} else {
clipboardManager.setPrimaryClip(
ClipData.newPlainText(null, "")
)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,12 @@ import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.platform.ClipboardManager
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.resources.icons.MiniEdit
import ru.tech.imageresizershrinker.core.ui.utils.provider.LocalEssentials
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedAlertDialog
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedButton
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.EnhancedIconButton
Expand All @@ -56,7 +56,7 @@ fun ShareButton(
enabled: Boolean = true,
onShare: () -> Unit,
onEdit: (() -> Unit)? = null,
onCopy: ((ClipboardManager) -> Unit)? = null
onCopy: ((LocalEssentials) -> Unit)? = null
) {
var showSelectionDialog by rememberSaveable {
mutableStateOf(false)
Expand Down Expand Up @@ -99,7 +99,7 @@ fun ShareButton(
)
},
text = {
val clipboardManager = LocalClipboardManager.current
val essentials = rememberLocalEssentials()

val scrollState = rememberScrollState()
Column(
Expand Down Expand Up @@ -131,7 +131,7 @@ fun ShareButton(
startIcon = Icons.Rounded.ContentCopy,
onClick = {
showSelectionDialog = false
onCopy(clipboardManager)
onCopy(essentials)
},
titleFontStyle = PreferenceItemDefaults.TitleFontStyleCentered
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,10 +98,7 @@ fun ColorInfo(
val context = LocalContext.current
val colorPasteError = rememberSaveable { mutableStateOf<String?>(null) }
val onCopyCustomColor = {
context.copyToClipboard(
label = context.getString(R.string.color),
value = getFormattedColor(color)
)
context.copyToClipboard(getFormattedColor(color))
}
val onPasteCustomColor = {
context.pasteColorFromClipboard(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,6 @@

package ru.tech.imageresizershrinker.core.ui.widget.other

import android.content.ClipData
import android.content.Intent
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Arrangement
import androidx.compose.foundation.layout.Column
Expand All @@ -38,7 +36,6 @@ import androidx.compose.runtime.Composable
import androidx.compose.runtime.getValue
import androidx.compose.runtime.mutableStateOf
import androidx.compose.runtime.remember
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
Expand All @@ -48,20 +45,18 @@ import androidx.compose.ui.graphics.Shape
import androidx.compose.ui.graphics.compositeOver
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.layout.onSizeChanged
import androidx.compose.ui.platform.LocalClipboardManager
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.platform.LocalDensity
import androidx.compose.ui.platform.LocalUriHandler
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import androidx.core.net.toUri
import kotlinx.coroutines.launch
import ru.tech.imageresizershrinker.core.resources.R
import ru.tech.imageresizershrinker.core.ui.shapes.MaterialStarShape
import ru.tech.imageresizershrinker.core.ui.utils.helper.LinkPreview
import ru.tech.imageresizershrinker.core.ui.utils.provider.rememberLocalEssentials
import ru.tech.imageresizershrinker.core.ui.widget.enhanced.hapticsCombinedClickable
import ru.tech.imageresizershrinker.core.ui.widget.image.Picture
import ru.tech.imageresizershrinker.core.ui.widget.modifier.container
Expand All @@ -71,12 +66,9 @@ fun LinkPreviewCard(
linkPreview: LinkPreview,
shape: Shape
) {
val clipboardManager = LocalClipboardManager.current.nativeClipboard
val coroutineScope = rememberCoroutineScope()
val essentials = rememberLocalEssentials()
val onLinkCopiedText = stringResource(R.string.copied)
val linkTextLabel = stringResource(R.string.image_link)
val context = LocalContext.current
val toastHostState = LocalToastHostState.current
val linkHandler = LocalUriHandler.current

Row(
modifier = Modifier
Expand All @@ -88,28 +80,14 @@ fun LinkPreviewCard(
)
.hapticsCombinedClickable(
onClick = {
linkPreview.link?.let {
context.startActivity(
Intent(
Intent.ACTION_VIEW,
it.toUri()
)
)
}
linkPreview.link?.let(linkHandler::openUri)
},
onLongClick = {
clipboardManager.setPrimaryClip(
ClipData.newPlainText(
linkTextLabel,
linkPreview.link
)
linkPreview.link?.let(essentials::copyToClipboard)
essentials.showToast(
message = onLinkCopiedText,
icon = Icons.Default.Link
)
coroutineScope.launch {
toastHostState.showToast(
message = onLinkCopiedText,
icon = Icons.Default.Link
)
}
},
),
verticalAlignment = Alignment.CenterVertically
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ fun Base64ToolsContent(
},
onCopy = { manager ->
component.cacheCurrentImage { uri ->
manager.setClip(uri.asClip(context))
manager.copyToClipboard(uri.asClip(context))
showConfetti()
}
},
Expand Down
Loading

0 comments on commit 06b53be

Please sign in to comment.