Added ability to extract accent color from wallpaper on 8.1+ devices

This commit is contained in:
Prathamesh More 2022-01-17 13:53:25 +05:30
parent 09ad243a14
commit 9d1018c03c
16 changed files with 117 additions and 6 deletions

View file

@ -69,6 +69,7 @@
<h2>v5.6.4</h2> <h2>v5.6.4</h2>
<h3>What's New</h3> <h3>What's New</h3>
<ul> <ul>
<li>Added accent color extraction on Android 8.1+ devices</li>
<li>Added Collapsing appbar to library tabs with an option to switch back to simple appbar <li>Added Collapsing appbar to library tabs with an option to switch back to simple appbar
</li> </li>
<li>Added Search tab</li> <li>Added Search tab</li>

View file

@ -20,6 +20,7 @@ import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID import code.name.monkey.retromusic.Constants.PRO_VERSION_PRODUCT_ID
import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager import code.name.monkey.retromusic.appshortcuts.DynamicShortcutManager
import code.name.monkey.retromusic.helper.WallpaperAccentManager
import com.anjlab.android.iab.v3.BillingProcessor import com.anjlab.android.iab.v3.BillingProcessor
import com.anjlab.android.iab.v3.PurchaseInfo import com.anjlab.android.iab.v3.PurchaseInfo
import org.koin.android.ext.koin.androidContext import org.koin.android.ext.koin.androidContext
@ -28,6 +29,7 @@ import org.koin.core.context.startKoin
class App : Application() { class App : Application() {
lateinit var billingProcessor: BillingProcessor lateinit var billingProcessor: BillingProcessor
private val wallpaperAccentManager = WallpaperAccentManager(this)
override fun onCreate() { override fun onCreate() {
super.onCreate() super.onCreate()
@ -44,6 +46,7 @@ class App : Application() {
.coloredNavigationBar(true) .coloredNavigationBar(true)
.commit() .commit()
} }
wallpaperAccentManager.init()
if (VersionUtils.hasNougatMR()) if (VersionUtils.hasNougatMR())
DynamicShortcutManager(this).initDynamicShortcuts() DynamicShortcutManager(this).initDynamicShortcuts()
@ -71,6 +74,7 @@ class App : Application() {
override fun onTerminate() { override fun onTerminate() {
super.onTerminate() super.onTerminate()
billingProcessor.release() billingProcessor.release()
wallpaperAccentManager.release()
} }
companion object { companion object {

View file

@ -159,3 +159,4 @@ const val PLAYBACK_SPEED = "playback_speed"
const val PLAYBACK_PITCH = "playback_pitch" const val PLAYBACK_PITCH = "playback_pitch"
const val CUSTOM_FONT = "custom_font" const val CUSTOM_FONT = "custom_font"
const val APPBAR_MODE = "appbar_mode" const val APPBAR_MODE = "appbar_mode"
const val WALLPAPER_ACCENT = "wallpaper_accent"

View file

@ -147,7 +147,7 @@ class MainActivity : AbsCastActivity(), OnSharedPreferenceChangeListener {
} }
override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) { override fun onSharedPreferenceChanged(sharedPreferences: SharedPreferences?, key: String?) {
if (key == GENERAL_THEME || key == MATERIAL_YOU || key == BLACK_THEME || key == ADAPTIVE_COLOR_APP || key == USER_NAME || key == TOGGLE_FULL_SCREEN || key == TOGGLE_VOLUME || key == ROUND_CORNERS || key == CAROUSEL_EFFECT || key == NOW_PLAYING_SCREEN_ID || key == TOGGLE_GENRE || key == BANNER_IMAGE_PATH || key == PROFILE_IMAGE_PATH || key == CIRCULAR_ALBUM_ART || key == KEEP_SCREEN_ON || key == TOGGLE_SEPARATE_LINE || key == TOGGLE_HOME_BANNER || key == TOGGLE_ADD_CONTROLS || key == ALBUM_COVER_STYLE || key == HOME_ARTIST_GRID_STYLE || key == ALBUM_COVER_TRANSFORM || key == DESATURATED_COLOR || key == EXTRA_SONG_INFO || key == TAB_TEXT_MODE || key == LANGUAGE_NAME || key == LIBRARY_CATEGORIES || key == CUSTOM_FONT|| key == APPBAR_MODE) { if (key == GENERAL_THEME || key == MATERIAL_YOU || key == WALLPAPER_ACCENT || key == BLACK_THEME || key == ADAPTIVE_COLOR_APP || key == USER_NAME || key == TOGGLE_FULL_SCREEN || key == TOGGLE_VOLUME || key == ROUND_CORNERS || key == CAROUSEL_EFFECT || key == NOW_PLAYING_SCREEN_ID || key == TOGGLE_GENRE || key == BANNER_IMAGE_PATH || key == PROFILE_IMAGE_PATH || key == CIRCULAR_ALBUM_ART || key == KEEP_SCREEN_ON || key == TOGGLE_SEPARATE_LINE || key == TOGGLE_HOME_BANNER || key == TOGGLE_ADD_CONTROLS || key == ALBUM_COVER_STYLE || key == HOME_ARTIST_GRID_STYLE || key == ALBUM_COVER_TRANSFORM || key == DESATURATED_COLOR || key == EXTRA_SONG_INFO || key == TAB_TEXT_MODE || key == LANGUAGE_NAME || key == LIBRARY_CATEGORIES || key == CUSTOM_FONT|| key == APPBAR_MODE) {
postRecreate() postRecreate()
} }
} }

View file

@ -14,6 +14,7 @@
*/ */
package code.name.monkey.retromusic.fragments.settings package code.name.monkey.retromusic.fragments.settings
import android.annotation.SuppressLint
import android.os.Build import android.os.Build
import android.os.Bundle import android.os.Bundle
import androidx.preference.Preference import androidx.preference.Preference
@ -37,6 +38,7 @@ import com.google.android.material.color.DynamicColors
*/ */
class ThemeSettingsFragment : AbsSettingsFragment() { class ThemeSettingsFragment : AbsSettingsFragment() {
@SuppressLint("CheckResult")
override fun invalidateSettings() { override fun invalidateSettings() {
val generalTheme: Preference? = findPreference(GENERAL_THEME) val generalTheme: Preference? = findPreference(GENERAL_THEME)
generalTheme?.let { generalTheme?.let {
@ -121,6 +123,11 @@ class ThemeSettingsFragment : AbsSettingsFragment() {
restartActivity() restartActivity()
true true
} }
val wallpaperAccent: ATESwitchPreference? = findPreference(WALLPAPER_ACCENT)
wallpaperAccent?.setOnPreferenceChangeListener { _, _ ->
restartActivity()
true
}
val customFont: ATESwitchPreference? = findPreference(CUSTOM_FONT) val customFont: ATESwitchPreference? = findPreference(CUSTOM_FONT)
customFont?.setOnPreferenceChangeListener { _, _ -> customFont?.setOnPreferenceChangeListener { _, _ ->
restartActivity() restartActivity()

View file

@ -0,0 +1,40 @@
package code.name.monkey.retromusic.helper
import android.app.WallpaperManager
import android.content.Context
import android.os.Build
import android.os.Handler
import android.os.Looper
import androidx.annotation.RequiresApi
import code.name.monkey.appthemehelper.ThemeStore
import code.name.monkey.appthemehelper.util.VersionUtils
import code.name.monkey.retromusic.util.PreferenceUtil
class WallpaperAccentManager(val context: Context) {
@RequiresApi(Build.VERSION_CODES.O_MR1)
private val onColorsChangedListener =
WallpaperManager.OnColorsChangedListener { colors, which ->
if (which == WallpaperManager.FLAG_SYSTEM && colors != null) {
ThemeStore.editTheme(context).wallpaperColor(colors.primaryColor.toArgb()).commit()
}
}
fun init() {
if (VersionUtils.hasOreoMR1() && PreferenceUtil.wallpaperAccent) {
WallpaperManager.getInstance(context).apply {
addOnColorsChangedListener(onColorsChangedListener, Handler(Looper.getMainLooper()))
ThemeStore.editTheme(context).wallpaperColor(
getWallpaperColors(WallpaperManager.FLAG_SYSTEM)?.primaryColor?.toArgb() ?: 0
).commit()
}
}
}
fun release() {
if (VersionUtils.hasOreoMR1()) {
WallpaperManager.getInstance(context)
.removeOnColorsChangedListener(onColorsChangedListener)
}
}
}

View file

@ -696,6 +696,9 @@ object PreferenceUtil {
} else { } else {
TopAppBarLayout.AppBarMode.SIMPLE TopAppBarLayout.AppBarMode.SIMPLE
} }
val wallpaperAccent
get() = sharedPreferences.getBoolean(WALLPAPER_ACCENT, VersionUtils.hasOreoMR1() && !VersionUtils.hasS())
} }
enum class LyricsType { enum class LyricsType {
REPLACE_LYRICS, OVER_LYRICS REPLACE_LYRICS, OVER_LYRICS

View file

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<bool name="wallpaper_accent_enabled">true</bool>
<bool name="wallpaper_accent_visible">true</bool>
</resources>

View file

@ -5,4 +5,6 @@
<bool name="colored_notification_available">false</bool> <bool name="colored_notification_available">false</bool>
<integer name="overScrollMode">0</integer> <integer name="overScrollMode">0</integer>
<bool name="wallpaper_accent_enabled">false</bool>
<bool name="wallpaper_accent_visible">false</bool>
</resources> </resources>

View file

@ -30,4 +30,7 @@
<bool name="colored_notification_available">true</bool> <bool name="colored_notification_available">true</bool>
<integer name="overScrollMode">2</integer> <integer name="overScrollMode">2</integer>
<bool name="allowBackup">true</bool> <bool name="allowBackup">true</bool>
<bool name="wallpaper_accent_enabled">false</bool>
<bool name="wallpaper_accent_visible">false</bool>
</resources> </resources>

View file

@ -534,4 +534,6 @@
<string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string> <string name="your_account_data_is_only_used_for_authentication">Your account data is only used for authentication.</string>
<string name="new_music_mix">New Music Mix</string> <string name="new_music_mix">New Music Mix</string>
<string name="pref_title_appbar_mode">App bar mode</string> <string name="pref_title_appbar_mode">App bar mode</string>
<string name="pref_title_wallpaper_accent">Wallpaper accent color</string>
<string name="pref_summary_wallpaper_accent">Extract accent color from wallpaper</string>
</resources> </resources>

View file

@ -43,6 +43,14 @@
android:layout="@layout/preference_category_title" android:layout="@layout/preference_category_title"
android:title="@string/colors"> android:title="@string/colors">
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATESwitchPreference
android:defaultValue="@bool/wallpaper_accent_enabled"
android:key="wallpaper_accent"
android:layout="@layout/list_item_view_switch"
android:summary="@string/pref_summary_wallpaper_accent"
android:title="@string/pref_title_wallpaper_accent"
app:isPreferenceVisible="@bool/wallpaper_accent_visible" />
<code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference <code.name.monkey.appthemehelper.common.prefs.supportv7.ATEColorPreference
android:dependency="material_you" android:dependency="material_you"
android:key="accent_color" android:key="accent_color"

View file

@ -59,6 +59,11 @@ private constructor(private val mContext: Context) : ThemeStorePrefKeys, ThemeSt
return this return this
} }
override fun wallpaperColor(color: Int): ThemeStore {
mEditor.putInt(ThemeStorePrefKeys.KEY_WALLPAPER_COLOR, color)
return this
}
override fun accentColorRes(@ColorRes colorRes: Int): ThemeStore { override fun accentColorRes(@ColorRes colorRes: Int): ThemeStore {
return accentColor(ContextCompat.getColor(mContext, colorRes)) return accentColor(ContextCompat.getColor(mContext, colorRes))
} }
@ -211,16 +216,30 @@ private constructor(private val mContext: Context) : ThemeStorePrefKeys, ThemeSt
return ContextCompat.getColor(context, R.color.m3_accent_color) return ContextCompat.getColor(context, R.color.m3_accent_color)
} }
val desaturatedColor = prefs(context).getBoolean("desaturated_color", false) val desaturatedColor = prefs(context).getBoolean("desaturated_color", false)
val color = prefs(context).getInt( println(isWallpaperAccentEnabled(context))
ThemeStorePrefKeys.KEY_ACCENT_COLOR, val color = if (isWallpaperAccentEnabled(context)) {
resolveColor(context, R.attr.colorAccent, Color.parseColor("#263238")) wallpaperColor(context)
) } else {
prefs(context).getInt(
ThemeStorePrefKeys.KEY_ACCENT_COLOR,
resolveColor(context, R.attr.colorAccent, Color.parseColor("#263238"))
)
}
return if (isWindowBackgroundDark(context) && desaturatedColor) ColorUtil.desaturateColor( return if (isWindowBackgroundDark(context) && desaturatedColor) ColorUtil.desaturateColor(
color, color,
0.4f 0.4f
) else color ) else color
} }
@CheckResult
@ColorInt
fun wallpaperColor(context: Context): Int {
return prefs(context).getInt(
ThemeStorePrefKeys.KEY_WALLPAPER_COLOR,
resolveColor(context, R.attr.colorAccent, Color.parseColor("#263238"))
)
}
@CheckResult @CheckResult
@ColorInt @ColorInt
fun navigationBarColor(context: Context): Int { fun navigationBarColor(context: Context): Int {
@ -307,7 +326,13 @@ private constructor(private val mContext: Context) : ThemeStorePrefKeys, ThemeSt
} }
private fun isMD3Enabled(context: Context): Boolean { private fun isMD3Enabled(context: Context): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context).getBoolean(ThemeStorePrefKeys.KEY_MATERIAL_YOU, VersionUtils.hasS()) return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean(ThemeStorePrefKeys.KEY_MATERIAL_YOU, VersionUtils.hasS())
}
private fun isWallpaperAccentEnabled(context: Context): Boolean {
return PreferenceManager.getDefaultSharedPreferences(context)
.getBoolean("wallpaper_accent", VersionUtils.hasOreoMR1() && !VersionUtils.hasS())
} }
} }
} }

View file

@ -34,6 +34,8 @@ internal interface ThemeStoreInterface {
fun accentColor(@ColorInt color: Int): ThemeStore fun accentColor(@ColorInt color: Int): ThemeStore
fun wallpaperColor(@ColorInt color: Int): ThemeStore
fun accentColorRes(@ColorRes colorRes: Int): ThemeStore fun accentColorRes(@ColorRes colorRes: Int): ThemeStore
fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore fun accentColorAttr(@AttrRes colorAttr: Int): ThemeStore

View file

@ -29,5 +29,6 @@ internal interface ThemeStorePrefKeys {
const val KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark" const val KEY_AUTO_GENERATE_PRIMARYDARK = "auto_generate_primarydark"
const val KEY_MATERIAL_YOU = "material_you" const val KEY_MATERIAL_YOU = "material_you"
const val KEY_WALLPAPER_COLOR = "wallpaper_color"
} }
} }

View file

@ -35,6 +35,13 @@ object VersionUtils {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O
} }
/**
* @return true if device is running API >= 27
*/
fun hasOreoMR1(): Boolean {
return Build.VERSION.SDK_INT >= Build.VERSION_CODES.O_MR1
}
/** /**
* @return true if device is running API >= 28 * @return true if device is running API >= 28
*/ */