aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/web
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-07-16 17:26:58 -0700
committerGitHub <noreply@github.com>2017-07-16 17:26:58 -0700
commitd90cb9b61cd2e033b46f4780ad1340c5f35b7751 (patch)
tree0294ce22bacb463c9cc95de8dc5581c1bd59a108 /app/src/main/kotlin/com/pitchedapps/frost/web
parentc3f1fc6a8b3216442a018bb04843dfa68d738918 (diff)
downloadfrost-d90cb9b61cd2e033b46f4780ad1340c5f35b7751.tar.gz
frost-d90cb9b61cd2e033b46f4780ad1340c5f35b7751.tar.bz2
frost-d90cb9b61cd2e033b46f4780ad1340c5f35b7751.zip
Add image viewing and downloading (#63)v1.3
* Commence aggressive image caching * Add glide toggle and css url parsing * Add image hook and refractor activities * Update version analytics * Implemented imageactivity but glide will not load * Create working image loader * Finalize image view * Finalize image view logic * Remove custom cache experiment
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/web')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt31
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt67
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt2
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt18
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt4
9 files changed, 148 insertions, 40 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
new file mode 100644
index 00000000..09241254
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
@@ -0,0 +1,16 @@
+package com.pitchedapps.frost.web
+
+import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
+import android.webkit.WebView
+import android.webkit.WebViewClient
+
+/**
+ * Created by Allan Wang on 2017-07-13.
+ */
+open class BaseWebViewClient : WebViewClient() {
+
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = shouldFrostInterceptRequest(view, request)
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
index aab3a165..4df6d6a7 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
@@ -1,9 +1,10 @@
package com.pitchedapps.frost.web
import android.net.Uri
-import android.os.Message
-import android.view.View
-import android.webkit.*
+import android.webkit.ConsoleMessage
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
+import android.webkit.WebView
import ca.allanwang.kau.utils.snackbar
import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.utils.L
@@ -20,9 +21,16 @@ class FrostChromeClient(webCore: FrostWebViewCore) : WebChromeClient() {
val titleObservable: BehaviorSubject<String> = webCore.titleObservable
val activityContract = (webCore.context as? ActivityWebContract)
+ companion object {
+ val consoleBlacklist = setOf(
+ "edge-chat"
+ )
+ }
+
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
+ if (consoleBlacklist.any { consoleMessage.message().contains(it) }) return true
L.i("Chrome Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
- return super.onConsoleMessage(consoleMessage)
+ return true
}
override fun onReceivedTitle(view: WebView, title: String) {
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 3340e7d2..3f976fb8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt
@@ -2,8 +2,9 @@ package com.pitchedapps.frost.web
import android.content.Context
import android.webkit.JavascriptInterface
-import ca.allanwang.kau.logging.KL
-import com.pitchedapps.frost.MainActivity
+import ca.allanwang.kau.utils.startActivity
+import com.pitchedapps.frost.activities.ImageActivity
+import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.dbflow.CookieModel
import com.pitchedapps.frost.facebook.formattedFbUrl
import com.pitchedapps.frost.utils.*
@@ -13,12 +14,18 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-06-01.
*/
-class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
+class FrostJSI(val webView: FrostWebViewCore) {
- val headerObservable: Subject<String>? = (context as? MainActivity)?.headerBadgeObservable
+ val context: Context
+ get() = webView.context
+
+ val activity: MainActivity?
+ get() = (context as? MainActivity)
+
+ val headerObservable: Subject<String>? = activity?.headerBadgeObservable
val cookies: ArrayList<CookieModel>
- get() = (context as? MainActivity)?.cookies() ?: arrayListOf()
+ get() = activity?.cookies() ?: arrayListOf()
@JavascriptInterface
fun loadUrl(url: String) {
@@ -35,8 +42,8 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
}
@JavascriptInterface
- fun contextMenu(url: String, text: String) {
- webView.post { webView.context.showWebContextMenu(WebContext(url.formattedFbUrl, text)) }
+ fun contextMenu(url: String, text: String?) {
+ webView.post { context.showWebContextMenu(WebContext(url.formattedFbUrl, text)) }
}
/**
@@ -45,7 +52,7 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
*/
@JavascriptInterface
fun longClick(start: Boolean) {
- (webView.context as? MainActivity)?.viewPager?.enableSwipe = !start
+ activity?.viewPager?.enableSwipe = !start
}
@JavascriptInterface
@@ -53,6 +60,14 @@ class FrostJSI(val context: Context, val webView: FrostWebViewCore) {
context.launchLogin(cookies, true)
}
+ /**
+ * Launch image overlay
+ */
+ @JavascriptInterface
+ fun loadImage(imageUrl: String, text: String?) {
+ context.launchImageActivity(imageUrl, text)
+ }
+
@JavascriptInterface
fun emit(flag: Int) {
webView.post { webView.frostWebClient.emit(flag) }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
new file mode 100644
index 00000000..45dc83aa
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
@@ -0,0 +1,67 @@
+package com.pitchedapps.frost.web
+
+import android.graphics.Bitmap.CompressFormat
+import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
+import android.webkit.WebView
+import ca.allanwang.kau.utils.use
+import com.pitchedapps.frost.utils.GlideApp
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.Prefs
+import okhttp3.HttpUrl
+import java.io.ByteArrayInputStream
+import java.io.ByteArrayOutputStream
+import java.io.InputStream
+
+
+/**
+ * Created by Allan Wang on 2017-07-13.
+ *
+ * Handler to decide when a request should be done by us
+ * This is the crux of Frost's optimizations for the web browser
+ */
+val blankResource: WebResourceResponse by lazy { WebResourceResponse("text/plain", "utf-8", ByteArrayInputStream("".toByteArray())) }
+
+//these hosts will redirect to a blank resource
+val blacklistHost: Set<String> by lazy {
+ setOf(
+ "edge-chat.facebook.com"
+ )
+}
+
+//these hosts will return null and skip logging
+val whitelistHost: Set<String> by lazy {
+ setOf(
+ "static.xx.fbcdn.net",
+ "m.facebook.com",
+ "touch.facebook.com"
+ )
+}
+
+//these hosts will skip ad inspection
+//this list does not have to include anything from the two above
+val adWhitelistHost: Set<String> by lazy {
+ setOf(
+ "scontent-sea1-1.xx.fbcdn.net"
+ )
+}
+
+var adblock: Set<String>? = null
+
+fun shouldFrostInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse? {
+ val httpUrl = HttpUrl.parse(request.url?.toString() ?: return null) ?: return null
+ val host = httpUrl.host()
+ val url = httpUrl.toString()
+ if (blacklistHost.contains(host)) return blankResource
+ if (whitelistHost.contains(host)) return null
+ if (!adWhitelistHost.contains(host)) {
+ if (adblock == null) adblock = view.context.assets.open("adblock.txt").bufferedReader().use { it.readLines().toSet() }
+ if (adblock?.any { url.contains(it) } ?: false) return blankResource
+ }
+ L.v("Intercept Request ${host} ${url}")
+ return null
+}
+
+fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse?
+ = this ?: if (request.url.path.endsWith(".css")) blankResource else null
+
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
index 7c0a6597..e7dae22a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebView.kt
@@ -69,7 +69,7 @@ class FrostWebView @JvmOverloads constructor(
frostWebClient = baseEnum?.webClient?.invoke(this) ?: FrostWebViewClient(this)
webViewClient = frostWebClient
webChromeClient = FrostChromeClient(this)
- addJavascriptInterface(FrostJSI(context, this), "Frost")
+ addJavascriptInterface(FrostJSI(this), "Frost")
setBackgroundColor(Color.TRANSPARENT)
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
index 5e5dc597..5b2b4bfd 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -4,10 +4,9 @@ import android.content.Context
import android.graphics.Bitmap
import android.webkit.WebResourceRequest
import android.webkit.WebView
-import android.webkit.WebViewClient
-import com.pitchedapps.frost.LoginActivity
-import com.pitchedapps.frost.MainActivity
-import com.pitchedapps.frost.SelectorActivity
+import com.pitchedapps.frost.activities.LoginActivity
+import com.pitchedapps.frost.activities.MainActivity
+import com.pitchedapps.frost.activities.SelectorActivity
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.injectors.*
@@ -17,7 +16,7 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-05-31.
*/
-open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
+open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient() {
val refreshObservable: Subject<Boolean> = webCore.refreshObservable
@@ -97,15 +96,9 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
return super.shouldOverrideUrlLoading(view, request)
}
- override fun onPageCommitVisible(view: WebView?, url: String?) {
- L.d("ASDF PCV")
- super.onPageCommitVisible(view, url)
- }
-
-// override fun onLoadResource(view: WebView, url: String) {
-// L.v("Load resource $url")
-// super.onLoadResource(view, url)
+// override fun onPageCommitVisible(view: WebView?, url: String?) {
+// L.d("ASDF PCV")
+// super.onPageCommitVisible(view, url)
// }
-
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
index 1e023dca..d96fba55 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewCore.kt
@@ -72,7 +72,7 @@ class FrostWebViewCore @JvmOverloads constructor(
dispose = refreshObservable.subscribeOn(AndroidSchedulers.mainThread()).subscribe {
if (it) {
loading = true
- if (isVisible()) fadeOut(duration = 200L)
+ if (isVisible) fadeOut(duration = 200L)
} else if (loading) {
dispose?.dispose()
if (animate && Prefs.animate) circularReveal(offset = 150L)
@@ -148,11 +148,12 @@ class FrostWebViewCore @JvmOverloads constructor(
if (scrollY > 10000) {
scrollTo(0, 0)
} else {
- val animator = ValueAnimator.ofInt(scrollY, 0)
- animator.duration = Math.min(scrollY, 500).toLong()
- animator.interpolator = DecelerateInterpolator()
- animator.addUpdateListener { scrollY = it.animatedValue as Int }
- animator.start()
+ ValueAnimator.ofInt(scrollY, 0).apply {
+ duration = Math.min(scrollY, 500).toLong()
+ interpolator = DecelerateInterpolator()
+ addUpdateListener { scrollY = it.animatedValue as Int }
+ start()
+ }
}
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
index b3b1cfe5..bcadf32a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
@@ -3,9 +3,7 @@ package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
-import android.webkit.JavascriptInterface
-import android.webkit.WebView
-import android.webkit.WebViewClient
+import android.webkit.*
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.utils.gone
import com.pitchedapps.frost.facebook.FbTab
@@ -56,7 +54,8 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_BASIC
setLayerType(View.LAYER_TYPE_HARDWARE, null)
- webViewClient = FrostWebViewClientSearch()
+ webViewClient = SearchWebViewClient()
+ webChromeClient = SearchChromeClient()
addJavascriptInterface(SearchJSI(), "Frost")
searchSubject.debounce(300, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
.map {
@@ -111,13 +110,22 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
*
* Barebones client that does what [FrostWebViewSearch] needs
*/
- inner class FrostWebViewClientSearch : WebViewClient() {
+ inner class SearchWebViewClient : BaseWebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
L.i("Search Page finished $url")
view.jsInject(JsAssets.SEARCH)
}
+
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = super.shouldInterceptRequest(view, request).filterCss(request)
+ }
+
+ class SearchChromeClient : WebChromeClient() {
+
+ //mute console
+ override fun onConsoleMessage(consoleMessage: ConsoleMessage) = true
}
inner class SearchJSI {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
index 38d4ad8c..d7a2db0a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/LoginWebView.kt
@@ -66,7 +66,7 @@ class LoginWebView @JvmOverloads constructor(
}
- inner class LoginClient : WebViewClient() {
+ inner class LoginClient : BaseWebViewClient() {
override fun onPageFinished(view: WebView, url: String) {
super.onPageFinished(view, url)
@@ -88,7 +88,7 @@ class LoginWebView @JvmOverloads constructor(
inner class LoginChromeClient : WebChromeClient() {
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
L.d("Login Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
- return super.onConsoleMessage(consoleMessage)
+ return true
}
override fun onProgressChanged(view: WebView, newProgress: Int) {