mirror of
https://github.com/AllanWang/Frost-for-Facebook.git
synced 2024-09-19 15:11:42 +02:00
Fix theming
This commit is contained in:
parent
f13b2d2998
commit
37f53e35f2
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -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))
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
@ -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/"
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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")
|
||||
|
@ -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(
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
@ -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()
|
||||
|
||||
|
@ -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()
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -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) }
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user