aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAllan Wang <me@allanwang.ca>2021-09-25 15:55:07 -0700
committerAllan Wang <me@allanwang.ca>2021-09-25 15:55:07 -0700
commit8db1930d7623ba071123f5978153679da7161278 (patch)
tree5ce5894c321fae7f0a2f5a9ab65c3dca031db724
parent1ac15f84b05e83d3c3482cf1498c74123852d658 (diff)
downloadfrost-8db1930d7623ba071123f5978153679da7161278.tar.gz
frost-8db1930d7623ba071123f5978153679da7161278.tar.bz2
frost-8db1930d7623ba071123f5978153679da7161278.zip
Create hilt web file chooser implementation
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt19
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt26
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt8
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt67
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt6
-rw-r--r--app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt13
6 files changed, 92 insertions, 47 deletions
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
index 3766aef7..84352cb4 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/BaseMainActivity.kt
@@ -24,14 +24,11 @@ import android.content.res.ColorStateList
import android.graphics.PointF
import android.graphics.drawable.Drawable
import android.graphics.drawable.RippleDrawable
-import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.view.ViewGroup
-import android.webkit.ValueCallback
-import android.webkit.WebChromeClient
import android.webkit.WebView
import android.widget.FrameLayout
import android.widget.ImageView
@@ -79,10 +76,9 @@ import com.mikepenz.iconics.typeface.IIcon
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.pitchedapps.frost.BuildConfig
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.contracts.FileChooserContract
-import com.pitchedapps.frost.contracts.FileChooserDelegate
import com.pitchedapps.frost.contracts.MainActivityContract
import com.pitchedapps.frost.contracts.VideoViewHolder
+import com.pitchedapps.frost.contracts.WebFileChooser
import com.pitchedapps.frost.databinding.ActivityMainBinding
import com.pitchedapps.frost.databinding.ActivityMainBottomTabsBinding
import com.pitchedapps.frost.databinding.ActivityMainDrawerWrapperBinding
@@ -149,7 +145,6 @@ import kotlin.math.abs
abstract class BaseMainActivity :
BaseActivity(),
MainActivityContract,
- FileChooserContract by FileChooserDelegate(),
VideoViewHolder,
SearchViewHolder {
@@ -167,6 +162,9 @@ abstract class BaseMainActivity :
@Inject
lateinit var genericDao: GenericDao
+ @Inject
+ lateinit var webFileChooser: WebFileChooser
+
interface ActivityMainContentBinding {
val root: View
val toolbar: Toolbar
@@ -715,16 +713,9 @@ abstract class BaseMainActivity :
return true
}
- override fun openFileChooser(
- filePathCallback: ValueCallback<Array<Uri>?>,
- fileChooserParams: WebChromeClient.FileChooserParams
- ) {
- openMediaPicker(filePathCallback, fileChooserParams)
- }
-
@SuppressLint("NewApi")
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- if (onActivityResultWeb(requestCode, resultCode, data)) return
+ if (webFileChooser.onActivityResultWeb(requestCode, resultCode, data)) return
super.onActivityResult(requestCode, resultCode, data)
fun hasRequest(flag: Int) = resultCode and flag > 0
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
index 689d9a65..ef7579a8 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/activities/WebOverlayActivity.kt
@@ -18,12 +18,9 @@ package com.pitchedapps.frost.activities
import android.content.Intent
import android.graphics.PointF
-import android.net.Uri
import android.os.Bundle
import android.view.Menu
import android.view.MenuItem
-import android.webkit.ValueCallback
-import android.webkit.WebChromeClient
import android.widget.FrameLayout
import androidx.appcompat.widget.Toolbar
import androidx.coordinatorlayout.widget.CoordinatorLayout
@@ -49,11 +46,9 @@ import ca.allanwang.kau.utils.withMainContext
import com.google.android.material.snackbar.BaseTransientBottomBar
import com.mikepenz.iconics.typeface.library.googlematerial.GoogleMaterial
import com.pitchedapps.frost.R
-import com.pitchedapps.frost.contracts.ActivityContract
-import com.pitchedapps.frost.contracts.FileChooserContract
-import com.pitchedapps.frost.contracts.FileChooserDelegate
import com.pitchedapps.frost.contracts.FrostContentContainer
import com.pitchedapps.frost.contracts.VideoViewHolder
+import com.pitchedapps.frost.contracts.WebFileChooser
import com.pitchedapps.frost.enums.OverlayContext
import com.pitchedapps.frost.facebook.FB_URL_BASE
import com.pitchedapps.frost.facebook.FbItem
@@ -70,10 +65,12 @@ import com.pitchedapps.frost.utils.frostSnackbar
import com.pitchedapps.frost.views.FrostContentWeb
import com.pitchedapps.frost.views.FrostVideoViewer
import com.pitchedapps.frost.views.FrostWebView
+import dagger.hilt.android.AndroidEntryPoint
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.launch
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
+import javax.inject.Inject
/**
* Created by Allan Wang on 2017-06-01.
@@ -155,12 +152,11 @@ class WebOverlayDesktopActivity : WebOverlayActivityBase(USER_AGENT_DESKTOP_CONS
class WebOverlayActivity : WebOverlayActivityBase()
@UseExperimental(ExperimentalCoroutinesApi::class)
+@AndroidEntryPoint
abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT) :
BaseActivity(),
- ActivityContract,
FrostContentContainer,
- VideoViewHolder,
- FileChooserContract by FileChooserDelegate() {
+ VideoViewHolder {
override val frameWrapper: FrameLayout by bindView(R.id.frame_wrapper)
val toolbar: Toolbar by bindView(R.id.overlay_toolbar)
@@ -169,6 +165,9 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
get() = content.coreView
private val coordinator: CoordinatorLayout by bindView(R.id.overlay_main_content)
+ @Inject
+ lateinit var webFileChooser: WebFileChooser
+
private inline val urlTest: String?
get() = intent.getStringExtra(ARG_URL) ?: intent.dataString
@@ -297,15 +296,8 @@ abstract class WebOverlayActivityBase(private val userAgent: String = USER_AGENT
kauSwipeOnDestroy()
}
- override fun openFileChooser(
- filePathCallback: ValueCallback<Array<Uri>?>,
- fileChooserParams: WebChromeClient.FileChooserParams
- ) {
- openMediaPicker(filePathCallback, fileChooserParams)
- }
-
override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
- if (onActivityResultWeb(requestCode, resultCode, data)) return
+ if (webFileChooser.onActivityResultWeb(requestCode, resultCode, data)) return
super.onActivityResult(requestCode, resultCode, data)
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
index 84edfee9..756b1f3d 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/ActivityContract.kt
@@ -17,18 +17,12 @@
package com.pitchedapps.frost.contracts
import com.mikepenz.iconics.typeface.IIcon
-import com.pitchedapps.frost.activities.MainActivity
import com.pitchedapps.frost.fragments.BaseFragment
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.channels.BroadcastChannel
-/**
- * All the contracts for [MainActivity]
- */
-interface ActivityContract : FileChooserActivityContract
-
@UseExperimental(ExperimentalCoroutinesApi::class)
-interface MainActivityContract : ActivityContract, MainFabContract {
+interface MainActivityContract : MainFabContract {
val fragmentChannel: BroadcastChannel<Int>
val headerBadgeChannel: BroadcastChannel<String>
fun setTitle(res: Int)
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
index 4853e7ff..21cb4948 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/contracts/FileChooser.kt
@@ -26,12 +26,78 @@ import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.utils.string
import com.pitchedapps.frost.R
import com.pitchedapps.frost.utils.L
+import dagger.Binds
+import dagger.Module
+import dagger.hilt.InstallIn
+import dagger.hilt.android.components.ActivityComponent
+import dagger.hilt.android.scopes.ActivityScoped
+import javax.inject.Inject
/**
* Created by Allan Wang on 2017-07-04.
*/
const val MEDIA_CHOOSER_RESULT = 67
+interface WebFileChooser {
+ fun openMediaPicker(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ )
+
+ fun onActivityResultWeb(
+ requestCode: Int,
+ resultCode: Int,
+ intent: Intent?
+ ): Boolean
+}
+
+class WebFileChooserImpl @Inject internal constructor(private val activity: Activity) :
+ WebFileChooser {
+ private var filePathCallback: ValueCallback<Array<Uri>?>? = null
+
+ override fun openMediaPicker(
+ filePathCallback: ValueCallback<Array<Uri>?>,
+ fileChooserParams: WebChromeClient.FileChooserParams
+ ) {
+ activity.kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) { granted, _ ->
+ if (!granted) {
+ L.d { "Failed to get write permissions" }
+ filePathCallback.onReceiveValue(null)
+ return@kauRequestPermissions
+ }
+ this.filePathCallback = filePathCallback
+ val intent = Intent()
+ intent.type = fileChooserParams.acceptTypes.firstOrNull()
+ intent.action = Intent.ACTION_GET_CONTENT
+ activity.startActivityForResult(
+ Intent.createChooser(intent, activity.string(R.string.pick_image)),
+ MEDIA_CHOOSER_RESULT
+ )
+ }
+ }
+
+ override fun onActivityResultWeb(
+ requestCode: Int,
+ resultCode: Int,
+ intent: Intent?
+ ): Boolean {
+ L.d { "FileChooser On activity results web $requestCode" }
+ if (requestCode != MEDIA_CHOOSER_RESULT) return false
+ val data = intent?.data
+ filePathCallback?.onReceiveValue(if (data != null) arrayOf(data) else null)
+ filePathCallback = null
+ return true
+ }
+}
+
+@Module
+@InstallIn(ActivityComponent::class)
+interface WebFileChooserModule {
+ @Binds
+ @ActivityScoped
+ fun webFileChooser(to: WebFileChooserImpl): WebFileChooser
+}
+
interface FileChooserActivityContract {
fun openFileChooser(
filePathCallback: ValueCallback<Array<Uri>?>,
@@ -59,6 +125,7 @@ class FileChooserDelegate : FileChooserContract {
) {
kauRequestPermissions(PERMISSION_WRITE_EXTERNAL_STORAGE) { granted, _ ->
if (!granted) {
+ L.d { "Failed to get write permissions" }
filePathCallback.onReceiveValue(null)
return@kauRequestPermissions
}
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
index ec012ed5..695e1226 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt
@@ -29,6 +29,7 @@ import ca.allanwang.kau.utils.launchMain
import com.pitchedapps.frost.contracts.FrostContentContainer
import com.pitchedapps.frost.contracts.FrostContentCore
import com.pitchedapps.frost.contracts.FrostContentParent
+import com.pitchedapps.frost.contracts.WebFileChooser
import com.pitchedapps.frost.db.CookieDao
import com.pitchedapps.frost.db.currentCookie
import com.pitchedapps.frost.facebook.FB_HOME_URL
@@ -70,6 +71,9 @@ class FrostWebView @JvmOverloads constructor(
lateinit var themeProvider: ThemeProvider
@Inject
+ lateinit var webFileChooser: WebFileChooser
+
+ @Inject
lateinit var cookieDao: CookieDao
override fun reload(animate: Boolean) {
@@ -98,7 +102,7 @@ class FrostWebView @JvmOverloads constructor(
// attempt to get custom client; otherwise fallback to original
frostWebClient = (container as? WebFragment)?.client(this) ?: FrostWebViewClient(this)
webViewClient = frostWebClient
- webChromeClient = FrostChromeClient(this, themeProvider)
+ webChromeClient = FrostChromeClient(this, themeProvider, webFileChooser)
addJavascriptInterface(FrostJSI(this), "Frost")
setBackgroundColor(Color.TRANSPARENT)
setDownloadListener { url, userAgent, contentDisposition, mimetype, contentLength ->
diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
index e687dd2d..61a76e70 100644
--- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
+++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostChromeClients.kt
@@ -30,11 +30,9 @@ import ca.allanwang.kau.permissions.kauRequestPermissions
import ca.allanwang.kau.utils.materialDialog
import com.afollestad.materialdialogs.callbacks.onDismiss
import com.afollestad.materialdialogs.input.input
-import com.pitchedapps.frost.R
-import com.pitchedapps.frost.contracts.ActivityContract
+import com.pitchedapps.frost.contracts.WebFileChooser
import com.pitchedapps.frost.injectors.ThemeProvider
import com.pitchedapps.frost.utils.L
-import com.pitchedapps.frost.utils.frostSnackbar
import com.pitchedapps.frost.views.FrostWebView
import kotlinx.coroutines.channels.SendChannel
@@ -49,13 +47,13 @@ import kotlinx.coroutines.channels.SendChannel
*/
class FrostChromeClient(
web: FrostWebView,
- private val themeProvider: ThemeProvider
+ private val themeProvider: ThemeProvider,
+ private val webFileChooser: WebFileChooser,
) : WebChromeClient() {
private val refresh: SendChannel<Boolean> = web.parent.refreshChannel
private val progress: SendChannel<Int> = web.parent.progressChannel
private val title: SendChannel<String> = web.parent.titleChannel
- private val activity = (web.context as? ActivityContract)
private val context = web.context!!
override fun getDefaultVideoPoster(): Bitmap? =
@@ -83,9 +81,8 @@ class FrostChromeClient(
filePathCallback: ValueCallback<Array<Uri>?>,
fileChooserParams: FileChooserParams
): Boolean {
- activity?.openFileChooser(filePathCallback, fileChooserParams)
- ?: webView.frostSnackbar(R.string.file_chooser_not_found, themeProvider)
- return activity != null
+ webFileChooser.openMediaPicker(filePathCallback, fileChooserParams)
+ return true
}
private fun JsResult.frostCancel() {