Skip to content
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
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,11 @@ object AndroidSettingsCatalog : SettingsCatalog {
setting = AppearanceSettings.PureBlack,
title = StringKey.PREF_PURE_BLACK_TITLE,
summary = StringKey.PREF_PURE_BLACK_SUMMARY
),
SettingItem.Switch(
setting = AppearanceSettings.CompactMode,
title = StringKey.PREF_COMPACT_MODE_TITLE,
summary = StringKey.PREF_COMPACT_MODE_SUMMARY
)
)
),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ val StringKey.resId: Int
StringKey.PREF_COLOUR_FROM_ARTWORK_SUMMARY -> R.string.pref_colour_from_artwork_summary
StringKey.PREF_PURE_BLACK_TITLE -> R.string.pref_pure_black_title
StringKey.PREF_PURE_BLACK_SUMMARY -> R.string.pref_pure_black_summary
StringKey.PREF_COMPACT_MODE_TITLE -> R.string.pref_compact_mode_title
StringKey.PREF_COMPACT_MODE_SUMMARY -> R.string.pref_compact_mode_summary
StringKey.PREF_CATEGORY_TITLE_WIDGETS -> R.string.pref_category_title_widgets
StringKey.PREF_WIDGET_OPACITY_TITLE -> R.string.pref_widget_opacity_title
StringKey.PREF_NAVIGATION_TITLE -> R.string.pref_navigation_title
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,13 @@ package com.simplecityapps.shuttle.ui.theme
import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.material3.MaterialTheme
import androidx.compose.runtime.Composable
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.getValue
import androidx.compose.ui.graphics.Color
import androidx.lifecycle.ViewModel
import androidx.lifecycle.compose.collectAsStateWithLifecycle
import androidx.lifecycle.viewModelScope
import com.simplecityapps.shuttle.designsystem.theme.LocalCompactMode
import com.simplecityapps.shuttle.designsystem.theme.S2Accent
import com.simplecityapps.shuttle.designsystem.theme.S2Theme
import com.simplecityapps.shuttle.settings.Accent
Expand All @@ -29,7 +31,8 @@ data class AppThemeState(
val theme: ThemeMode = ThemeMode.DayNight,
val accent: Accent = Accent.Default,
val dynamicColour: Boolean = false,
val pureBlack: Boolean = false
val pureBlack: Boolean = false,
val compactMode: Boolean = false
)

/** The Appearance settings the Compose theme follows, live, so a change in Settings restyles the app without a restart. */
Expand All @@ -44,6 +47,7 @@ class AppThemeViewModel @Inject constructor(
observeSetting(AppearanceSettings.AccentColour),
observeSetting(AppearanceSettings.DynamicColour),
observeSetting(AppearanceSettings.PureBlack),
observeSetting(AppearanceSettings.CompactMode),
::AppThemeState
).stateIn(
scope = viewModelScope,
Expand All @@ -52,7 +56,8 @@ class AppThemeViewModel @Inject constructor(
theme = readSetting(AppearanceSettings.Theme),
accent = readSetting(AppearanceSettings.AccentColour),
dynamicColour = readSetting(AppearanceSettings.DynamicColour),
pureBlack = readSetting(AppearanceSettings.PureBlack)
pureBlack = readSetting(AppearanceSettings.PureBlack),
compactMode = readSetting(AppearanceSettings.CompactMode)
)
)
}
Expand Down Expand Up @@ -81,17 +86,19 @@ fun S2AppTheme(
// Always the same call, so toggling pure black recolours the content instead of moving it to a new
// composition branch, which would drop its saved state (the shell's back stacks among it).
val colorScheme = MaterialTheme.colorScheme
MaterialTheme(
colorScheme = if (darkTheme && state.pureBlack) {
colorScheme.copy(background = Color.Black, surface = Color.Black, surfaceContainerLowest = Color.Black)
} else {
colorScheme
},
motionScheme = MaterialTheme.motionScheme,
shapes = MaterialTheme.shapes,
typography = MaterialTheme.typography,
content = content
)
CompositionLocalProvider(LocalCompactMode provides state.compactMode) {
MaterialTheme(
colorScheme = if (darkTheme && state.pureBlack) {
colorScheme.copy(background = Color.Black, surface = Color.Black, surfaceContainerLowest = Color.Black)
} else {
colorScheme
},
motionScheme = MaterialTheme.motionScheme,
shapes = MaterialTheme.shapes,
typography = MaterialTheme.typography,
content = content
)
}
}
}

Expand Down
4 changes: 4 additions & 0 deletions android/app/src/main/res/values/strings_settings.xml
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,10 @@
<string name="pref_pure_black_title">Pure black</string>
<!-- Settings: Summary of the pure black switch -->
<string name="pref_pure_black_summary">Black backgrounds in dark theme, for AMOLED screens</string>
<!-- Settings: Title of the compact mode switch -->
<string name="pref_compact_mode_title">Compact mode</string>
<!-- Settings: Summary of the compact mode switch -->
<string name="pref_compact_mode_summary">Smaller rows, artwork and headers across Home, Library and Settings</string>
<!-- Settings: Title of the switch that takes the app colours from the wallpaper (Android 12+) -->
<string name="pref_dynamic_colour_title">Dynamic colour</string>
<!-- Settings: Summary of the dynamic colour switch -->
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ class SettingKeysTest {
"AppearanceSettings.ColourFromArtwork: pref_theme_colour_from_artwork = true",
"AppearanceSettings.ShowHomeOnLaunch: pref_show_home_on_launch = false",
"AppearanceSettings.WidgetBackgroundOpacity: widget_background_opacity = 100",
"AppearanceSettings.CompactMode: pref_compact_mode = false",
"ArtworkSettings.WifiOnly: artwork_wifi_only = true",
"ArtworkSettings.LocalOnly: artwork_local_only = false",
"ArtworkSettings.MediaSessionArtwork: media_session_artwork = true",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ class SettingsScreenTest {

robot.assertDisplayed("Dark")
robot.assertSwitchOn("Pure black")
robot.assertSwitchOff("Compact mode")
robot.assertSwitchOff("Show Home on launch")
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ class AppearanceSettings @Inject constructor(
val colourFromArtwork = store.preference(ColourFromArtwork)
val showHomeOnLaunch = store.preference(ShowHomeOnLaunch)
val widgetBackgroundOpacity = store.preference(WidgetBackgroundOpacity)
val compactMode = store.preference(CompactMode)

companion object {
val Theme = Setting.enumOrdinalString("pref_theme", ThemeMode.DayNight, ThemeMode.entries)
Expand All @@ -59,5 +60,8 @@ class AppearanceSettings @Inject constructor(

/** A percentage. The key predates the Glance widgets, so old values carry over. */
val WidgetBackgroundOpacity = Setting.int("widget_background_opacity", 100)

/** Tighter rows, smaller artwork and shorter headers across Home, Library and Settings. Off by default. */
val CompactMode = Setting.boolean("pref_compact_mode", false)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
package com.simplecityapps.shuttle.designsystem.theme

import androidx.compose.runtime.compositionLocalOf

/**
* Whether the UI lays out compact: smaller rows, artwork and headers across Home, Library and
* Settings. Off by default; the Appearance setting flips it live, and every reader below
* recomposes on change. Density only — it never changes icons, placeholders or navigation shape;
* those stay separate design decisions.
*/
val LocalCompactMode = compositionLocalOf { false }
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,8 @@ enum class StringKey {
PREF_COLOUR_FROM_ARTWORK_SUMMARY,
PREF_PURE_BLACK_TITLE,
PREF_PURE_BLACK_SUMMARY,
PREF_COMPACT_MODE_TITLE,
PREF_COMPACT_MODE_SUMMARY,
PREF_CATEGORY_TITLE_WIDGETS,
PREF_WIDGET_OPACITY_TITLE,
PREF_NAVIGATION_TITLE,
Expand Down
2 changes: 2 additions & 0 deletions ios/S2/en.lproj/Localizable.strings
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@
"pref_colour_from_artwork_summary" = "Tint the player with colours from the album art";
"pref_pure_black_title" = "Pure black";
"pref_pure_black_summary" = "Black backgrounds in dark theme, for AMOLED screens";
"pref_compact_mode_title" = "Compact mode";
"pref_compact_mode_summary" = "Smaller rows, artwork and headers across Home, Library and Settings";
"pref_category_title_widgets" = "Widgets";
"pref_widget_opacity_title" = "Background opacity";
"pref_navigation_title" = "Navigation";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class IosSettingsCatalogTest {
AppearanceSettings.Theme.key,
AppearanceSettings.DynamicColour.key,
AppearanceSettings.AccentColour.key,
AppearanceSettings.CompactMode.key,
AppearanceSettings.WidgetBackgroundOpacity.key,
PlaybackSettings.UsbDacDirectOutput.key,
ArtworkSettings.WifiOnly.key,
Expand Down
Loading