Add colors theme object

This commit is contained in:
Andrew 2024-06-12 19:00:06 +09:30
parent 31d2ea2dc4
commit f1000ac6e6
7 changed files with 144 additions and 26 deletions

View File

@ -48,6 +48,7 @@ import org.thoughtcrime.securesms.onboarding.pickname.startPickDisplayNameActivi
import org.thoughtcrime.securesms.service.KeyCachingService
import org.thoughtcrime.securesms.showOpenUrlDialog
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
@ -57,7 +58,6 @@ import org.thoughtcrime.securesms.ui.components.FilledButton
import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.large
import org.thoughtcrime.securesms.ui.session_accent
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
import org.thoughtcrime.securesms.util.start
import kotlin.time.Duration.Companion.milliseconds
@ -226,8 +226,8 @@ private fun MessageText(text: String, isOutgoing: Boolean, modifier: Modifier) {
Box(modifier = modifier then Modifier.fillMaxWidth()) {
MessageText(
text,
color = if (isOutgoing) session_accent else classicDarkColors[2],
textColor = if (isOutgoing) MaterialTheme.colors.primary else Color.Unspecified,
color = if (isOutgoing) LocalColors.current.backgroundBubbleSent else LocalColors.current.backgroundBubbleReceived,
textColor = if (isOutgoing) LocalColors.current.textBubbleSent else LocalColors.current.textBubbleReceived,
modifier = Modifier.align(if (isOutgoing) Alignment.TopEnd else Alignment.TopStart)
)
}

View File

@ -38,6 +38,7 @@ import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.home.HomeActivity
import org.thoughtcrime.securesms.notifications.PushRegistry
import org.thoughtcrime.securesms.ui.AppTheme
import org.thoughtcrime.securesms.ui.LocalColors
import org.thoughtcrime.securesms.ui.LocalDimensions
import org.thoughtcrime.securesms.ui.PreviewTheme
import org.thoughtcrime.securesms.ui.ThemeResPreviewParameterProvider
@ -46,7 +47,6 @@ import org.thoughtcrime.securesms.ui.components.OutlineButton
import org.thoughtcrime.securesms.ui.contentDescription
import org.thoughtcrime.securesms.ui.h8
import org.thoughtcrime.securesms.ui.h9
import org.thoughtcrime.securesms.ui.session_accent
import org.thoughtcrime.securesms.ui.small
import org.thoughtcrime.securesms.util.setUpActionBarSessionLogo
import javax.inject.Inject
@ -153,7 +153,7 @@ fun NotificationRadioButton(
onClick = onClick,
modifier = Modifier.weight(1f).contentDescription(contentDescription),
colors = ButtonDefaults.outlinedButtonColors(backgroundColor = MaterialTheme.colors.background, contentColor = Color.White),
border = if (selected) BorderStroke(ButtonDefaults.OutlinedBorderSize, session_accent) else ButtonDefaults.outlinedBorder,
border = if (selected) BorderStroke(ButtonDefaults.OutlinedBorderSize, LocalColors.current.primary) else ButtonDefaults.outlinedBorder,
shape = RoundedCornerShape(8.dp)
) {
Column(
@ -161,7 +161,7 @@ fun NotificationRadioButton(
) {
Text(stringResource(title), style = MaterialTheme.typography.h8)
Text(stringResource(explanation), style = MaterialTheme.typography.small)
tag?.let { Text(stringResource(it), color = session_accent, style = MaterialTheme.typography.h9) }
tag?.let { Text(stringResource(it), color = LocalColors.current.primary, style = MaterialTheme.typography.h9) }
}
}
RadioButton(selected = selected, modifier = Modifier.align(Alignment.CenterVertically), onClick = onClick)

View File

@ -1,5 +1,6 @@
package org.thoughtcrime.securesms.ui
import android.content.Context
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Box
import androidx.compose.foundation.layout.Column
@ -16,6 +17,7 @@ import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.tooling.preview.PreviewParameter
import org.session.libsession.utilities.TextSecurePreferences
val colorDestructive = Color(0xffFF453A)
@ -53,9 +55,6 @@ const val oceanLight5 = 0xffE7F3F4
const val oceanLight6 = 0xffECFAFB
const val oceanLight7 = 0xffFCFFFF
val session_accent = Color(0xFF31F196)
val ocean_accent = Color(0xff57C9FA)
val Colors.disabled @Composable get() = onSurface.copy(alpha = ContentAlpha.disabled)
val oceanLights = arrayOf(oceanLight0, oceanLight1, oceanLight2, oceanLight3, oceanLight4, oceanLight5, oceanLight6, oceanLight7)
@ -144,3 +143,13 @@ fun outlinedTextFieldColors(
unfocusedBorderColor = Color(classicDark3),
placeholderColor = if (isError) colorDestructive else MaterialTheme.colors.onSurface.copy(ContentAlpha.medium)
)
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
}

View File

@ -364,7 +364,7 @@ fun ProgressArc(progress: Float, modifier: Modifier = Modifier) {
fun Arc(
modifier: Modifier = Modifier,
percentage: Float = 0.25f,
fillColor: Color = session_accent,
fillColor: Color = LocalColors.current.primary,
backgroundColor: Color = classicDarkColors[3],
strokeWidth: Dp = 18.dp,
sweepAngle: Float = 310f,

View File

@ -30,6 +30,8 @@ import androidx.compose.ui.unit.sp
import com.google.accompanist.themeadapter.appcompat.createAppCompatTheme
import com.google.android.material.color.MaterialColors
import network.loki.messenger.R
import org.session.libsession.utilities.AppTextSecurePreferences
import org.thoughtcrime.securesms.util.themeState
val LocalCellColor = staticCompositionLocalOf { Color.Black }
val LocalButtonColor = staticCompositionLocalOf { Color.Black }
@ -52,6 +54,81 @@ data class Dimensions(
val dividerIndent: Dp = 80.dp,
)
val LocalColors = staticCompositionLocalOf { SessionColors() }
data class SessionColors(
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 backgroundBubbleSent get() = primary
}
val primaryGreen = Color(0xFF31F196)
val primaryBlue = Color(0xFF57C9FA)
val primaryPurple = Color(0xFFC993FF)
val primaryPink = Color(0xFFFF95EF)
val primaryRed = Color(0xFFFF9C8E)
val primaryOrange = Color(0xFFFCB159)
val primaryYellow = Color(0xFFFAD657)
val dangerDark = Color(0xFFFF3A3A)
val dangerLight = Color(0xFFE12D19)
val disabledDark = Color(0xFFA1A2A1)
val disabledLioht = Color(0xFF6D6D6D)
val primaryColors = listOf(
primaryGreen,
primaryBlue,
primaryPurple,
primaryPink,
primaryRed,
primaryOrange,
primaryYellow,
)
private class UnresolvedColor(val function: (Boolean, Boolean) -> Color) {
operator fun invoke(isLight: Boolean, isClassic: Boolean) = function(isLight, isClassic)
constructor(light: Color, dark: Color): this(function = { isLight, _ -> if (isLight) light else dark })
constructor(classicDark: Color, classicLight: Color, oceanDark: Color, oceanLight: Color): this(function = { isLight, isClassic -> if (isLight) if (isClassic) classicLight else oceanLight else if (isClassic) classicDark else oceanDark })
}
private class UnresolvedSessionColors(
val danger: UnresolvedColor = UnresolvedColor(dark = dangerDark, light = dangerLight),
val disabled: UnresolvedColor = UnresolvedColor(dark = disabledDark, light = disabledLioht),
val background: UnresolvedColor = UnresolvedColor(Color.Black, Color.White, oceanDarkColors[2], oceanLightColors[7]),
val backgroundSecondary: UnresolvedColor = UnresolvedColor(classicDarkColors[1], classicLightColors[5], oceanDarkColors[1], oceanLightColors[6]),
val text: UnresolvedColor = UnresolvedColor(Color.White, Color.Black, oceanDarkColors[1], oceanLightColors[1]),
val textSecondary: UnresolvedColor = UnresolvedColor(classicDarkColors[5], classicLightColors[1], oceanDarkColors[5], oceanLightColors[2]),
val borders: UnresolvedColor = UnresolvedColor(classicDarkColors[3], classicLightColors[3], oceanDarkColors[4], oceanLightColors[3]),
val textBubbleSent: UnresolvedColor = UnresolvedColor(Color.Black, Color.Black, Color.Black, oceanLightColors[1]),
val backgroundBubbleReceived: UnresolvedColor = UnresolvedColor(classicDarkColors[2], classicLightColors[4], oceanDarkColors[4], oceanLightColors[4]),
val textBubbleReceived: UnresolvedColor = UnresolvedColor(Color.White, classicLightColors[4], oceanDarkColors[4], oceanLightColors[4]),
) {
operator fun invoke(primary: Color, isLight: Boolean, isClassic: Boolean) = SessionColors(
primary = primary,
danger = danger(isLight, isClassic),
disabled = disabled(isLight, isClassic),
background = background(isLight, isClassic),
backgroundSecondary = backgroundSecondary(isLight, isClassic),
text = text(isLight, isClassic),
textSecondary = textSecondary(isLight, isClassic),
borders = borders(isLight, isClassic),
textBubbleSent = textBubbleSent(isLight, isClassic),
backgroundBubbleReceived = backgroundBubbleReceived(isLight, isClassic),
textBubbleReceived = textBubbleReceived(isLight, isClassic),
)
}
/**
* Converts current Theme to Compose Theme.
*/
@ -63,6 +140,15 @@ fun AppTheme(
val surface = context.getColorFromTheme(R.attr.colorSettingsBackground)
val themeState = AppTextSecurePreferences(context).themeState()
val sessionColors = UnresolvedSessionColors()(themeState.accent, themeState.isLight, themeState.isClassic)
val textSelectionColors = TextSelectionColors(
handleColor = MaterialTheme.colors.secondary,
backgroundColor = MaterialTheme.colors.secondary.copy(alpha = 0.5f)
)
CompositionLocalProvider(
*listOf(
LocalCellColor to R.attr.colorSettingsBackground,
@ -72,10 +158,10 @@ fun AppTheme(
).map { (local, attr) -> local provides context.getColorFromTheme(attr) }.toTypedArray()
) {
AppCompatTheme(surface = surface) {
CompositionLocalProvider(LocalTextSelectionColors provides TextSelectionColors(
handleColor = MaterialTheme.colors.secondary,
backgroundColor = MaterialTheme.colors.secondary.copy(alpha = 0.5f)
)) {
CompositionLocalProvider(
LocalColors provides sessionColors,
LocalTextSelectionColors provides textSelectionColors
) {
content()
}
}

View File

@ -12,6 +12,13 @@ import androidx.fragment.app.DialogFragment
import network.loki.messenger.R
import org.session.libsession.utilities.TextSecurePreferences
import org.thoughtcrime.securesms.BaseActionBarActivity
import org.thoughtcrime.securesms.ui.primaryBlue
import org.thoughtcrime.securesms.ui.primaryGreen
import org.thoughtcrime.securesms.ui.primaryOrange
import org.thoughtcrime.securesms.ui.primaryPink
import org.thoughtcrime.securesms.ui.primaryPurple
import org.thoughtcrime.securesms.ui.primaryRed
import org.thoughtcrime.securesms.ui.primaryYellow
fun BaseActionBarActivity.setUpActionBarSessionLogo(hideBackButton: Boolean = false) {
val actionbar = supportActionBar!!
@ -100,7 +107,21 @@ data class ThemeState (
@StyleRes val theme: Int,
@StyleRes val accentStyle: Int,
val followSystem: Boolean
)
) {
val isLight = theme in setOf(R.style.Classic_Light, R.style.Ocean_Light)
val isClassic = theme in setOf(R.style.Classic_Light, R.style.Classic_Dark)
val accent = when(accentStyle) {
R.style.PrimaryGreen -> primaryGreen
R.style.PrimaryBlue -> primaryBlue
R.style.PrimaryPurple -> primaryPurple
R.style.PrimaryPink -> primaryPink
R.style.PrimaryRed -> primaryRed
R.style.PrimaryOrange -> primaryOrange
R.style.PrimaryYellow -> primaryYellow
else -> primaryGreen
}
}
inline fun <reified T: Activity> Activity.show() = Intent(this, T::class.java).also(::startActivity).also { overridePendingTransition(R.anim.slide_from_bottom, R.anim.fade_scale_out) }
inline fun <reified T: Activity> Activity.push() = Intent(this, T::class.java).also(::startActivity).also { overridePendingTransition(R.anim.slide_from_right, R.anim.fade_scale_out) }

View File

@ -1,6 +1,7 @@
package org.session.libsession.utilities
import android.content.Context
import android.graphics.Color
import android.hardware.Camera
import android.net.Uri
import android.provider.Settings
@ -986,9 +987,11 @@ interface TextSecurePreferences {
setBooleanPreference(context, FINGERPRINT_KEY_GENERATED, true)
}
@JvmStatic
fun getAccentColorName(context: Context): String? = getStringPreference(context, SELECTED_ACCENT_COLOR, ORANGE_ACCENT)
@JvmStatic @StyleRes
fun getAccentColorStyle(context: Context): Int? {
return when (getStringPreference(context, SELECTED_ACCENT_COLOR, ORANGE_ACCENT)) {
fun getAccentColorStyle(context: Context): Int? = when (getAccentColorName(context)) {
GREEN_ACCENT -> R.style.PrimaryGreen
BLUE_ACCENT -> R.style.PrimaryBlue
PURPLE_ACCENT -> R.style.PrimaryPurple
@ -998,7 +1001,6 @@ interface TextSecurePreferences {
YELLOW_ACCENT -> R.style.PrimaryYellow
else -> null
}
}
@JvmStatic
fun setAccentColorStyle(context: Context, @StyleRes newColor: Int?) {