From 3b4b164f524575c9dc10955d329710ba0706c9ed Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sat, 25 Sep 2021 16:54:09 -0700 Subject: Create frost web component for jsi --- .../com/pitchedapps/frost/views/FrostWebView.kt | 44 +++++++++++++++++++++- .../kotlin/com/pitchedapps/frost/web/FrostJSI.kt | 41 ++++++++++---------- 2 files changed, 65 insertions(+), 20 deletions(-) (limited to 'app/src') 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 695e1226..f384d134 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/views/FrostWebView.kt @@ -18,6 +18,7 @@ package com.pitchedapps.frost.views import android.animation.ValueAnimator import android.annotation.SuppressLint +import android.app.Activity import android.content.Context import android.graphics.Color import android.util.AttributeSet @@ -44,8 +45,15 @@ import com.pitchedapps.frost.web.FrostChromeClient import com.pitchedapps.frost.web.FrostJSI import com.pitchedapps.frost.web.FrostWebViewClient import com.pitchedapps.frost.web.NestedWebView +import dagger.BindsInstance +import dagger.hilt.DefineComponent +import dagger.hilt.EntryPoint +import dagger.hilt.EntryPoints +import dagger.hilt.InstallIn import dagger.hilt.android.AndroidEntryPoint +import dagger.hilt.android.components.ViewComponent import javax.inject.Inject +import javax.inject.Scope import kotlin.math.abs import kotlin.math.max import kotlin.math.min @@ -61,6 +69,9 @@ class FrostWebView @JvmOverloads constructor( defStyleAttr: Int = 0 ) : NestedWebView(context, attrs, defStyleAttr), FrostContentCore { + @Inject + lateinit var activity: Activity + @Inject lateinit var fbCookie: FbCookie @@ -76,6 +87,9 @@ class FrostWebView @JvmOverloads constructor( @Inject lateinit var cookieDao: CookieDao + @Inject + lateinit var frostWebComponentBuilder: FrostWebComponentBuilder + override fun reload(animate: Boolean) { if (parent.registerTransition(false, animate)) super.reload() @@ -90,6 +104,8 @@ class FrostWebView @JvmOverloads constructor( @SuppressLint("SetJavaScriptEnabled") override fun bind(container: FrostContentContainer): View { + val component = frostWebComponentBuilder.frostWebView(this).build() + val entryPoint = EntryPoints.get(component, FrostWebEntryPoint::class.java) userAgentString = USER_AGENT with(settings) { javaScriptEnabled = true @@ -103,7 +119,7 @@ class FrostWebView @JvmOverloads constructor( frostWebClient = (container as? WebFragment)?.client(this) ?: FrostWebViewClient(this) webViewClient = frostWebClient webChromeClient = FrostChromeClient(this, themeProvider, webFileChooser) - addJavascriptInterface(FrostJSI(this), "Frost") + addJavascriptInterface(entryPoint.frostJsi(), "Frost") setBackgroundColor(Color.TRANSPARENT) setDownloadListener { url, userAgent, contentDisposition, mimetype, contentLength -> context.ctxCoroutine.launchMain { @@ -235,3 +251,29 @@ class FrostWebView @JvmOverloads constructor( super.destroy() } } + +@Scope +@Retention(AnnotationRetention.BINARY) +@Target( + AnnotationTarget.FUNCTION, + AnnotationTarget.TYPE, + AnnotationTarget.CLASS +) +annotation class FrostWebScoped + +@FrostWebScoped +@DefineComponent(parent = ViewComponent::class) +interface FrostWebComponent + +@DefineComponent.Builder +interface FrostWebComponentBuilder { + fun frostWebView(@BindsInstance web: FrostWebView): FrostWebComponentBuilder + fun build(): FrostWebComponent +} + +@EntryPoint +@InstallIn(FrostWebComponent::class) +interface FrostWebEntryPoint { + @FrostWebScoped + fun frostJsi(): FrostJSI +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt index 9a853dae..3ead78f4 100644 --- a/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt +++ b/app/src/main/kotlin/com/pitchedapps/frost/web/FrostJSI.kt @@ -16,12 +16,11 @@ */ package com.pitchedapps.frost.web -import android.content.Context +import android.app.Activity import android.webkit.JavascriptInterface import ca.allanwang.kau.utils.ctxCoroutine import com.pitchedapps.frost.activities.MainActivity import com.pitchedapps.frost.activities.WebOverlayActivityBase -import com.pitchedapps.frost.contracts.MainActivityContract import com.pitchedapps.frost.contracts.VideoViewHolder import com.pitchedapps.frost.db.CookieEntity import com.pitchedapps.frost.facebook.FbCookie @@ -35,19 +34,23 @@ import com.pitchedapps.frost.utils.showWebContextMenu import com.pitchedapps.frost.views.FrostWebView import kotlinx.coroutines.channels.SendChannel import kotlinx.coroutines.launch +import javax.inject.Inject /** * Created by Allan Wang on 2017-06-01. */ -class FrostJSI(val web: FrostWebView) { - - private val fbCookie: FbCookie get() = web.fbCookie - private val prefs: Prefs get() = web.prefs - private val context: Context = web.context - private val activity: MainActivity? = context as? MainActivity - private val header: SendChannel? = activity?.headerBadgeChannel +class FrostJSI @Inject internal constructor( + val web: FrostWebView, + private val activity: Activity, + private val fbCookie: FbCookie, + private val prefs: Prefs +) { + + private val mainActivity: MainActivity? = activity as? MainActivity + private val webActivity: WebOverlayActivityBase? = activity as? WebOverlayActivityBase + private val header: SendChannel? = mainActivity?.headerBadgeChannel private val refresh: SendChannel = web.parent.refreshChannel - private val cookies: List = activity?.cookies() ?: arrayListOf() + private val cookies: List = activity.cookies() /** * Attempts to load the url in an overlay @@ -61,7 +64,7 @@ class FrostJSI(val web: FrostWebView) { fun loadVideo(url: String?, isGif: Boolean): Boolean = if (url != null && prefs.enablePip) { web.post { - (context as? VideoViewHolder)?.showVideo(url, isGif) + (activity as? VideoViewHolder)?.showVideo(url, isGif) ?: L.e { "Could not load video; contract not implemented" } } true @@ -82,7 +85,7 @@ class FrostJSI(val web: FrostWebView) { fun contextMenu(url: String?, text: String?) { // url will be formatted through webcontext web.post { - context.showWebContextMenu( + activity.showWebContextMenu( WebContext(url.takeIf { it.isIndependent }, text), fbCookie, prefs @@ -96,7 +99,7 @@ class FrostJSI(val web: FrostWebView) { */ @JavascriptInterface fun longClick(start: Boolean) { - activity?.contentBinding?.viewpager?.enableSwipe = !start + mainActivity?.contentBinding?.viewpager?.enableSwipe = !start if (web.frostWebClient.urlSupportsRefresh) { web.parent.swipeDisabledByAction = start } @@ -113,15 +116,15 @@ class FrostJSI(val web: FrostWebView) { web.parent.swipeDisabledByAction = disable if (disable) { // locked onto an input field; ensure content is visible - (context as? MainActivityContract)?.collapseAppBar() + mainActivity?.collapseAppBar() } } @JavascriptInterface fun loadLogin() { L.d { "Sign up button found; load login" } - context.ctxCoroutine.launch { - fbCookie.logout(context, deleteCookie = false) + activity.ctxCoroutine.launch { + fbCookie.logout(activity, deleteCookie = false) } } @@ -130,7 +133,7 @@ class FrostJSI(val web: FrostWebView) { */ @JavascriptInterface fun loadImage(imageUrl: String, text: String?) { - context.launchImageActivity(imageUrl, text) + activity.launchImageActivity(imageUrl, text) } @JavascriptInterface @@ -159,8 +162,8 @@ class FrostJSI(val web: FrostWebView) { @JavascriptInterface fun allowHorizontalScrolling(enable: Boolean) { - activity?.contentBinding?.viewpager?.enableSwipe = enable - (context as? WebOverlayActivityBase)?.swipeBack?.disallowIntercept = !enable + mainActivity?.contentBinding?.viewpager?.enableSwipe = enable + webActivity?.swipeBack?.disallowIntercept = !enable } private var isScrolling = false -- cgit v1.2.3