package com.github.libretube.helpers import android.app.Activity import android.content.Context import android.content.res.Configuration import android.graphics.Color import android.text.Spanned import androidx.appcompat.app.AppCompatActivity import androidx.appcompat.app.AppCompatDelegate import androidx.core.text.HtmlCompat import androidx.core.text.parseAsHtml import com.github.libretube.R import com.github.libretube.constants.PreferenceKeys import com.github.libretube.ui.adapters.IconsSheetAdapter import com.google.android.material.color.DynamicColors import com.google.android.material.color.MaterialColors object ThemeHelper { /** * Set the theme, including accent color and night mode */ fun updateTheme(activity: AppCompatActivity) { var accentColor = PreferenceHelper.getString(PreferenceKeys.ACCENT_COLOR, "") if (accentColor.isEmpty()) { accentColor = if (DynamicColors.isDynamicColorAvailable()) "my" else "blue" PreferenceHelper.putString(PreferenceKeys.ACCENT_COLOR, accentColor) } activity.setTheme(getTheme(accentColor)) if (accentColor == "my") DynamicColors.applyToActivityIfAvailable(activity) val pureThemeEnabled = PreferenceHelper.getBoolean( PreferenceKeys.PURE_THEME, false ) if (pureThemeEnabled) activity.theme.applyStyle(R.style.Pure, true) } /** * Update the accent color of the app and apply dynamic colors if needed */ private fun getTheme(accentColor: String): Int { return when (accentColor) { // set the accent color, use the pure black/white theme if enabled "my" -> R.style.BaseTheme "red" -> R.style.Theme_Red "blue" -> R.style.Theme_Blue "yellow" -> R.style.Theme_Yellow "green" -> R.style.Theme_Green "purple" -> R.style.Theme_Purple "monochrome" -> R.style.Theme_Monochrome "violet" -> R.style.Theme_Violet else -> throw IllegalArgumentException() } } fun applyDialogActivityTheme(activity: Activity) { activity.theme.applyStyle(R.style.DialogActivity, true) } /** * set the theme mode (light, dark, auto) */ fun getThemeMode(themeMode: String): Int { return when (themeMode) { "A" -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM "L" -> AppCompatDelegate.MODE_NIGHT_NO "D" -> AppCompatDelegate.MODE_NIGHT_YES else -> AppCompatDelegate.MODE_NIGHT_FOLLOW_SYSTEM } } /** * change the app icon */ fun changeIcon(context: Context, newLogoActivityAlias: String) { // Branding is intentionally fixed to the red YouTube-style launcher icon. // Keep this method for settings compatibility, but never enable legacy aliases. PreferenceHelper.putString(PreferenceKeys.APP_ICON, IconsSheetAdapter.Companion.AppIcon.Default.activityAlias) } /** * Get a color by a color resource attr */ fun getThemeColor(context: Context, colorCode: Int) = MaterialColors.getColor(context, colorCode, Color.TRANSPARENT) /** * Get the styled app name */ fun getStyledAppName(context: Context): Spanned { val colorPrimary = getThemeColor(context, androidx.appcompat.R.attr.colorPrimaryDark) val hexColor = "#%06X".format(0xFFFFFF and colorPrimary) return "LibreTube" .parseAsHtml(HtmlCompat.FROM_HTML_MODE_COMPACT) } fun isDarkMode(context: Context): Boolean { val darkModeFlag = context.resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK return darkModeFlag == Configuration.UI_MODE_NIGHT_YES } }