mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-09-19 15:11:42 +02:00
Create hilt web file chooser implementation
This commit is contained in:
parent
1ac15f84b0
commit
8db1930d76
@ -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
|
||||
|
@ -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)
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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
|
||||
@ -69,6 +70,9 @@ class FrostWebView @JvmOverloads constructor(
|
||||
@Inject
|
||||
lateinit var themeProvider: ThemeProvider
|
||||
|
||||
@Inject
|
||||
lateinit var webFileChooser: WebFileChooser
|
||||
|
||||
@Inject
|
||||
lateinit var cookieDao: CookieDao
|
||||
|
||||
@ -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 ->
|
||||
|
@ -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() {
|
||||
|
Loading…
Reference in New Issue
Block a user