feat: revamp message field, colours, typing, attachments

This commit is contained in:
Infi 2023-02-05 04:43:42 +01:00
parent e1abc4fff5
commit fcddb8a968
11 changed files with 220 additions and 180 deletions

View File

@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.*
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.* import androidx.compose.runtime.*
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.IntOffset import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize import androidx.compose.ui.unit.IntSize
import chat.revolt.api.settings.GlobalState import chat.revolt.api.settings.GlobalState
@ -43,6 +44,7 @@ class MainActivity : ComponentActivity() {
val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo) val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo)
val RevoltTweenIntSize: FiniteAnimationSpec<IntSize> = tween(400, easing = EaseInOutExpo) val RevoltTweenIntSize: FiniteAnimationSpec<IntSize> = tween(400, easing = EaseInOutExpo)
val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo) val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo)
val RevoltTweenDp: FiniteAnimationSpec<Dp> = tween(400, easing = EaseInOutExpo)
@OptIn(ExperimentalAnimationApi::class) @OptIn(ExperimentalAnimationApi::class)
@Composable @Composable

View File

@ -1,32 +1,37 @@
package chat.revolt.components.chat package chat.revolt.components.chat
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.*
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.interaction.MutableInteractionSource
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.foundation.text.BasicTextField
import androidx.compose.foundation.text.KeyboardActions
import androidx.compose.foundation.text.KeyboardOptions
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Add import androidx.compose.material.icons.filled.Add
import androidx.compose.material.icons.filled.KeyboardArrowRight
import androidx.compose.material.icons.filled.Send import androidx.compose.material.icons.filled.Send
import androidx.compose.material3.* import androidx.compose.material3.*
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember import androidx.compose.runtime.remember
import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.focus.FocusRequester import androidx.compose.ui.focus.FocusRequester
import androidx.compose.ui.focus.focusRequester import androidx.compose.ui.focus.focusRequester
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.SolidColor
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.input.VisualTransformation
import androidx.compose.ui.tooling.preview.Preview import androidx.compose.ui.tooling.preview.Preview
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import chat.revolt.R import chat.revolt.R
import chat.revolt.RevoltTweenFloat
import chat.revolt.RevoltTweenInt
import chat.revolt.api.schemas.ChannelType import chat.revolt.api.schemas.ChannelType
@OptIn(ExperimentalMaterial3Api::class) @OptIn(ExperimentalMaterial3Api::class)
@Composable @Composable
fun MessageField( fun MessageField(
showButtons: Boolean,
onToggleButtons: (Boolean) -> Unit,
messageContent: String, messageContent: String,
onMessageContentChange: (String) -> Unit, onMessageContentChange: (String) -> Unit,
onAddAttachment: () -> Unit, onAddAttachment: () -> Unit,
@ -46,90 +51,85 @@ fun MessageField(
ChannelType.SavedMessages -> R.string.message_field_placeholder_notes ChannelType.SavedMessages -> R.string.message_field_placeholder_notes
} }
val sendButtonVisible = (messageContent.isNotBlank() || forceSendButton) && !disabled
Row(modifier) { Row(modifier) {
// Additional buttons (currently adding an attachment) BasicTextField(
AnimatedVisibility(visible = showButtons) {
Row(Modifier.weight(1f)) {
ElevatedButton(
onClick = {
focusRequester.freeFocus() // hide keyboard because it's annoying
onAddAttachment()
},
modifier = Modifier.size(56.dp),
contentPadding = PaddingValues(0.dp),
shape = CircleShape
) {
Icon(
Icons.Default.Add,
contentDescription = stringResource(id = R.string.add_attachment_alt)
)
}
}
}
// The small chevron you see when the buttons are hidden
AnimatedVisibility(visible = !showButtons) {
Column(
verticalArrangement = Arrangement.Center,
horizontalAlignment = Alignment.CenterHorizontally,
modifier = Modifier.height(56.dp)
) {
Icon(
Icons.Default.KeyboardArrowRight,
contentDescription = stringResource(id = R.string.show_more_alt),
modifier = Modifier
.clickable(onClick = {
onToggleButtons(true)
})
.size(24.dp + 8.dp)
.padding(vertical = 4.dp)
)
}
}
TextField(
value = messageContent, value = messageContent,
onValueChange = onMessageContentChange, onValueChange = onMessageContentChange,
singleLine = false, singleLine = false,
shape = MaterialTheme.shapes.extraLarge,
enabled = !disabled, enabled = !disabled,
placeholder = { textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onSurface),
Text( cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
stringResource(
id = placeholderResource,
channelName
)
)
},
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
errorIndicatorColor = Color.Transparent,
placeholderColor = Color.Gray,
),
modifier = Modifier modifier = Modifier
.weight(1f) .weight(1f)
.padding(start = 8.dp) .focusRequester(focusRequester),
.focusRequester(focusRequester) keyboardOptions = KeyboardOptions.Default,
) keyboardActions = KeyboardActions.Default,
decorationBox = @Composable { innerTextField ->
// Send button (visible when text is entered or when forceSendButton is true) TextFieldDefaults.TextFieldDecorationBox(
AnimatedVisibility(visible = (messageContent.isNotBlank() || forceSendButton) && !disabled) { value = messageContent,
Button( innerTextField = innerTextField,
onClick = onSendMessage, enabled = !disabled,
modifier = Modifier singleLine = false,
.padding(start = 8.dp) visualTransformation = VisualTransformation.None,
.size(56.dp), interactionSource = remember { MutableInteractionSource() },
contentPadding = PaddingValues(0.dp), placeholder = {
shape = CircleShape Text(
) { stringResource(
Icon( id = placeholderResource,
Icons.Default.Send, channelName
contentDescription = stringResource(id = R.string.send_alt) )
)
},
colors = TextFieldDefaults.textFieldColors(
focusedIndicatorColor = Color.Transparent,
unfocusedIndicatorColor = Color.Transparent,
disabledIndicatorColor = Color.Transparent,
errorIndicatorColor = Color.Transparent,
placeholderColor = Color.Gray
),
contentPadding = PaddingValues(16.dp),
leadingIcon = {
Icon(
Icons.Default.Add,
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
contentDescription = stringResource(id = R.string.unknown),
modifier = Modifier
.clip(CircleShape)
.size(32.dp)
.clickable {
focusRequester.freeFocus() // hide keyboard because it's annoying
onAddAttachment()
}
.padding(4.dp)
)
},
trailingIcon = {
AnimatedVisibility(sendButtonVisible,
enter = slideInVertically(
animationSpec = RevoltTweenInt,
initialOffsetY = { it }
) + fadeIn(animationSpec = RevoltTweenFloat),
exit = slideOutVertically(
animationSpec = RevoltTweenInt,
targetOffsetY = { it }
) + fadeOut(animationSpec = RevoltTweenFloat)) {
Icon(
Icons.Default.Send,
tint = MaterialTheme.colorScheme.primary,
contentDescription = stringResource(id = R.string.unknown),
modifier = Modifier
.clip(CircleShape)
.size(32.dp)
.clickable { onSendMessage() }
.padding(4.dp)
)
}
}
) )
} }
} )
} }
} }
@ -137,8 +137,6 @@ fun MessageField(
@Composable @Composable
fun MessageFieldPreview() { fun MessageFieldPreview() {
MessageField( MessageField(
showButtons = true,
onToggleButtons = {},
messageContent = "Hello world!", messageContent = "Hello world!",
onMessageContentChange = {}, onMessageContentChange = {},
onSendMessage = {}, onSendMessage = {},

View File

@ -1,22 +1,17 @@
package chat.revolt.components.screens.chat package chat.revolt.components.screens.chat
import androidx.compose.animation.AnimatedVisibility import androidx.compose.animation.AnimatedVisibility
import androidx.compose.foundation.border import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.horizontalScroll import androidx.compose.foundation.horizontalScroll
import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.*
import androidx.compose.foundation.layout.Spacer
import androidx.compose.foundation.layout.padding
import androidx.compose.foundation.layout.width
import androidx.compose.foundation.rememberScrollState import androidx.compose.foundation.rememberScrollState
import androidx.compose.material.icons.Icons import androidx.compose.material.icons.Icons
import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Close
import androidx.compose.material3.CircularProgressIndicator import androidx.compose.material3.*
import androidx.compose.material3.Icon
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import chat.revolt.R import chat.revolt.R
@ -30,24 +25,30 @@ fun AttachmentManager(
) { ) {
Row( Row(
modifier = Modifier modifier = Modifier
.fillMaxWidth()
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
.horizontalScroll(rememberScrollState()) .horizontalScroll(rememberScrollState())
.padding(horizontal = 8.dp) .padding(horizontal = 8.dp, vertical = 4.dp)
) { ) {
AnimatedVisibility(uploading) { AnimatedVisibility(uploading) {
CircularProgressIndicator() CircularProgressIndicator(
modifier = Modifier.padding(4.dp),
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.7f)
)
} }
attachments.forEach { attachment -> attachments.forEach { attachment ->
Row( Row(
modifier = Modifier modifier = Modifier
.padding(4.dp) .padding(4.dp)
.border( .clip(MaterialTheme.shapes.small)
1.dp,
MaterialTheme.colorScheme.onBackground.copy(alpha = 0.3f),
MaterialTheme.shapes.small
)
.clickable { .clickable {
onRemove(attachment) onRemove(attachment)
} }
.background(
color = MaterialTheme.colorScheme.background,
shape = MaterialTheme.shapes.small
)
.padding(8.dp) .padding(8.dp)
) { ) {
Text(attachment.filename, maxLines = 1) Text(attachment.filename, maxLines = 1)

View File

@ -7,6 +7,7 @@ import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip import androidx.compose.ui.draw.clip
@ -26,7 +27,10 @@ fun DrawerChannel(
.padding(vertical = 4.dp, horizontal = 8.dp) .padding(vertical = 4.dp, horizontal = 8.dp)
.fillMaxWidth() .fillMaxWidth()
.clip(MaterialTheme.shapes.medium) .clip(MaterialTheme.shapes.medium)
.background(if (selected) MaterialTheme.colorScheme.surface else MaterialTheme.colorScheme.surfaceVariant) .background(
if (selected) MaterialTheme.colorScheme.surface
else MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)
)
.clickable(onClick = onClick) .clickable(onClick = onClick)
.padding(vertical = 8.dp, horizontal = 16.dp) .padding(vertical = 8.dp, horizontal = 16.dp)
) { ) {

View File

@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.size
import androidx.compose.foundation.shape.CircleShape import androidx.compose.foundation.shape.CircleShape
import androidx.compose.material3.MaterialTheme import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text import androidx.compose.material3.Text
import androidx.compose.material3.surfaceColorAtElevation
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Alignment import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
@ -41,7 +42,7 @@ fun DrawerServer(
.padding(8.dp) .padding(8.dp)
.size(48.dp) .size(48.dp)
.clip(CircleShape) .clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceVariant) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp))
.clickable(onClick = onClick) .clickable(onClick = onClick)
) { ) {
Text( Text(

View File

@ -22,7 +22,7 @@ fun DrawerServerlikeIcon(
.padding(8.dp) .padding(8.dp)
.size(48.dp) .size(48.dp)
.clip(CircleShape) .clip(CircleShape)
.background(MaterialTheme.colorScheme.surfaceVariant) .background(MaterialTheme.colorScheme.surface)
) { ) {
content() content()
} }

View File

@ -0,0 +1,64 @@
package chat.revolt.components.screens.chat
import androidx.compose.animation.*
import androidx.compose.foundation.background
import androidx.compose.foundation.layout.Row
import androidx.compose.foundation.layout.fillMaxWidth
import androidx.compose.foundation.layout.padding
import androidx.compose.material3.MaterialTheme
import androidx.compose.material3.Text
import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp
import chat.revolt.R
import chat.revolt.RevoltTweenFloat
import chat.revolt.RevoltTweenInt
import chat.revolt.api.RevoltAPI
@Composable
fun TypingIndicator(
users: List<String>,
) {
fun typingMessageResource(): Int {
return when (users.size) {
0 -> R.string.typing_blank
1 -> R.string.typing_one
in 2..4 -> R.string.typing_many
else -> R.string.typing_several
}
}
AnimatedVisibility(
visible = users.isNotEmpty(),
enter = slideInVertically(
animationSpec = RevoltTweenInt,
initialOffsetY = { it }
) + fadeIn(animationSpec = RevoltTweenFloat),
exit = slideOutVertically(
animationSpec = RevoltTweenInt,
targetOffsetY = { it }
) + fadeOut(animationSpec = RevoltTweenFloat)
) {
Row(
Modifier
.background(MaterialTheme.colorScheme.surface)
.fillMaxWidth()
.padding(all = 4.dp)
) {
Text(
text = stringResource(
id = typingMessageResource(),
users.joinToString {
RevoltAPI.userCache[it]?.let { u ->
u.username ?: u.id
} ?: it
}
),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
}
}

View File

@ -85,14 +85,16 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = vie
DismissibleNavigationDrawer( DismissibleNavigationDrawer(
drawerState = channelDrawerState, drawerState = channelDrawerState,
drawerContent = { drawerContent = {
ModalDrawerSheet(drawerContainerColor = MaterialTheme.colorScheme.surfaceVariant) { ModalDrawerSheet(
drawerContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)
) {
Column(Modifier.fillMaxWidth()) { Column(Modifier.fillMaxWidth()) {
Row { Row {
Column( Column(
modifier = Modifier modifier = Modifier
.fillMaxHeight() .fillMaxHeight()
.verticalScroll(rememberScrollState()) .verticalScroll(rememberScrollState())
.background(MaterialTheme.colorScheme.surface) .background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
) { ) {
DrawerServerlikeIcon( DrawerServerlikeIcon(
onClick = { onClick = {

View File

@ -5,6 +5,7 @@ import android.widget.Toast
import androidx.activity.compose.rememberLauncherForActivityResult import androidx.activity.compose.rememberLauncherForActivityResult
import androidx.activity.result.contract.ActivityResultContracts import androidx.activity.result.contract.ActivityResultContracts
import androidx.compose.animation.* import androidx.compose.animation.*
import androidx.compose.animation.core.animateDpAsState
import androidx.compose.foundation.background import androidx.compose.foundation.background
import androidx.compose.foundation.clickable import androidx.compose.foundation.clickable
import androidx.compose.foundation.layout.* import androidx.compose.foundation.layout.*
@ -24,7 +25,6 @@ import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.AnnotatedString import androidx.compose.ui.text.AnnotatedString
import androidx.compose.ui.text.font.FontWeight import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.text.style.TextOverflow
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.compose.ui.window.Dialog import androidx.compose.ui.window.Dialog
import androidx.compose.ui.window.DialogProperties import androidx.compose.ui.window.DialogProperties
@ -34,6 +34,7 @@ import androidx.lifecycle.viewModelScope
import androidx.lifecycle.viewmodel.compose.viewModel import androidx.lifecycle.viewmodel.compose.viewModel
import androidx.navigation.NavController import androidx.navigation.NavController
import chat.revolt.R import chat.revolt.R
import chat.revolt.RevoltTweenDp
import chat.revolt.RevoltTweenFloat import chat.revolt.RevoltTweenFloat
import chat.revolt.RevoltTweenInt import chat.revolt.RevoltTweenInt
import chat.revolt.api.RevoltAPI import chat.revolt.api.RevoltAPI
@ -55,6 +56,7 @@ import chat.revolt.components.generic.CollapsibleCard
import chat.revolt.components.generic.PageHeader import chat.revolt.components.generic.PageHeader
import chat.revolt.components.screens.chat.AttachmentManager import chat.revolt.components.screens.chat.AttachmentManager
import chat.revolt.components.screens.chat.ChannelIcon import chat.revolt.components.screens.chat.ChannelIcon
import chat.revolt.components.screens.chat.TypingIndicator
import io.ktor.http.* import io.ktor.http.*
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.datetime.Instant import kotlinx.datetime.Instant
@ -89,20 +91,6 @@ class ChannelScreenViewModel : ViewModel() {
fun setMessageContent(content: String) { fun setMessageContent(content: String) {
_messageContent = content _messageContent = content
if (content.isEmpty()) {
_showButtons = true
} else if (showButtons) {
_showButtons = false
}
}
private var _showButtons by mutableStateOf(true)
val showButtons: Boolean
get() = _showButtons
fun setShowButtons(show: Boolean) {
_showButtons = show
} }
private var _attachments = mutableStateListOf<FileArgs>() private var _attachments = mutableStateListOf<FileArgs>()
@ -262,23 +250,6 @@ class ChannelScreenViewModel : ViewModel() {
} }
} }
fun typingMessageResource(): Int {
return when (typingUsers.size) {
0 -> R.string.typing_blank
1 -> R.string.typing_one
in 2..4 -> R.string.typing_many
else -> R.string.typing_several
}
}
fun getTypingUsernames(): String {
return typingUsers.joinToString {
RevoltAPI.userCache[it]?.let { u ->
u.username ?: u.id
} ?: it
}
}
private fun regroupMessages(newMessages: List<MessageSchema> = renderableMessages) { private fun regroupMessages(newMessages: List<MessageSchema> = renderableMessages) {
val groupedMessages = arrayListOf<MessageSchema>() val groupedMessages = arrayListOf<MessageSchema>()
@ -430,6 +401,11 @@ fun ChannelScreen(
} }
} }
val scrollDownFABPadding by animateDpAsState(
if (viewModel.typingUsers.isNotEmpty()) 32.dp else 0.dp,
animationSpec = RevoltTweenDp
)
LaunchedEffect(channelId) { LaunchedEffect(channelId) {
viewModel.fetchChannel(channelId) viewModel.fetchChannel(channelId)
} }
@ -488,7 +464,7 @@ fun ChannelScreen(
val isScrolledToBottom = remember(lazyListState) { val isScrolledToBottom = remember(lazyListState) {
derivedStateOf { derivedStateOf {
lazyListState.firstVisibleItemIndex <= 5 lazyListState.firstVisibleItemIndex <= 6
} }
} }
@ -505,6 +481,10 @@ fun ChannelScreen(
contentAlignment = Alignment.BottomEnd contentAlignment = Alignment.BottomEnd
) { ) {
LazyColumn(state = lazyListState, reverseLayout = true) { LazyColumn(state = lazyListState, reverseLayout = true) {
item {
Spacer(modifier = Modifier.height(32.dp))
}
items(viewModel.renderableMessages) { message -> items(viewModel.renderableMessages) { message ->
Message(message) Message(message)
} }
@ -540,6 +520,7 @@ fun ChannelScreen(
) { ) {
ExtendedFloatingActionButton( ExtendedFloatingActionButton(
modifier = Modifier modifier = Modifier
.padding(bottom = scrollDownFABPadding)
.align(Alignment.BottomEnd) .align(Alignment.BottomEnd)
.padding(16.dp), .padding(16.dp),
text = { text = {
@ -560,34 +541,10 @@ fun ChannelScreen(
containerColor = MaterialTheme.colorScheme.primary containerColor = MaterialTheme.colorScheme.primary
) )
} }
}
AnimatedVisibility( TypingIndicator(
visible = viewModel.typingUsers.isNotEmpty(), users = viewModel.typingUsers
enter = slideInVertically( )
animationSpec = RevoltTweenInt,
initialOffsetY = { it }
) + fadeIn(animationSpec = RevoltTweenFloat),
exit = slideOutVertically(
animationSpec = RevoltTweenInt,
targetOffsetY = { it }
) + fadeOut(animationSpec = RevoltTweenFloat)
) {
Row(
Modifier
.background(MaterialTheme.colorScheme.surfaceVariant)
.fillMaxWidth()
.padding(all = 4.dp)
) {
Text(
text = stringResource(
id = viewModel.typingMessageResource(),
viewModel.getTypingUsernames()
),
maxLines = 1,
overflow = TextOverflow.Ellipsis,
)
}
} }
AnimatedVisibility(visible = viewModel.attachments.isNotEmpty()) { AnimatedVisibility(visible = viewModel.attachments.isNotEmpty()) {
@ -599,8 +556,6 @@ fun ChannelScreen(
} }
MessageField( MessageField(
showButtons = viewModel.showButtons,
onToggleButtons = viewModel::setShowButtons,
messageContent = viewModel.messageContent, messageContent = viewModel.messageContent,
onMessageContentChange = viewModel::setMessageContent, onMessageContentChange = viewModel::setMessageContent,
onSendMessage = viewModel::sendPendingMessage, onSendMessage = viewModel::sendPendingMessage,

View File

@ -1,6 +1,7 @@
package chat.revolt.screens.settings package chat.revolt.screens.settings
import android.widget.Toast import android.widget.Toast
import androidx.compose.foundation.background
import androidx.compose.foundation.isSystemInDarkTheme import androidx.compose.foundation.isSystemInDarkTheme
import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Column
import androidx.compose.foundation.layout.fillMaxSize import androidx.compose.foundation.layout.fillMaxSize
@ -12,9 +13,11 @@ import androidx.compose.material3.Text
import androidx.compose.material3.dynamicDarkColorScheme import androidx.compose.material3.dynamicDarkColorScheme
import androidx.compose.runtime.Composable import androidx.compose.runtime.Composable
import androidx.compose.ui.Modifier import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.Color
import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.stringResource import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.font.FontWeight
import androidx.compose.ui.unit.dp import androidx.compose.ui.unit.dp
import androidx.lifecycle.ViewModel import androidx.lifecycle.ViewModel
import androidx.lifecycle.viewModelScope import androidx.lifecycle.viewModelScope
@ -75,13 +78,25 @@ fun AppearanceSettingsScreen(
modifier = Modifier.padding(bottom = 10.dp) modifier = Modifier.padding(bottom = 10.dp)
) )
Text(
text = "old revolt blue will come back soon i promise, needs a bit of optimisation first 🐈",
style = MaterialTheme.typography.headlineMedium.copy(
color = MaterialTheme.colorScheme.background,
fontWeight = FontWeight.Bold
),
modifier = Modifier
.padding(bottom = 10.dp)
.clip(MaterialTheme.shapes.medium)
.background(MaterialTheme.colorScheme.primary)
.padding(10.dp)
)
FlowRow( FlowRow(
mainAxisSpacing = 10.dp, mainAxisSpacing = 10.dp,
crossAxisSpacing = 10.dp, crossAxisSpacing = 10.dp,
) { ) {
ThemeChip( ThemeChip(
color = Color(0xff172333), color = Color(0xff1e1e1e),
text = stringResource(id = R.string.settings_appearance_theme_revolt), text = stringResource(id = R.string.settings_appearance_theme_revolt),
selected = GlobalState.theme == Theme.Revolt, selected = GlobalState.theme == Theme.Revolt,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),
@ -108,7 +123,7 @@ fun AppearanceSettingsScreen(
} }
ThemeChip( ThemeChip(
color = if (isSystemInDarkTheme()) Color(0xff172333) else Color(0xfff7f7f7), color = if (isSystemInDarkTheme()) Color(0xff1e1e1e) else Color(0xfff7f7f7),
text = stringResource(id = R.string.settings_appearance_theme_none), text = stringResource(id = R.string.settings_appearance_theme_none),
selected = GlobalState.theme == Theme.None, selected = GlobalState.theme == Theme.None,
modifier = Modifier.weight(1f), modifier = Modifier.weight(1f),

View File

@ -14,18 +14,17 @@ import androidx.compose.ui.platform.LocalView
import androidx.core.view.ViewCompat import androidx.core.view.ViewCompat
val RevoltColorScheme = darkColorScheme( val RevoltColorScheme = darkColorScheme(
primary = Color(0xfffe4654), primary = Color(0xffda4e5b),
onPrimary = Color(0xffffffff), onPrimary = Color(0xffffffff),
secondary = Color(0xfffd6671), secondary = Color(0xffe96a7a),
onSecondary = Color(0xffffffff), onSecondary = Color(0xffffffff),
tertiary = Color(0xffff6667), background = Color(0xff121212),
onTertiary = Color(0xffffffff),
background = Color(0xff101823),
onBackground = Color(0xffffffff), onBackground = Color(0xffffffff),
surfaceVariant = Color(0xff172333), surfaceVariant = Color(0xff1e1e1e),
onSurfaceVariant = Color(0xffffffff), onSurfaceVariant = Color(0xffffffff),
surface = Color(0xff111a26), surface = Color(0xff2b2b2b),
onSurface = Color(0xffffffff), onSurface = Color(0xffffffff),
surfaceTint = Color(0xffc0c0c0),
) )
val AmoledColorScheme = RevoltColorScheme.copy( val AmoledColorScheme = RevoltColorScheme.copy(
@ -38,18 +37,17 @@ val AmoledColorScheme = RevoltColorScheme.copy(
) )
val LightColorScheme = lightColorScheme( val LightColorScheme = lightColorScheme(
primary = Color(0xfffe4654), primary = Color(0xffda4e5b),
onPrimary = Color(0xffffffff), onPrimary = Color(0xffffffff),
secondary = Color(0xfffd6671), secondary = Color(0xffe96a7a),
onSecondary = Color(0xffffffff), onSecondary = Color(0xffffffff),
tertiary = Color(0xffff6667),
onTertiary = Color(0xffffffff),
background = Color(0xffffffff), background = Color(0xffffffff),
onBackground = Color(0xff000000), onBackground = Color(0xff000000),
surfaceVariant = Color(0xffe6e6e6), surfaceVariant = Color(0xffe0e0e0),
onSurfaceVariant = Color(0xff000000), onSurfaceVariant = Color(0xff000000),
surface = Color(0xffdddddd), surface = Color(0xfff5f5f5),
onSurface = Color(0xff000000), onSurface = Color(0xff000000),
surfaceTint = Color(0xff000000),
) )
enum class Theme { enum class Theme {