Skip to content
This repository was archived by the owner on Apr 10, 2026. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
75 changes: 56 additions & 19 deletions app/src/main/kotlin/com/metrolist/music/MainActivity.kt
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ import com.metrolist.innertube.models.SongItem
import com.metrolist.innertube.models.WatchEndpoint
import com.metrolist.music.constants.AppBarHeight
import com.metrolist.music.constants.AppLanguageKey
import com.metrolist.music.constants.ApplyDynamicThemeToAppKey
import com.metrolist.music.constants.CheckForUpdatesKey
import com.metrolist.music.constants.DarkModeKey
import com.metrolist.music.constants.DefaultOpenTabKey
Expand All @@ -137,9 +138,11 @@ import com.metrolist.music.constants.PureBlackKey
import com.metrolist.music.constants.SYSTEM_DEFAULT
import com.metrolist.music.constants.SlimNavBarHeight
import com.metrolist.music.constants.SlimNavBarKey
import com.metrolist.music.constants.StaticThemeColorKey
import com.metrolist.music.constants.StopMusicOnTaskClearKey
import com.metrolist.music.constants.UpdateNotificationsEnabledKey
import com.metrolist.music.constants.UseNewMiniPlayerDesignKey
import com.metrolist.music.constants.UseSystemMaterialYouKey
import com.metrolist.music.db.MusicDatabase
import com.metrolist.music.db.entities.SearchHistory
import com.metrolist.music.extensions.toEnum
Expand Down Expand Up @@ -371,7 +374,11 @@ class MainActivity : ComponentActivity() {
}
}

val enableDynamicTheme by rememberPreference(DynamicThemeKey, defaultValue = true)
val dynamicTheme by rememberPreference(DynamicThemeKey, defaultValue = true)
val applyDynamicThemeToApp by rememberPreference(ApplyDynamicThemeToAppKey, defaultValue = true)
val useSystemMaterialYou by rememberPreference(UseSystemMaterialYouKey, defaultValue = true)
val staticThemeColor by rememberPreference(StaticThemeColorKey, defaultValue = DefaultThemeColor.toArgb())

val darkTheme by rememberEnumPreference(DarkModeKey, defaultValue = DarkMode.AUTO)
val isSystemInDarkTheme = isSystemInDarkTheme()
val useDarkTheme = remember(darkTheme, isSystemInDarkTheme) {
Expand All @@ -387,14 +394,14 @@ class MainActivity : ComponentActivity() {
pureBlackEnabled && useDarkTheme
}

var themeColor by rememberSaveable(stateSaver = ColorSaver) {
var albumArtColor by rememberSaveable(stateSaver = ColorSaver) {
mutableStateOf(DefaultThemeColor)
}

LaunchedEffect(playerConnection, enableDynamicTheme) {
LaunchedEffect(playerConnection, dynamicTheme) {
val playerConnection = playerConnection
if (!enableDynamicTheme || playerConnection == null) {
themeColor = DefaultThemeColor
if (!dynamicTheme || playerConnection == null) {
albumArtColor = DefaultThemeColor
return@LaunchedEffect
}

Expand All @@ -412,22 +419,40 @@ class MainActivity : ComponentActivity() {
.crossfade(false)
.build()
)
themeColor = result.image?.toBitmap()?.extractThemeColor() ?: DefaultThemeColor
albumArtColor = result.image?.toBitmap()?.extractThemeColor() ?: DefaultThemeColor
} catch (e: Exception) {
// Fallback to default on error
themeColor = DefaultThemeColor
albumArtColor = DefaultThemeColor
}
}
} else {
themeColor = DefaultThemeColor
albumArtColor = DefaultThemeColor
}
}
}

val appThemeColor = remember(albumArtColor, dynamicTheme, applyDynamicThemeToApp, useSystemMaterialYou, staticThemeColor) {
if (dynamicTheme && applyDynamicThemeToApp && albumArtColor != DefaultThemeColor) {
albumArtColor
} else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S && useSystemMaterialYou) {
DefaultThemeColor
} else {
Color(staticThemeColor)
}
}

val playerThemeColor = remember(albumArtColor, dynamicTheme, appThemeColor) {
if (dynamicTheme && albumArtColor != DefaultThemeColor) {
albumArtColor
} else {
appThemeColor
}
}

MetrolistTheme(
darkTheme = useDarkTheme,
pureBlack = pureBlack,
themeColor = themeColor,
themeColor = appThemeColor,
) {
BoxWithConstraints(
modifier = Modifier
Expand Down Expand Up @@ -789,11 +814,17 @@ class MainActivity : ComponentActivity() {

if (!showRail && currentRoute != "wrapped") {
Box {
BottomSheetPlayer(
state = playerBottomSheetState,
navController = navController,
pureBlack = pureBlack
)
MetrolistTheme(
darkTheme = useDarkTheme,
pureBlack = pureBlack,
themeColor = playerThemeColor,
) {
BottomSheetPlayer(
state = playerBottomSheetState,
navController = navController,
pureBlack = pureBlack
)
}
Comment on lines +817 to +827

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

There's duplicated code for wrapping the BottomSheetPlayer with MetrolistTheme. This logic appears again on lines 871-881. To improve maintainability and reduce redundancy, consider extracting this themed player into its own composable function or a variable.


AppNavigationBar(
navigationItems = navigationItems,
Expand Down Expand Up @@ -837,11 +868,17 @@ class MainActivity : ComponentActivity() {
}
} else {
if (currentRoute != "wrapped") {
BottomSheetPlayer(
state = playerBottomSheetState,
navController = navController,
pureBlack = pureBlack
)
MetrolistTheme(
darkTheme = useDarkTheme,
pureBlack = pureBlack,
themeColor = playerThemeColor,
) {
BottomSheetPlayer(
state = playerBottomSheetState,
navController = navController,
pureBlack = pureBlack
)
}
}

Box(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ import java.time.ZoneOffset

val EnableDynamicIconKey = booleanPreferencesKey("enableDynamicIcon")
val DynamicThemeKey = booleanPreferencesKey("dynamicTheme")
val ApplyDynamicThemeToAppKey = booleanPreferencesKey("applyDynamicThemeToApp")
val StaticThemeColorKey = intPreferencesKey("staticThemeColor")
val UseSystemMaterialYouKey = booleanPreferencesKey("useSystemMaterialYou")
val DarkModeKey = stringPreferencesKey("darkMode")
val PureBlackKey = booleanPreferencesKey("pureBlack")
val PureBlackMiniPlayerKey = booleanPreferencesKey("pureBlackMiniPlayer")
Expand Down
Loading