From 329e3da1c0f57df5747f23b9bda3d6143c0f3822 Mon Sep 17 00:00:00 2001 From: Zachary Wander Date: Wed, 17 Jan 2024 23:24:14 -0500 Subject: [PATCH 1/2] feat: add Mastodon Redirect support and "Open Link" share target --- app/src/main/AndroidManifest.xml | 34 +++++++++++++++---- app/src/main/java/app/pachli/MainActivity.kt | 16 +++++++++ .../components/view/ViewLinkActivity.kt | 26 ++++++++++++++ app/src/main/res/values/strings.xml | 2 ++ .../core/activity/BottomSheetActivity.kt | 6 ++-- .../app/pachli/core/activity/LinkHelper.kt | 18 ++++++---- .../core/activity/BottomSheetActivityTest.kt | 2 +- .../src/main/res/values/styles.xml | 13 +++++++ 8 files changed, 102 insertions(+), 15 deletions(-) create mode 100644 app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index ed559231b..f9563f811 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -58,44 +58,45 @@ - + - + - + - + - + - + @@ -103,10 +104,31 @@ + + + + + + + + + + + + + + + + + + viewUrl(url, PostLookupFallbackBehavior.OPEN_IN_BROWSER) + } + } + } + companion object { private const val DRAWER_ITEM_ADD_ACCOUNT: Long = -13 private const val DRAWER_ITEM_ANNOUNCEMENTS: Long = 14 diff --git a/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt b/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt new file mode 100644 index 000000000..e0bcb4364 --- /dev/null +++ b/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt @@ -0,0 +1,26 @@ +package app.pachli.components.view + +import android.content.Intent +import android.net.Uri +import android.os.Bundle +import app.pachli.BaseActivity +import app.pachli.core.navigation.MainActivityIntent +import dagger.hilt.android.AndroidEntryPoint + +@AndroidEntryPoint +class ViewLinkActivity : BaseActivity() { + override fun onCreate(savedInstanceState: Bundle?) { + super.onCreate(savedInstanceState) + + if (intent?.action == Intent.ACTION_SEND) { + val link = intent.getStringExtra(Intent.EXTRA_TEXT) + + val launchIntent = MainActivityIntent(this) + launchIntent.action = "dev.zwander.mastodonredirect.intent.action.OPEN_FEDI_LINK" + launchIntent.data = link?.let { Uri.parse(it) } + + startActivity(launchIntent) + finish() + } + } +} diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 04e1ecaee..ac522f3fd 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -716,4 +716,6 @@ validating nodeinfo %1$s failed: %2$s fetching /api/v1/instance failed: %1$s parsing server capabilities failed: %1$s + + Open Link diff --git a/core/activity/src/main/kotlin/app/pachli/core/activity/BottomSheetActivity.kt b/core/activity/src/main/kotlin/app/pachli/core/activity/BottomSheetActivity.kt index 1ee6d58de..e77fbc8ff 100644 --- a/core/activity/src/main/kotlin/app/pachli/core/activity/BottomSheetActivity.kt +++ b/core/activity/src/main/kotlin/app/pachli/core/activity/BottomSheetActivity.kt @@ -118,6 +118,7 @@ abstract class BottomSheetActivity : BaseActivity() { when (fallbackBehavior) { PostLookupFallbackBehavior.OPEN_IN_BROWSER -> openLink(url) PostLookupFallbackBehavior.DISPLAY_ERROR -> Toast.makeText(this, getString(R.string.post_lookup_error_format, url), Toast.LENGTH_SHORT).show() + PostLookupFallbackBehavior.OPEN_IN_BROWSER_FORCED -> openLink(url, true) } } @@ -151,8 +152,8 @@ abstract class BottomSheetActivity : BaseActivity() { } @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) - open fun openLink(url: String) { - (this as Context).openLink(url) + open fun openLink(url: String, forceBrowser: Boolean = false) { + (this as Context).openLink(url, forceBrowser) } private fun showQuerySheet() { @@ -217,4 +218,5 @@ abstract class BottomSheetActivity : BaseActivity() { enum class PostLookupFallbackBehavior { OPEN_IN_BROWSER, DISPLAY_ERROR, + OPEN_IN_BROWSER_FORCED, } diff --git a/core/activity/src/main/kotlin/app/pachli/core/activity/LinkHelper.kt b/core/activity/src/main/kotlin/app/pachli/core/activity/LinkHelper.kt index c80ab99c2..ba09d659f 100644 --- a/core/activity/src/main/kotlin/app/pachli/core/activity/LinkHelper.kt +++ b/core/activity/src/main/kotlin/app/pachli/core/activity/LinkHelper.kt @@ -37,7 +37,7 @@ import timber.log.Timber * @param uri the uri to open * @param context context */ -fun openLinkInCustomTab(uri: Uri, context: Context) { +fun openLinkInCustomTab(uri: Uri, context: Context, forceBrowser: Boolean = false) { val toolbarColor = MaterialColors.getColor(context, com.google.android.material.R.attr.colorSurface, Color.BLACK) val navigationbarColor = MaterialColors.getColor(context, android.R.attr.navigationBarColor, Color.BLACK) val navigationbarDividerColor = MaterialColors.getColor(context, com.google.android.material.R.attr.dividerColor, Color.BLACK) @@ -55,7 +55,7 @@ fun openLinkInCustomTab(uri: Uri, context: Context) { customTabsIntent.launchUrl(context, uri) } catch (e: ActivityNotFoundException) { Timber.w("Activity was not found for intent $customTabsIntent") - openLinkInBrowser(uri, context) + openLinkInBrowser(uri, context, forceBrowser) } } @@ -65,8 +65,14 @@ fun openLinkInCustomTab(uri: Uri, context: Context) { * @param uri the uri to open * @param context context */ -private fun openLinkInBrowser(uri: Uri?, context: Context) { +private fun openLinkInBrowser(uri: Uri?, context: Context, forceBrowser: Boolean = false) { val intent = Intent(Intent.ACTION_VIEW, uri) + + if (forceBrowser) { + // Forces the link to open in the browser instead of another deep-linked app. + intent.selector = Intent(Intent.ACTION_VIEW, Uri.parse("https://")) + } + try { context.startActivity(intent) } catch (e: ActivityNotFoundException) { @@ -80,13 +86,13 @@ private fun openLinkInBrowser(uri: Uri?, context: Context) { * @receiver the Context to open the link from * @param url a string containing the url to open */ -fun Context.openLink(url: String) { +fun Context.openLink(url: String, forceBrowser: Boolean = false) { val uri = url.toUri().normalizeScheme() val useCustomTabs = PreferenceManager.getDefaultSharedPreferences(this).getBoolean(PrefKeys.CUSTOM_TABS, false) if (useCustomTabs) { - openLinkInCustomTab(uri, this) + openLinkInCustomTab(uri, this, forceBrowser) } else { - openLinkInBrowser(uri, this) + openLinkInBrowser(uri, this, forceBrowser) } } diff --git a/core/activity/src/test/kotlin/app/pachli/core/activity/BottomSheetActivityTest.kt b/core/activity/src/test/kotlin/app/pachli/core/activity/BottomSheetActivityTest.kt index 372ec88da..5fe9ae830 100644 --- a/core/activity/src/test/kotlin/app/pachli/core/activity/BottomSheetActivityTest.kt +++ b/core/activity/src/test/kotlin/app/pachli/core/activity/BottomSheetActivityTest.kt @@ -259,7 +259,7 @@ class BottomSheetActivityTest { bottomSheet = mock() } - override fun openLink(url: String) { + override fun openLink(url: String, forceBrowser: Boolean) { this.link = url } diff --git a/core/designsystem/src/main/res/values/styles.xml b/core/designsystem/src/main/res/values/styles.xml index 47cb93e78..e2bd49cee 100644 --- a/core/designsystem/src/main/res/values/styles.xml +++ b/core/designsystem/src/main/res/values/styles.xml @@ -181,4 +181,17 @@ + + From 6521f0502d2bc2cb52e79f00ec47e6a9cacaed3f Mon Sep 17 00:00:00 2001 From: Nik Clayton Date: Fri, 23 Feb 2024 14:34:20 +0100 Subject: [PATCH 2/2] Update app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt --- .../main/java/app/pachli/components/view/ViewLinkActivity.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt b/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt index e0bcb4364..395c9b33e 100644 --- a/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt +++ b/app/src/main/java/app/pachli/components/view/ViewLinkActivity.kt @@ -3,7 +3,7 @@ package app.pachli.components.view import android.content.Intent import android.net.Uri import android.os.Bundle -import app.pachli.BaseActivity +import app.pachli.core.activity.BaseActivity import app.pachli.core.navigation.MainActivityIntent import dagger.hilt.android.AndroidEntryPoint