aboutsummaryrefslogtreecommitdiff
path: root/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
diff options
context:
space:
mode:
Diffstat (limited to 'app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt')
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt128
1 files changed, 85 insertions, 43 deletions
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 0795efe2..85dfb254 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
@@ -2,80 +2,122 @@ package com.pitchedapps.frost.web
import android.annotation.SuppressLint
import android.content.Context
-import android.graphics.Color
-import android.support.v4.view.NestedScrollingChild
-import android.util.AttributeSet
+import android.os.Handler
import android.view.View
+import android.webkit.JavascriptInterface
import android.webkit.WebView
-import ca.allanwang.kau.utils.*
+import android.webkit.WebViewClient
import com.pitchedapps.frost.facebook.FbTab
import com.pitchedapps.frost.facebook.USER_AGENT_BASIC
-import com.pitchedapps.frost.utils.Prefs
-import io.reactivex.android.schedulers.AndroidSchedulers
-import io.reactivex.disposables.Disposable
-import io.reactivex.subjects.BehaviorSubject
+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 io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
+import org.jsoup.Jsoup
+import org.jsoup.nodes.TextNode
+import java.util.concurrent.TimeUnit
+@SuppressLint("ViewConstructor")
/**
* 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
*/
-class FrostWebViewSearch (context: Context) : WebView(context) {
- var baseUrl: String? = null
- var baseEnum: FbTab? = null
- internal var frostWebClient: FrostWebViewClient? = null
+class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebView(context) {
+
+ val searchSubject = PublishSubject.create<String>()
init {
- gone()
+// gone()
setupWebview()
}
@SuppressLint("SetJavaScriptEnabled")
- fun setupWebview(url: String, enum: FbTab? = null) {
- baseUrl = url
- baseEnum = enum
+ fun setupWebview() {
settings.javaScriptEnabled = true
settings.userAgentString = USER_AGENT_BASIC
-// settings.domStorageEnabled = true
setLayerType(View.LAYER_TYPE_HARDWARE, null)
- frostWebClient = baseEnum?.webClient?.invoke(this) ?: FrostWebViewClient(this)
- webViewClient = frostWebClient
- webChromeClient = FrostChromeClient(this)
- addJavascriptInterface(FrostJSI(context, this), "Frost")
- setBackgroundColor(Color.TRANSPARENT)
+ webViewClient = FrostWebViewClientSearch()
+ addJavascriptInterface(SearchJSI(), "Frost")
+ searchSubject.debounce(200, TimeUnit.MILLISECONDS).subscribeOn(Schedulers.newThread())
+ .map {
+ Jsoup.parse(it).select("a:not([rel*='keywords(']):not([href=#])[rel]").map {
+ element ->
+// L.d("Search element ${element.text()} ${element.textNodes().size} ${element.attr("href")}")
+ Pair(element.textNodes(), element.attr("href"))
+ }.filter { it.first.isNotEmpty() }
+ }
+ .subscribe {
+ content: List<Pair<List<TextNode>, String>> ->
+ content.forEach {
+// L.e("Search result ${it.second}")
+ }
+ contract.emitSearchResponse()
+ }
+ reload()
+ Handler().postDelayed({
+ query("hi")
+ }, 5000)
}
- fun loadUrl(url: String?, animate: Boolean) {
- if (url == null) return
- registerTransition(animate)
- super.loadUrl(url)
+ override fun reload() {
+ super.loadUrl(FbTab.SEARCH.url)
}
- fun reload(animate: Boolean) {
- registerTransition(animate)
- super.reload()
+ fun query(input: String) {
+ JsBuilder().js("var input=document.getElementById('main-search-input');input.click(),input.value='$input';").build().inject(this) {
+ L.d("Searching for $input")
+ }
}
/**
- * Hook onto the refresh observable for one cycle
- * Animate toggles between the fancy ripple and the basic fade
- * The cycle only starts on the first load since there may have been another process when this is registered
+ * Created by Allan Wang on 2017-05-31.
+ *
+ * Barebones client that does what [FrostWebViewSearch] needs
*/
- fun registerTransition(animate: Boolean) {
- var dispose: Disposable? = null
- var loading = false
- dispose = refreshObservable.subscribeOn(AndroidSchedulers.mainThread()).subscribe {
- if (it) {
- loading = true
- if (isVisible()) fadeOut(duration = 200L)
- } else if (loading) {
- dispose?.dispose()
- if (animate && Prefs.animate) circularReveal(offset = 150L)
- else fadeIn(duration = 100L)
+ inner class FrostWebViewClientSearch : WebViewClient() {
+
+ override fun onPageFinished(view: WebView, url: String) {
+ super.onPageFinished(view, url)
+ L.i("Search Page finished $url")
+ view.jsInject(JsAssets.SEARCH)
+ }
+ }
+
+ inner class SearchJSI {
+ @JavascriptInterface
+ fun handleHtml(html: String) {
+// L.d("Search received response $html")
+ searchSubject.onNext(html)
+ }
+
+ @JavascriptInterface
+ fun emit(flag: Int) {
+ L.d("Search flag")
+ when (flag) {
+ 0 -> {
+ JsBuilder().js("document.getElementById('main-search-input').click()").build().inject(this@FrostWebViewSearch) {
+ L.d("Search click")
+ }
+ }
+ 1 -> { //something is not found in the search view; this is effectively useless
+ L.d("Search subject error; reverting to full overlay")
+ searchSubject.onComplete()
+ contract.searchOverlayError()
+ }
}
}
}
+ interface SearchContract {
+ fun searchOverlayError()
+ //todo add args
+ fun emitSearchResponse()
+ }
}
+
+
+