refactor: Ensure copying text experience is consistent (#1115)
Previous code was inconsistent about whether or not a notification toast was shown after copying text (contrary to platform guidelines), and there was some code duplication. Fix this with a new `ClipboardUseCase` with a `copyTextTo` method that handles copying text to the clipboard and showing a message afterwards (depending on platform level).
This commit is contained in:
parent
c84a77e862
commit
5c048311b2
|
@ -21,9 +21,6 @@ import android.Manifest
|
||||||
import android.animation.Animator
|
import android.animation.Animator
|
||||||
import android.animation.AnimatorListenerAdapter
|
import android.animation.AnimatorListenerAdapter
|
||||||
import android.app.DownloadManager
|
import android.app.DownloadManager
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.graphics.Color
|
import android.graphics.Color
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
|
@ -53,6 +50,7 @@ import app.pachli.core.navigation.AttachmentViewData
|
||||||
import app.pachli.core.navigation.ViewMediaActivityIntent
|
import app.pachli.core.navigation.ViewMediaActivityIntent
|
||||||
import app.pachli.core.navigation.ViewThreadActivityIntent
|
import app.pachli.core.navigation.ViewThreadActivityIntent
|
||||||
import app.pachli.core.navigation.pachliAccountId
|
import app.pachli.core.navigation.pachliAccountId
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
import app.pachli.databinding.ActivityViewMediaBinding
|
import app.pachli.databinding.ActivityViewMediaBinding
|
||||||
import app.pachli.fragment.MediaActionsListener
|
import app.pachli.fragment.MediaActionsListener
|
||||||
import app.pachli.pager.ImagePagerAdapter
|
import app.pachli.pager.ImagePagerAdapter
|
||||||
|
@ -83,6 +81,9 @@ class ViewMediaActivity : BaseActivity(), MediaActionsListener {
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var clipboard: ClipboardUseCase
|
||||||
|
|
||||||
private val viewModel: ViewMediaViewModel by viewModels()
|
private val viewModel: ViewMediaViewModel by viewModels()
|
||||||
|
|
||||||
private val binding by viewBinding(ActivityViewMediaBinding::inflate)
|
private val binding by viewBinding(ActivityViewMediaBinding::inflate)
|
||||||
|
@ -260,8 +261,7 @@ class ViewMediaActivity : BaseActivity(), MediaActionsListener {
|
||||||
|
|
||||||
private fun copyLink() {
|
private fun copyLink() {
|
||||||
val url = imageUrl ?: attachmentViewData!![binding.viewPager.currentItem].attachment.url
|
val url = imageUrl ?: attachmentViewData!![binding.viewPager.currentItem].attachment.url
|
||||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
clipboard.copyTextTo(url)
|
||||||
clipboard.setPrimaryClip(ClipData.newPlainText(null, url))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun shareMedia() {
|
private fun shareMedia() {
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
package app.pachli.components.account
|
package app.pachli.components.account
|
||||||
|
|
||||||
import android.animation.ArgbEvaluator
|
import android.animation.ArgbEvaluator
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.res.ColorStateList
|
import android.content.res.ColorStateList
|
||||||
import android.content.res.Configuration
|
import android.content.res.Configuration
|
||||||
|
@ -83,6 +80,7 @@ import app.pachli.core.network.model.Relationship
|
||||||
import app.pachli.core.network.parseAsMastodonHtml
|
import app.pachli.core.network.parseAsMastodonHtml
|
||||||
import app.pachli.core.preferences.AppTheme
|
import app.pachli.core.preferences.AppTheme
|
||||||
import app.pachli.core.preferences.PrefKeys
|
import app.pachli.core.preferences.PrefKeys
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
import app.pachli.core.ui.LinkListener
|
import app.pachli.core.ui.LinkListener
|
||||||
import app.pachli.core.ui.extensions.reduceSwipeSensitivity
|
import app.pachli.core.ui.extensions.reduceSwipeSensitivity
|
||||||
import app.pachli.core.ui.getDomain
|
import app.pachli.core.ui.getDomain
|
||||||
|
@ -129,6 +127,9 @@ class AccountActivity :
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var draftsAlert: DraftsAlert
|
lateinit var draftsAlert: DraftsAlert
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var clipboard: ClipboardUseCase
|
||||||
|
|
||||||
private val viewModel: AccountViewModel by viewModels()
|
private val viewModel: AccountViewModel by viewModels()
|
||||||
|
|
||||||
private val binding: ActivityAccountBinding by viewBinding(ActivityAccountBinding::inflate)
|
private val binding: ActivityAccountBinding by viewBinding(ActivityAccountBinding::inflate)
|
||||||
|
@ -498,10 +499,7 @@ class AccountActivity :
|
||||||
view.setOnLongClickListener {
|
view.setOnLongClickListener {
|
||||||
loadedAccount?.let { loadedAccount ->
|
loadedAccount?.let { loadedAccount ->
|
||||||
val fullUsername = getFullUsername(loadedAccount)
|
val fullUsername = getFullUsername(loadedAccount)
|
||||||
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
clipboard.copyTextTo(fullUsername, R.string.account_username_copied)
|
||||||
clipboard.setPrimaryClip(ClipData.newPlainText(null, fullUsername))
|
|
||||||
Snackbar.make(binding.root, getString(R.string.account_username_copied), Snackbar.LENGTH_SHORT)
|
|
||||||
.show()
|
|
||||||
}
|
}
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,9 +17,6 @@
|
||||||
package app.pachli.components.search.fragments
|
package app.pachli.components.search.fragments
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
@ -55,6 +52,7 @@ import app.pachli.core.network.model.Attachment
|
||||||
import app.pachli.core.network.model.Poll
|
import app.pachli.core.network.model.Poll
|
||||||
import app.pachli.core.network.model.Status
|
import app.pachli.core.network.model.Status
|
||||||
import app.pachli.core.network.model.Status.Mention
|
import app.pachli.core.network.model.Status.Mention
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
import app.pachli.interfaces.StatusActionListener
|
import app.pachli.interfaces.StatusActionListener
|
||||||
import app.pachli.view.showMuteAccountDialog
|
import app.pachli.view.showMuteAccountDialog
|
||||||
import app.pachli.viewdata.StatusViewData
|
import app.pachli.viewdata.StatusViewData
|
||||||
|
@ -75,6 +73,9 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var clipboard: ClipboardUseCase
|
||||||
|
|
||||||
override val data: Flow<PagingData<StatusViewData>>
|
override val data: Flow<PagingData<StatusViewData>>
|
||||||
get() = viewModel.statusesFlow
|
get() = viewModel.statusesFlow
|
||||||
|
|
||||||
|
@ -281,8 +282,7 @@ class SearchStatusesFragment : SearchFragment<StatusViewData>(), StatusActionLis
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.status_copy_link -> {
|
R.id.status_copy_link -> {
|
||||||
val clipboard = requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
|
statusUrl?.let { clipboard.copyTextTo(it) }
|
||||||
clipboard.setPrimaryClip(ClipData.newPlainText(null, statusUrl))
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.status_open_as -> {
|
R.id.status_open_as -> {
|
||||||
|
|
|
@ -17,21 +17,18 @@
|
||||||
|
|
||||||
package app.pachli.components.trending
|
package app.pachli.components.trending
|
||||||
|
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.os.Build
|
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import androidx.core.view.AccessibilityDelegateCompat
|
import androidx.core.view.AccessibilityDelegateCompat
|
||||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat
|
||||||
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
import androidx.core.view.accessibility.AccessibilityNodeInfoCompat.AccessibilityActionCompat
|
||||||
import androidx.recyclerview.widget.RecyclerView
|
import androidx.recyclerview.widget.RecyclerView
|
||||||
import app.pachli.R
|
import app.pachli.R
|
||||||
import app.pachli.core.ui.accessibility.PachliRecyclerViewAccessibilityDelegate
|
import app.pachli.core.ui.accessibility.PachliRecyclerViewAccessibilityDelegate
|
||||||
|
import app.pachli.core.ui.di.UseCaseEntryPoint
|
||||||
import app.pachli.view.PreviewCardView
|
import app.pachli.view.PreviewCardView
|
||||||
import app.pachli.view.PreviewCardView.Target
|
import app.pachli.view.PreviewCardView.Target
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accessbility delete for [TrendingLinkViewHolder].
|
* Accessbility delete for [TrendingLinkViewHolder].
|
||||||
|
@ -44,6 +41,9 @@ internal class TrendingLinksAccessibilityDelegate(
|
||||||
private val recyclerView: RecyclerView,
|
private val recyclerView: RecyclerView,
|
||||||
val listener: PreviewCardView.OnClickListener,
|
val listener: PreviewCardView.OnClickListener,
|
||||||
) : PachliRecyclerViewAccessibilityDelegate(recyclerView) {
|
) : PachliRecyclerViewAccessibilityDelegate(recyclerView) {
|
||||||
|
private val useCaseEntryPoint = EntryPointAccessors.fromApplication<UseCaseEntryPoint>(context.applicationContext)
|
||||||
|
val clipboard = useCaseEntryPoint.clipboardUseCase
|
||||||
|
|
||||||
private val openLinkAction = AccessibilityActionCompat(
|
private val openLinkAction = AccessibilityActionCompat(
|
||||||
app.pachli.core.ui.R.id.action_open_link,
|
app.pachli.core.ui.R.id.action_open_link,
|
||||||
context.getString(R.string.action_open_link),
|
context.getString(R.string.action_open_link),
|
||||||
|
@ -85,19 +85,7 @@ internal class TrendingLinksAccessibilityDelegate(
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
app.pachli.core.ui.R.id.action_copy_item -> {
|
app.pachli.core.ui.R.id.action_copy_item -> {
|
||||||
val clipboard = ContextCompat.getSystemService(
|
clipboard.copyTextTo(viewHolder.link.url)
|
||||||
context,
|
|
||||||
ClipboardManager::class.java,
|
|
||||||
) as ClipboardManager
|
|
||||||
val clip = ClipData.newPlainText("", viewHolder.link.url)
|
|
||||||
clipboard.setPrimaryClip(clip)
|
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
context.getString(app.pachli.core.ui.R.string.item_copied),
|
|
||||||
Toast.LENGTH_SHORT,
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
app.pachli.core.ui.R.id.action_open_byline_account -> {
|
app.pachli.core.ui.R.id.action_open_byline_account -> {
|
||||||
|
|
|
@ -16,8 +16,6 @@
|
||||||
package app.pachli.fragment
|
package app.pachli.fragment
|
||||||
|
|
||||||
import android.Manifest
|
import android.Manifest
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.DialogInterface
|
import android.content.DialogInterface
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
|
@ -60,6 +58,7 @@ import app.pachli.core.network.model.Attachment
|
||||||
import app.pachli.core.network.model.Status
|
import app.pachli.core.network.model.Status
|
||||||
import app.pachli.core.network.parseAsMastodonHtml
|
import app.pachli.core.network.parseAsMastodonHtml
|
||||||
import app.pachli.core.network.retrofit.MastodonApi
|
import app.pachli.core.network.retrofit.MastodonApi
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
import app.pachli.core.ui.extensions.getErrorString
|
import app.pachli.core.ui.extensions.getErrorString
|
||||||
import app.pachli.interfaces.StatusActionListener
|
import app.pachli.interfaces.StatusActionListener
|
||||||
import app.pachli.usecase.TimelineCases
|
import app.pachli.usecase.TimelineCases
|
||||||
|
@ -95,6 +94,9 @@ abstract class SFragment<T : IStatusViewData> : Fragment(), StatusActionListener
|
||||||
@Inject
|
@Inject
|
||||||
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
lateinit var downloadUrlUseCase: DownloadUrlUseCase
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
lateinit var clipboard: ClipboardUseCase
|
||||||
|
|
||||||
private var serverCanTranslate = false
|
private var serverCanTranslate = false
|
||||||
|
|
||||||
protected abstract var pachliAccountId: Long
|
protected abstract var pachliAccountId: Long
|
||||||
|
@ -296,9 +298,7 @@ abstract class SFragment<T : IStatusViewData> : Fragment(), StatusActionListener
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.status_copy_link -> {
|
R.id.status_copy_link -> {
|
||||||
(requireActivity().getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager).apply {
|
statusUrl?.let { clipboard.copyTextTo(it) }
|
||||||
setPrimaryClip(ClipData.newPlainText(null, statusUrl))
|
|
||||||
}
|
|
||||||
return@setOnMenuItemClickListener true
|
return@setOnMenuItemClickListener true
|
||||||
}
|
}
|
||||||
R.id.status_open_as -> {
|
R.id.status_open_as -> {
|
||||||
|
|
|
@ -0,0 +1,67 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Pachli Association
|
||||||
|
*
|
||||||
|
* This file is a part of Pachli.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.pachli.core.ui
|
||||||
|
|
||||||
|
import android.content.ClipData
|
||||||
|
import android.content.ClipboardManager
|
||||||
|
import android.content.Context
|
||||||
|
import android.os.Build
|
||||||
|
import android.widget.Toast
|
||||||
|
import androidx.annotation.StringRes
|
||||||
|
import androidx.core.content.ContextCompat
|
||||||
|
import dagger.hilt.android.qualifiers.ApplicationContext
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies plain text to the clipboard as the primary clip.
|
||||||
|
*/
|
||||||
|
class ClipboardUseCase @Inject constructor(
|
||||||
|
@ApplicationContext val context: Context,
|
||||||
|
) {
|
||||||
|
private val clipboard: ClipboardManager by lazy {
|
||||||
|
ContextCompat.getSystemService(
|
||||||
|
context,
|
||||||
|
ClipboardManager::class.java,
|
||||||
|
) as ClipboardManager
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies [text] to the clipboard as the primary clip, with optional
|
||||||
|
* [label]. If necessary displays a toast showing [message] to confirm
|
||||||
|
* copy is complete.
|
||||||
|
*
|
||||||
|
* @param text Text to copy.
|
||||||
|
* @param message Optional message to show after completion.
|
||||||
|
* @param label Optional user-visible label to associate with the copied
|
||||||
|
* text, see [ClipData.newPlainText].
|
||||||
|
*/
|
||||||
|
fun copyTextTo(
|
||||||
|
text: CharSequence,
|
||||||
|
@StringRes message: Int = R.string.item_copied,
|
||||||
|
label: CharSequence = "",
|
||||||
|
) {
|
||||||
|
clipboard.setPrimaryClip(ClipData.newPlainText(label, text))
|
||||||
|
notify(message)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun notify(@StringRes message: Int) {
|
||||||
|
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
||||||
|
Toast.makeText(context, context.getString(message), Toast.LENGTH_SHORT).show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -17,18 +17,15 @@
|
||||||
|
|
||||||
package app.pachli.core.ui.accessibility
|
package app.pachli.core.ui.accessibility
|
||||||
|
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.os.Build
|
|
||||||
import android.view.LayoutInflater
|
import android.view.LayoutInflater
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.view.ViewGroup
|
import android.view.ViewGroup
|
||||||
import android.widget.ArrayAdapter
|
import android.widget.ArrayAdapter
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.core.content.ContextCompat
|
|
||||||
import app.pachli.core.ui.R
|
import app.pachli.core.ui.R
|
||||||
import app.pachli.core.ui.databinding.SimpleListItem1CopyButtonBinding
|
import app.pachli.core.ui.databinding.SimpleListItem1CopyButtonBinding
|
||||||
|
import app.pachli.core.ui.di.UseCaseEntryPoint
|
||||||
|
import dagger.hilt.android.EntryPointAccessors
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An [ArrayAdapter] that shows a "copy" button next to each item.
|
* An [ArrayAdapter] that shows a "copy" button next to each item.
|
||||||
|
@ -49,27 +46,16 @@ class ArrayAdapterWithCopyButton<T : CharSequence>(
|
||||||
fun onClick(position: Int)
|
fun onClick(position: Int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val useCaseEntryPoint = EntryPointAccessors.fromApplication<UseCaseEntryPoint>(context.applicationContext)
|
||||||
|
private val clipboard = useCaseEntryPoint.clipboardUseCase
|
||||||
|
|
||||||
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
override fun getView(position: Int, convertView: View?, parent: ViewGroup): View {
|
||||||
val binding = if (convertView == null) {
|
val binding = if (convertView == null) {
|
||||||
SimpleListItem1CopyButtonBinding.inflate(LayoutInflater.from(context), parent, false).apply {
|
SimpleListItem1CopyButtonBinding.inflate(LayoutInflater.from(context), parent, false).apply {
|
||||||
text1.setOnClickListener { listener.onClick(position) }
|
text1.setOnClickListener { listener.onClick(position) }
|
||||||
|
|
||||||
copy.setOnClickListener {
|
copy.setOnClickListener {
|
||||||
getItem(position)?.let { text ->
|
getItem(position)?.let { clipboard.copyTextTo(it) }
|
||||||
val clipboard = ContextCompat.getSystemService(
|
|
||||||
context,
|
|
||||||
ClipboardManager::class.java,
|
|
||||||
) as ClipboardManager
|
|
||||||
val clip = ClipData.newPlainText("", text)
|
|
||||||
clipboard.setPrimaryClip(clip)
|
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
|
||||||
Toast.makeText(
|
|
||||||
context,
|
|
||||||
context.getString(R.string.item_copied),
|
|
||||||
Toast.LENGTH_SHORT,
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -0,0 +1,33 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2024 Pachli Association
|
||||||
|
*
|
||||||
|
* This file is a part of Pachli.
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify it under the terms of the
|
||||||
|
* GNU General Public License as published by the Free Software Foundation; either version 3 of the
|
||||||
|
* License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* Pachli is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even
|
||||||
|
* the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
||||||
|
* Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License along with Pachli; if not,
|
||||||
|
* see <http://www.gnu.org/licenses>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package app.pachli.core.ui.di
|
||||||
|
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
|
import dagger.hilt.EntryPoint
|
||||||
|
import dagger.hilt.InstallIn
|
||||||
|
import dagger.hilt.components.SingletonComponent
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for use cases that need to be field-injected in to classes
|
||||||
|
* Hilt does not manage.
|
||||||
|
*/
|
||||||
|
@EntryPoint
|
||||||
|
@InstallIn(SingletonComponent::class)
|
||||||
|
interface UseCaseEntryPoint {
|
||||||
|
val clipboardUseCase: ClipboardUseCase
|
||||||
|
}
|
|
@ -17,8 +17,6 @@
|
||||||
|
|
||||||
package app.pachli.feature.about
|
package app.pachli.feature.about
|
||||||
|
|
||||||
import android.content.ClipData
|
|
||||||
import android.content.ClipboardManager
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import android.os.Bundle
|
import android.os.Bundle
|
||||||
import android.text.SpannableString
|
import android.text.SpannableString
|
||||||
|
@ -28,9 +26,7 @@ import android.text.style.URLSpan
|
||||||
import android.text.util.Linkify
|
import android.text.util.Linkify
|
||||||
import android.view.View
|
import android.view.View
|
||||||
import android.widget.TextView
|
import android.widget.TextView
|
||||||
import android.widget.Toast
|
|
||||||
import androidx.annotation.StringRes
|
import androidx.annotation.StringRes
|
||||||
import androidx.core.content.ContextCompat.getSystemService
|
|
||||||
import androidx.fragment.app.Fragment
|
import androidx.fragment.app.Fragment
|
||||||
import androidx.fragment.app.viewModels
|
import androidx.fragment.app.viewModels
|
||||||
import androidx.lifecycle.lifecycleScope
|
import androidx.lifecycle.lifecycleScope
|
||||||
|
@ -39,13 +35,18 @@ import app.pachli.core.common.extensions.hide
|
||||||
import app.pachli.core.common.extensions.show
|
import app.pachli.core.common.extensions.show
|
||||||
import app.pachli.core.common.extensions.viewBinding
|
import app.pachli.core.common.extensions.viewBinding
|
||||||
import app.pachli.core.common.util.versionName
|
import app.pachli.core.common.util.versionName
|
||||||
|
import app.pachli.core.ui.ClipboardUseCase
|
||||||
import app.pachli.core.ui.NoUnderlineURLSpan
|
import app.pachli.core.ui.NoUnderlineURLSpan
|
||||||
import app.pachli.feature.about.databinding.FragmentAboutBinding
|
import app.pachli.feature.about.databinding.FragmentAboutBinding
|
||||||
import dagger.hilt.android.AndroidEntryPoint
|
import dagger.hilt.android.AndroidEntryPoint
|
||||||
|
import javax.inject.Inject
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
|
||||||
@AndroidEntryPoint
|
@AndroidEntryPoint
|
||||||
class AboutFragment : Fragment(R.layout.fragment_about) {
|
class AboutFragment : Fragment(R.layout.fragment_about) {
|
||||||
|
@Inject
|
||||||
|
lateinit var clipboard: ClipboardUseCase
|
||||||
|
|
||||||
private val viewModel: AboutFragmentViewModel by viewModels()
|
private val viewModel: AboutFragmentViewModel by viewModels()
|
||||||
|
|
||||||
private val binding by viewBinding(FragmentAboutBinding::bind)
|
private val binding by viewBinding(FragmentAboutBinding::bind)
|
||||||
|
@ -100,16 +101,7 @@ class AboutFragment : Fragment(R.layout.fragment_about) {
|
||||||
|
|
||||||
binding.copyDeviceInfo.setOnClickListener {
|
binding.copyDeviceInfo.setOnClickListener {
|
||||||
val text = "$version\n\nDevice:\n\n$deviceInfo\n\nAccount:\n\n${binding.accountInfo.text}"
|
val text = "$version\n\nDevice:\n\n$deviceInfo\n\nAccount:\n\n${binding.accountInfo.text}"
|
||||||
val clipboard = getSystemService(requireContext(), ClipboardManager::class.java) as ClipboardManager
|
clipboard.copyTextTo(text, R.string.about_copied, "Pachli version information")
|
||||||
val clip = ClipData.newPlainText("Pachli version information", text)
|
|
||||||
clipboard.setPrimaryClip(clip)
|
|
||||||
if (Build.VERSION.SDK_INT <= Build.VERSION_CODES.S_V2) {
|
|
||||||
Toast.makeText(
|
|
||||||
requireContext(),
|
|
||||||
getString(R.string.about_copied),
|
|
||||||
Toast.LENGTH_SHORT,
|
|
||||||
).show()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue