From f5ad39946ee251b7f359ec619c3cbd48397db8fa Mon Sep 17 00:00:00 2001 From: Konrad Pozniak Date: Fri, 28 Jun 2024 17:36:31 +0200 Subject: [PATCH] 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) --- .../com/keylesspalace/tusky/MainActivity.kt | 157 ++++++++++-------- 1 file changed, 89 insertions(+), 68 deletions(-) diff --git a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt index c572b9fae..894757a79 100644 --- a/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt +++ b/app/src/main/java/com/keylesspalace/tusky/MainActivity.kt @@ -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