diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt new file mode 100644 index 0000000000000000000000000000000000000000..6a5507360948cbc9053871709f0fb16c4e98a2e6 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationItemView.kt @@ -0,0 +1,173 @@ +package org.briarproject.briar.desktop.conversation + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.ColumnScope +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.size +import androidx.compose.foundation.lazy.LazyColumn +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.material.Card +import androidx.compose.material.Icon +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.icons.Icons +import androidx.compose.material.icons.filled.Done +import androidx.compose.material.icons.filled.DoneAll +import androidx.compose.material.icons.filled.Schedule +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.unit.Dp +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.briarproject.bramble.api.sync.GroupId +import org.briarproject.bramble.api.sync.MessageId +import org.briarproject.briar.api.client.SessionId +import org.briarproject.briar.desktop.conversation.ConversationRequestItem.RequestType.INTRODUCTION +import org.briarproject.briar.desktop.theme.msgIn +import org.briarproject.briar.desktop.theme.msgOut +import org.briarproject.briar.desktop.theme.msgStroke +import org.briarproject.briar.desktop.theme.privateMessageDate +import org.briarproject.briar.desktop.theme.textPrimary +import org.briarproject.briar.desktop.utils.InternationalizationUtils +import org.briarproject.briar.desktop.utils.PreviewUtils.preview +import org.briarproject.briar.desktop.utils.TimeUtils.getFormattedTimestamp +import java.time.Instant + +fun main() = preview { + LazyColumn { + item { + ConversationNoticeItemView( + ConversationNoticeItem( + msgText = "Let's test a received notice message.", + text = "Text of notice message.", + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = Instant.now().toEpochMilli(), + autoDeleteTimer = 0, + isIncoming = true, + isRead = true, + isSent = false, + isSeen = false, + ) + ) + } + item { + ConversationMessageItemView( + ConversationMessageItem( + text = "This is a medium-sized message that has been sent before receiving the request message.", + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = Instant.now().toEpochMilli(), + autoDeleteTimer = 0, + isIncoming = false, + isRead = false, + isSent = true, + isSeen = true, + ) + ) + } + item { + ConversationRequestItemView( + ConversationRequestItem( + requestedGroupId = null, + requestType = INTRODUCTION, + sessionId = SessionId(getRandomId()), + answered = false, + msgText = "Short message.", + text = "Text of notice message.", + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = Instant.now().toEpochMilli(), + autoDeleteTimer = 0, + isIncoming = true, + isRead = true, + isSent = false, + isSeen = false, + ) + ) + } + item { + ConversationNoticeItemView( + ConversationNoticeItem( + msgText = "This is a long long long message that spans over several lines.\n\nIt ends here.", + text = "Text of notice message.", + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = Instant.now().toEpochMilli(), + autoDeleteTimer = 0, + isIncoming = false, + isRead = false, + isSent = true, + isSeen = true, + ) + ) + } + item { + ConversationMessageItemView( + ConversationMessageItem( + text = "Just also receiving a normal message.", + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = Instant.now().toEpochMilli(), + autoDeleteTimer = 0, + isIncoming = true, + isRead = true, + isSent = false, + isSeen = false, + ) + ) + } + } +} + +@Composable +fun ConversationItemView( + item: ConversationItem, + content: @Composable () -> Unit +) { + val alignment = if (item.isIncoming) Alignment.Start else Alignment.End + val color = if (item.isIncoming) MaterialTheme.colors.msgIn else MaterialTheme.colors.msgOut + val shape = if (item.isIncoming) + RoundedCornerShape(topStart = 4.dp, topEnd = 16.dp, bottomStart = 16.dp, bottomEnd = 16.dp) + else + RoundedCornerShape(topStart = 16.dp, topEnd = 4.dp, bottomStart = 16.dp, bottomEnd = 16.dp) + + Column(Modifier.fillMaxWidth()) { + Column(Modifier.fillMaxWidth(fraction = 0.8f).align(alignment)) { + Card( + backgroundColor = color, + elevation = 2.dp, + shape = shape, + border = BorderStroke(Dp.Hairline, MaterialTheme.colors.msgStroke), + modifier = Modifier.align(alignment).padding(8.dp), + ) { + content() + } + } + } +} + +@Composable +fun ColumnScope.ConversationItemStatusView(item: ConversationItem, rowModifier: Modifier = Modifier) { + val statusColor = if (item.isIncoming) MaterialTheme.colors.textPrimary else MaterialTheme.colors.privateMessageDate + val statusAlignment = if (item.isIncoming) Alignment.End else Alignment.Start + Row(rowModifier.align(statusAlignment)) { + Text( + text = getFormattedTimestamp(item.time), + fontSize = 12.sp, + color = statusColor, + ) + if (!item.isIncoming) { + val modifier = Modifier.padding(start = 4.dp).size(12.dp).align(Alignment.CenterVertically) + val icon = + if (item.isSeen) Icons.Filled.DoneAll // acknowledged + else if (item.isSent) Icons.Filled.Done // sent + else Icons.Filled.Schedule // waiting + Icon(icon, InternationalizationUtils.i18n("access.message.sent"), modifier, statusColor) + } + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt new file mode 100644 index 0000000000000000000000000000000000000000..74833a0d0790f76c6b2f878dca62fbf0f4a15ddf --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationMessageItemView.kt @@ -0,0 +1,58 @@ +package org.briarproject.briar.desktop.conversation + +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.padding +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.briarproject.bramble.api.sync.GroupId +import org.briarproject.bramble.api.sync.MessageId +import org.briarproject.briar.desktop.theme.textPrimary +import org.briarproject.briar.desktop.utils.PreviewUtils.preview +import java.time.Instant + +fun main() = preview( + "text" to "This is a long long long message that spans over several lines.\n\nIt ends here.", + "time" to Instant.now().toEpochMilli(), + "isIncoming" to false, + "isRead" to false, + "isSent" to false, + "isSeen" to true, +) { + ConversationMessageItemView( + ConversationMessageItem( + text = getStringParameter("text"), + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = getLongParameter("time"), + autoDeleteTimer = 0, + isIncoming = getBooleanParameter("isIncoming"), + isRead = getBooleanParameter("isRead"), + isSent = getBooleanParameter("isSent"), + isSeen = getBooleanParameter("isSeen"), + ) + ) +} + +@Composable +fun ConversationMessageItemView(m: ConversationMessageItem) { + val textColor = if (m.isIncoming) MaterialTheme.colors.textPrimary else Color.White + ConversationItemView(m) { + Column( + Modifier.padding(12.dp, 8.dp) + ) { + Text( + m.text!!, + fontSize = 16.sp, + color = textColor, + modifier = Modifier.align(Alignment.Start).padding(bottom = 8.dp) + ) + ConversationItemStatusView(m) + } + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt new file mode 100644 index 0000000000000000000000000000000000000000..6bea0b49922220fb54bdfd8c41c66fecb462fda1 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationNoticeItemView.kt @@ -0,0 +1,80 @@ +package org.briarproject.briar.desktop.conversation + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.briarproject.bramble.api.sync.GroupId +import org.briarproject.bramble.api.sync.MessageId +import org.briarproject.briar.desktop.theme.noticeIn +import org.briarproject.briar.desktop.theme.noticeOut +import org.briarproject.briar.desktop.theme.privateMessageDate +import org.briarproject.briar.desktop.theme.textPrimary +import org.briarproject.briar.desktop.theme.textSecondary +import org.briarproject.briar.desktop.utils.PreviewUtils.preview +import java.time.Instant + +fun main() = preview( + "msgText" to "This is a long long long message that spans over several lines.\n\nIt ends here.", + "text" to "Text of notice message.", + "time" to Instant.now().toEpochMilli(), + "isIncoming" to false, + "isRead" to false, + "isSent" to false, + "isSeen" to true, +) { + ConversationNoticeItemView( + ConversationNoticeItem( + msgText = getStringParameter("msgText"), + text = getStringParameter("text"), + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = getLongParameter("time"), + autoDeleteTimer = 0, + isIncoming = getBooleanParameter("isIncoming"), + isRead = getBooleanParameter("isRead"), + isSent = getBooleanParameter("isSent"), + isSeen = getBooleanParameter("isSeen"), + ) + ) +} + +@Composable +fun ConversationNoticeItemView(m: ConversationNoticeItem) { + val textColor = if (m.isIncoming) MaterialTheme.colors.textPrimary else Color.White + val noticeBackground = if (m.isIncoming) MaterialTheme.colors.noticeIn else MaterialTheme.colors.noticeOut + val noticeColor = if (m.isIncoming) MaterialTheme.colors.textSecondary else MaterialTheme.colors.privateMessageDate + ConversationItemView(m) { + Column(Modifier.width(IntrinsicSize.Max)) { + Text( + m.msgText, + fontSize = 16.sp, + color = textColor, + modifier = Modifier.padding(12.dp, 8.dp).align(Alignment.Start) + ) + Column( + Modifier.fillMaxWidth().background(noticeBackground).padding(12.dp, 8.dp) + ) { + Text( + text = m.text!!, + fontSize = 14.sp, + fontStyle = FontStyle.Italic, + color = noticeColor, + modifier = Modifier.align(Alignment.Start).padding(bottom = 8.dp) + ) + ConversationItemStatusView(m) + } + } + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt new file mode 100644 index 0000000000000000000000000000000000000000..07b6bf6d6f5fb75ed4e6a7efc6b4046e80d25484 --- /dev/null +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationRequestItemView.kt @@ -0,0 +1,99 @@ +package org.briarproject.briar.desktop.conversation + +import androidx.compose.foundation.background +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.IntrinsicSize +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.fillMaxWidth +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.material.MaterialTheme +import androidx.compose.material.Text +import androidx.compose.material.TextButton +import androidx.compose.runtime.Composable +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.Color +import androidx.compose.ui.text.font.FontStyle +import androidx.compose.ui.unit.dp +import androidx.compose.ui.unit.sp +import org.briarproject.bramble.api.sync.GroupId +import org.briarproject.bramble.api.sync.MessageId +import org.briarproject.briar.api.client.SessionId +import org.briarproject.briar.desktop.conversation.ConversationRequestItem.RequestType.INTRODUCTION +import org.briarproject.briar.desktop.theme.buttonTextNegative +import org.briarproject.briar.desktop.theme.buttonTextPositive +import org.briarproject.briar.desktop.theme.noticeIn +import org.briarproject.briar.desktop.theme.noticeOut +import org.briarproject.briar.desktop.theme.privateMessageDate +import org.briarproject.briar.desktop.theme.textPrimary +import org.briarproject.briar.desktop.theme.textSecondary +import org.briarproject.briar.desktop.utils.PreviewUtils.preview +import java.time.Instant + +fun main() = preview( + "msgText" to "Short message", + "text" to "Text of notice message.", + "time" to Instant.now().toEpochMilli(), + "isIncoming" to true, + "isRead" to false, + "isSent" to false, + "isSeen" to true, +) { + ConversationRequestItemView( + ConversationRequestItem( + requestedGroupId = null, + requestType = INTRODUCTION, + sessionId = SessionId(getRandomId()), + answered = false, + msgText = getStringParameter("msgText"), + text = getStringParameter("text"), + id = MessageId(getRandomId()), + groupId = GroupId(getRandomId()), + time = getLongParameter("time"), + autoDeleteTimer = 0, + isIncoming = getBooleanParameter("isIncoming"), + isRead = getBooleanParameter("isRead"), + isSent = getBooleanParameter("isSent"), + isSeen = getBooleanParameter("isSeen"), + ) + ) +} + +@Composable +fun ConversationRequestItemView(m: ConversationRequestItem) { + val statusAlignment = if (m.isIncoming) Alignment.End else Alignment.Start + val textColor = if (m.isIncoming) MaterialTheme.colors.textPrimary else Color.White + val noticeBackground = if (m.isIncoming) MaterialTheme.colors.noticeIn else MaterialTheme.colors.noticeOut + val noticeColor = if (m.isIncoming) MaterialTheme.colors.textSecondary else MaterialTheme.colors.privateMessageDate + ConversationItemView(m) { + Column(Modifier.width(IntrinsicSize.Max)) { + Text( + m.msgText, + fontSize = 16.sp, + color = textColor, + modifier = Modifier.padding(12.dp, 8.dp).align(Alignment.Start) + ) + Column( + Modifier.fillMaxWidth().background(noticeBackground).padding(12.dp, 8.dp) + ) { + Text( + text = m.text!!, + fontSize = 14.sp, + fontStyle = FontStyle.Italic, + color = noticeColor, + modifier = Modifier.align(Alignment.Start), + ) + Row(modifier = Modifier.align(statusAlignment)) { + TextButton({}) { + Text("Decline".uppercase(), fontSize = 16.sp, color = MaterialTheme.colors.buttonTextNegative) + } + TextButton({}) { + Text("Accept".uppercase(), fontSize = 16.sp, color = MaterialTheme.colors.buttonTextPositive) + } + } + ConversationItemStatusView(m) + } + } + } +} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt index bde1041e197380018711a1741127dbb4ef920319..654a3472ec4557e99f407100e412bd97b42d2e48 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/conversation/ConversationScreen.kt @@ -21,7 +21,6 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.MaterialTheme import androidx.compose.material.Scaffold -import androidx.compose.material.Text import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue @@ -81,8 +80,9 @@ fun ConversationScreen( ) { items(viewModel.messages) { m -> when (m) { - is ConversationMessageItem -> TextBubble(m) - else -> Text("Placeholder for something else.") + is ConversationMessageItem -> ConversationMessageItemView(m) + is ConversationNoticeItem -> ConversationNoticeItemView(m) + is ConversationRequestItem -> ConversationRequestItemView(m) } } } diff --git a/src/main/kotlin/org/briarproject/briar/desktop/conversation/TextBubble.kt b/src/main/kotlin/org/briarproject/briar/desktop/conversation/TextBubble.kt deleted file mode 100644 index 044eba7d4187c805e1a212668d2b8a61419839b8..0000000000000000000000000000000000000000 --- a/src/main/kotlin/org/briarproject/briar/desktop/conversation/TextBubble.kt +++ /dev/null @@ -1,85 +0,0 @@ -package org.briarproject.briar.desktop.conversation - -import androidx.compose.foundation.layout.Column -import androidx.compose.foundation.layout.Row -import androidx.compose.foundation.layout.fillMaxWidth -import androidx.compose.foundation.layout.padding -import androidx.compose.foundation.layout.size -import androidx.compose.foundation.shape.RoundedCornerShape -import androidx.compose.material.Card -import androidx.compose.material.Icon -import androidx.compose.material.MaterialTheme -import androidx.compose.material.Text -import androidx.compose.material.icons.Icons -import androidx.compose.material.icons.filled.Done -import androidx.compose.material.icons.filled.DoneAll -import androidx.compose.material.icons.filled.Schedule -import androidx.compose.runtime.Composable -import androidx.compose.ui.Alignment -import androidx.compose.ui.Modifier -import androidx.compose.ui.unit.dp -import androidx.compose.ui.unit.sp -import org.briarproject.bramble.api.sync.GroupId -import org.briarproject.bramble.api.sync.MessageId -import org.briarproject.briar.desktop.theme.awayMsgBubble -import org.briarproject.briar.desktop.theme.localMsgBubble -import org.briarproject.briar.desktop.utils.InternationalizationUtils.i18n -import org.briarproject.briar.desktop.utils.PreviewUtils.preview -import org.briarproject.briar.desktop.utils.TimeUtils -import java.time.Instant - -fun main() = preview( - "text" to "Lorem ipsum dolor sit amet.", - "time" to Instant.now().toEpochMilli(), - "isIncoming" to false, - "isRead" to false, - "isSent" to false, - "isSeen" to false, -) { - TextBubble( - ConversationMessageItem( - text = getStringParameter("text"), - id = MessageId(getRandomId()), - groupId = GroupId(getRandomId()), - time = getLongParameter("time"), - autoDeleteTimer = 0, - isIncoming = getBooleanParameter("isIncoming"), - isRead = getBooleanParameter("isRead"), - isSent = getBooleanParameter("isSent"), - isSeen = getBooleanParameter("isSeen"), - ) - ) -} - -@Composable -fun TextBubble(m: ConversationMessageItem) { - val alignment = if (m.isIncoming) Alignment.Start else Alignment.End - val color = if (m.isIncoming) MaterialTheme.colors.awayMsgBubble else MaterialTheme.colors.localMsgBubble - val shape = if (m.isIncoming) - RoundedCornerShape(topStart = 10.dp, topEnd = 10.dp, bottomEnd = 10.dp) - else - RoundedCornerShape(topStart = 10.dp, topEnd = 10.dp, bottomStart = 10.dp) - - Column(Modifier.fillMaxWidth()) { - Column(Modifier.fillMaxWidth(fraction = 0.8f).align(alignment)) { - Card(Modifier.align(alignment), backgroundColor = color, shape = shape) { - Column( - Modifier.padding(8.dp) - ) { - Text(m.text!!, fontSize = 14.sp, modifier = Modifier.align(Alignment.Start)) - Row(modifier = Modifier.padding(top = 4.dp)) { - Text(TimeUtils.getFormattedTimestamp(m.time), Modifier.padding(end = 4.dp), fontSize = 10.sp) - if (!m.isIncoming) { - val modifier = Modifier.size(12.dp).align(Alignment.CenterVertically) - val icon = - if (m.isSeen) Icons.Filled.DoneAll // acknowledged - else if (m.isSent) Icons.Filled.Done // sent - else Icons.Filled.Schedule // waiting - Icon(icon, i18n("access.message.sent"), modifier) - } - } - } - } - } - } -} diff --git a/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt b/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt index f3fa146562a1680be413e2ea10c92029df4db076..c91d4cce51243cdbe52c6b3f9f61278332bc24e1 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/theme/Colors.kt @@ -2,8 +2,11 @@ package org.briarproject.briar.desktop.theme import androidx.compose.ui.graphics.Color -val Night500 = Color(0xff435B77) -val Night700 = Color(0xff2E3D4F) +val Night50 = Color(0xffebf3fa) +val Night500 = Color(0xff435b77) +val Night700 = Color(0xff2e3d4f) +val Night800 = Color(0xff212d3b) +val Night950 = Color(0xff0e171f) val Gray50 = Color(0xfffafafa) val Gray100 = Color(0xfff2f2f2) @@ -17,10 +20,19 @@ val Gray900 = Color(0xff2e2e2e) val Gray950 = Color(0xff1f1f1f) val materialDarkBg = Color(0xff121212) -val Blue500 = Color(0xff1f78d1) +val Red500 = Color(0xffdb3b21) + +val Blue400 = Color(0xff418cd8) +val Blue500 = Color(0xff1f78d1) // todo: unused in Android +val Blue600 = Color(0xff1b69b6) val Blue800 = Color(0xff134a81) val Lime300 = Color(0xff95DE2D) val Lime500 = Color(0xff74B816) +val TextPrimaryMaterialDark = Color(0xffffffff) +val TextPrimaryMaterialLight = Color(0xde000000) +val TextSecondaryMaterialDark = Color(0xb3ffffff) +val TextSecondaryMaterialLight = Color(0x8a000000) + val briarError = Color(0xffb00020) diff --git a/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt b/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt index d04411c20142f0cb2fdfa1fdfdbe6d732a8e4c62..07559de1c5a7be9dfbee964a54d4a102f18147e9 100644 --- a/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt +++ b/src/main/kotlin/org/briarproject/briar/desktop/theme/Theme.kt @@ -13,8 +13,16 @@ val Colors.outline: Color get() = if (isLight) Gray900 else Gray200 val Colors.surfaceVariant: Color get() = if (isLight) Gray100 else Gray950 val Colors.sidebarSurface: Color get() = if (isLight) Gray200 else Gray900 val Colors.selectedCard: Color get() = if (isLight) Gray400 else Gray700 -val Colors.localMsgBubble: Color get() = Blue500 -val Colors.awayMsgBubble: Color get() = if (isLight) Gray300 else Gray800 +val Colors.msgStroke: Color get() = if (isLight) Gray300 else Gray900 +val Colors.msgIn: Color get() = if (isLight) Color.White else Night700 +val Colors.msgOut: Color get() = if (isLight) Blue400 else Blue600 +val Colors.noticeIn: Color get() = if (isLight) Night50 else Night800 +val Colors.noticeOut: Color get() = if (isLight) Blue600 else Blue800 +val Colors.textPrimary: Color get() = if (isLight) TextPrimaryMaterialLight else TextPrimaryMaterialDark +val Colors.textSecondary: Color get() = if (isLight) TextSecondaryMaterialLight else TextSecondaryMaterialDark +val Colors.privateMessageDate: Color get() = Gray200 +val Colors.buttonTextNegative: Color get() = Red500 +val Colors.buttonTextPositive: Color get() = Blue400 val DarkColors = darkColors( primary = Blue500,