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:
		
					parent
					
						
							
								8ca92d9fde
							
						
					
				
			
			
				commit
				
					
						59fb710f64
					
				
			
		
					 3 changed files with 77 additions and 8 deletions
				
			
		|  | @ -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 { | ||||
|  |  | |||
|  | @ -10,6 +10,19 @@ | |||
|         android:title="@string/action_open_as" | ||||
|         app:showAsAction="never" /> | ||||
| 
 | ||||
|     <item | ||||
|         android:id="@+id/action_account_share" | ||||
|         android:title="@string/action_share"> | ||||
|         <menu> | ||||
|             <item | ||||
|                 android:id="@+id/action_share_account_link" | ||||
|                 android:title="@string/action_share_account_link" /> | ||||
|             <item | ||||
|                 android:id="@+id/action_share_account_username" | ||||
|                 android:title="@string/action_share_account_username" /> | ||||
|         </menu> | ||||
|     </item> | ||||
| 
 | ||||
|     <item android:id="@+id/action_mute" | ||||
|         android:title="@string/action_mute" | ||||
|         app:showAsAction="never" /> | ||||
|  |  | |||
|  | @ -103,6 +103,8 @@ | |||
|     <string name="action_unfollow">Unfollow</string> | ||||
|     <string name="action_block">Block</string> | ||||
|     <string name="action_unblock">Unblock</string> | ||||
|     <string name="action_share_account_link">Share link to account</string> | ||||
|     <string name="action_share_account_username">Share username of account</string> | ||||
|     <string name="action_hide_reblogs">Hide boosts</string> | ||||
|     <string name="action_show_reblogs">Show boosts</string> | ||||
|     <string name="action_report">Report</string> | ||||
|  | @ -181,7 +183,10 @@ | |||
| 
 | ||||
|     <string name="send_post_link_to">Share post URL to…</string> | ||||
|     <string name="send_post_content_to">Share post to…</string> | ||||
|     <string name="send_account_link_to">Share account URL to…</string> | ||||
|     <string name="send_account_username_to">Share account username to…</string> | ||||
|     <string name="send_media_to">Share media to…</string> | ||||
|     <string name="account_username_copied">Username copied</string> | ||||
| 
 | ||||
|     <string name="confirmation_reported">Sent!</string> | ||||
|     <string name="confirmation_unblocked">User unblocked</string> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue