1
0
mirror of https://github.com/AllanWang/Frost-for-Facebook.git synced 2024-09-18 21:12:24 +02:00

Fix theming

This commit is contained in:
Allan Wang 2023-06-20 23:21:27 -07:00
parent f13b2d2998
commit 37f53e35f2
No known key found for this signature in database
GPG Key ID: C93E3F9C679D7A56
12 changed files with 118 additions and 53 deletions

View File

@ -27,6 +27,7 @@ import androidx.compose.material3.lightColorScheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext
/** Main Frost compose theme. */
@ -34,13 +35,14 @@ import androidx.compose.ui.platform.LocalContext
fun FrostTheme(
isDarkTheme: Boolean = isSystemInDarkTheme(),
isDynamicColor: Boolean = true,
transparent: Boolean = true,
modifier: Modifier = Modifier,
content: @Composable () -> Unit
) {
val context = LocalContext.current
val dynamicColor = isDynamicColor && Build.VERSION.SDK_INT >= Build.VERSION_CODES.S
val colorScheme =
remember(dynamicColor, isDarkTheme) {
remember(dynamicColor, isDarkTheme, transparent) {
when {
dynamicColor && isDarkTheme -> {
dynamicDarkColorScheme(context)
@ -53,5 +55,11 @@ fun FrostTheme(
}
}
MaterialTheme(colorScheme = colorScheme) { Surface(modifier = modifier, content = content) }
MaterialTheme(colorScheme = colorScheme) {
Surface(
modifier = modifier,
color = if (transparent) Color.Transparent else MaterialTheme.colorScheme.surface,
content = content,
)
}
}

View File

@ -31,7 +31,7 @@ import androidx.compose.ui.viewinterop.AndroidView
import androidx.core.widget.NestedScrollView
import com.google.common.flogger.FluentLogger
import com.pitchedapps.frost.ext.WebTargetId
import com.pitchedapps.frost.view.NestedWebView
import com.pitchedapps.frost.view.FrostWebView
import com.pitchedapps.frost.web.state.FrostWebStore
import com.pitchedapps.frost.web.state.TabAction
import com.pitchedapps.frost.web.state.TabAction.ResponseAction.LoadUrlResponseAction
@ -126,7 +126,7 @@ class FrostWebCompose(
AndroidView(
factory = { context ->
val childView =
NestedWebView(context)
FrostWebView(context)
.apply {
onCreated(this)
@ -150,9 +150,6 @@ class FrostWebCompose(
}
.also { webView = it }
// Workaround a crash on certain devices that expect WebView to be
// wrapped in a ViewGroup.
// b/243567497
val parentLayout = NestedScrollView(context)
parentLayout.layoutParams =
FrameLayout.LayoutParams(
@ -176,17 +173,3 @@ class FrostWebCompose(
private val logger = FluentLogger.forEnclosingClass()
}
}
// override fun onReceivedError(
// view: WebView,
// request: WebResourceRequest?,
// error: WebResourceError?
// ) {
// super.onReceivedError(view, request, error)
//
// if (error != null) {
// state.errorsForCurrentRequest.add(WebViewError(request, error))
// }
// }
// }

View File

@ -24,7 +24,7 @@ const val WWW_FACEBOOK_COM = "www.$FACEBOOK_COM"
const val WWW_MESSENGER_COM = "www.$MESSENGER_COM"
const val HTTPS_FACEBOOK_COM = "https://$WWW_FACEBOOK_COM"
const val HTTPS_MESSENGER_COM = "https://$WWW_MESSENGER_COM"
const val FACEBOOK_BASE_COM = "m.$FACEBOOK_COM"
const val FACEBOOK_BASE_COM = "touch.$FACEBOOK_COM"
const val FB_URL_BASE = "https://$FACEBOOK_BASE_COM/"
const val FACEBOOK_MBASIC_COM = "mbasic.$FACEBOOK_COM"
const val FB_URL_MBASIC_BASE = "https://$FACEBOOK_MBASIC_COM/"

View File

@ -24,7 +24,6 @@ import dagger.Provides
import dagger.hilt.InstallIn
import dagger.hilt.components.SingletonComponent
import javax.inject.Qualifier
import javax.inject.Singleton
@Qualifier annotation class Frost
@ -54,7 +53,7 @@ object FrostModule {
"Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:109.0) Gecko/20100101 Firefox/112.0"
private const val USER_AGENT_WINDOWS_FROST =
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.90 Safari/537.36"
"Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36"
@Provides @Singleton @Frost fun userAgent(): String = USER_AGENT_WINDOWS_FROST
@Provides @Frost fun userAgent(): String = USER_AGENT_WINDOWS_FROST
}

View File

@ -21,6 +21,7 @@ import androidx.activity.ComponentActivity
import androidx.activity.compose.setContent
import androidx.core.view.WindowCompat
import com.google.common.flogger.FluentLogger
import com.pitchedapps.frost.R
import com.pitchedapps.frost.compose.FrostTheme
import com.pitchedapps.frost.web.state.FrostWebStore
import dagger.hilt.android.AndroidEntryPoint
@ -38,6 +39,8 @@ class MainActivity : ComponentActivity() {
@Inject lateinit var store: FrostWebStore
override fun onCreate(savedInstanceState: Bundle?) {
// TODO make configurable
setTheme(R.style.FrostTheme_Transparent)
super.onCreate(savedInstanceState)
logger.atInfo().log("onCreate main activity")

View File

@ -41,6 +41,7 @@ import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.runtime.setValue
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.lifecycle.viewmodel.compose.viewModel
import com.pitchedapps.frost.compose.webview.FrostWebCompose
import com.pitchedapps.frost.ext.WebTargetId
@ -59,6 +60,7 @@ fun MainScreenWebView(modifier: Modifier = Modifier, homeTabs: List<MainTabItem>
Scaffold(
modifier = modifier,
containerColor = Color.Transparent,
topBar = { MainTopBar(modifier = modifier) },
bottomBar = {
MainBottomBar(

View File

@ -0,0 +1,54 @@
/*
* Copyright 2023 Allan Wang
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package com.pitchedapps.frost.view
import android.content.Context
import android.graphics.Color
import android.util.AttributeSet
import com.pitchedapps.frost.hilt.Frost
import dagger.hilt.android.AndroidEntryPoint
import java.util.Optional
import javax.inject.Inject
@AndroidEntryPoint
class FrostWebView
@JvmOverloads
constructor(context: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) :
NestedWebView(context, attrs, defStyleAttr) {
@Inject @Frost lateinit var userAgent: Optional<String>
init {
userAgent.ifPresent {
settings.userAgentString = it
println("Set user agent to $it")
}
with(settings) {
// noinspection SetJavaScriptEnabled
javaScriptEnabled = true
mediaPlaybackRequiresUserGesture = false // TODO check if we need this
allowFileAccess = true
// textZoom
domStorageEnabled = true
setLayerType(LAYER_TYPE_HARDWARE, null)
setBackgroundColor(Color.TRANSPARENT)
// Download listener
// JS Interface
}
}
}

View File

@ -30,7 +30,7 @@ import androidx.core.view.ViewCompat
*
* Webview extension that handles nested scrolls
*/
class NestedWebView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
open class NestedWebView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
WebView(context, attrs, defStyleAttr), NestedScrollingChild3 {
// No JvmOverloads due to hilt
@ -109,21 +109,17 @@ class NestedWebView(context: Context, attrs: AttributeSet?, defStyleAttr: Int) :
override fun isNestedScrollingEnabled() = childHelper.isNestedScrollingEnabled
override fun startNestedScroll(axes: Int, type: Int): Boolean {
TODO("not implemented")
}
override fun startNestedScroll(axes: Int, type: Int): Boolean =
childHelper.startNestedScroll(axes, type)
override fun startNestedScroll(axes: Int) = childHelper.startNestedScroll(axes)
override fun stopNestedScroll(type: Int) {
TODO("not implemented")
}
override fun stopNestedScroll(type: Int) = childHelper.stopNestedScroll(type)
override fun stopNestedScroll() = childHelper.stopNestedScroll()
override fun hasNestedScrollingParent(type: Int): Boolean {
TODO("not implemented")
}
override fun hasNestedScrollingParent(type: Int): Boolean =
childHelper.hasNestedScrollingParent(type)
override fun hasNestedScrollingParent() = childHelper.hasNestedScrollingParent()

View File

@ -17,6 +17,7 @@
package com.pitchedapps.frost.webview
import android.graphics.Bitmap
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebResourceResponse
import android.webkit.WebView
@ -26,6 +27,7 @@ import com.pitchedapps.frost.ext.WebTargetId
import com.pitchedapps.frost.facebook.FACEBOOK_BASE_COM
import com.pitchedapps.frost.facebook.WWW_FACEBOOK_COM
import com.pitchedapps.frost.facebook.isExplicitIntent
import com.pitchedapps.frost.facebook.isFacebookUrl
import com.pitchedapps.frost.web.FrostWebHelper
import com.pitchedapps.frost.web.state.FrostWebStore
import com.pitchedapps.frost.web.state.TabAction
@ -132,21 +134,23 @@ class FrostWebViewClient(
// refresh.offer(true)
}
// private fun injectBackgroundColor() {
// web?.setBackgroundColor(
// when {
// isMain -> Color.TRANSPARENT
// web.url.isFacebookUrl -> themeProvider.bgColor.withAlpha(255)
// else -> Color.WHITE
// }
// )
// }
// private fun WebView.injectBackgroundColor(url: String?) {
// setBackgroundColor(
// when {
// isMain -> Color.TRANSPARENT
// url.isFacebookUrl -> themeProvider.bgColor.withAlpha(255)
// else -> Color.WHITE
// }
// )
// }
override fun onPageCommitVisible(view: WebView, url: String?) {
super.onPageCommitVisible(view, url)
frostJsInjectors.injectOnPageCommitVisible(view, url)
when {
url.isFacebookUrl -> frostJsInjectors.facebookInjectOnPageCommitVisible(view, url)
}
}
// injectBackgroundColor()
// when {
// url.isFacebookUrl -> {
// v { "FB Page commit visible" }
@ -251,6 +255,14 @@ class FrostWebViewClient(
return super.shouldOverrideUrlLoading(view, request)
}
override fun onReceivedError(
view: WebView?,
request: WebResourceRequest?,
error: WebResourceError?
) {
super.onReceivedError(view, request, error)
}
companion object {
private val logger = FluentLogger.forEnclosingClass()
}

View File

@ -20,6 +20,8 @@ import android.content.Context
import android.webkit.WebView
import com.google.common.flogger.FluentLogger
import com.pitchedapps.frost.webview.injection.assets.JsActions
import com.pitchedapps.frost.webview.injection.assets.JsAssets
import com.pitchedapps.frost.webview.injection.assets.inject
import dagger.hilt.android.qualifiers.ApplicationContext
import java.io.BufferedReader
import java.io.FileNotFoundException
@ -37,9 +39,9 @@ internal constructor(
@Volatile private var theme: JsInjector = JsInjector.EMPTY
fun injectOnPageCommitVisible(view: WebView, url: String?) {
fun facebookInjectOnPageCommitVisible(view: WebView, url: String?) {
logger.atInfo().log("inject page commit visible %b", theme != JsInjector.EMPTY)
theme.inject(view)
listOf(theme, JsAssets.CLICK_A).inject(view)
}
private fun getTheme(): JsInjector {
@ -49,7 +51,8 @@ internal constructor(
.open("frost/css/facebook/themes/material_glass.css")
.bufferedReader()
.use(BufferedReader::readText)
JsBuilder().css(content).build()
logger.atInfo().log("css %s", content)
JsBuilder().css(content).single("material_glass").build()
} catch (e: FileNotFoundException) {
logger.atSevere().withCause(e).log("CssAssets file not found")
JsActions.EMPTY

View File

@ -75,7 +75,6 @@ class JsBuilder {
val tag = this.tag
val builder =
StringBuilder().apply {
append("!function(){")
if (css.isNotBlank()) {
val cssMin = css.replace(Regex("\\s*\n\\s*"), "")
append("var a=document.createElement('style');")
@ -89,16 +88,18 @@ class JsBuilder {
append(js)
}
}
var content = builder.append("}()").toString()
var content = builder.toString()
if (tag != null) {
content = singleInjector(tag, content)
}
return content
return wrapAnonymous(content)
}
private fun wrapAnonymous(body: String) = "(function(){$body})();"
private fun singleInjector(tag: String, content: String) =
"""
if (!window.hasOwnProperty("$tag") {
if (!window.hasOwnProperty("$tag")) {
console.log("Registering $tag");
window.$tag = true;
$content

View File

@ -75,3 +75,7 @@ enum class JsAssets(private val singleLoad: Boolean = true) : JsInjector {
withContext(Dispatchers.IO) { JsAssets.values().forEach { it.load(context) } }
}
}
fun List<JsInjector>.inject(webView: WebView) {
forEach { it.inject(webView) }
}