override onNewIntent in MainActivity to improve sharing (#4527)

When investigating #4517, I found that sharing to Tusky sometimes just
does nothing.
This is because when `MainActivity` is already open, it isn't always
restarted (`onCreate` not called) but instead the Intent is delivered to
`onNewIntent` of the existing `MainActivity`. This fixes the issue by
overriding `onNewIntent`.

The problem does not always reproduce, it seems to depend on what is
shared from where and on the Android version. `MainActivity` must be
open for the problem to occur though.

This probably also fixes the issue that sometimes Tusky does not show
the right tab when clicking on a notification
(https://github.com/tuskyapp/Tusky/issues/2691)
This commit is contained in:
Konrad Pozniak 2024-06-28 17:36:31 +02:00 committed by GitHub
parent 1c1d39443b
commit f5ad39946e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 89 additions and 68 deletions

View File

@ -223,74 +223,7 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
// check for savedInstanceState in order to not handle intent events more than once
if (intent != null && savedInstanceState == null) {
val notificationId = intent.getIntExtra(NOTIFICATION_ID, -1)
if (notificationId != -1) {
// opened from a notification action, cancel the notification
val notificationManager = getSystemService(
NOTIFICATION_SERVICE
) as NotificationManager
notificationManager.cancel(intent.getStringExtra(NOTIFICATION_TAG), notificationId)
}
/** there are two possibilities the accountId can be passed to MainActivity:
* - from our code as Long Intent Extra TUSKY_ACCOUNT_ID
* - from share shortcuts as String 'android.intent.extra.shortcut.ID'
*/
var tuskyAccountId = intent.getLongExtra(TUSKY_ACCOUNT_ID, -1)
if (tuskyAccountId == -1L) {
val accountIdString = intent.getStringExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID)
if (accountIdString != null) {
tuskyAccountId = accountIdString.toLong()
}
}
val accountRequested = tuskyAccountId != -1L
if (accountRequested && tuskyAccountId != activeAccount.id) {
accountManager.setActiveAccount(tuskyAccountId)
}
val openDrafts = intent.getBooleanExtra(OPEN_DRAFTS, false)
if (canHandleMimeType(intent.type) || intent.hasExtra(COMPOSE_OPTIONS)) {
// Sharing to Tusky from an external app
if (accountRequested) {
// The correct account is already active
forwardToComposeActivity(intent)
} else {
// No account was provided, show the chooser
showAccountChooserDialog(
getString(R.string.action_share_as),
true,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
val requestedId = account.id
if (requestedId == activeAccount.id) {
// The correct account is already active
forwardToComposeActivity(intent)
} else {
// A different account was requested, restart the activity
intent.putExtra(TUSKY_ACCOUNT_ID, requestedId)
changeAccount(requestedId, intent)
}
}
}
)
}
} else if (openDrafts) {
val intent = DraftsActivity.newIntent(this)
startActivity(intent)
} else if (accountRequested && intent.hasExtra(NOTIFICATION_TYPE)) {
// user clicked a notification, show follow requests for type FOLLOW_REQUEST,
// otherwise show notification tab
if (intent.getStringExtra(NOTIFICATION_TYPE) == Notification.Type.FOLLOW_REQUEST.name) {
val intent = AccountListActivity.newIntent(
this,
AccountListActivity.Type.FOLLOW_REQUESTS
)
startActivityWithSlideInAnimation(intent)
} else {
showNotificationTab = true
}
}
showNotificationTab = handleIntent(intent, activeAccount)
}
window.statusBarColor = Color.TRANSPARENT // don't draw a status bar, the DrawerLayout and the MaterialDrawerLayout have their own
setContentView(binding.root)
@ -417,6 +350,94 @@ class MainActivity : BottomSheetActivity(), ActionButtonActivity, MenuProvider {
draftsAlert.observeInContext(this, true)
}
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
val activeAccount = accountManager.activeAccount ?: return
val showNotificationTab = handleIntent(intent, activeAccount)
if (showNotificationTab) {
val tabs = activeAccount.tabPreferences
val position = tabs.indexOfFirst { it.id == NOTIFICATIONS }
if (position != -1) {
binding.viewPager.setCurrentItem(position, false)
}
}
}
/** Handle an incoming Intent,
* @returns true when the intent is coming from an notification and the interface should show the notification tab.
*/
private fun handleIntent(intent: Intent, activeAccount: AccountEntity): Boolean {
val notificationId = intent.getIntExtra(NOTIFICATION_ID, -1)
if (notificationId != -1) {
// opened from a notification action, cancel the notification
val notificationManager = getSystemService(
NOTIFICATION_SERVICE
) as NotificationManager
notificationManager.cancel(intent.getStringExtra(NOTIFICATION_TAG), notificationId)
}
/** there are two possibilities the accountId can be passed to MainActivity:
* - from our code as Long Intent Extra TUSKY_ACCOUNT_ID
* - from share shortcuts as String 'android.intent.extra.shortcut.ID'
*/
var tuskyAccountId = intent.getLongExtra(TUSKY_ACCOUNT_ID, -1)
if (tuskyAccountId == -1L) {
val accountIdString = intent.getStringExtra(ShortcutManagerCompat.EXTRA_SHORTCUT_ID)
if (accountIdString != null) {
tuskyAccountId = accountIdString.toLong()
}
}
val accountRequested = tuskyAccountId != -1L
if (accountRequested && tuskyAccountId != activeAccount.id) {
accountManager.setActiveAccount(tuskyAccountId)
}
val openDrafts = intent.getBooleanExtra(OPEN_DRAFTS, false)
if (canHandleMimeType(intent.type) || intent.hasExtra(COMPOSE_OPTIONS)) {
// Sharing to Tusky from an external app
if (accountRequested) {
// The correct account is already active
forwardToComposeActivity(intent)
} else {
// No account was provided, show the chooser
showAccountChooserDialog(
getString(R.string.action_share_as),
true,
object : AccountSelectionListener {
override fun onAccountSelected(account: AccountEntity) {
val requestedId = account.id
if (requestedId == activeAccount.id) {
// The correct account is already active
forwardToComposeActivity(intent)
} else {
// A different account was requested, restart the activity
intent.putExtra(TUSKY_ACCOUNT_ID, requestedId)
changeAccount(requestedId, intent)
}
}
}
)
}
} else if (openDrafts) {
val draftsIntent = DraftsActivity.newIntent(this)
startActivity(draftsIntent)
} else if (accountRequested && intent.hasExtra(NOTIFICATION_TYPE)) {
// user clicked a notification, show follow requests for type FOLLOW_REQUEST,
// otherwise show notification tab
if (intent.getStringExtra(NOTIFICATION_TYPE) == Notification.Type.FOLLOW_REQUEST.name) {
val accountListIntent = AccountListActivity.newIntent(
this,
AccountListActivity.Type.FOLLOW_REQUESTS
)
startActivityWithSlideInAnimation(accountListIntent)
} else {
return true
}
}
return false
}
private fun showDirectMessageBadge(showBadge: Boolean) {
directMessageTab?.let { tab ->
tab.badge?.isVisible = showBadge