diff --git a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt index af0b61451f..f9b5eff141 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/onboarding/landing/Landing.kt @@ -194,7 +194,7 @@ private fun MessageText(text: String, isOutgoing: Boolean, modifier: Modifier) { Box(modifier = modifier then Modifier.fillMaxWidth()) { MessageText( text, - color = if (isOutgoing) LocalColors.current.backgroundBubbleSent else LocalColors.current.backgroundBubbleReceived, + color = if (isOutgoing) LocalColors.current.primary else LocalColors.current.backgroundBubbleReceived, textColor = if (isOutgoing) LocalColors.current.textBubbleSent else LocalColors.current.textBubbleReceived, modifier = Modifier.align(if (isOutgoing) Alignment.TopEnd else Alignment.TopStart) ) diff --git a/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt index c569441382..afe33400ff 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/preferences/appearance/AppearanceSettingsViewModel.kt @@ -6,6 +6,7 @@ import dagger.hilt.android.lifecycle.HiltViewModel import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow import org.session.libsession.utilities.TextSecurePreferences +import org.thoughtcrime.securesms.ui.theme.selectedTheme import org.thoughtcrime.securesms.util.ThemeState import org.thoughtcrime.securesms.util.themeState import javax.inject.Inject @@ -26,11 +27,17 @@ class AppearanceSettingsViewModel @Inject constructor(private val prefs: TextSec prefs.setThemeStyle(newThemeStyle) // update UI state _uiState.value = prefs.themeState() + + // force compose to refresh its style reference + selectedTheme = null } fun setNewFollowSystemSettings(followSystemSettings: Boolean) { prefs.setFollowSystemSettings(followSystemSettings) _uiState.value = prefs.themeState() + + // force compose to refresh its style reference + selectedTheme = null } } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt deleted file mode 100644 index fb387f89a5..0000000000 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/color/ColorsFromPreferences.kt +++ /dev/null @@ -1,43 +0,0 @@ -package org.thoughtcrime.securesms.ui.color - -import androidx.compose.runtime.Composable -import androidx.compose.ui.graphics.Color -import org.session.libsession.utilities.TextSecurePreferences -import org.session.libsession.utilities.TextSecurePreferences.Companion.BLUE_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_DARK -import org.session.libsession.utilities.TextSecurePreferences.Companion.CLASSIC_LIGHT -import org.session.libsession.utilities.TextSecurePreferences.Companion.GREEN_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.OCEAN_LIGHT -import org.session.libsession.utilities.TextSecurePreferences.Companion.ORANGE_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.PINK_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.PURPLE_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.RED_ACCENT -import org.session.libsession.utilities.TextSecurePreferences.Companion.YELLOW_ACCENT -import org.thoughtcrime.securesms.ui.theme.ThemeColors -import org.thoughtcrime.securesms.ui.theme.LightDarkColors -import org.thoughtcrime.securesms.ui.theme.primaryBlue -import org.thoughtcrime.securesms.ui.theme.primaryGreen -import org.thoughtcrime.securesms.ui.theme.primaryOrange -import org.thoughtcrime.securesms.ui.theme.primaryPink -import org.thoughtcrime.securesms.ui.theme.primaryPurple -import org.thoughtcrime.securesms.ui.theme.primaryRed -import org.thoughtcrime.securesms.ui.theme.primaryYellow - -/** - * Retrieve the current [ThemeColors] from [TextSecurePreferences] and current system settings. - */ -@Composable -fun TextSecurePreferences.colors(): ThemeColors = lightDarkColors().colors() -private fun TextSecurePreferences.lightDarkColors() = LightDarkColors(isClassic(), isLight(), getFollowSystemSettings(), primaryColor()) -private fun TextSecurePreferences.isLight(): Boolean = getThemeStyle() in setOf(CLASSIC_LIGHT, OCEAN_LIGHT) -private fun TextSecurePreferences.isClassic(): Boolean = getThemeStyle() in setOf(CLASSIC_DARK, CLASSIC_LIGHT) -private fun TextSecurePreferences.primaryColor(): Color = when(getSelectedAccentColor()) { - GREEN_ACCENT -> primaryGreen - BLUE_ACCENT -> primaryBlue - PURPLE_ACCENT -> primaryPurple - PINK_ACCENT -> primaryPink - RED_ACCENT -> primaryRed - ORANGE_ACCENT -> primaryOrange - YELLOW_ACCENT -> primaryYellow - else -> Color.Unspecified -} diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt new file mode 100644 index 0000000000..3ff4d55b61 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColorSet.kt @@ -0,0 +1,10 @@ +package org.thoughtcrime.securesms.ui.theme + +/** + * This class holds two instances of [ThemeColors], [light] representing the [ThemeColors] to use when the system is in a + * light theme, and [dark] representing the [ThemeColors] to use when the system is in a dark theme. + */ +data class ThemeColorSet( + val light: ThemeColors, + val dark: ThemeColors +) \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt index 3fa582af4f..5631a3a4d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeColors.kt @@ -190,35 +190,4 @@ private fun ThemeColors() { Text("error", style = base) } } -} - - -/** - * This class holds two instances of [ThemeColors], [light] representing the [ThemeColors] to use when the system is in a - * light theme, and [dark] representing the [ThemeColors] to use when the system is in a dark theme. - * - * If the user has [followSystemSettings] turned on then [light] should be equal to [dark]. - */ -data class LightDarkColors( - val light: ThemeColors, - val dark: ThemeColors -) { - @Composable - fun colors() = if (light == dark || isSystemInDarkTheme()) dark else light -} - -/** - * Courtesy constructor that sets [light] and [dark] based on properties. - */ -fun LightDarkColors(isClassic: Boolean, isLight: Boolean, followSystemSettings: Boolean, primaryOrUnspecified: Color): LightDarkColors { - val primary = primaryOrUnspecified.takeOrElse { if (isClassic) primaryGreen else primaryBlue } - val light = when { - isLight || followSystemSettings -> if (isClassic) ClassicLight(primary) else OceanLight(primary) - else -> if (isClassic) ClassicDark(primary) else OceanDark(primary) - } - val dark = when { - isLight && !followSystemSettings -> if (isClassic) ClassicLight(primary) else OceanLight(primary) - else -> if (isClassic) ClassicDark(primary) else OceanDark(primary) - } - return LightDarkColors(light, dark) } \ No newline at end of file diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt new file mode 100644 index 0000000000..8988e84ca7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/ThemeFromPreferences.kt @@ -0,0 +1,65 @@ +package org.thoughtcrime.securesms.ui.theme + +import androidx.compose.foundation.isSystemInDarkTheme +import androidx.compose.runtime.Composable +import androidx.compose.ui.graphics.Color +import org.session.libsession.utilities.TextSecurePreferences +import org.session.libsession.utilities.TextSecurePreferences.Companion.BLUE_ACCENT +import org.session.libsession.utilities.TextSecurePreferences.Companion.ORANGE_ACCENT +import org.session.libsession.utilities.TextSecurePreferences.Companion.PINK_ACCENT +import org.session.libsession.utilities.TextSecurePreferences.Companion.PURPLE_ACCENT +import org.session.libsession.utilities.TextSecurePreferences.Companion.RED_ACCENT +import org.session.libsession.utilities.TextSecurePreferences.Companion.YELLOW_ACCENT + + +/** + * Returns the compose theme based on saved preferences + * Some behaviour is hardcoded to cater for legacy usage of people with themes already set + * But future themes will be picked and set directly from the "Appearance" screen + */ +@Composable +fun TextSecurePreferences.getComposeTheme(): ThemeColors { + val selectedTheme = getThemeStyle() + + // get the chosen primary color from the preferences + val selectedPrimary = primaryColor() + + // create a theme set with the appropriate primary + val colorSet = when(selectedTheme){ + TextSecurePreferences.OCEAN_DARK, + TextSecurePreferences.OCEAN_LIGHT -> ThemeColorSet( + light = OceanLight(selectedPrimary), + dark = OceanDark(selectedPrimary) + ) + + else -> ThemeColorSet( + light = ClassicLight(selectedPrimary), + dark = ClassicDark(selectedPrimary) + ) + } + + // deliver the right set from the light/dark mode chosen + val theme = when{ + getFollowSystemSettings() -> if(isSystemInDarkTheme()) colorSet.dark else colorSet.light + + selectedTheme == TextSecurePreferences.CLASSIC_LIGHT || + selectedTheme == TextSecurePreferences.OCEAN_LIGHT -> colorSet.light + + else -> colorSet.dark + } + + return theme +} + +fun TextSecurePreferences.primaryColor(): Color = when(getSelectedAccentColor()) { + BLUE_ACCENT -> primaryBlue + PURPLE_ACCENT -> primaryPurple + PINK_ACCENT -> primaryPink + RED_ACCENT -> primaryRed + ORANGE_ACCENT -> primaryOrange + YELLOW_ACCENT -> primaryYellow + else -> primaryGreen +} + + + diff --git a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt index 961c89fe4d..c00b39d425 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/ui/theme/Themes.kt @@ -1,7 +1,7 @@ package org.thoughtcrime.securesms.ui.theme -import android.content.Context import androidx.compose.foundation.background +import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.layout.Box import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.foundation.text.selection.LocalTextSelectionColors @@ -10,16 +10,18 @@ import androidx.compose.material.MaterialTheme import androidx.compose.material.Shapes import androidx.compose.runtime.Composable import androidx.compose.runtime.CompositionLocalProvider +import androidx.compose.runtime.compositionLocalOf import androidx.compose.runtime.staticCompositionLocalOf import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.tooling.preview.PreviewParameterProvider import androidx.compose.ui.unit.dp import org.session.libsession.utilities.AppTextSecurePreferences -import org.thoughtcrime.securesms.ui.color.colors // Globally accessible composition local objects -val LocalColors = staticCompositionLocalOf { ClassicDark() } +val LocalColors = compositionLocalOf { ClassicDark() } +var selectedTheme: ThemeColors? = null /** * Apply a Material2 compose theme based on user selections in SharedPreferences. @@ -28,7 +30,15 @@ val LocalColors = staticCompositionLocalOf { ClassicDark() } fun SessionMaterialTheme( content: @Composable () -> Unit ) { - SessionMaterialTheme(LocalContext.current.colors()) { content() } + // set the theme data if it hasn't been done yet + if(selectedTheme == null) { + // Some values can be set from the preferences, and if not should fallback to a default value + val context = LocalContext.current + val preferences = AppTextSecurePreferences(context) + selectedTheme = preferences.getComposeTheme() + } + + SessionMaterialTheme(colors = selectedTheme ?: ClassicDark()) { content() } } /** @@ -54,8 +64,6 @@ fun SessionMaterialTheme( } } -@Composable private fun Context.colors() = AppTextSecurePreferences(this).colors() - val pillShape = RoundedCornerShape(percent = 50) val buttonShape = pillShape