mirror of
https://github.com/oxen-io/session-android.git
synced 2024-11-27 12:05:22 +00:00
Cleaning up the code for theming and decoupling the isClassic logic
This commit is contained in:
parent
96157d65a6
commit
17c381b5f7
@ -60,30 +60,6 @@ val Colors.disabled @Composable get() = onSurface.copy(alpha = ContentAlpha.disa
|
||||
|
||||
val blackAlpha40 = Color.Black.copy(alpha = 0.4f)
|
||||
|
||||
val LocalColors = staticCompositionLocalOf { sessionColors(isLight = false, isClassic = true) }
|
||||
|
||||
data class SessionColors(
|
||||
val isLight: Boolean = false,
|
||||
val primary: Color = Color.Unspecified,
|
||||
val danger: Color = Color.Unspecified,
|
||||
val disabled: Color = Color.Unspecified,
|
||||
val background: Color = Color.Unspecified,
|
||||
val backgroundSecondary: Color = Color.Unspecified,
|
||||
val text: Color = Color.Unspecified,
|
||||
val textSecondary: Color = Color.Unspecified,
|
||||
val borders: Color = Color.Unspecified,
|
||||
val textBubbleSent: Color = Color.Unspecified,
|
||||
val backgroundBubbleReceived: Color = Color.Unspecified,
|
||||
val textBubbleReceived: Color = Color.Unspecified,
|
||||
) {
|
||||
val backgroundLight get() = if (isLight) backgroundSecondary else Color.White
|
||||
val onBackgroundLight get() = if (isLight) text else background
|
||||
val button get() = if (isLight) text else primary
|
||||
val divider get() = text.copy(alpha = TabRowDefaults.DividerOpacity)
|
||||
val backgroundBubbleSent get() = primary
|
||||
@Composable fun radioButtonColors() = RadioButtonDefaults.colors(selectedColor = primary, unselectedColor = text, disabledColor = disabled)
|
||||
}
|
||||
|
||||
val primaryGreen = Color(0xFF31F196)
|
||||
val primaryBlue = Color(0xFF57C9FA)
|
||||
val primaryPurple = Color(0xFFC993FF)
|
||||
@ -97,77 +73,6 @@ val dangerLight = Color(0xFFE12D19)
|
||||
val disabledDark = Color(0xFFA1A2A1)
|
||||
val disabledLight = Color(0xFF6D6D6D)
|
||||
|
||||
fun sessionColors(
|
||||
isLight: Boolean,
|
||||
isClassic: Boolean,
|
||||
primary: Color = if (isClassic) primaryGreen else primaryBlue
|
||||
): SessionColors = if (isClassic) {
|
||||
if (isLight) classicLight else classicDark
|
||||
} else {
|
||||
if (isLight) oceanLight else oceanDark
|
||||
}.copy(
|
||||
primary = primary
|
||||
)
|
||||
|
||||
val classicDark = SessionColors(
|
||||
isLight = false,
|
||||
primary = primaryGreen,
|
||||
danger = dangerDark,
|
||||
disabled = disabledDark,
|
||||
background = Color.Black,
|
||||
backgroundSecondary = classicDark1,
|
||||
text = Color.White,
|
||||
textSecondary = classicDark5,
|
||||
borders = classicDark3,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = classicDark2,
|
||||
textBubbleReceived = Color.White,
|
||||
)
|
||||
|
||||
val classicLight = SessionColors(
|
||||
isLight = true,
|
||||
primary = primaryGreen,
|
||||
danger = dangerLight,
|
||||
disabled = disabledLight,
|
||||
background = Color.White,
|
||||
backgroundSecondary = classicLight5,
|
||||
text = Color.Black,
|
||||
textSecondary = classicLight1,
|
||||
borders = classicLight3,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = classicLight4,
|
||||
textBubbleReceived = classicLight4,
|
||||
)
|
||||
|
||||
val oceanDark = SessionColors(
|
||||
isLight = false,
|
||||
primary = primaryBlue,
|
||||
danger = dangerDark,
|
||||
disabled = disabledDark,
|
||||
background = oceanDark2,
|
||||
backgroundSecondary = oceanDark1,
|
||||
text = Color.White,
|
||||
textSecondary = oceanDark5,
|
||||
borders = oceanDark4,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = oceanDark4,
|
||||
textBubbleReceived = oceanDark4,
|
||||
)
|
||||
|
||||
val oceanLight = SessionColors(
|
||||
isLight = true,
|
||||
primary = primaryBlue,
|
||||
danger = dangerLight,
|
||||
disabled = disabledLight,
|
||||
background = oceanLight7,
|
||||
backgroundSecondary = oceanLight6,
|
||||
text = oceanLight1,
|
||||
textSecondary = oceanLight2,
|
||||
borders = oceanLight3,
|
||||
textBubbleSent = oceanLight1,
|
||||
backgroundBubbleReceived = oceanLight4,
|
||||
textBubbleReceived = oceanLight4
|
||||
)
|
||||
|
||||
@Composable
|
||||
fun transparentButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent)
|
||||
@ -175,55 +80,6 @@ fun transparentButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Co
|
||||
@Composable
|
||||
fun destructiveButtonColors() = ButtonDefaults.buttonColors(backgroundColor = Color.Transparent, contentColor = LocalColors.current.danger)
|
||||
|
||||
@Composable
|
||||
fun Colors(name: String, colors: List<Color>) {
|
||||
Column {
|
||||
colors.forEachIndexed { i, it ->
|
||||
Box(Modifier.background(it)) {
|
||||
Text("$name: $i")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewThemeColors(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
|
||||
) {
|
||||
PreviewTheme(sessionColors) { ThemeColors() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemeColors() {
|
||||
Column {
|
||||
Box(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
Text("primary", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primaryVariant)) {
|
||||
Text("primaryVariant", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondary)) {
|
||||
Text("secondary", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondaryVariant)) {
|
||||
Text("secondaryVariant", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.surface)) {
|
||||
Text("surface", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primarySurface)) {
|
||||
Text("primarySurface", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.background)) {
|
||||
Text("background", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.error)) {
|
||||
Text("error", style = MaterialTheme.typography.base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun outlinedTextFieldColors(
|
||||
isError: Boolean
|
||||
@ -234,13 +90,3 @@ fun outlinedTextFieldColors(
|
||||
unfocusedBorderColor = LocalColors.current.borders,
|
||||
placeholderColor = if (isError) LocalColors.current.danger else LocalColors.current.textSecondary
|
||||
)
|
||||
|
||||
fun TextSecurePreferences.Companion.getAccentColor(context: Context): Color = when (getAccentColorName(context)) {
|
||||
BLUE_ACCENT -> primaryBlue
|
||||
PURPLE_ACCENT -> primaryPurple
|
||||
PINK_ACCENT -> primaryPink
|
||||
RED_ACCENT -> primaryRed
|
||||
ORANGE_ACCENT -> primaryOrange
|
||||
YELLOW_ACCENT -> primaryYellow
|
||||
else -> primaryGreen
|
||||
}
|
||||
|
@ -0,0 +1,6 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
data class SessionColorSet(
|
||||
val lightTheme: SessionColors,
|
||||
val darkTheme: SessionColors
|
||||
)
|
@ -0,0 +1,50 @@
|
||||
package org.thoughtcrime.securesms.ui
|
||||
|
||||
import androidx.compose.material.Colors
|
||||
import androidx.compose.material.RadioButtonDefaults
|
||||
import androidx.compose.material.TabRowDefaults
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.graphics.Color
|
||||
|
||||
data class SessionColors(
|
||||
val isLight: Boolean = false,
|
||||
val primary: Color = Color.Unspecified,
|
||||
val danger: Color = Color.Unspecified,
|
||||
val disabled: Color = Color.Unspecified,
|
||||
val background: Color = Color.Unspecified,
|
||||
val backgroundSecondary: Color = Color.Unspecified,
|
||||
val text: Color = Color.Unspecified,
|
||||
val textSecondary: Color = Color.Unspecified,
|
||||
val borders: Color = Color.Unspecified,
|
||||
val textBubbleSent: Color = Color.Unspecified,
|
||||
val backgroundBubbleReceived: Color = Color.Unspecified,
|
||||
val textBubbleReceived: Color = Color.Unspecified,
|
||||
) {
|
||||
// To delete and instead use figma terms and add them to the data class above ------
|
||||
val backgroundLight get() = if (isLight) backgroundSecondary else Color.White
|
||||
val onBackgroundLight get() = if (isLight) text else background
|
||||
val button get() = if (isLight) text else primary
|
||||
val backgroundBubbleSent get() = primary
|
||||
// --------------------------------------------------------------------------------
|
||||
|
||||
@Composable
|
||||
fun radioButtonColors() = RadioButtonDefaults.colors(selectedColor = primary, unselectedColor = text, disabledColor = disabled)
|
||||
|
||||
val divider get() = text.copy(alpha = TabRowDefaults.DividerOpacity)
|
||||
|
||||
fun toMaterialColors() = Colors(
|
||||
primary = background,
|
||||
primaryVariant = backgroundSecondary,
|
||||
secondary = background,
|
||||
secondaryVariant = background,
|
||||
background = background,
|
||||
surface = background,
|
||||
error = danger,
|
||||
onPrimary = text,
|
||||
onSecondary = text,
|
||||
onBackground = text,
|
||||
onSurface = text,
|
||||
onError = text,
|
||||
isLight = isLight
|
||||
)
|
||||
}
|
@ -4,6 +4,7 @@ import android.content.Context
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.text.selection.LocalTextSelectionColors
|
||||
import androidx.compose.foundation.text.selection.TextSelectionColors
|
||||
@ -11,12 +12,20 @@ import androidx.compose.material.Colors
|
||||
import androidx.compose.material.LocalContentColor
|
||||
import androidx.compose.material.MaterialTheme
|
||||
import androidx.compose.material.Shapes
|
||||
import androidx.compose.material.Text
|
||||
import androidx.compose.material.primarySurface
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.CompositionLocalProvider
|
||||
import androidx.compose.runtime.compositionLocalOf
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameter
|
||||
import androidx.compose.ui.tooling.preview.PreviewParameterProvider
|
||||
import network.loki.messenger.R
|
||||
import org.session.libsession.utilities.AppTextSecurePreferences
|
||||
import org.session.libsession.utilities.TextSecurePreferences
|
||||
import org.thoughtcrime.securesms.util.ThemeState
|
||||
import org.thoughtcrime.securesms.util.themeState
|
||||
|
||||
@ -27,7 +36,7 @@ import org.thoughtcrime.securesms.util.themeState
|
||||
fun SessionMaterialTheme(
|
||||
content: @Composable () -> Unit
|
||||
) {
|
||||
SessionMaterialTheme(LocalContext.current.sessionColors()) { content() }
|
||||
SessionMaterialTheme(LocalContext.current.composeTheme()) { content() }
|
||||
}
|
||||
|
||||
/**
|
||||
@ -58,24 +67,104 @@ fun SessionMaterialTheme(
|
||||
}
|
||||
}
|
||||
|
||||
private fun SessionColors.toMaterialColors() = Colors(
|
||||
primary = background,
|
||||
primaryVariant = backgroundSecondary,
|
||||
secondary = background,
|
||||
secondaryVariant = background,
|
||||
background = background,
|
||||
surface = background,
|
||||
error = danger,
|
||||
onPrimary = text,
|
||||
onSecondary = text,
|
||||
onBackground = text,
|
||||
onSurface = text,
|
||||
onError = text,
|
||||
isLight = isLight
|
||||
// Compose theme holder
|
||||
val LocalColors = compositionLocalOf { classicDark }
|
||||
|
||||
// Our themes
|
||||
val classicDark = SessionColors(
|
||||
isLight = false,
|
||||
primary = primaryGreen,
|
||||
danger = dangerDark,
|
||||
disabled = disabledDark,
|
||||
background = Color.Black,
|
||||
backgroundSecondary = classicDark1,
|
||||
text = Color.White,
|
||||
textSecondary = classicDark5,
|
||||
borders = classicDark3,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = classicDark2,
|
||||
textBubbleReceived = Color.White,
|
||||
)
|
||||
|
||||
@Composable private fun Context.sessionColors() = AppTextSecurePreferences(this).themeState().sessionColors()
|
||||
@Composable private fun ThemeState.sessionColors() = sessionColors(if (followSystem) !isSystemInDarkTheme() else isLight, isClassic, accent)
|
||||
val classicLight = SessionColors(
|
||||
isLight = true,
|
||||
primary = primaryGreen,
|
||||
danger = dangerLight,
|
||||
disabled = disabledLight,
|
||||
background = Color.White,
|
||||
backgroundSecondary = classicLight5,
|
||||
text = Color.Black,
|
||||
textSecondary = classicLight1,
|
||||
borders = classicLight3,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = classicLight4,
|
||||
textBubbleReceived = classicLight4,
|
||||
)
|
||||
|
||||
val oceanDark = SessionColors(
|
||||
isLight = false,
|
||||
primary = primaryBlue,
|
||||
danger = dangerDark,
|
||||
disabled = disabledDark,
|
||||
background = oceanDark2,
|
||||
backgroundSecondary = oceanDark1,
|
||||
text = Color.White,
|
||||
textSecondary = oceanDark5,
|
||||
borders = oceanDark4,
|
||||
textBubbleSent = Color.Black,
|
||||
backgroundBubbleReceived = oceanDark4,
|
||||
textBubbleReceived = oceanDark4,
|
||||
)
|
||||
|
||||
val oceanLight = SessionColors(
|
||||
isLight = true,
|
||||
primary = primaryBlue,
|
||||
danger = dangerLight,
|
||||
disabled = disabledLight,
|
||||
background = oceanLight7,
|
||||
backgroundSecondary = oceanLight6,
|
||||
text = oceanLight1,
|
||||
textSecondary = oceanLight2,
|
||||
borders = oceanLight3,
|
||||
textBubbleSent = oceanLight1,
|
||||
backgroundBubbleReceived = oceanLight4,
|
||||
textBubbleReceived = oceanLight4
|
||||
)
|
||||
|
||||
val classicTheme = SessionColorSet(
|
||||
lightTheme = classicLight,
|
||||
darkTheme = classicDark
|
||||
)
|
||||
|
||||
val oceanTheme = SessionColorSet(
|
||||
lightTheme = oceanLight,
|
||||
darkTheme = oceanDark
|
||||
)
|
||||
|
||||
@Composable private fun Context.composeTheme() = AppTextSecurePreferences(this).themeState().composeTheme()
|
||||
// We still need to match xml values for now but once we go full Compose all of this can go
|
||||
@Composable private fun ThemeState.composeTheme(): SessionColors {
|
||||
// pick the theme based on xml value
|
||||
val colorSet = when (theme) {
|
||||
R.style.Ocean_Light,
|
||||
R.style.Ocean_Dark -> oceanTheme
|
||||
|
||||
else -> classicTheme
|
||||
}
|
||||
|
||||
// get the mode (light/dark/system) from settings
|
||||
val colorMode =
|
||||
when {
|
||||
followSystem -> { // user decided to 'match system settings'
|
||||
if(isSystemInDarkTheme()) colorSet.darkTheme else colorSet.lightTheme
|
||||
}
|
||||
isLight -> colorSet.lightTheme
|
||||
else -> colorSet.darkTheme
|
||||
}
|
||||
|
||||
// set the accent as per user choice
|
||||
return colorMode.copy(primary = accent)
|
||||
}
|
||||
|
||||
val sessionShapes = Shapes(
|
||||
small = RoundedCornerShape(50)
|
||||
@ -98,9 +187,44 @@ fun PreviewTheme(
|
||||
|
||||
class SessionColorsParameterProvider : PreviewParameterProvider<SessionColors> {
|
||||
override val values = sequenceOf(
|
||||
sessionColors(isLight = false, isClassic = true),
|
||||
sessionColors(isLight = true, isClassic = true),
|
||||
sessionColors(isLight = false, isClassic = false),
|
||||
sessionColors(isLight = true, isClassic = false),
|
||||
classicDark, classicLight, oceanDark, oceanLight
|
||||
)
|
||||
}
|
||||
|
||||
@Preview
|
||||
@Composable
|
||||
fun PreviewThemeColors(
|
||||
@PreviewParameter(SessionColorsParameterProvider::class) sessionColors: SessionColors
|
||||
) {
|
||||
PreviewTheme(sessionColors) { ThemeColors() }
|
||||
}
|
||||
|
||||
@Composable
|
||||
private fun ThemeColors() {
|
||||
Column {
|
||||
Box(Modifier.background(MaterialTheme.colors.primary)) {
|
||||
Text("primary", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primaryVariant)) {
|
||||
Text("primaryVariant", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondary)) {
|
||||
Text("secondary", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.secondaryVariant)) {
|
||||
Text("secondaryVariant", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.surface)) {
|
||||
Text("surface", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.primarySurface)) {
|
||||
Text("primarySurface", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.background)) {
|
||||
Text("background", style = MaterialTheme.typography.base)
|
||||
}
|
||||
Box(Modifier.background(MaterialTheme.colors.error)) {
|
||||
Text("error", style = MaterialTheme.typography.base)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user