diff --git a/app/src/main/java/at/bitfire/icsdroid/MainActivity.kt b/app/src/main/java/at/bitfire/icsdroid/MainActivity.kt index 71878dff..5f366de8 100644 --- a/app/src/main/java/at/bitfire/icsdroid/MainActivity.kt +++ b/app/src/main/java/at/bitfire/icsdroid/MainActivity.kt @@ -21,7 +21,7 @@ class MainActivity : AppCompatActivity() { super.onCreate(savedInstanceState) setContentThemed { - MainApp(savedInstanceState, intent.extras, ::finish) + MainApp(savedInstanceState, intent, ::finish) } } diff --git a/app/src/main/java/at/bitfire/icsdroid/ui/nav/Destination.kt b/app/src/main/java/at/bitfire/icsdroid/ui/nav/Destination.kt index 04c330d3..ead7fd65 100644 --- a/app/src/main/java/at/bitfire/icsdroid/ui/nav/Destination.kt +++ b/app/src/main/java/at/bitfire/icsdroid/ui/nav/Destination.kt @@ -17,5 +17,6 @@ sealed interface Destination : NavKey { data class AddSubscription( val title: String? = null, @param:ColorInt val color: Int? = null, + val url: String? = null, ): Destination } diff --git a/app/src/main/java/at/bitfire/icsdroid/ui/nav/MainApp.kt b/app/src/main/java/at/bitfire/icsdroid/ui/nav/MainApp.kt index 16440f79..16aa39be 100644 --- a/app/src/main/java/at/bitfire/icsdroid/ui/nav/MainApp.kt +++ b/app/src/main/java/at/bitfire/icsdroid/ui/nav/MainApp.kt @@ -9,11 +9,11 @@ import android.content.Intent import android.net.Uri import android.os.Bundle import androidx.compose.runtime.Composable -import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.setValue +import androidx.core.content.IntentCompat import androidx.core.os.BundleCompat import androidx.lifecycle.viewmodel.navigation3.rememberViewModelStoreNavEntryDecorator import androidx.navigation3.runtime.entry @@ -32,15 +32,30 @@ import at.bitfire.icsdroid.ui.screen.SubscriptionsScreen import java.util.ServiceLoader /** - * Computes the correct initial destination from some intent extras: + * Computes the correct initial destination from some intent: * - If [AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE] is present -> [Destination.AddSubscription] * - Otherwise: [Destination.SubscriptionList] */ -private fun calculateInitialDestination(intentExtras: Bundle?): Destination { - return if (intentExtras?.containsKey(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE) == true) { +private fun calculateInitialDestination(intent: Intent): Destination { + val extras = intent.extras ?: Bundle.EMPTY + val text = extras.getString(Intent.EXTRA_TEXT) + ?.trim() + ?.takeUnless { it.isEmpty() } + val stream = BundleCompat.getParcelable(extras, Intent.EXTRA_STREAM, Uri::class.java) + ?.toString() + val data = intent.dataString + + return if (extras.containsKey(AccountManager.KEY_ACCOUNT_AUTHENTICATOR_RESPONSE)) { // If KEY_ACCOUNT_AUTHENTICATOR_RESPONSE was given, intent was launched from authenticator, // open the add subscription screen Destination.AddSubscription() + } else if (text != null || stream != null || data != null) { + // If a URL was given, open the add subscription screen + Destination.AddSubscription( + title = extras.getString("title"), + color = extras.takeIf { it.containsKey("color") }?.getInt("color", -1), + url = text ?: stream ?: data + ) } else { // If no condition matches, show the subscriptions list Destination.SubscriptionList @@ -50,20 +65,20 @@ private fun calculateInitialDestination(intentExtras: Bundle?): Destination { @Composable fun MainApp( savedInstanceState: Bundle?, - intentExtras: Bundle?, + intent: Intent, onFinish: () -> Unit, ) { // If EXTRA_PERMISSION is true, request the calendar permissions - val requestPermissions = intentExtras?.getBoolean(EXTRA_REQUEST_CALENDAR_PERMISSION, false) == true + val requestPermissions = intent.getBooleanExtra(EXTRA_REQUEST_CALENDAR_PERMISSION, false) // show error message from calling intent, if available var showingErrorMessage by remember { - mutableStateOf(savedInstanceState == null && intentExtras?.containsKey(EXTRA_ERROR_MESSAGE) == true) + mutableStateOf(savedInstanceState == null && intent.hasExtra(EXTRA_ERROR_MESSAGE)) } - if (showingErrorMessage && intentExtras != null) { + if (showingErrorMessage) { AlertDialog( - intentExtras.getString(EXTRA_ERROR_MESSAGE)!!, - BundleCompat.getSerializable(intentExtras, EXTRA_THROWABLE, Throwable::class.java) + intent.getStringExtra(EXTRA_ERROR_MESSAGE)!!, + IntentCompat.getSerializableExtra(intent, EXTRA_THROWABLE, Throwable::class.java) ) { showingErrorMessage = false } } @@ -75,7 +90,7 @@ fun MainApp( if (show) service.Content() } - val backStack = rememberNavBackStack(calculateInitialDestination(intentExtras)) + val backStack = rememberNavBackStack(calculateInitialDestination(intent)) fun goBack(depth: Int = 1) { if (backStack.size <= 1) onFinish() @@ -98,22 +113,10 @@ fun MainApp( ) } entry { destination -> - var url: String? = null - LaunchedEffect(intentExtras) { - if (intentExtras != null) { - intentExtras.getString(Intent.EXTRA_TEXT) - ?.trim() - ?.let { url = it } - BundleCompat.getParcelable(intentExtras, Intent.EXTRA_STREAM, Uri::class.java) - ?.toString() - ?.let { url = it } - } - } - AddSubscriptionScreen( title = destination.title, color = destination.color, - url = url, + url = destination.url, onBackRequested = { goBack() } ) }