From fd2cbf25f5744a939ef6245809a1655e013a6420 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Sun, 10 Jan 2021 22:29:01 -0800 Subject: Start converting pref colors into themeProvider colors --- .../com/pitchedapps/frost/injectors/CssAsset.kt | 36 +++++ .../com/pitchedapps/frost/injectors/CssAssets.kt | 115 ---------------- .../pitchedapps/frost/injectors/CssSmallAssets.kt | 36 ----- .../pitchedapps/frost/injectors/ThemeProvider.kt | 146 +++++++++++++++++++++ 4 files changed, 182 insertions(+), 151 deletions(-) create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAsset.kt delete mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt delete mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/CssSmallAssets.kt create mode 100644 app/src/main/kotlin/com/pitchedapps/frost/injectors/ThemeProvider.kt (limited to 'app/src/main/kotlin/com/pitchedapps/frost/injectors') diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAsset.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAsset.kt new file mode 100644 index 00000000..b384efad --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAsset.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2020 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 . + */ +package com.pitchedapps.frost.injectors + +import android.webkit.WebView +import com.pitchedapps.frost.prefs.Prefs + +/** + * Small misc inline css assets + */ +enum class CssAsset(private val content: String) : InjectorContract { + FullSizeImage("div._4prr[style*=\"max-width\"][style*=\"max-height\"]{max-width:none !important;max-height:none !important}") + ; + + val injector: JsInjector by lazy { + JsBuilder().css(content).single("css-small-assets-$name").build() + } + + override fun inject(webView: WebView, prefs: Prefs) { + injector.inject(webView, prefs) + } +} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt deleted file mode 100644 index e012de3f..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssAssets.kt +++ /dev/null @@ -1,115 +0,0 @@ -/* - * Copyright 2018 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 . - */ -package com.pitchedapps.frost.injectors - -import android.content.Context -import android.graphics.Color -import android.webkit.WebView -import androidx.annotation.VisibleForTesting -import ca.allanwang.kau.utils.adjustAlpha -import ca.allanwang.kau.utils.colorToBackground -import ca.allanwang.kau.utils.colorToForeground -import ca.allanwang.kau.utils.toRgbaString -import ca.allanwang.kau.utils.use -import ca.allanwang.kau.utils.withAlpha -import com.pitchedapps.frost.prefs.Prefs -import com.pitchedapps.frost.utils.L -import java.io.BufferedReader -import java.io.FileNotFoundException -import java.util.Locale -import kotlinx.coroutines.Dispatchers -import kotlinx.coroutines.withContext - -private const val THEME_FOLDER = "themes" - -/** - * Created by Allan Wang on 2017-05-31. - * Mapping of the available assets - * The enum name must match the css file name - */ -enum class CssAssets(val folder: String = THEME_FOLDER) : InjectorContract { - MATERIAL_LIGHT, MATERIAL_DARK, MATERIAL_AMOLED, MATERIAL_GLASS, CUSTOM - ; - - @VisibleForTesting - internal val file = "${name.toLowerCase(Locale.CANADA)}.css" - - /** - * Note that while this can be loaded from any thread, it is typically done through [load] - */ - private var injector: JsInjector? = null - - private fun injector(context: Context, prefs: Prefs): JsInjector = - injector ?: createInjector(context, prefs).also { injector = it } - - /** - * Note that while this can be loaded from any thread, it is typically done through [load] - */ - private fun createInjector(context: Context, prefs: Prefs): JsInjector = - try { - var content = - context.assets.open("css/$folder/$file").bufferedReader() - .use(BufferedReader::readText) - if (this == CUSTOM) { - val bt = if (Color.alpha(prefs.bgColor) == 255) - prefs.bgColor.toRgbaString() - else - "transparent" - - val bb = prefs.bgColor.colorToForeground(0.35f) - - content = content - .replace("\$T\$", prefs.textColor.toRgbaString()) - .replace("\$TT\$", prefs.textColor.colorToBackground(0.05f).toRgbaString()) - .replace("\$A\$", prefs.accentColor.toRgbaString()) - .replace("\$AT\$", prefs.iconColor.toRgbaString()) - .replace("\$B\$", prefs.bgColor.toRgbaString()) - .replace("\$BT\$", bt) - .replace("\$BBT\$", bb.withAlpha(51).toRgbaString()) - .replace("\$O\$", prefs.bgColor.withAlpha(255).toRgbaString()) - .replace("\$OO\$", bb.withAlpha(255).toRgbaString()) - .replace("\$D\$", prefs.textColor.adjustAlpha(0.3f).toRgbaString()) - .replace("\$TI\$", bb.withAlpha(60).toRgbaString()) - .replace("\$C\$", bt) - } - JsBuilder().css(content).build() - } catch (e: FileNotFoundException) { - L.e(e) { "CssAssets file not found" } - JsInjector(JsActions.EMPTY.function) - } - - override fun inject(webView: WebView, prefs: Prefs) = - injector(webView.context, prefs).inject(webView, prefs) - - fun reset() { - injector = null - } - - companion object { - - // Ensures that all non themes and the selected theme are loaded - suspend fun load(context: Context, prefs: Prefs) { - withContext(Dispatchers.IO) { - val currentTheme = prefs.themeInjector as? CssAssets - val (themes, others) = values().partition { it.folder == THEME_FOLDER } - themes.filter { it != currentTheme }.forEach { it.reset() } - currentTheme?.injector(context, prefs) - others.forEach { it.injector(context, prefs) } - } - } - } -} \ No newline at end of file diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssSmallAssets.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssSmallAssets.kt deleted file mode 100644 index 30ee7a8f..00000000 --- a/app/src/main/kotlin/com/pitchedapps/frost/injectors/CssSmallAssets.kt +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright 2020 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 . - */ -package com.pitchedapps.frost.injectors - -import android.webkit.WebView -import com.pitchedapps.frost.prefs.Prefs - -/** - * Small misc inline css assets - */ -enum class CssSmallAssets(private val content: String) : InjectorContract { - FullSizeImage("div._4prr[style*=\"max-width\"][style*=\"max-height\"]{max-width:none !important;max-height:none !important}") - ; - - val injector: JsInjector by lazy { - JsBuilder().css(content).single("css-small-assets-$name").build() - } - - override fun inject(webView: WebView, prefs: Prefs) { - injector.inject(webView, prefs) - } -} diff --git a/app/src/main/kotlin/com/pitchedapps/frost/injectors/ThemeProvider.kt b/app/src/main/kotlin/com/pitchedapps/frost/injectors/ThemeProvider.kt new file mode 100644 index 00000000..5a9576d2 --- /dev/null +++ b/app/src/main/kotlin/com/pitchedapps/frost/injectors/ThemeProvider.kt @@ -0,0 +1,146 @@ +/* + * Copyright 2018 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 . + */ +package com.pitchedapps.frost.injectors + +import android.content.Context +import android.graphics.Color +import ca.allanwang.kau.utils.adjustAlpha +import ca.allanwang.kau.utils.colorToBackground +import ca.allanwang.kau.utils.colorToForeground +import ca.allanwang.kau.utils.isColorVisibleOn +import ca.allanwang.kau.utils.toRgbaString +import ca.allanwang.kau.utils.use +import ca.allanwang.kau.utils.withAlpha +import com.pitchedapps.frost.enums.FACEBOOK_BLUE +import com.pitchedapps.frost.enums.Theme +import com.pitchedapps.frost.enums.ThemeCategory +import com.pitchedapps.frost.prefs.Prefs +import com.pitchedapps.frost.utils.L +import java.io.BufferedReader +import java.io.FileNotFoundException +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext + +/** + * Created by Allan Wang on 2017-05-31. + * Mapping of the available assets + * The enum name must match the css file name + */ +class ThemeProvider(private val context: Context, private val prefs: Prefs) { + + var theme: Theme = Theme.values[prefs.theme] + + private val injectors: MutableMap = mutableMapOf() + + val textColor: Int + get() = theme.textColorGetter(prefs) + + val accentColor: Int + get() = theme.accentColorGetter(prefs) + + val accentColorForWhite: Int + get() = when { + accentColor.isColorVisibleOn(Color.WHITE) -> accentColor + textColor.isColorVisibleOn(Color.WHITE) -> textColor + else -> FACEBOOK_BLUE + } + + val nativeBgColor: Int + get() = bgColor.withAlpha(30) + + fun nativeBgColor(unread: Boolean) = bgColor + .colorToForeground(if (unread) 0.7f else 0.0f) + .withAlpha(30) + + val bgColor: Int + get() = theme.backgroundColorGetter(prefs) + + val headerColor: Int + get() = theme.headerColorGetter(prefs) + + val iconColor: Int + get() = theme.iconColorGetter(prefs) + + val isCustomTheme: Boolean + get() = theme == Theme.CUSTOM + + /** + * Note that while this can be loaded from any thread, it is typically done through [preload]] + */ + fun injector(category: ThemeCategory): InjectorContract = + injectors.getOrPut(category) { createInjector(category) } + + /** + * Note that while this can be loaded from any thread, it is typically done through [preload] + */ + private fun createInjector(category: ThemeCategory): InjectorContract { + val file = theme.file ?: return JsActions.EMPTY + try { + var content = + context.assets.open("css/${category.folder}/theme/${file}").bufferedReader() + .use(BufferedReader::readText) + if (theme == Theme.CUSTOM) { + val bt = if (Color.alpha(prefs.bgColor) == 255) + prefs.bgColor.toRgbaString() + else + "transparent" + + val bb = prefs.bgColor.colorToForeground(0.35f) + + content = content + .replace("\$T\$", prefs.textColor.toRgbaString()) + .replace("\$TT\$", prefs.textColor.colorToBackground(0.05f).toRgbaString()) + .replace("\$A\$", prefs.accentColor.toRgbaString()) + .replace("\$AT\$", prefs.iconColor.toRgbaString()) + .replace("\$B\$", prefs.bgColor.toRgbaString()) + .replace("\$BT\$", bt) + .replace("\$BBT\$", bb.withAlpha(51).toRgbaString()) + .replace("\$O\$", prefs.bgColor.withAlpha(255).toRgbaString()) + .replace("\$OO\$", bb.withAlpha(255).toRgbaString()) + .replace("\$D\$", prefs.textColor.adjustAlpha(0.3f).toRgbaString()) + .replace("\$TI\$", bb.withAlpha(60).toRgbaString()) + .replace("\$C\$", bt) + } + return JsBuilder().css(content).build() + } catch (e: FileNotFoundException) { + L.e(e) { "CssAssets file not found" } + return JsActions.EMPTY + } + } + + fun setTheme(id: Int) { + theme = Theme.values[id] + reset() + } + + fun reset() { + injectors.clear() + } + + suspend fun preload() { + withContext(Dispatchers.IO) { + reset() + ThemeCategory.values().forEach { injector(it) } + } + } + + companion object { + fun module() = org.koin.dsl.module { + single { ThemeProvider(get(), get()) } + } + } +} \ No newline at end of file -- cgit v1.2.3