aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt1
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt43
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt (renamed from app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt)13
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt24
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt35
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt (renamed from app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt)76
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/MessageWebView.kt81
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/SearchWebView.kt (renamed from app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt)39
11 files changed, 229 insertions, 119 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
index ba76e594..1227fd6b 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/MainActivity.kt
@@ -55,7 +55,7 @@ import com.pitchedapps.frost.utils.*
import com.pitchedapps.frost.utils.iab.validatePro
import com.pitchedapps.frost.views.BadgedIcon
import com.pitchedapps.frost.views.FrostViewPager
-import com.pitchedapps.frost.web.FrostWebViewSearch
+import com.pitchedapps.frost.web.SearchWebView
import io.reactivex.android.schedulers.AndroidSchedulers
import io.reactivex.disposables.Disposable
import io.reactivex.schedulers.Schedulers
@@ -63,7 +63,7 @@ import io.reactivex.subjects.PublishSubject
import org.jsoup.Jsoup
import java.util.concurrent.TimeUnit
-class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract,
+class MainActivity : BaseActivity(), SearchWebView.SearchContract,
ActivityWebContract, FileChooserContract by FileChooserDelegate() {
lateinit var adapter: SectionsPagerAdapter
@@ -78,13 +78,13 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract,
var webFragmentObservable = PublishSubject.create<Int>()!!
var lastPosition = -1
val headerBadgeObservable = PublishSubject.create<String>()
- var hiddenSearchView: FrostWebViewSearch? = null
+ var hiddenSearchView: SearchWebView? = null
var firstLoadFinished = false
set(value) {
L.d("First fragment load has finished")
field = value
if (value && hiddenSearchView == null) {
- hiddenSearchView = FrostWebViewSearch(this, this)
+ hiddenSearchView = SearchWebView(this, this)
}
}
var searchView: SearchView? = null
@@ -354,7 +354,7 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract,
R.id.action_settings to GoogleMaterial.Icon.gmd_settings,
R.id.action_search to GoogleMaterial.Icon.gmd_search)
if (Prefs.searchBar) {
- if (firstLoadFinished && hiddenSearchView == null) hiddenSearchView = FrostWebViewSearch(this, this)
+ if (firstLoadFinished && hiddenSearchView == null) hiddenSearchView = SearchWebView(this, this)
if (searchView == null) searchView = bindSearchView(menu, R.id.action_search, Prefs.iconColor) {
textObserver = {
observable, _ ->
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
index 875f1c49..3b0125be 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/facebook/FbCookie.kt
@@ -94,12 +94,14 @@ object FbCookie {
* When coming back to the main app, switch back to our original account before continuing
*/
fun switchBackUser(callback: () -> Unit) {
- if (Prefs.prevId != -1L && Prefs.prevId != Prefs.userId) {
- switchUser(Prefs.prevId) {
- L.d("Switch back user", "${Prefs.userId} to ${Prefs.prevId}")
+ if (Prefs.prevId == -1L) return callback()
+ val prevId = Prefs.prevId
+ Prefs.prevId = -1L
+ if (prevId != Prefs.userId) {
+ switchUser(prevId) {
+ L.d("Switch back user", "${Prefs.userId} to ${prevId}")
callback()
}
} else callback()
- if (Prefs.prevId != -1L) Prefs.prevId = -1L
}
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
index 4c44c1bf..de270948 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/JsActions.kt
@@ -15,6 +15,7 @@ enum class JsActions(body: String) : InjectorContract {
*/
LOGIN_CHECK("document.getElementById('signup-button')&&Frost.loadLogin();"),
BASE_HREF("document.write(\"<base href='$FB_URL_BASE'/>\");"),
+ GET_MESSAGES("setTimeout(function(){Frost.handleHtml(document.getElementById('threadlist_rows').outerHtml)},1000)"),
EMPTY("");
val function = "!function(){$body}();"
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
index 38282bf7..ad977d1a 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/services/NotificationService.kt
@@ -17,7 +17,9 @@ import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import com.pitchedapps.frost.utils.frostAnswersCustom
+import com.pitchedapps.frost.web.MessageWebView
import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.uiThread
import org.jsoup.Jsoup
import org.jsoup.nodes.Element
import java.util.concurrent.Future
@@ -45,17 +47,29 @@ class NotificationService : JobService() {
return false
}
+
override fun onStartJob(params: JobParameters?): Boolean {
future = doAsync {
if (Prefs.notificationAllAccounts) {
- loadFbCookiesSync().forEach {
- data ->
- fetchNotifications(data)
- }
+ val cookies = loadFbCookiesSync()
+ cookies.forEach { fetchGeneralNotifications(it) }
+// if (Prefs.notificationsInstantMessages) {
+// Prefs.prevId = Prefs.userId
+// uiThread {
+// val messageWebView = MessageWebView(this@NotificationService, params)
+// cookies.forEach { messageWebView.request(it) }
+// }
+// return@doAsync
+// }
} else {
val currentCookie = loadFbCookie(Prefs.userId)
- if (currentCookie != null)
- fetchNotifications(currentCookie)
+ if (currentCookie != null) {
+ fetchGeneralNotifications(currentCookie)
+// if (Prefs.notificationsInstantMessages) {
+// uiThread { MessageWebView(this@NotificationService, params).request(currentCookie) }
+// return@doAsync
+// }
+ }
}
L.d("Finished notifications")
jobFinished(params, false)
@@ -69,12 +83,6 @@ class NotificationService : JobService() {
return null
}
- fun fetchNotifications(data: CookieModel) {
- fetchGeneralNotifications(data)
-// fetchMessageNotifications(data)
- debugNotification("Hello")
- }
-
fun fetchGeneralNotifications(data: CookieModel) {
L.i("Notif fetch for $data")
val doc = Jsoup.connect(FbTab.NOTIFICATIONS.url).cookie(FACEBOOK_COM, data.cookie).userAgent(USER_AGENT_BASIC).get()
@@ -96,7 +104,8 @@ class NotificationService : JobService() {
newLatestEpoch = notif.timestamp
notifCount++
}
- if (newLatestEpoch != prevLatestEpoch) prevNotifTime.copy(epoch = newLatestEpoch).update()
+ if (newLatestEpoch != prevLatestEpoch) prevNotifTime.copy(epoch = newLatestEpoch).save()
+ L.d("Notif new latest epoch ${lastNotificationTime(data.id).epoch}")
frostAnswersCustom("Notifications") {
putCustomAttribute("Type", "General")
putCustomAttribute("Count", notifCount)
@@ -120,10 +129,9 @@ class NotificationService : JobService() {
return NotificationContent(data, notifId.toInt(), a.attr("href"), null, text, epoch, pUrl)
}
- fun fetchMessageNotifications(data: CookieModel) {
- if (!Prefs.notificationsInstantMessages) return
+ fun fetchMessageNotifications(data: CookieModel, content: String) {
L.i("Notif IM fetch for $data")
- val doc = Jsoup.connect(FbTab.MESSAGES.url).cookie(FACEBOOK_COM, data.cookie).userAgent(USER_AGENT_BASIC).get()
+ val doc = Jsoup.parseBodyFragment(content)
val unreadNotifications = (doc.getElementById("threadlist_rows") ?: return L.eThrow("Notification messages not found")).getElementsByClass("aclb")
var notifCount = 0
L.d("IM notif count ${unreadNotifications.size}")
@@ -146,7 +154,8 @@ class NotificationService : JobService() {
newLatestEpoch = notif.timestamp
notifCount++
}
-// if (newLatestEpoch != prevLatestEpoch) prevNotifTime.copy(epochIm = newLatestEpoch).update()
+ if (newLatestEpoch != prevLatestEpoch) prevNotifTime.copy(epochIm = newLatestEpoch).save()
+ L.d("Notif new latest im epoch ${lastNotificationTime(data.id).epochIm}")
frostAnswersCustom("Notifications") {
putCustomAttribute("Type", "Message")
putCustomAttribute("Count", notifCount)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
deleted file mode 100644
index 09241254..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/BaseWebViewClient.kt
+++ /dev/null
@@ -1,16 +0,0 @@
-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/FrostChromeClients.kt
index 4df6d6a7..b8ba0d1d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
@@ -14,6 +14,19 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-05-31.
+ *
+ * Collection of chrome clients
+ */
+
+/**
+ * Nothing more than a client without logging
+ */
+class QuietChromeClient : WebChromeClient() {
+ override fun onConsoleMessage(consoleMessage: ConsoleMessage) = true
+}
+
+/**
+ * The default chrome client
*/
class FrostChromeClient(webCore: FrostWebViewCore) : WebChromeClient() {
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
index 45dc83aa..3f2891d0 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostRequestInterceptor.kt
@@ -1,17 +1,12 @@
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
/**
@@ -62,6 +57,23 @@ fun shouldFrostInterceptRequest(view: WebView, request: WebResourceRequest): Web
return null
}
+/**
+ * Wrapper to ensure that null exceptions are not reached
+ */
+fun WebResourceRequest.query(action: (url: String) -> Boolean): Boolean {
+ return action(url?.path ?: return false)
+}
+
+/**
+ * Generic filter passthrough
+ * If Resource is already nonnull, pass it, otherwise check if filter is met and override the response accordingly
+ */
+fun WebResourceResponse?.filter(request: WebResourceRequest, filter: (url: String) -> Boolean): WebResourceResponse?
+ = this ?: if (request.query { filter(it) }) blankResource else null
+
fun WebResourceResponse?.filterCss(request: WebResourceRequest): WebResourceResponse?
- = this ?: if (request.url.path.endsWith(".css")) blankResource else null
+ = filter(request) { it.endsWith(".css") }
+
+fun WebResourceResponse?.filterImage(request: WebResourceRequest): WebResourceResponse?
+ = filter(request) { it.contains(".jpg") || it.contains(".png") }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
deleted file mode 100644
index 10648e73..00000000
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClientMenu.kt
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.pitchedapps.frost.web
-
-import android.webkit.WebView
-import com.pitchedapps.frost.facebook.FB_URL_BASE
-import com.pitchedapps.frost.injectors.JsAssets
-import com.pitchedapps.frost.injectors.jsInject
-
-/**
- * Created by Allan Wang on 2017-05-31.
- */
-class FrostWebViewClientMenu(webCore: FrostWebViewCore) : FrostWebViewClient(webCore) {
-
- private val String.shouldInjectMenu
- get() = when (removePrefix(FB_URL_BASE)) {
- "settings",
- "settings#",
- "settings#!/settings?soft=bookmarks" -> true
- else -> false
- }
-
- override fun onPageFinished(view: WebView, url: String) {
- super.onPageFinished(view, url)
- if (url.shouldInjectMenu) jsInject(JsAssets.MENU)
- }
-
- override fun emit(flag: Int) {
- super.emit(flag)
- super.injectAndFinish()
- }
-
- override fun onPageFinishedActions(url: String) {
- if (!url.shouldInjectMenu) injectAndFinish()
- }
-
-} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
index 5b2b4bfd..3e6ddd06 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClients.kt
@@ -3,11 +3,14 @@ package com.pitchedapps.frost.web
import android.content.Context
import android.graphics.Bitmap
import android.webkit.WebResourceRequest
+import android.webkit.WebResourceResponse
import android.webkit.WebView
+import android.webkit.WebViewClient
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.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.injectors.*
import com.pitchedapps.frost.utils.*
@@ -15,6 +18,23 @@ import io.reactivex.subjects.Subject
/**
* Created by Allan Wang on 2017-05-31.
+ *
+ * Collection of webview clients
+ */
+
+/**
+ * The base of all webview clients
+ * Used to ensure that resources are properly intercepted
+ */
+open class BaseWebViewClient : WebViewClient() {
+
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = shouldFrostInterceptRequest(view, request)
+
+}
+
+/**
+ * The default webview client
*/
open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient() {
@@ -96,9 +116,57 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : BaseWebViewClient
return super.shouldOverrideUrlLoading(view, request)
}
-// override fun onPageCommitVisible(view: WebView?, url: String?) {
-// L.d("ASDF PCV")
-// super.onPageCommitVisible(view, url)
-// }
+}
+
+/**
+ * Client variant for the menu view
+ */
+class FrostWebViewClientMenu(webCore: FrostWebViewCore) : FrostWebViewClient(webCore) {
+
+ private val String.shouldInjectMenu
+ get() = when (removePrefix(FB_URL_BASE)) {
+ "settings",
+ "settings#",
+ "settings#!/settings?soft=bookmarks" -> true
+ else -> false
+ }
+
+ override fun onPageFinished(view: WebView, url: String) {
+ super.onPageFinished(view, url)
+ if (url.shouldInjectMenu) jsInject(JsAssets.MENU)
+ }
+
+ override fun emit(flag: Int) {
+ super.emit(flag)
+ super.injectAndFinish()
+ }
+
+ override fun onPageFinishedActions(url: String) {
+ if (!url.shouldInjectMenu) injectAndFinish()
+ }
+}
+
+/**
+ * Headless client that injects content after a page load
+ * The JSI is meant to handle everything else
+ */
+class HeadlessWebViewClient(val tag: String, val postInjection: InjectorContract) : BaseWebViewClient() {
+
+ override fun onPageStarted(view: WebView, url: String, favicon: Bitmap?) {
+ super.onPageStarted(view, url, favicon)
+ L.d("Headless Page $tag Started", url)
+ }
+
+ override fun onPageFinished(view: WebView, url: String) {
+ super.onPageFinished(view, url)
+ L.d("Headless Page $tag Finished", url)
+ postInjection.inject(view)
+ }
+
+ /**
+ * In addition to general filtration, we will also strip away css and images
+ */
+ override fun shouldInterceptRequest(view: WebView, request: WebResourceRequest): WebResourceResponse?
+ = super.shouldInterceptRequest(view, request).filterCss(request).filterImage(request)
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/MessageWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/MessageWebView.kt
new file mode 100644
index 00000000..0f3a12b6
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/MessageWebView.kt
@@ -0,0 +1,81 @@
+package com.pitchedapps.frost.web
+
+import android.annotation.SuppressLint
+import android.app.job.JobParameters
+import android.webkit.JavascriptInterface
+import android.webkit.WebView
+import ca.allanwang.kau.utils.gone
+import com.pitchedapps.frost.dbflow.CookieModel
+import com.pitchedapps.frost.facebook.FbCookie
+import com.pitchedapps.frost.facebook.FbTab
+import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
+import com.pitchedapps.frost.injectors.JsActions
+import com.pitchedapps.frost.services.NotificationService
+import com.pitchedapps.frost.utils.L
+import com.pitchedapps.frost.utils.frostAnswersCustom
+import org.jetbrains.anko.doAsync
+import org.jetbrains.anko.runOnUiThread
+
+@SuppressLint("ViewConstructor")
+/**
+ * Created by Allan Wang on 2017-07-17.
+ *
+ * Bare boned headless view made solely to extract conversation info
+ */
+class MessageWebView(val service: NotificationService, val params: JobParameters?) : WebView(service) {
+
+ init {
+ gone()
+ setupWebview()
+ }
+
+ @SuppressLint("SetJavaScriptEnabled")
+ private fun setupWebview() {
+ settings.javaScriptEnabled = true
+ settings.userAgentString = USER_AGENT_BASIC
+ webViewClient = HeadlessWebViewClient("MessageNotifs", JsActions.GET_MESSAGES)
+ webChromeClient = QuietChromeClient()
+ addJavascriptInterface(MessageJSI(), "Frost")
+ }
+
+ private val startTime = System.currentTimeMillis()
+ private val endTime: Long by lazy { System.currentTimeMillis() }
+ private var inProgress = false
+ private val pendingRequests: MutableList<CookieModel> = mutableListOf()
+ private lateinit var data: CookieModel
+
+ fun request(data: CookieModel) {
+ pendingRequests.add(data)
+ if (inProgress) return
+ inProgress = true
+ load(data)
+ }
+
+ private fun load(data: CookieModel) {
+ L.d("Notif retrieving messages", data.toString())
+ this.data = data
+ FbCookie.setWebCookie(data.cookie) { context.runOnUiThread { L.d("Notif messages load"); loadUrl(FbTab.MESSAGES.url) } }
+ }
+
+ inner class MessageJSI {
+ @JavascriptInterface
+ fun handleHtml(html: String) {
+ L.d("Notif messages received", data.toString())
+ doAsync { service.fetchMessageNotifications(data, html) }
+ pendingRequests.remove(data)
+ if (pendingRequests.isEmpty()) {
+ val time = endTime - startTime
+ L.d("Notif messages finished $time")
+ frostAnswersCustom("Notifications") {
+ putCustomAttribute("Message retrieval duration", time)
+ }
+ post { destroy() }
+ service.jobFinished(params, false)
+ service.future = null
+ } else {
+ load(pendingRequests.first())
+ }
+ }
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/SearchWebView.kt
index bcadf32a..325d0333 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/SearchWebView.kt
@@ -3,14 +3,14 @@ package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
import android.view.View
-import android.webkit.*
+import android.webkit.JavascriptInterface
+import android.webkit.WebView
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.utils.gone
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
import com.pitchedapps.frost.injectors.JsAssets
import com.pitchedapps.frost.injectors.JsBuilder
-import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
import com.pitchedapps.frost.utils.Prefs
import io.reactivex.schedulers.Schedulers
@@ -23,11 +23,10 @@ import java.util.concurrent.TimeUnit
/**
* Created by Allan Wang on 2017-06-25.
*
- * A bare bone search view meant solely to extract data from the web
- * This should be hidden
+ * A bare bone headless search view meant solely to extract search results from the web
* Having a single webview allows us to avoid loading the whole page with each query
*/
-class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebView(context) {
+class SearchWebView(context: Context, val contract: SearchContract) : WebView(context) {
val searchSubject = PublishSubject.create<String>()
@@ -50,12 +49,11 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
}
@SuppressLint("SetJavaScriptEnabled")
- fun setupWebview() {
+ private fun setupWebview() {
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_BASIC
- setLayerType(View.LAYER_TYPE_HARDWARE, null)
- webViewClient = SearchWebViewClient()
- webChromeClient = SearchChromeClient()
+ webViewClient = HeadlessWebViewClient("Search", JsAssets.SEARCH)
+ webChromeClient = QuietChromeClient()
addJavascriptInterface(SearchJSI(), "Frost")
searchSubject.debounce(300, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
.map {
@@ -105,29 +103,6 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
JsBuilder().js("var e=document.getElementById('main-search-input');if(e){e.value='$input';var n=new Event('input',{bubbles:!0,cancelable:!0});e.dispatchEvent(n),e.dispatchEvent(new Event('focus'))}else console.log('Input field not found');").build().inject(this)
}
- /**
- * Created by Allan Wang on 2017-05-31.
- *
- * Barebones client that does what [FrostWebViewSearch] needs
- */
- 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 {
@JavascriptInterface
fun handleHtml(html: String) {