package sh.sar.basedbank.util import android.content.Context import android.graphics.Bitmap import android.graphics.Color import android.os.Build import androidx.appcompat.app.AppCompatActivity import com.google.android.material.color.DynamicColors import com.google.android.material.color.DynamicColorsOptions import sh.sar.basedbank.R object ThemeHelper { const val PRESET_BLUE = "blue" const val PRESET_RED = "red" const val PRESET_GREEN = "green" const val PRESET_CUSTOM = "custom" fun isSystemTheme(context: Context): Boolean = context.getSharedPreferences("prefs", Context.MODE_PRIVATE) .getString("theme", "system") == "system" fun getAccentPreset(context: Context): String = context.getSharedPreferences("prefs", Context.MODE_PRIVATE) .getString("accent_preset", PRESET_BLUE) ?: PRESET_BLUE fun getCustomColor(context: Context): Int? { val hex = context.getSharedPreferences("prefs", Context.MODE_PRIVATE) .getString("accent_custom_color", null) ?: return null return try { Color.parseColor(hex) } catch (_: Exception) { null } } fun presetSeedColor(context: Context, preset: String): Int = when (preset) { PRESET_RED -> Color.parseColor("#D32F2F") PRESET_GREEN -> Color.parseColor("#4CAF50") PRESET_CUSTOM -> getCustomColor(context) ?: Color.parseColor("#3F65AD") else -> Color.parseColor("#3F65AD") } fun isPitchBlackEnabled(context: Context): Boolean = context.getSharedPreferences("prefs", Context.MODE_PRIVATE) .getBoolean("pitch_black", false) /** * Apply the user-chosen accent theme to the given activity. * Must be called BEFORE super.onCreate() so window-level attributes * (status bar color, etc.) are resolved from the correct overlay. * Has no effect when the theme is set to "system" (dynamic colors are * handled by BasedBankApp via DynamicColors.applyToActivitiesIfAvailable). */ fun applyAccent(activity: AppCompatActivity) { if (isSystemTheme(activity)) return val preset = getAccentPreset(activity) val seed = presetSeedColor(activity, preset) if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) { val bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888) bitmap.setPixel(0, 0, seed) DynamicColors.applyToActivityIfAvailable( activity, DynamicColorsOptions.Builder().setContentBasedSource(bitmap).build() ) } else { // API < 31: apply a simple style overlay (partial palette, but functional) val styleRes = when (preset) { PRESET_RED -> R.style.ThemeOverlay_Accent_Orange PRESET_GREEN -> R.style.ThemeOverlay_Accent_Green else -> R.style.ThemeOverlay_Accent_Blue } activity.theme.applyStyle(styleRes, true) } val prefs = activity.getSharedPreferences("prefs", Context.MODE_PRIVATE) val isDark = prefs.getString("theme", "system") == "dark" if (isDark && prefs.getBoolean("pitch_black", false)) { activity.theme.applyStyle(R.style.ThemeOverlay_PitchBlack, true) } } }