From 5a6bf455cb2e550c18f94d8aeaaa91c2260cb75a Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Wed, 15 Nov 2017 02:47:13 -0500 Subject: Fix/bad overlay (#490) * Fix intent launching * Add some tests and update kotlin --- app/src/main/assets/js/context_a.js | 1 - app/src/main/assets/js/context_a.min.js | 3 +-- .../kotlin/com/pitchedapps/frost/utils/Utils.kt | 23 +++++++++++++++--- .../kotlin/com/pitchedapps/frost/web/FrostJSI.kt | 1 + .../frost/web/FrostUrlOverlayValidator.kt | 7 ++++-- .../pitchedapps/frost/web/FrostWebViewClients.kt | 14 +++++------ app/src/main/res/xml/frost_changelog.xml | 10 ++++++-- .../kotlin/com/pitchedapps/frost/utils/UrlTests.kt | 27 ++++++++++++++++++++++ 8 files changed, 69 insertions(+), 17 deletions(-) create mode 100644 app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt (limited to 'app/src') diff --git a/app/src/main/assets/js/context_a.js b/app/src/main/assets/js/context_a.js index 260d5506..dfc75a80 100644 --- a/app/src/main/assets/js/context_a.js +++ b/app/src/main/assets/js/context_a.js @@ -48,7 +48,6 @@ if (!window.hasOwnProperty('frost_context_a')) { return; } - if (url.includes('photoset_token')) return; console.log('Context Content', url, text); if (typeof Frost !== 'undefined') Frost.contextMenu(url, text); diff --git a/app/src/main/assets/js/context_a.min.js b/app/src/main/assets/js/context_a.min.js index e3127cdc..260b41ff 100644 --- a/app/src/main/assets/js/context_a.min.js +++ b/app/src/main/assets/js/context_a.min.js @@ -24,8 +24,7 @@ var l=i.src e.stopPropagation(), void e.preventDefault() } -if(o.includes("photoset_token"))return -;console.log("Context Content",o,n),"undefined"!=typeof Frost&&Frost.contextMenu(o,n), +console.log("Context Content",o,n),"undefined"!=typeof Frost&&Frost.contextMenu(o,n), e.stopPropagation(), e.preventDefault() } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt index c644499e..082f4758 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/utils/Utils.kt @@ -1,5 +1,6 @@ package com.pitchedapps.frost.utils +import android.annotation.SuppressLint import android.app.Activity import android.content.Context import android.content.Intent @@ -163,6 +164,7 @@ fun Activity.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = fun View.frostSnackbar(@StringRes text: Int, builder: Snackbar.() -> Unit = {}) = snackbar(text, Snackbar.LENGTH_LONG, frostSnackbar(builder)) +@SuppressLint("RestrictedApi") private inline fun frostSnackbar(crossinline builder: Snackbar.() -> Unit): Snackbar.() -> Unit = { builder() //hacky workaround, but it has proper checks and shouldn't crash @@ -191,18 +193,33 @@ fun Context.createPrivateMediaFile(extension: String) = createPrivateMediaFile(" * @returns {@code true} if activity is resolved, {@code false} otherwise */ fun Context.resolveActivityForUri(uri: Uri): Boolean { - if (uri.toString().isFacebookUrl && !uri.toString().contains("intent:")) return false //ignore response as we will be triggering ourself val intent = Intent(Intent.ACTION_VIEW, uri) if (intent.resolveActivity(packageManager) == null) return false startActivity(intent) return true } +/** + * [true] if url contains [FACEBOOK_COM] + */ inline val String?.isFacebookUrl - get() = this != null && this.contains(FACEBOOK_COM) + get() = this != null && contains(FACEBOOK_COM) +/** + * [true] is url is a video and can be accepted by VideoViewer + */ inline val String?.isVideoUrl - get() = this != null && (this.startsWith(VIDEO_REDIRECT) || this.startsWith("https://video-")) + get() = this != null && (startsWith(VIDEO_REDIRECT) || startsWith("https://video-")) + +/** + * [true] is url can be displayed in a different webview + */ +inline val String?.isIndependent + get() = this == null || (startsWith("http") && !isFacebookUrl) + || !contains("photoset_token") + +inline val String?.isExplicitIntent + get() = this != null && startsWith("intent://") fun Context.frostChangelog() = showChangelog(R.xml.frost_changelog, Prefs.textColor) { theme() diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt index 9941c90c..6bdb459e 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt @@ -56,6 +56,7 @@ class FrostJSI(val webView: FrostWebViewCore) { @JavascriptInterface fun contextMenu(url: String, text: String?) { + if (!text.isIndependent) return //url will be formatted through webcontext webView.post { context.showWebContextMenu(WebContext(url, text)) } } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt index e8f9fee9..d1f144a6 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostUrlOverlayValidator.kt @@ -18,7 +18,7 @@ import org.jetbrains.anko.runOnUiThread * cannot be resolved on a new window and must instead * by loaded in the current page * This helper method will collect all known cases and launch the overlay accordingly - * Returns {@code true} (default) if action is consumed, {@code false} otherwise + * Returns [true] (default) if action is consumed, [false] otherwise * * Note that this is not always called on the main thread! * UI related methods should always be posted or they may not be properly executed. @@ -28,7 +28,10 @@ import org.jetbrains.anko.runOnUiThread * as we have no need of sending a new intent to the same activity */ fun FrostWebViewCore.requestWebOverlay(url: String): Boolean { - if (url == "#") return false + if (url == "#" || !url.isIndependent) { + L.i("Forbid overlay switch", url) + return false + } if (url.isVideoUrl && context is VideoViewHolder) { L.i("Found video", url) context.runOnUiThread { (context as VideoViewHolder).showVideo(url) } diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt index c8c7e2e7..67881ada 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt @@ -144,15 +144,15 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient L.i("Url Loading", request.url?.toString()) val path = request.url?.path ?: return super.shouldOverrideUrlLoading(view, request) L.v("Url Loading Path", path) - request.url?.toString()?.apply { - if (contains("intent") && contains("com.facebook")) { - L.i("Skip facebook intent request") - return true - } + val url = request.url.toString() + if (url.isExplicitIntent) { + if (!url.contains("com.facebook")) + view.context.resolveActivityForUri(request.url) + return true } if (path.startsWith("/composer/")) return launchRequest(request) - if (request.url.toString().contains("scontent-sea1-1.xx.fbcdn.net") && (path.endsWith(".jpg") || path.endsWith(".png"))) - return launchImage(request.url.toString()) + if (url.contains("scontent-sea1-1.xx.fbcdn.net") && (path.endsWith(".jpg") || path.endsWith(".png"))) + return launchImage(url) if (Prefs.linksInDefaultApp && view.context.resolveActivityForUri(request.url)) return true return super.shouldOverrideUrlLoading(view, request) } diff --git a/app/src/main/res/xml/frost_changelog.xml b/app/src/main/res/xml/frost_changelog.xml index c9c30dbb..f583cd82 100644 --- a/app/src/main/res/xml/frost_changelog.xml +++ b/app/src/main/res/xml/frost_changelog.xml @@ -6,13 +6,19 @@ --> - + - + + + + + + + diff --git a/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt new file mode 100644 index 00000000..4062cf98 --- /dev/null +++ b/app/src/test/kotlin/com/pitchedapps/frost/utils/UrlTests.kt @@ -0,0 +1,27 @@ +package com.pitchedapps.frost.utils + +import com.pitchedapps.frost.facebook.FACEBOOK_COM +import org.junit.Test +import kotlin.test.assertFalse +import kotlin.test.assertTrue + +/** + * Created by Allan Wang on 2017-11-15. + */ +class UrlTests { + + val GOOGLE = "https://www.google.ca" + + @Test + fun independence() { + assertTrue(GOOGLE.isIndependent, "google") + assertTrue(FACEBOOK_COM.isIndependent, "facebook") + assertFalse("#!/photos/viewer/?photoset_token=pcb.1234".isIndependent, "photo") + } + + @Test + fun isFacebook() { + assertFalse(GOOGLE.isFacebookUrl, "google") + assertTrue(FACEBOOK_COM.isFacebookUrl, "facebook") + } +} \ No newline at end of file -- cgit v1.2.3