more color options and some fixes

This commit is contained in:
Avently committed 2023-04-27 20:22:25 +07:00
1 parent 1efc7aafd8
commit 6a0ff7a029
27 files changed
+187 -131

No files matched your search

@@ -17,6 +17,7 @@ import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
@@ -82,20 +83,14 @@ class MainActivity: FragmentActivity() {
}
setContent {
SimpleXTheme {
Surface(
Modifier
.themedBackground()
.fillMaxSize()
) {
MainPage(
m,
userAuthorized,
laFailed,
::runAuthenticate,
::setPerformLA,
showLANotice = { showLANotice(m.controller.appPrefs.laNoticeShown, this) }
)
}
MainPage(
m,
userAuthorized,
laFailed,
::runAuthenticate,
::setPerformLA,
showLANotice = { showLANotice(m.controller.appPrefs.laNoticeShown, this) }
)
}
}
SimplexApp.context.schedulePeriodicServiceRestartWorker()
@@ -151,7 +151,7 @@ class AppPreferences(val context: Context) {
val confirmDBUpgrades = mkBoolPreference(SHARED_PREFS_CONFIRM_DB_UPGRADES, false)
val currentTheme = mkStrPreference(SHARED_PREFS_CURRENT_THEME, DefaultTheme.SYSTEM.name)
val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.BLUE.name)
val systemDarkTheme = mkStrPreference(SHARED_PREFS_SYSTEM_DARK_THEME, DefaultTheme.SIMPLEX.name)
val themeOverrides = mkMapPreference(SHARED_PREFS_THEMES, mapOf(), encode = {
json.encodeToString(MapSerializer(String.serializer(), ThemeOverrides.serializer()), it)
}, decode = {
@@ -13,7 +13,6 @@ val SimplexGreen = Color(77, 218, 103, 255)
val SecretColor = Color(0x40808080)
val LightGray = Color(241, 242, 246, 255)
val DarkGray = Color(43, 44, 46, 255)
val DarkGrayBackground = Color(38, 38, 38, 255)
val HighOrLowlight = Color(139, 135, 134, 255)
val MessagePreviewDark = Color(179, 175, 174, 255)
val MessagePreviewLight = Color(49, 45, 44, 255)
@@ -12,12 +12,13 @@ import androidx.compose.ui.graphics.*
import androidx.compose.ui.unit.dp
import chat.simplex.app.R
import chat.simplex.app.SimplexApp
import chat.simplex.app.views.helpers.generalGetString
import chat.simplex.app.views.helpers.*
import kotlinx.coroutines.flow.MutableStateFlow
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
enum class DefaultTheme {
SYSTEM, LIGHT, DARK, BLUE;
SYSTEM, LIGHT, DARK, SIMPLEX;
// Call it only with base theme, not SYSTEM
fun hasChangedAnyColor(colors: Colors): Boolean {
@@ -25,7 +26,7 @@ enum class DefaultTheme {
SYSTEM -> return false
LIGHT -> LightColorPalette
DARK -> DarkColorPalette
BLUE -> BlueColorPalette
SIMPLEX -> SimplexColorPalette
}
return with(palette) {
colors.primary != primary ||
@@ -38,10 +39,15 @@ enum class DefaultTheme {
}
}
enum class ThemeColor {
PRIMARY, PRIMARY_VARIANT, SECONDARY, SECONDARY_VARIANT, BACKGROUND, SURFACE;
data class AppColors(
val sentMessage: Color,
val receivedMessage: Color
)
fun fromColors(colors: Colors): Color {
enum class ThemeColor {
PRIMARY, PRIMARY_VARIANT, SECONDARY, SECONDARY_VARIANT, BACKGROUND, SURFACE, SENT_MESSAGE, RECEIVED_MESSAGE;
fun fromColors(colors: Colors, appColors: AppColors): Color {
return when (this) {
PRIMARY -> colors.primary
PRIMARY_VARIANT -> colors.primaryVariant
@@ -49,6 +55,8 @@ enum class ThemeColor {
SECONDARY_VARIANT -> colors.secondaryVariant
BACKGROUND -> colors.background
SURFACE -> colors.surface
SENT_MESSAGE -> appColors.sentMessage
RECEIVED_MESSAGE -> appColors.receivedMessage
}
}
@@ -60,23 +68,30 @@ enum class ThemeColor {
SECONDARY_VARIANT -> generalGetString(R.string.color_secondary_variant)
BACKGROUND -> generalGetString(R.string.color_background)
SURFACE -> generalGetString(R.string.color_surface)
SENT_MESSAGE -> generalGetString(R.string.color_sent_message)
RECEIVED_MESSAGE -> generalGetString(R.string.color_received_message)
}
}
@Serializable
data class ThemeColors(
@SerialName("accent")
val primary: String? = null,
@SerialName("accentVariant")
val primaryVariant: String? = null,
val secondary: String? = null,
val secondaryVariant: String? = null,
val background: String? = null,
@SerialName("menus")
val surface: String? = null,
val sentMessage: String? = null,
val receivedMessage: String? = null,
) {
fun toColors(base: DefaultTheme): Colors {
val baseColors = when (base) {
DefaultTheme.LIGHT -> LightColorPalette
DefaultTheme.DARK -> DarkColorPalette
DefaultTheme.BLUE -> BlueColorPalette
DefaultTheme.SIMPLEX -> SimplexColorPalette
// shouldn't be here
DefaultTheme.SYSTEM -> LightColorPalette
}
@@ -89,6 +104,20 @@ data class ThemeColors(
surface = surface?.colorFromReadableHex() ?: baseColors.surface,
)
}
fun toAppColors(base: DefaultTheme): AppColors {
val baseColors = when (base) {
DefaultTheme.LIGHT -> LightColorPaletteApp
DefaultTheme.DARK -> DarkColorPaletteApp
DefaultTheme.SIMPLEX -> SimplexColorPaletteApp
// shouldn't be here
DefaultTheme.SYSTEM -> LightColorPaletteApp
}
return baseColors.copy(
sentMessage = sentMessage?.colorFromReadableHex() ?: baseColors.sentMessage,
receivedMessage = receivedMessage?.colorFromReadableHex() ?: baseColors.receivedMessage,
)
}
}
private fun String.colorFromReadableHex(): Color =
@@ -107,13 +136,15 @@ data class ThemeOverrides (
ThemeColor.SECONDARY_VARIANT -> colors.copy(secondaryVariant = color)
ThemeColor.BACKGROUND -> colors.copy(background = color)
ThemeColor.SURFACE -> colors.copy(surface = color)
ThemeColor.SENT_MESSAGE -> colors.copy(sentMessage = color)
ThemeColor.RECEIVED_MESSAGE -> colors.copy(receivedMessage = color)
})
}
}
fun Modifier.themedBackground(baseTheme: DefaultTheme = CurrentColors.value.base, shape: Shape = RectangleShape): Modifier {
return if (baseTheme == DefaultTheme.BLUE) {
this.background(brush = Brush.linearGradient(listOf(Color(0xff0C0B13), Color(0xff151D36)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f)), shape = shape)
return if (baseTheme == DefaultTheme.SIMPLEX) {
this.background(brush = Brush.linearGradient(listOf(CurrentColors.value.colors.background.darker(0.5f), CurrentColors.value.colors.background.lighter(0.2f)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f)), shape = shape)
} else {
this.background(color = CurrentColors.value.colors.background, shape = shape)
}
@@ -130,7 +161,7 @@ val DarkColorPalette = darkColors(
primaryVariant = SimplexBlue,
secondary = DarkGray,
// background = Color.Black,
surface = Color(0xFF121212),
surface = Color(0xFF222222),
// background = Color(0xFF121212),
// surface = Color(0xFF121212),
error = Color.Red,
@@ -138,6 +169,11 @@ val DarkColorPalette = darkColors(
onSurface = Color(0xFFFFFBFA),
// onError: Color = Color.Black,
)
val DarkColorPaletteApp = AppColors(
sentMessage = Color(0x1E45B8FF),
receivedMessage = Color(0x20B1B0B5)
)
val LightColorPalette = lightColors(
primary = SimplexBlue, // If this value changes also need to update #0088ff in string resource files
primaryVariant = SimplexBlue,
@@ -150,20 +186,28 @@ val LightColorPalette = lightColors(
// onBackground = Color.Black,
// onSurface = Color.Black,
)
val LightColorPaletteApp = AppColors(
sentMessage = Color(0x1E45B8FF),
receivedMessage = Color(0x20B1B0B5)
)
val BlueColorPalette = darkColors(
val SimplexColorPalette = darkColors(
primary = Color(0xff70F0F9), // If this value changes also need to update #0088ff in string resource files
primaryVariant = Color(0xff298AE7),
secondary = Color(0xff2C464D),
background = Color(0xff111528),
// surface = Color.Black,
// background = Color(0xFF121212),
surface = Color(0xFF1C1C22),
surface = Color(0xff151b38),
error = Color.Red,
onBackground = Color(0xFFFFFBFA),
onSurface = Color(0xFFFFFBFA),
// onBackground = Color(0xFFFFFBFA),
// onSurface = Color(0xFFFFFBFA),
// onError: Color = Color.Black,
)
val SimplexColorPaletteApp = AppColors(
sentMessage = Color(0x1E45B8FF),
receivedMessage = Color(0x20B1B0B5)
)
val CurrentColors: MutableStateFlow<ThemeManager.ActiveTheme> = MutableStateFlow(ThemeManager.currentColors(isInNightMode()))
@@ -14,12 +14,12 @@ object ThemeManager {
SimplexApp.context.chatModel.controller.appPrefs
}
data class ActiveTheme(val name: String, val base: DefaultTheme, val colors: Colors)
data class ActiveTheme(val name: String, val base: DefaultTheme, val colors: Colors, val appColors: AppColors)
private fun systemDarkThemeColors(): Pair<Colors, DefaultTheme> = when (appPrefs.systemDarkTheme.get()) {
DefaultTheme.DARK.name -> DarkColorPalette to DefaultTheme.DARK
DefaultTheme.BLUE.name -> BlueColorPalette to DefaultTheme.BLUE
else -> BlueColorPalette to DefaultTheme.BLUE
DefaultTheme.SIMPLEX.name -> SimplexColorPalette to DefaultTheme.SIMPLEX
else -> SimplexColorPalette to DefaultTheme.SIMPLEX
}
fun currentColors(darkForSystemTheme: Boolean): ActiveTheme {
@@ -33,15 +33,15 @@ object ThemeManager {
}
val theme = themeOverrides[nonSystemThemeName]
val baseTheme = when (nonSystemThemeName) {
DefaultTheme.LIGHT.name -> Pair(LightColorPalette, DefaultTheme.LIGHT)
DefaultTheme.DARK.name -> Pair(DarkColorPalette, DefaultTheme.DARK)
DefaultTheme.BLUE.name -> Pair(BlueColorPalette, DefaultTheme.BLUE)
else -> Pair(LightColorPalette, DefaultTheme.LIGHT)
DefaultTheme.LIGHT.name -> Triple(DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp)
DefaultTheme.DARK.name -> Triple(DefaultTheme.DARK, DarkColorPalette, DarkColorPaletteApp)
DefaultTheme.SIMPLEX.name -> Triple(DefaultTheme.SIMPLEX, SimplexColorPalette, SimplexColorPaletteApp)
else -> Triple(DefaultTheme.LIGHT, LightColorPalette, LightColorPaletteApp)
}
if (theme == null) {
return ActiveTheme(themeName, baseTheme.second, baseTheme.first)
return ActiveTheme(themeName, baseTheme.first, baseTheme.second, baseTheme.third)
}
return ActiveTheme(themeName, baseTheme.second, theme.colors.toColors(theme.base))
return ActiveTheme(themeName, baseTheme.first, theme.colors.toColors(theme.base), theme.colors.toAppColors(theme.base))
}
fun currentThemeOverrides(darkForSystemTheme: Boolean): ThemeOverrides {
@@ -81,9 +81,9 @@ object ThemeManager {
)
allThemes.add(
Triple(
BlueColorPalette,
DefaultTheme.BLUE,
generalGetString(R.string.theme_blue)
SimplexColorPalette,
DefaultTheme.SIMPLEX,
generalGetString(R.string.theme_simplex)
)
)
return allThemes
@@ -110,9 +110,9 @@ object ThemeManager {
if (colorToSet == null) {
// Setting default color from a base theme
colorToSet = when(nonSystemThemeName) {
DefaultTheme.LIGHT.name -> name.fromColors(LightColorPalette)
DefaultTheme.DARK.name -> name.fromColors(DarkColorPalette)
DefaultTheme.BLUE.name -> name.fromColors(BlueColorPalette)
DefaultTheme.LIGHT.name -> name.fromColors(LightColorPalette, LightColorPaletteApp)
DefaultTheme.DARK.name -> name.fromColors(DarkColorPalette, DarkColorPaletteApp)
DefaultTheme.SIMPLEX.name -> name.fromColors(SimplexColorPalette, SimplexColorPaletteApp)
// Will not be here
else -> return
}
@@ -1,19 +1,17 @@
package chat.simplex.app.views
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.fillMaxSize
import androidx.compose.material.MaterialTheme
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import chat.simplex.app.ui.theme.themedBackground
@Composable
fun SplashView() {
Surface(
Modifier
.themedBackground()
.fillMaxSize()
.fillMaxSize(),
color = MaterialTheme.colors.background
) {
// Image(
// painter = painterResource(R.drawable.logo),
@@ -2,6 +2,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@@ -10,16 +11,16 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import chat.simplex.app.R
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.chat.item.SentColorLight
@Composable
fun ComposeFileView(fileName: String, cancelFile: () -> Unit, cancelEnabled: Boolean) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
Row(
Modifier
.height(60.dp)
.fillMaxWidth()
.padding(top = 8.dp)
.background(SentColorLight),
.background(sentColor),
verticalAlignment = Alignment.CenterVertically
) {
Icon(
@@ -14,21 +14,18 @@ import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.app.R
import chat.simplex.app.model.durationText
import chat.simplex.app.ui.theme.DEFAULT_PADDING_HALF
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.views.chat.item.SentColorLight
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.helpers.UploadContent
import chat.simplex.app.views.helpers.base64ToBitmap
@Composable
fun ComposeImageView(media: ComposePreview.MediaPreview, cancelImages: () -> Unit, cancelEnabled: Boolean) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
Row(
Modifier
.padding(top = 8.dp)
.background(SentColorLight),
.background(sentColor),
verticalAlignment = Alignment.CenterVertically,
) {
LazyRow(
@@ -14,7 +14,6 @@ import androidx.compose.ui.unit.sp
import chat.simplex.app.R
import chat.simplex.app.model.durationText
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.chat.item.SentColorLight
import chat.simplex.app.views.helpers.*
import kotlinx.coroutines.flow.distinctUntilChanged
@@ -57,12 +56,13 @@ fun ComposeVoiceView(
.height(3.dp)
.background(MaterialTheme.colors.primary)
)
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
Row(
Modifier
.height(60.dp)
.fillMaxWidth()
.padding(top = 8.dp)
.background(SentColorLight),
.background(sentColor),
verticalAlignment = Alignment.CenterVertically
) {
IconButton(
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
@@ -13,8 +14,7 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import chat.simplex.app.R
import chat.simplex.app.model.*
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.chat.item.*
import kotlinx.datetime.Clock
@@ -25,10 +25,12 @@ fun ContextItemView(
cancelContextItem: () -> Unit
) {
val sent = contextItem.chatDir.sent
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Row(
Modifier
.padding(top = 8.dp)
.background(if (sent) SentColorLight else ReceivedColorLight),
.background(if (sent) sentColor else receivedColor),
verticalAlignment = Alignment.CenterVertically
) {
Row(
@@ -22,23 +22,20 @@ fun CIEventView(ci: ChatItem) {
fun chatEventTextView(text: AnnotatedString) {
Text(text, style = MaterialTheme.typography.body1.copy(lineHeight = 22.sp))
}
Surface {
Row(
Modifier.padding(horizontal = 6.dp, vertical = 6.dp),
verticalAlignment = Alignment.CenterVertically
) {
val memberDisplayName = ci.memberDisplayName
if (memberDisplayName != null) {
chatEventTextView(
buildAnnotatedString {
withStyle(chatEventStyle) { append(memberDisplayName) }
append(" ")
}.plus(chatEventText(ci))
)
} else {
chatEventTextView(chatEventText(ci))
}
Row(
Modifier.padding(horizontal = 6.dp, vertical = 6.dp),
verticalAlignment = Alignment.CenterVertically
) {
val memberDisplayName = ci.memberDisplayName
if (memberDisplayName != null) {
chatEventTextView(
buildAnnotatedString {
withStyle(chatEventStyle) { append(memberDisplayName) }
append(" ")
}.plus(chatEventText(ci))
)
} else {
chatEventTextView(chatEventText(ci))
}
}
}
@@ -8,7 +8,6 @@ import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
@@ -69,12 +68,14 @@ fun CIGroupInvitationView(
}
}
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Surface(
modifier = if (action) Modifier.clickable(onClick = {
joinGroup(groupInvitation.groupId)
}) else Modifier,
shape = RoundedCornerShape(18.dp),
color = if (sent) SentColorLight else ReceivedColorLight,
color = if (sent) sentColor else receivedColor,
) {
Box(
Modifier
@@ -156,9 +156,11 @@ private fun PlayPauseButton(
pause: () -> Unit,
longClick: () -> Unit
) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Surface(
Modifier.drawRingModifier(angle, strokeColor, strokeWidth),
color = if (sent) SentColorLight else ReceivedColorLight,
color = if (sent) sentColor else receivedColor,
shape = MaterialTheme.shapes.small.copy(CornerSize(percent = 50))
) {
Box(
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.*
@@ -13,15 +14,16 @@ import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.app.model.ChatItem
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.ui.theme.*
@Composable
fun DeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showMember: Boolean = false) {
val sent = ci.chatDir.sent
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Surface(
shape = RoundedCornerShape(18.dp),
color = if (sent) SentColorLight else ReceivedColorLight,
color = if (sent) sentColor else receivedColor,
) {
Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
@@ -29,11 +29,6 @@ import chat.simplex.app.views.helpers.*
import kotlinx.datetime.Clock
import kotlin.math.min
val SentColorLight = Color(0x1E45B8FF)
val ReceivedColorLight = Color(0x20B1B0B5)
val SentQuoteColorLight = Color(0x2545B8FF)
val ReceivedQuoteColorLight = Color(0x25B1B0B5)
@Composable
fun FramedItemView(
chatInfo: ChatInfo,
@@ -54,6 +49,9 @@ fun FramedItemView(
return if (chatInfo is ChatInfo.Group) chatInfo.groupInfo.membership else null
}
@Composable
fun Color.toQuote(): Color = if (isInDarkTheme()) lighter(0.2f) else darker(0.2f)
@Composable
fun ciQuotedMsgView(qi: CIQuote) {
Box(
@@ -70,9 +68,11 @@ fun FramedItemView(
@Composable
fun FramedItemHeader(caption: String, italic: Boolean, icon: Painter? = null) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Row(
Modifier
.background(if (sent) SentQuoteColorLight else ReceivedQuoteColorLight)
.background(if (sent) sentColor.toQuote() else receivedColor.toQuote())
.fillMaxWidth()
.padding(start = 8.dp, top = 6.dp, end = 12.dp, bottom = if (ci.quotedItem == null) 6.dp else 0.dp),
horizontalArrangement = Arrangement.spacedBy(4.dp),
@@ -100,9 +100,11 @@ fun FramedItemView(
@Composable
fun ciQuoteView(qi: CIQuote) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Row(
Modifier
.background(if (sent) SentQuoteColorLight else ReceivedQuoteColorLight)
.background(if (sent) sentColor.toQuote() else receivedColor.toQuote())
.fillMaxWidth()
.combinedClickable(
onLongClick = { showMenu.value = true },
@@ -163,13 +165,15 @@ fun FramedItemView(
val transparentBackground = (ci.content.msgContent is MsgContent.MCImage || ci.content.msgContent is MsgContent.MCVideo) &&
!ci.meta.isLive && ci.content.text.isEmpty() && ci.quotedItem == null
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Box(Modifier
.clip(RoundedCornerShape(18.dp))
.background(
when {
transparentBackground -> Color.Transparent
sent -> SentColorLight
else -> ReceivedColorLight
sent -> sentColor
else -> receivedColor
}
)) {
var metaColor = HighOrLowlight
@@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
@@ -18,6 +19,7 @@ import androidx.compose.ui.unit.sp
import chat.simplex.app.R
import chat.simplex.app.model.ChatItem
import chat.simplex.app.model.MsgErrorType
import chat.simplex.app.ui.theme.CurrentColors
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.views.helpers.AlertManager
import chat.simplex.app.views.helpers.generalGetString
@@ -50,10 +52,11 @@ fun IntegrityErrorItemView(msgError: MsgErrorType, ci: ChatItem, timedMessagesTT
@Composable
fun CIMsgError(ci: ChatItem, timedMessagesTTL: Int?, showMember: Boolean = false, onClick: () -> Unit) {
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Surface(
Modifier.clickable(onClick = onClick),
shape = RoundedCornerShape(18.dp),
color = ReceivedColorLight,
color = receivedColor,
) {
Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
@@ -5,6 +5,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.RoundedCornerShape
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.text.*
@@ -16,15 +17,16 @@ import androidx.compose.ui.unit.sp
import chat.simplex.app.R
import chat.simplex.app.model.CIDeleted
import chat.simplex.app.model.ChatItem
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.ui.theme.*
import chat.simplex.app.views.helpers.generalGetString
@Composable
fun MarkedDeletedItemView(ci: ChatItem, timedMessagesTTL: Int?, showMember: Boolean = false) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
val receivedColor = CurrentColors.collectAsState().value.appColors.receivedMessage
Surface(
shape = RoundedCornerShape(18.dp),
color = if (ci.chatDir.sent) SentColorLight else ReceivedColorLight,
color = if (ci.chatDir.sent) sentColor else receivedColor,
) {
Row(
Modifier.padding(horizontal = 12.dp, vertical = 6.dp),
@@ -224,7 +224,7 @@ fun ChatPreviewView(
color = MaterialTheme.colors.onPrimary,
fontSize = 11.sp,
modifier = Modifier
.background(if (stopped || showNtfsIcon) HighOrLowlight else MaterialTheme.colors.primary, shape = CircleShape)
.background(if (stopped || showNtfsIcon) MaterialTheme.colors.secondary else MaterialTheme.colors.primary, shape = CircleShape)
.badgeLayout()
.padding(horizontal = 3.dp)
.padding(vertical = 1.dp)
@@ -37,7 +37,6 @@ class AlertManager {
) {
showAlert {
AlertDialog(
backgroundColor = if (isInDarkTheme()) DarkGrayBackground else MaterialTheme.colors.background,
onDismissRequest = this::hideAlert,
title = alertTitle(title),
text = alertText(text),
@@ -56,7 +55,7 @@ class AlertManager {
Dialog(onDismissRequest = this::hideAlert) {
Column(
Modifier
.background(if (isInDarkTheme()) DarkGrayBackground else MaterialTheme.colors.background, RoundedCornerShape(corner = CornerSize(25.dp)))
.background(MaterialTheme.colors.surface, RoundedCornerShape(corner = CornerSize(25.dp)))
.padding(bottom = DEFAULT_PADDING)
) {
Text(
@@ -106,7 +105,6 @@ class AlertManager {
}) { Text(confirmText, color = if (destructive) MaterialTheme.colors.error else Color.Unspecified) }
}
},
backgroundColor = if (isInDarkTheme()) DarkGrayBackground else MaterialTheme.colors.background,
shape = RoundedCornerShape(corner = CornerSize(25.dp))
)
}
@@ -142,7 +140,6 @@ class AlertManager {
}) { Text(confirmText, color = if (destructive) Color.Red else Color.Unspecified, textAlign = TextAlign.End) }
}
},
backgroundColor = if (isInDarkTheme()) DarkGrayBackground else MaterialTheme.colors.background,
shape = RoundedCornerShape(corner = CornerSize(25.dp))
)
}
@@ -168,7 +165,6 @@ class AlertManager {
}) { Text(confirmText, color = Color.Unspecified) }
}
},
backgroundColor = if (isInDarkTheme()) DarkGrayBackground else MaterialTheme.colors.background,
shape = RoundedCornerShape(corner = CornerSize(25.dp))
)
}
@@ -8,7 +8,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.geometry.Offset
import androidx.compose.ui.graphics.Brush
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.text.style.TextAlign
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.tooling.preview.Preview
@@ -45,8 +44,8 @@ fun CloseSheetBar(close: (() -> Unit)?, endButtons: @Composable RowScope.() -> U
@Composable
fun AppBarTitle(title: String, withPadding: Boolean = true) {
val theme = CurrentColors.collectAsState()
val brush = if (theme.value.base == DefaultTheme.BLUE)
Brush.linearGradient(listOf(Color(0xff1068D9), Color(0xff41A9F5)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f))
val brush = if (theme.value.base == DefaultTheme.SIMPLEX)
Brush.linearGradient(listOf(MaterialTheme.colors.primaryVariant.darker(0.2f), MaterialTheme.colors.primaryVariant.lighter(0.2f)), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f))
else // color is not updated when changing themes if I pass null here
Brush.linearGradient(listOf(MaterialTheme.colors.primaryVariant, MaterialTheme.colors.primaryVariant), Offset(0f, Float.POSITIVE_INFINITY), Offset(Float.POSITIVE_INFINITY, 0f))
Text(
@@ -20,7 +20,6 @@ fun DefaultDropdownMenu(
dropdownMenuItems: (@Composable () -> Unit)?
) {
MaterialTheme(
colors = MaterialTheme.colors.copy(surface = MaterialTheme.colors.surface),
shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(corner = CornerSize(25.dp)))
) {
DropdownMenu(
@@ -44,11 +43,13 @@ fun ExposedDropdownMenuBoxScope.DefaultExposedDropdownMenu(
dropdownMenuItems: (@Composable () -> Unit)?
) {
MaterialTheme(
colors = MaterialTheme.colors.copy(surface = if (isInDarkTheme()) Color(0xFF080808) else MaterialTheme.colors.background),
shapes = MaterialTheme.shapes.copy(medium = RoundedCornerShape(corner = CornerSize(25.dp)))
) {
ExposedDropdownMenu(
modifier = Modifier.widthIn(min = 200.dp).then(modifier),
modifier = Modifier
.widthIn(min = 200.dp)
.background(MaterialTheme.colors.surface)
.then(modifier),
expanded = expanded.value,
onDismissRequest = {
expanded.value = false
@@ -7,6 +7,7 @@ import androidx.compose.foundation.background
import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.Composable
import androidx.compose.runtime.collectAsState
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.asImageBitmap
@@ -19,9 +20,7 @@ import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
import chat.simplex.app.R
import chat.simplex.app.model.LinkPreview
import chat.simplex.app.ui.theme.HighOrLowlight
import chat.simplex.app.ui.theme.SimpleXTheme
import chat.simplex.app.views.chat.item.SentColorLight
import chat.simplex.app.ui.theme.*
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import org.jsoup.Jsoup
@@ -79,8 +78,9 @@ suspend fun getLinkPreview(url: String): LinkPreview? {
@Composable
fun ComposeLinkView(linkPreview: LinkPreview?, cancelPreview: () -> Unit) {
val sentColor = CurrentColors.collectAsState().value.appColors.sentMessage
Row(
Modifier.fillMaxWidth().padding(top = 8.dp).background(SentColorLight),
Modifier.fillMaxWidth().padding(top = 8.dp).background(sentColor),
verticalAlignment = Alignment.CenterVertically
) {
if (linkPreview == null) {
@@ -584,6 +584,9 @@ fun getBitmapFromVideo(uri: Uri, timestamp: Long? = null, random: Boolean = true
fun Color.darker(factor: Float = 0.1f): Color =
Color(max(red * (1 - factor), 0f), max(green * (1 - factor), 0f), max(blue * (1 - factor), 0f), alpha)
fun Color.lighter(factor: Float = 0.1f): Color =
Color(min(red * (1 + factor), 1f), min(green * (1 + factor), 1f), min(blue * (1 + factor), 1f), alpha)
fun ByteArray.toBase64String() = Base64.encodeToString(this, Base64.DEFAULT)
fun String.toByteArrayFromBase64() = Base64.decode(this, Base64.DEFAULT)
@@ -4,6 +4,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
@@ -44,7 +45,7 @@ fun ConnectViaLinkView(m: ChatModel, close: () -> Unit) {
}
TabRow(
selectedTabIndex = selection.value.ordinal,
backgroundColor = MaterialTheme.colors.background,
backgroundColor = Color.Transparent,
contentColor = MaterialTheme.colors.primary,
) {
tabTitles.forEachIndexed { index, it ->
@@ -5,6 +5,7 @@ import androidx.compose.material.*
import androidx.compose.runtime.*
import androidx.compose.runtime.saveable.rememberSaveable
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.res.painterResource
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.sp
@@ -67,7 +68,7 @@ fun CreateLinkView(m: ChatModel, initialSelection: CreateLinkTab) {
}
TabRow(
selectedTabIndex = selection.value.ordinal,
backgroundColor = MaterialTheme.colors.background,
backgroundColor = Color.Transparent,
contentColor = MaterialTheme.colors.primary,
) {
tabTitles.forEachIndexed { index, it ->
@@ -1,7 +1,6 @@
package chat.simplex.app.views.usersettings
import SectionBottomSpacer
import SectionCustomFooter
import SectionDividerSpaced
import SectionItemView
import SectionItemViewSpaceBetween
@@ -170,13 +169,10 @@ fun AppearanceView(m: ChatModel) {
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.primary)
}
// Not allowed to change title color since it is using gradient brush with custom colors
if (currentTheme.base != DefaultTheme.BLUE) {
SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT, currentTheme.colors.primaryVariant) }) {
val title = generalGetString(R.string.color_primary_variant)
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.primaryVariant)
}
SectionItemViewSpaceBetween({ editColor(ThemeColor.PRIMARY_VARIANT, currentTheme.colors.primaryVariant) }) {
val title = generalGetString(R.string.color_primary_variant)
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.primaryVariant)
}
SectionItemViewSpaceBetween({ editColor(ThemeColor.SECONDARY, currentTheme.colors.secondary) }) {
val title = generalGetString(R.string.color_secondary)
@@ -199,11 +195,21 @@ fun AppearanceView(m: ChatModel) {
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = colors.surface)
}
SectionItemViewSpaceBetween({ editColor(ThemeColor.SENT_MESSAGE, currentTheme.appColors.sentMessage) }) {
val title = generalGetString(R.string.color_sent_message)
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = currentTheme.appColors.sentMessage)
}
SectionItemViewSpaceBetween({ editColor(ThemeColor.RECEIVED_MESSAGE, currentTheme.appColors.receivedMessage) }) {
val title = generalGetString(R.string.color_received_message)
Text(title)
Icon(painterResource(R.drawable.ic_circle_filled), title, tint = currentTheme.appColors.receivedMessage)
}
}
val isInDarkTheme = isInDarkTheme()
if (currentTheme.base.hasChangedAnyColor(currentTheme.colors)) {
SectionItemView({ ThemeManager.resetAllThemeColors(darkForSystemTheme = isInDarkTheme) }) {
Text(generalGetString(R.string.reset_color), color = colors.error)
Text(generalGetString(R.string.reset_color), color = colors.primary)
}
}
SectionSpacer()
@@ -215,7 +221,7 @@ fun AppearanceView(m: ChatModel) {
SectionItemView({
val overrides = ThemeManager.currentThemeOverrides(isInDarkTheme)
theme.value = yaml.encodeToString<ThemeOverrides>(overrides)
exportThemeLauncher.launch("SimpleX-${overrides.base.name}.yml")
exportThemeLauncher.launch("simplex.theme")
}) {
Text(generalGetString(R.string.export_theme), color = colors.primary)
}
@@ -231,7 +237,7 @@ fun AppearanceView(m: ChatModel) {
}
// Can not limit to YAML mime type since it's unsupported by Android
SectionItemView({ importThemeLauncher.launch("*/*") }) {
Text(generalGetString(R.string.import_theme), color = colors.error)
Text(generalGetString(R.string.import_theme), color = colors.primary)
}
}
SectionBottomSpacer()
@@ -276,7 +282,7 @@ fun ColorPicker(initialColor: Color, onColorChanged: (Color) -> Unit) {
modifier = Modifier
.fillMaxWidth()
.height(300.dp),
showAlphaBar = false,
showAlphaBar = true,
onColorChanged = { color: HsvColor ->
onColorChanged(color.toColor())
}
@@ -329,7 +335,7 @@ private fun DarkThemeSelector(state: State<String?>, onSelected: (String) -> Uni
val values by remember {
val darkThemes = ArrayList<Pair<String, String>>()
darkThemes.add(DefaultTheme.DARK.name to generalGetString(R.string.theme_dark))
darkThemes.add(DefaultTheme.BLUE.name to generalGetString(R.string.theme_blue))
darkThemes.add(DefaultTheme.SIMPLEX.name to generalGetString(R.string.theme_simplex))
mutableStateOf(darkThemes.toList())
}
ExposedDropDownSettingRow(
@@ -1156,7 +1156,7 @@
<string name="theme_system">System</string>
<string name="theme_light">Light</string>
<string name="theme_dark">Dark</string>
<string name="theme_blue">Blue</string>
<string name="theme_simplex">SimpleX</string>
<!-- Languages -->
<string name="language_system">System</string>
@@ -1175,7 +1175,9 @@
<string name="color_secondary">Secondary</string>
<string name="color_secondary_variant">Additional secondary</string>
<string name="color_background">Background</string>
<string name="color_surface">Surface</string>
<string name="color_surface">Menus &amp; alerts</string>
<string name="color_sent_message">Sent message</string>
<string name="color_received_message">Received message</string>
<!-- Preferences.kt -->
<string name="chat_preferences_you_allow">You allow</string>