feat: revamp message field, colours, typing, attachments
This commit is contained in:
parent
e1abc4fff5
commit
fcddb8a968
|
|
@ -11,6 +11,7 @@ import androidx.compose.foundation.layout.*
|
|||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.*
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.unit.Dp
|
||||
import androidx.compose.ui.unit.IntOffset
|
||||
import androidx.compose.ui.unit.IntSize
|
||||
import chat.revolt.api.settings.GlobalState
|
||||
|
|
@ -43,6 +44,7 @@ class MainActivity : ComponentActivity() {
|
|||
val RevoltTweenInt: FiniteAnimationSpec<IntOffset> = tween(400, easing = EaseInOutExpo)
|
||||
val RevoltTweenIntSize: FiniteAnimationSpec<IntSize> = tween(400, easing = EaseInOutExpo)
|
||||
val RevoltTweenFloat: FiniteAnimationSpec<Float> = tween(400, easing = EaseInOutExpo)
|
||||
val RevoltTweenDp: FiniteAnimationSpec<Dp> = tween(400, easing = EaseInOutExpo)
|
||||
|
||||
@OptIn(ExperimentalAnimationApi::class)
|
||||
@Composable
|
||||
|
|
|
|||
|
|
@ -1,32 +1,37 @@
|
|||
package chat.revolt.components.chat
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
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.filled.Add
|
||||
import androidx.compose.material.icons.filled.KeyboardArrowRight
|
||||
import androidx.compose.material.icons.filled.Send
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Alignment
|
||||
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.graphics.Color
|
||||
import androidx.compose.ui.graphics.SolidColor
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.input.VisualTransformation
|
||||
import androidx.compose.ui.tooling.preview.Preview
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.revolt.R
|
||||
import chat.revolt.RevoltTweenFloat
|
||||
import chat.revolt.RevoltTweenInt
|
||||
import chat.revolt.api.schemas.ChannelType
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun MessageField(
|
||||
showButtons: Boolean,
|
||||
onToggleButtons: (Boolean) -> Unit,
|
||||
messageContent: String,
|
||||
onMessageContentChange: (String) -> Unit,
|
||||
onAddAttachment: () -> Unit,
|
||||
|
|
@ -46,90 +51,85 @@ fun MessageField(
|
|||
ChannelType.SavedMessages -> R.string.message_field_placeholder_notes
|
||||
}
|
||||
|
||||
val sendButtonVisible = (messageContent.isNotBlank() || forceSendButton) && !disabled
|
||||
|
||||
Row(modifier) {
|
||||
// Additional buttons (currently adding an attachment)
|
||||
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(
|
||||
BasicTextField(
|
||||
value = messageContent,
|
||||
onValueChange = onMessageContentChange,
|
||||
singleLine = false,
|
||||
shape = MaterialTheme.shapes.extraLarge,
|
||||
enabled = !disabled,
|
||||
placeholder = {
|
||||
Text(
|
||||
stringResource(
|
||||
id = placeholderResource,
|
||||
channelName
|
||||
)
|
||||
)
|
||||
},
|
||||
colors = TextFieldDefaults.textFieldColors(
|
||||
focusedIndicatorColor = Color.Transparent,
|
||||
unfocusedIndicatorColor = Color.Transparent,
|
||||
disabledIndicatorColor = Color.Transparent,
|
||||
errorIndicatorColor = Color.Transparent,
|
||||
placeholderColor = Color.Gray,
|
||||
),
|
||||
textStyle = LocalTextStyle.current.copy(color = MaterialTheme.colorScheme.onSurface),
|
||||
cursorBrush = SolidColor(MaterialTheme.colorScheme.primary),
|
||||
modifier = Modifier
|
||||
.weight(1f)
|
||||
.padding(start = 8.dp)
|
||||
.focusRequester(focusRequester)
|
||||
)
|
||||
|
||||
// Send button (visible when text is entered or when forceSendButton is true)
|
||||
AnimatedVisibility(visible = (messageContent.isNotBlank() || forceSendButton) && !disabled) {
|
||||
Button(
|
||||
onClick = onSendMessage,
|
||||
modifier = Modifier
|
||||
.padding(start = 8.dp)
|
||||
.size(56.dp),
|
||||
contentPadding = PaddingValues(0.dp),
|
||||
shape = CircleShape
|
||||
) {
|
||||
Icon(
|
||||
Icons.Default.Send,
|
||||
contentDescription = stringResource(id = R.string.send_alt)
|
||||
.focusRequester(focusRequester),
|
||||
keyboardOptions = KeyboardOptions.Default,
|
||||
keyboardActions = KeyboardActions.Default,
|
||||
decorationBox = @Composable { innerTextField ->
|
||||
TextFieldDefaults.TextFieldDecorationBox(
|
||||
value = messageContent,
|
||||
innerTextField = innerTextField,
|
||||
enabled = !disabled,
|
||||
singleLine = false,
|
||||
visualTransformation = VisualTransformation.None,
|
||||
interactionSource = remember { MutableInteractionSource() },
|
||||
placeholder = {
|
||||
Text(
|
||||
stringResource(
|
||||
id = placeholderResource,
|
||||
channelName
|
||||
)
|
||||
)
|
||||
},
|
||||
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
|
||||
fun MessageFieldPreview() {
|
||||
MessageField(
|
||||
showButtons = true,
|
||||
onToggleButtons = {},
|
||||
messageContent = "Hello world!",
|
||||
onMessageContentChange = {},
|
||||
onSendMessage = {},
|
||||
|
|
|
|||
|
|
@ -1,22 +1,17 @@
|
|||
package chat.revolt.components.screens.chat
|
||||
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.foundation.border
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.horizontalScroll
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.material.icons.Icons
|
||||
import androidx.compose.material.icons.filled.Close
|
||||
import androidx.compose.material3.CircularProgressIndicator
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.revolt.R
|
||||
|
|
@ -30,24 +25,30 @@ fun AttachmentManager(
|
|||
) {
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.fillMaxWidth()
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp))
|
||||
.horizontalScroll(rememberScrollState())
|
||||
.padding(horizontal = 8.dp)
|
||||
.padding(horizontal = 8.dp, vertical = 4.dp)
|
||||
) {
|
||||
AnimatedVisibility(uploading) {
|
||||
CircularProgressIndicator()
|
||||
CircularProgressIndicator(
|
||||
modifier = Modifier.padding(4.dp),
|
||||
color = MaterialTheme.colorScheme.onBackground.copy(alpha = 0.7f)
|
||||
)
|
||||
}
|
||||
|
||||
attachments.forEach { attachment ->
|
||||
Row(
|
||||
modifier = Modifier
|
||||
.padding(4.dp)
|
||||
.border(
|
||||
1.dp,
|
||||
MaterialTheme.colorScheme.onBackground.copy(alpha = 0.3f),
|
||||
MaterialTheme.shapes.small
|
||||
)
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.clickable {
|
||||
onRemove(attachment)
|
||||
}
|
||||
.background(
|
||||
color = MaterialTheme.colorScheme.background,
|
||||
shape = MaterialTheme.shapes.small
|
||||
)
|
||||
.padding(8.dp)
|
||||
) {
|
||||
Text(attachment.filename, maxLines = 1)
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@ 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.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
|
|
@ -26,7 +27,10 @@ fun DrawerChannel(
|
|||
.padding(vertical = 4.dp, horizontal = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.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)
|
||||
.padding(vertical = 8.dp, horizontal = 16.dp)
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -8,6 +8,7 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -41,7 +42,7 @@ fun DrawerServer(
|
|||
.padding(8.dp)
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(3.dp))
|
||||
.clickable(onClick = onClick)
|
||||
) {
|
||||
Text(
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ fun DrawerServerlikeIcon(
|
|||
.padding(8.dp)
|
||||
.size(48.dp)
|
||||
.clip(CircleShape)
|
||||
.background(MaterialTheme.colorScheme.surfaceVariant)
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
) {
|
||||
content()
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -85,14 +85,16 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = vie
|
|||
DismissibleNavigationDrawer(
|
||||
drawerState = channelDrawerState,
|
||||
drawerContent = {
|
||||
ModalDrawerSheet(drawerContainerColor = MaterialTheme.colorScheme.surfaceVariant) {
|
||||
ModalDrawerSheet(
|
||||
drawerContainerColor = MaterialTheme.colorScheme.surfaceColorAtElevation(1.dp)
|
||||
) {
|
||||
Column(Modifier.fillMaxWidth()) {
|
||||
Row {
|
||||
Column(
|
||||
modifier = Modifier
|
||||
.fillMaxHeight()
|
||||
.verticalScroll(rememberScrollState())
|
||||
.background(MaterialTheme.colorScheme.surface)
|
||||
.background(MaterialTheme.colorScheme.surfaceColorAtElevation(2.dp))
|
||||
) {
|
||||
DrawerServerlikeIcon(
|
||||
onClick = {
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import android.widget.Toast
|
|||
import androidx.activity.compose.rememberLauncherForActivityResult
|
||||
import androidx.activity.result.contract.ActivityResultContracts
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.core.animateDpAsState
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
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.text.AnnotatedString
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.compose.ui.window.Dialog
|
||||
import androidx.compose.ui.window.DialogProperties
|
||||
|
|
@ -34,6 +34,7 @@ import androidx.lifecycle.viewModelScope
|
|||
import androidx.lifecycle.viewmodel.compose.viewModel
|
||||
import androidx.navigation.NavController
|
||||
import chat.revolt.R
|
||||
import chat.revolt.RevoltTweenDp
|
||||
import chat.revolt.RevoltTweenFloat
|
||||
import chat.revolt.RevoltTweenInt
|
||||
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.screens.chat.AttachmentManager
|
||||
import chat.revolt.components.screens.chat.ChannelIcon
|
||||
import chat.revolt.components.screens.chat.TypingIndicator
|
||||
import io.ktor.http.*
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.datetime.Instant
|
||||
|
|
@ -89,20 +91,6 @@ class ChannelScreenViewModel : ViewModel() {
|
|||
|
||||
fun setMessageContent(content: String) {
|
||||
_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>()
|
||||
|
|
@ -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) {
|
||||
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) {
|
||||
viewModel.fetchChannel(channelId)
|
||||
}
|
||||
|
|
@ -488,7 +464,7 @@ fun ChannelScreen(
|
|||
|
||||
val isScrolledToBottom = remember(lazyListState) {
|
||||
derivedStateOf {
|
||||
lazyListState.firstVisibleItemIndex <= 5
|
||||
lazyListState.firstVisibleItemIndex <= 6
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -505,6 +481,10 @@ fun ChannelScreen(
|
|||
contentAlignment = Alignment.BottomEnd
|
||||
) {
|
||||
LazyColumn(state = lazyListState, reverseLayout = true) {
|
||||
item {
|
||||
Spacer(modifier = Modifier.height(32.dp))
|
||||
}
|
||||
|
||||
items(viewModel.renderableMessages) { message ->
|
||||
Message(message)
|
||||
}
|
||||
|
|
@ -540,6 +520,7 @@ fun ChannelScreen(
|
|||
) {
|
||||
ExtendedFloatingActionButton(
|
||||
modifier = Modifier
|
||||
.padding(bottom = scrollDownFABPadding)
|
||||
.align(Alignment.BottomEnd)
|
||||
.padding(16.dp),
|
||||
text = {
|
||||
|
|
@ -560,34 +541,10 @@ fun ChannelScreen(
|
|||
containerColor = MaterialTheme.colorScheme.primary
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
AnimatedVisibility(
|
||||
visible = viewModel.typingUsers.isNotEmpty(),
|
||||
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,
|
||||
)
|
||||
}
|
||||
TypingIndicator(
|
||||
users = viewModel.typingUsers
|
||||
)
|
||||
}
|
||||
|
||||
AnimatedVisibility(visible = viewModel.attachments.isNotEmpty()) {
|
||||
|
|
@ -599,8 +556,6 @@ fun ChannelScreen(
|
|||
}
|
||||
|
||||
MessageField(
|
||||
showButtons = viewModel.showButtons,
|
||||
onToggleButtons = viewModel::setShowButtons,
|
||||
messageContent = viewModel.messageContent,
|
||||
onMessageContentChange = viewModel::setMessageContent,
|
||||
onSendMessage = viewModel::sendPendingMessage,
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
package chat.revolt.screens.settings
|
||||
|
||||
import android.widget.Toast
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.isSystemInDarkTheme
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
|
|
@ -12,9 +13,11 @@ import androidx.compose.material3.Text
|
|||
import androidx.compose.material3.dynamicDarkColorScheme
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Modifier
|
||||
import androidx.compose.ui.draw.clip
|
||||
import androidx.compose.ui.graphics.Color
|
||||
import androidx.compose.ui.platform.LocalContext
|
||||
import androidx.compose.ui.res.stringResource
|
||||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.unit.dp
|
||||
import androidx.lifecycle.ViewModel
|
||||
import androidx.lifecycle.viewModelScope
|
||||
|
|
@ -75,13 +78,25 @@ fun AppearanceSettingsScreen(
|
|||
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(
|
||||
mainAxisSpacing = 10.dp,
|
||||
crossAxisSpacing = 10.dp,
|
||||
) {
|
||||
ThemeChip(
|
||||
color = Color(0xff172333),
|
||||
color = Color(0xff1e1e1e),
|
||||
text = stringResource(id = R.string.settings_appearance_theme_revolt),
|
||||
selected = GlobalState.theme == Theme.Revolt,
|
||||
modifier = Modifier.weight(1f),
|
||||
|
|
@ -108,7 +123,7 @@ fun AppearanceSettingsScreen(
|
|||
}
|
||||
|
||||
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),
|
||||
selected = GlobalState.theme == Theme.None,
|
||||
modifier = Modifier.weight(1f),
|
||||
|
|
|
|||
|
|
@ -14,18 +14,17 @@ import androidx.compose.ui.platform.LocalView
|
|||
import androidx.core.view.ViewCompat
|
||||
|
||||
val RevoltColorScheme = darkColorScheme(
|
||||
primary = Color(0xfffe4654),
|
||||
primary = Color(0xffda4e5b),
|
||||
onPrimary = Color(0xffffffff),
|
||||
secondary = Color(0xfffd6671),
|
||||
secondary = Color(0xffe96a7a),
|
||||
onSecondary = Color(0xffffffff),
|
||||
tertiary = Color(0xffff6667),
|
||||
onTertiary = Color(0xffffffff),
|
||||
background = Color(0xff101823),
|
||||
background = Color(0xff121212),
|
||||
onBackground = Color(0xffffffff),
|
||||
surfaceVariant = Color(0xff172333),
|
||||
surfaceVariant = Color(0xff1e1e1e),
|
||||
onSurfaceVariant = Color(0xffffffff),
|
||||
surface = Color(0xff111a26),
|
||||
surface = Color(0xff2b2b2b),
|
||||
onSurface = Color(0xffffffff),
|
||||
surfaceTint = Color(0xffc0c0c0),
|
||||
)
|
||||
|
||||
val AmoledColorScheme = RevoltColorScheme.copy(
|
||||
|
|
@ -38,18 +37,17 @@ val AmoledColorScheme = RevoltColorScheme.copy(
|
|||
)
|
||||
|
||||
val LightColorScheme = lightColorScheme(
|
||||
primary = Color(0xfffe4654),
|
||||
primary = Color(0xffda4e5b),
|
||||
onPrimary = Color(0xffffffff),
|
||||
secondary = Color(0xfffd6671),
|
||||
secondary = Color(0xffe96a7a),
|
||||
onSecondary = Color(0xffffffff),
|
||||
tertiary = Color(0xffff6667),
|
||||
onTertiary = Color(0xffffffff),
|
||||
background = Color(0xffffffff),
|
||||
onBackground = Color(0xff000000),
|
||||
surfaceVariant = Color(0xffe6e6e6),
|
||||
surfaceVariant = Color(0xffe0e0e0),
|
||||
onSurfaceVariant = Color(0xff000000),
|
||||
surface = Color(0xffdddddd),
|
||||
surface = Color(0xfff5f5f5),
|
||||
onSurface = Color(0xff000000),
|
||||
surfaceTint = Color(0xff000000),
|
||||
)
|
||||
|
||||
enum class Theme {
|
||||
|
|
|
|||
Loading…
Reference in New Issue