aboutsummaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2017-07-04 17:22:36 -0400
committerGitHub <noreply@github.com>2017-07-04 17:22:36 -0400
commita67f99fcf210792da5e028570efbad61407aeab2 (patch)
tree3a2d617e9d9649828f13e581d8491c0371c67223 /app
parent4cf368be0cd2f179485b05a3d2cd9b7bc236ba8e (diff)
downloadfrost-a67f99fcf210792da5e028570efbad61407aeab2.tar.gz
frost-a67f99fcf210792da5e028570efbad61407aeab2.tar.bz2
frost-a67f99fcf210792da5e028570efbad61407aeab2.zip
Dev (#21) - fix search and file chooser
* Fix up search and add file chooser * Fix repeating file chooser
Diffstat (limited to 'app')
-rw-r--r--app/src/main/assets/.gitignore3
-rw-r--r--app/src/main/assets/js/search_query.js10
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt20
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt23
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt56
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/WebContract.kt8
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt16
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt21
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt16
9 files changed, 149 insertions, 24 deletions
diff --git a/app/src/main/assets/.gitignore b/app/src/main/assets/.gitignore
index 62c89355..0d3aee97 100644
--- a/app/src/main/assets/.gitignore
+++ b/app/src/main/assets/.gitignore
@@ -1 +1,2 @@
-.idea/ \ No newline at end of file
+.idea/
+js/search_query.min.js
diff --git a/app/src/main/assets/js/search_query.js b/app/src/main/assets/js/search_query.js
new file mode 100644
index 00000000..806519de
--- /dev/null
+++ b/app/src/main/assets/js/search_query.js
@@ -0,0 +1,10 @@
+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')
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
index d52c12ac..b2dc676c 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/MainActivity.kt
@@ -5,6 +5,7 @@ import android.app.PendingIntent
import android.content.Context
import android.content.Intent
import android.graphics.drawable.ColorDrawable
+import android.net.Uri
import android.os.Build
import android.os.Bundle
import android.support.annotation.StringRes
@@ -17,7 +18,10 @@ import android.support.v4.view.ViewPager
import android.support.v7.widget.Toolbar
import android.view.Menu
import android.view.MenuItem
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
import ca.allanwang.kau.changelog.showChangelog
+import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
import ca.allanwang.kau.searchview.SearchItem
import ca.allanwang.kau.searchview.SearchView
import ca.allanwang.kau.searchview.bindSearchView
@@ -35,6 +39,9 @@ import com.mikepenz.google_material_typeface_library.GoogleMaterial
import com.mikepenz.iconics.IconicsDrawable
import com.mikepenz.materialdrawer.AccountHeader
import com.mikepenz.materialdrawer.Drawer
+import com.pitchedapps.frost.contracts.ActivityWebContract
+import com.pitchedapps.frost.contracts.FileChooserContract
+import com.pitchedapps.frost.contracts.FileChooserDelegate
import com.pitchedapps.frost.dbflow.loadFbCookie
import com.pitchedapps.frost.dbflow.loadFbTabs
import com.pitchedapps.frost.facebook.FbCookie
@@ -53,7 +60,8 @@ import io.reactivex.subjects.PublishSubject
import org.jsoup.Jsoup
import java.util.concurrent.TimeUnit
-class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract {
+class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract,
+ ActivityWebContract, FileChooserContract by FileChooserDelegate() {
lateinit var adapter: SectionsPagerAdapter
val toolbar: Toolbar by bindView(R.id.toolbar)
@@ -366,7 +374,12 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract {
return true
}
+ override fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ openFileChooser(this, filePathCallback, fileChooserParams)
+ }
+
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if (onActivityResultWeb(requestCode, resultCode, data)) return
super.onActivityResult(requestCode, resultCode, data)
if (requestCode == ACTIVITY_SETTINGS) {
when (resultCode) {
@@ -391,6 +404,11 @@ class MainActivity : BaseActivity(), FrostWebViewSearch.SearchContract {
}
}
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ kauOnRequestPermissionsResult(permissions, grantResults)
+ }
+
override fun onResume() {
super.onResume()
FbCookie.switchBackUser { }
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
index dd7f60b7..1bd4777d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/WebOverlayActivity.kt
@@ -1,14 +1,21 @@
package com.pitchedapps.frost
import android.content.Intent
+import android.net.Uri
import android.os.Bundle
import android.support.design.widget.CoordinatorLayout
import android.support.design.widget.Snackbar
import android.support.v7.app.AppCompatActivity
import android.support.v7.widget.Toolbar
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
+import ca.allanwang.kau.permissions.kauOnRequestPermissionsResult
import ca.allanwang.kau.utils.*
import com.jude.swipbackhelper.SwipeBackHelper
import com.mikepenz.google_material_typeface_library.GoogleMaterial
+import com.pitchedapps.frost.contracts.ActivityWebContract
+import com.pitchedapps.frost.contracts.FileChooserContract
+import com.pitchedapps.frost.contracts.FileChooserDelegate
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.utils.*
import com.pitchedapps.frost.web.FrostWebView
@@ -17,7 +24,8 @@ import com.pitchedapps.frost.web.FrostWebView
/**
* Created by Allan Wang on 2017-06-01.
*/
-open class WebOverlayActivity : AppCompatActivity() {
+open class WebOverlayActivity : AppCompatActivity(),
+ ActivityWebContract, FileChooserContract by FileChooserDelegate() {
val toolbar: Toolbar by bindView(R.id.overlay_toolbar)
val frostWeb: FrostWebView by bindView(R.id.overlay_frost_webview)
@@ -106,4 +114,17 @@ open class WebOverlayActivity : AppCompatActivity() {
finishSlideOut()
}
}
+
+ override fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ openFileChooser(this, filePathCallback, fileChooserParams)
+ }
+
+ override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
+ if (onActivityResultWeb(requestCode, resultCode, data)) return
+ }
+
+ override fun onRequestPermissionsResult(requestCode: Int, permissions: Array<out String>, grantResults: IntArray) {
+ super.onRequestPermissionsResult(requestCode, permissions, grantResults)
+ kauOnRequestPermissionsResult(permissions, grantResults)
+ }
} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
new file mode 100644
index 00000000..5b2cfa49
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
@@ -0,0 +1,56 @@
+package com.pitchedapps.frost.contracts
+
+import android.app.Activity
+import android.content.Intent
+import android.net.Uri
+import android.webkit.ValueCallback
+import android.webkit.WebChromeClient
+import ca.allanwang.kau.permissions.PERMISSION_READ_EXTERNAL_STORAGE
+import ca.allanwang.kau.permissions.kauRequestPermissions
+import com.pitchedapps.frost.utils.L
+
+/**
+ * Created by Allan Wang on 2017-07-04.
+ */
+const val FILE_CHOOSER_REQUEST = 67
+
+interface FileChooserActivityContract {
+ fun openFileChooser(filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams)
+}
+
+interface FileChooserContract {
+ var filePathCallback: ValueCallback<Array<Uri>>?
+ fun openFileChooser(activity: Activity, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams)
+ fun onActivityResultWeb(requestCode: Int, resultCode: Int, intent: Intent?): Boolean
+}
+
+class FileChooserDelegate : FileChooserContract {
+
+ override var filePathCallback: ValueCallback<Array<Uri>>? = null
+
+ override fun openFileChooser(activity: Activity, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: WebChromeClient.FileChooserParams) {
+ activity.kauRequestPermissions(PERMISSION_READ_EXTERNAL_STORAGE) {
+ granted, _ ->
+ if (!granted) return@kauRequestPermissions
+ val contentSelectionIntent = Intent(Intent.ACTION_GET_CONTENT)
+ contentSelectionIntent.addCategory(Intent.CATEGORY_OPENABLE)
+ contentSelectionIntent.type = fileChooserParams.acceptTypes?.joinToString(separator = "|") ?: "*/*"
+ activity.startActivityForResult(contentSelectionIntent, FILE_CHOOSER_REQUEST)
+ this.filePathCallback?.onReceiveValue(null)
+ this.filePathCallback = filePathCallback
+ }
+ }
+
+ override fun onActivityResultWeb(requestCode: Int, resultCode: Int, intent: Intent?): Boolean {
+ L.d("On activity results web $requestCode")
+ if (requestCode != FILE_CHOOSER_REQUEST) return false
+ var results: Uri? = null
+
+ if (resultCode == Activity.RESULT_OK && intent != null) results = Uri.parse(intent.dataString)
+ L.d("Callback received; ${filePathCallback != null}")
+ filePathCallback?.onReceiveValue(if (results == null) null else arrayOf(results))
+ filePathCallback = null
+ return true
+ }
+
+} \ No newline at end of file
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/WebContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/WebContract.kt
new file mode 100644
index 00000000..2485a468
--- /dev/null
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/WebContract.kt
@@ -0,0 +1,8 @@
+package com.pitchedapps.frost.contracts
+
+/**
+ * Created by Allan Wang on 2017-07-04.
+ *
+ * Combination of all the core functions implemented by the Activity
+ */
+interface ActivityWebContract : FileChooserActivityContract \ 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 00e72cc7..363bf795 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClient.kt
@@ -2,10 +2,13 @@ package com.pitchedapps.frost.web
import android.net.Uri
import android.webkit.*
+import ca.allanwang.kau.utils.snackbar
+import com.pitchedapps.frost.contracts.ActivityWebContract
import com.pitchedapps.frost.utils.L
import io.reactivex.subjects.BehaviorSubject
import io.reactivex.subjects.Subject
+
/**
* Created by Allan Wang on 2017-05-31.
*/
@@ -13,6 +16,7 @@ class FrostChromeClient(webCore: FrostWebViewCore) : WebChromeClient() {
val progressObservable: Subject<Int> = webCore.progressObservable
val titleObservable: BehaviorSubject<String> = webCore.titleObservable
+ val activityContract = (webCore.context as? ActivityWebContract)
override fun onConsoleMessage(consoleMessage: ConsoleMessage): Boolean {
L.i("Chrome Console ${consoleMessage.lineNumber()}: ${consoleMessage.message()}")
@@ -30,15 +34,9 @@ class FrostChromeClient(webCore: FrostWebViewCore) : WebChromeClient() {
progressObservable.onNext(newProgress)
}
- override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>?, fileChooserParams: FileChooserParams?): Boolean {
- L.d("On show file chooser")
- fileChooserParams?.apply {
- L.d(filenameHint ?: "hi")
- L.d("$mode")
- L.d(acceptTypes.contentToString())
- }
-
- return super.onShowFileChooser(webView, filePathCallback, fileChooserParams)
+ override fun onShowFileChooser(webView: WebView, filePathCallback: ValueCallback<Array<Uri>>, fileChooserParams: FileChooserParams): Boolean {
+ activityContract?.openFileChooser(filePathCallback, fileChooserParams) ?: webView.snackbar("File chooser not found")
+ return activityContract != null
}
override fun onGeolocationPermissionsShowPrompt(origin: String, callback: GeolocationPermissions.Callback) {
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 709ab7ac..62c28527 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewClient.kt
@@ -11,10 +11,7 @@ import com.pitchedapps.frost.SelectorActivity
import com.pitchedapps.frost.facebook.FACEBOOK_COM
import com.pitchedapps.frost.facebook.FbCookie
import com.pitchedapps.frost.injectors.*
-import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.Prefs
-import com.pitchedapps.frost.utils.cookies
-import com.pitchedapps.frost.utils.launchNewTask
+import com.pitchedapps.frost.utils.*
import io.reactivex.subjects.Subject
/**
@@ -76,8 +73,20 @@ open class FrostWebViewClient(val webCore: FrostWebViewCore) : WebViewClient() {
L.d("Emit $flag")
}
- override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest?): Boolean {
- L.i("Url Loading ${request?.url?.path}")
+ /**
+ * Helper to format the request and launch it
+ * returns true to override the url
+ */
+ private fun launchRequest(request: WebResourceRequest): Boolean {
+ L.d("Launching ${request.url}")
+ webCore.context.launchWebOverlay(request.url.toString())
+ return true
+ }
+
+ override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest): Boolean {
+ L.i("Url Loading ${request.url}")
+ val path = request.url.path
+ if (path.startsWith("/composer/")) return launchRequest(request)
return super.shouldOverrideUrlLoading(view, request)
}
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 83dccb9a..fb2e1851 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostWebViewSearch.kt
@@ -16,6 +16,7 @@ import com.pitchedapps.frost.injectors.jsInject
import com.pitchedapps.frost.utils.L
import io.reactivex.schedulers.Schedulers
import io.reactivex.subjects.PublishSubject
+import org.jetbrains.anko.runOnUiThread
import org.jsoup.Jsoup
import java.util.concurrent.TimeUnit
@@ -61,8 +62,11 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
Jsoup.parse(it).select("a:not([rel*='keywords(']):not([href=#])[rel]").map {
element ->
//split text into separate items
+ L.i("Search element ${element.attr("href")}")
val texts = element.select("div").map { (it.ownText()) }.filter { it.isNotBlank() }
- Pair(texts, element.attr("href"))
+ val pair = Pair(texts, element.attr("href"))
+ L.i("Search element potential $pair")
+ pair
}.filter { it.first.isNotEmpty() }
}
.filter { content -> Pair(content.lastOrNull()?.second, content.size) != previousResult }
@@ -72,7 +76,6 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
L.d("Search element count ${content.size}")
contract.emitSearchResponse(content.map {
(texts, href) ->
- L.i("Search element $texts $href")
SearchItem(href, texts[0], texts.getOrNull(1))
})
}
@@ -86,7 +89,7 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
var pauseLoad: Boolean
get() = settings.blockNetworkLoads
set(value) {
- settings.blockNetworkLoads = value
+ context.runOnUiThread { settings.blockNetworkLoads = value }
}
override fun reload() {
@@ -97,8 +100,9 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
* Sets the input to have our given text, then dispatches the input event so the webpage recognizes it
*/
fun query(input: String) {
+ pauseLoad = false
L.d("Searching attempt", input)
- 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)}else console.log('Input field not found')").build().inject(this)
+ 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)
}
/**
@@ -118,7 +122,8 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
inner class SearchJSI {
@JavascriptInterface
fun handleHtml(html: String) {
- L.d("Search received response")
+ L.d("Search received response ${contract.isSearchOpened}")
+ if (!contract.isSearchOpened) pauseLoad = true
searchSubject.onNext(html)
}
@@ -127,7 +132,6 @@ class FrostWebViewSearch(context: Context, val contract: SearchContract) : WebVi
when (flag) {
0 -> {
L.d("Search loaded successfully")
- if (!contract.isSearchOpened) pauseLoad = true
}
1 -> { //something is not found in the search view; this is effectively useless
L.eThrow("Search subject error; reverting to full overlay")