Don't overwrite the active account when composing from a notification (#3688)

Fix a bug where the active account can be overwritten.

1. Have two accounts logged in to Tusky, A and B
2. Open Tusky as account A
3. Send a DM to account B (doesn't have to be a DM, just anything that creates a notification for account B)
4. Restart Tusky so the Android notification for the DM is displayed immediately. You are still acting as account A.
5. Drag down the Android notification, you should see two options, "Quick reply" and "Compose"
6. Tap "Compose"
7. ComposeActivity will start. You are now acting as account B. Compose and send a reply
8. You'll be returned to the "Home" tab.

The UI will show you are still account A (i.e., it's account A's avatar at the top of the screen, if you have the "Show username in toolbars" option turned on it will be account A's username in the toolbar).

But you are now seeing the home timeline for account B.

Fix this.

ComposeViewModel
- Do not rely on the active account in sendStatus(), receive the account ID as a parameter

ComposeActivity
- Use either the account ID from the intent, or the current active account. **Do not** change the active account
- Pass the account ID to use in the sendStatus() call
This commit is contained in:
Nik Clayton 2023-05-29 13:32:56 +02:00 committed by GitHub
parent 4a4dbe9012
commit 34de33220c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 16 additions and 9 deletions

View File

@ -142,6 +142,9 @@ class ComposeActivity :
private lateinit var emojiBehavior: BottomSheetBehavior<*>
private lateinit var scheduleBehavior: BottomSheetBehavior<*>
/** The account that is being used to compose the status */
private lateinit var activeAccount: AccountEntity
private var photoUploadUri: Uri? = null
private val preferences by unsafeLazy { PreferenceManager.getDefaultSharedPreferences(this) }
@ -208,10 +211,15 @@ class ComposeActivity :
notificationManager.cancel(notificationId)
}
val accountId = intent.getLongExtra(ACCOUNT_ID_EXTRA, -1)
if (accountId != -1L) {
accountManager.setActiveAccount(accountId)
}
// If started from an intent then compose as the account ID from the intent.
// Otherwise use the active account. If null then the user is not logged in,
// and return from the activity.
val intentAccountId = intent.getLongExtra(ACCOUNT_ID_EXTRA, -1)
activeAccount = if (intentAccountId != -1L) {
accountManager.getAccountById(intentAccountId)
} else {
accountManager.activeAccount
} ?: return
val theme = preferences.getString("appTheme", APP_THEME_DEFAULT)
if (theme == "black") {
@ -220,8 +228,6 @@ class ComposeActivity :
setContentView(binding.root)
setupActionBar()
// do not do anything when not logged in, activity will be finished in super.onCreate() anyway
val activeAccount = accountManager.activeAccount ?: return
setupAvatar(activeAccount)
val mediaAdapter = MediaPreviewAdapter(
@ -955,7 +961,7 @@ class ComposeActivity :
enableButtons(true, viewModel.editing)
} else if (characterCount <= maximumTootCharacters) {
lifecycleScope.launch {
viewModel.sendStatus(contentText, spoilerText)
viewModel.sendStatus(contentText, spoilerText, activeAccount.id)
deleteDraftAndFinish()
}
} else {

View File

@ -283,7 +283,8 @@ class ComposeViewModel @Inject constructor(
*/
suspend fun sendStatus(
content: String,
spoilerText: String
spoilerText: String,
accountId: Long
) {
if (!scheduledTootId.isNullOrEmpty()) {
api.deleteScheduledStatus(scheduledTootId!!)
@ -310,7 +311,7 @@ class ComposeViewModel @Inject constructor(
poll = poll.value,
replyingStatusContent = null,
replyingStatusAuthorUsername = null,
accountId = accountManager.activeAccount!!.id,
accountId = accountId,
draftId = draftId,
idempotencyKey = randomAlphanumericString(16),
retries = 0,