Share and copy menu items for account page (#3120)

* Share and copy menu items for account page (first attempt)]

* Always include domain in username in 'handle' copy

* Remove profile copy options, rename 'handle' to 'username'

* Long press on username in profile to copy it to clipboard

* Changes for code review: localUsername not username, Snackbar not Toast

* Do not trust getDomain() when getting full username. This means full-username build has to happen in AccountActivity instead of Account

* Replace != null -> \!\! idiom with more kotlin-y (and more threadsafe) ?.let pattern

* Unnecessary import

* Comment clarifying safety of \!\!
This commit is contained in:
mcclure 2023-01-09 15:08:46 -05:00 committed by GitHub
commit 59fb710f64
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 77 additions and 8 deletions

View file

@ -16,6 +16,8 @@
package com.keylesspalace.tusky.components.account
import android.animation.ArgbEvaluator
import android.content.ClipData
import android.content.ClipboardManager
import android.content.Context
import android.content.Intent
import android.content.res.ColorStateList
@ -407,6 +409,20 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
binding.accountUsernameTextView.text = usernameFormatted
binding.accountDisplayNameTextView.text = account.name.emojify(account.emojis, binding.accountDisplayNameTextView, animateEmojis)
// Long press on username to copy it to clipboard
for (view in listOf(binding.accountUsernameTextView, binding.accountDisplayNameTextView)) {
view.setOnLongClickListener {
loadedAccount?.let { loadedAccount ->
val fullUsername = getFullUsername(loadedAccount)
val clipboard = getSystemService(Context.CLIPBOARD_SERVICE) as ClipboardManager
clipboard.setPrimaryClip(ClipData.newPlainText(null, fullUsername))
Snackbar.make(binding.root, getString(R.string.account_username_copied), Snackbar.LENGTH_SHORT)
.show()
}
true
}
}
val emojifiedNote = account.note.parseAsMastodonHtml().emojify(account.emojis, binding.accountNoteTextView, animateEmojis)
setClickableText(binding.accountNoteTextView, emojifiedNote, emptyList(), null, this)
@ -712,9 +728,9 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
getString(R.string.action_mute)
}
if (loadedAccount != null) {
loadedAccount?.let { loadedAccount ->
val muteDomain = menu.findItem(R.id.action_mute_domain)
domain = getDomain(loadedAccount?.url)
domain = getDomain(loadedAccount.url)
if (domain.isEmpty()) {
// If we can't get the domain, there's no way we can mute it anyway...
menu.removeItem(R.id.action_mute_domain)
@ -842,23 +858,47 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
when (item.itemId) {
R.id.action_open_in_web -> {
// If the account isn't loaded yet, eat the input.
if (loadedAccount?.url != null) {
openLink(loadedAccount!!.url)
loadedAccount?.let { loadedAccount ->
openLink(loadedAccount.url)
}
return true
}
R.id.action_open_as -> {
if (loadedAccount != null) {
loadedAccount?.let { loadedAccount ->
showAccountChooserDialog(
item.title, false,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
openAsAccount(loadedAccount!!.url, account)
openAsAccount(loadedAccount.url, account)
}
}
)
}
}
R.id.action_share_account_link -> {
// If the account isn't loaded yet, eat the input.
loadedAccount?.let { loadedAccount ->
val url = loadedAccount.url
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, url)
sendIntent.type = "text/plain"
startActivity(Intent.createChooser(sendIntent, resources.getText(R.string.send_account_link_to)))
}
return true
}
R.id.action_share_account_username -> {
// If the account isn't loaded yet, eat the input.
loadedAccount?.let { loadedAccount ->
val fullUsername = getFullUsername(loadedAccount)
val sendIntent = Intent()
sendIntent.action = Intent.ACTION_SEND
sendIntent.putExtra(Intent.EXTRA_TEXT, fullUsername)
sendIntent.type = "text/plain"
startActivity(Intent.createChooser(sendIntent, resources.getText(R.string.send_account_username_to)))
}
return true
}
R.id.action_block -> {
toggleBlock()
return true
@ -880,8 +920,8 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
return true
}
R.id.action_report -> {
if (loadedAccount != null) {
startActivity(ReportActivity.getIntent(this, viewModel.accountId, loadedAccount!!.username))
loadedAccount?.let { loadedAccount ->
startActivity(ReportActivity.getIntent(this, viewModel.accountId, loadedAccount.username))
}
return true
}
@ -895,6 +935,17 @@ class AccountActivity : BottomSheetActivity(), ActionButtonActivity, HasAndroidI
} else null
}
private fun getFullUsername(account: Account): String {
if (account.isRemote()) {
return "@" + account.username
} else {
val localUsername = account.localUsername
// Note: !! here will crash if this pane is ever shown to a logged-out user. With AccountActivity this is believed to be impossible.
val domain = accountManager.activeAccount!!.domain
return "@$localUsername@$domain"
}
}
override fun androidInjector() = dispatchingAndroidInjector
companion object {