feat: initial direct messages and better group chats
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
557a8957f2
commit
1db1ffcb95
|
|
@ -101,6 +101,7 @@ android {
|
|||
}
|
||||
lintOptions {
|
||||
abortOnError false
|
||||
disable 'MissingTranslation'
|
||||
}
|
||||
namespace 'chat.revolt'
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
package chat.revolt.api.internals
|
||||
|
||||
import chat.revolt.api.RevoltAPI
|
||||
import chat.revolt.api.schemas.Channel
|
||||
|
||||
object ChannelUtils {
|
||||
fun resolveDMName(channel: Channel): String? {
|
||||
return channel.name
|
||||
?: RevoltAPI.userCache[channel.recipients?.first { u -> u != RevoltAPI.selfId }]?.username
|
||||
}
|
||||
|
||||
fun resolveDMPartner(channel: Channel): String? {
|
||||
return channel.recipients?.first { u -> u != RevoltAPI.selfId }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,10 +1,17 @@
|
|||
package chat.revolt.components.chat
|
||||
|
||||
import androidx.compose.animation.*
|
||||
import androidx.compose.animation.AnimatedVisibility
|
||||
import androidx.compose.animation.fadeIn
|
||||
import androidx.compose.animation.fadeOut
|
||||
import androidx.compose.animation.slideInVertically
|
||||
import androidx.compose.animation.slideOutVertically
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.clickable
|
||||
import androidx.compose.foundation.interaction.MutableInteractionSource
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.PaddingValues
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.foundation.text.BasicTextField
|
||||
import androidx.compose.foundation.text.KeyboardActions
|
||||
|
|
@ -12,7 +19,13 @@ 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.Send
|
||||
import androidx.compose.material3.*
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.Icon
|
||||
import androidx.compose.material3.LocalTextStyle
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.material3.TextFieldDefaults
|
||||
import androidx.compose.material3.surfaceColorAtElevation
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -107,7 +120,7 @@ fun MessageField(
|
|||
Icon(
|
||||
Icons.Default.Add,
|
||||
tint = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.5f),
|
||||
contentDescription = stringResource(id = R.string.unknown),
|
||||
contentDescription = stringResource(id = R.string.add_attachment_alt),
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.size(32.dp)
|
||||
|
|
@ -132,7 +145,7 @@ fun MessageField(
|
|||
Icon(
|
||||
Icons.Default.Send,
|
||||
tint = MaterialTheme.colorScheme.primary,
|
||||
contentDescription = stringResource(id = R.string.unknown),
|
||||
contentDescription = stringResource(id = R.string.send_alt),
|
||||
modifier = Modifier
|
||||
.clip(CircleShape)
|
||||
.size(32.dp)
|
||||
|
|
|
|||
|
|
@ -9,6 +9,7 @@ import androidx.compose.foundation.layout.size
|
|||
import androidx.compose.foundation.layout.width
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.Text
|
||||
import androidx.compose.runtime.Composable
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -123,6 +124,65 @@ fun UserAvatar(
|
|||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
@Composable
|
||||
fun GroupIcon(
|
||||
name: String,
|
||||
modifier: Modifier = Modifier,
|
||||
icon: AutumnResource? = null,
|
||||
rawUrl: String? = null,
|
||||
size: Dp = 40.dp,
|
||||
onLongClick: (() -> Unit)? = null,
|
||||
onClick: (() -> Unit)? = null,
|
||||
) {
|
||||
Box(
|
||||
modifier = modifier
|
||||
.size(size),
|
||||
contentAlignment = Alignment.BottomEnd
|
||||
) {
|
||||
if (icon != null) {
|
||||
RemoteImage(
|
||||
url = rawUrl ?: "$REVOLT_FILES/icons/${icon.id!!}/group.png",
|
||||
contentScale = ContentScale.Crop,
|
||||
description = stringResource(id = R.string.avatar_alt, name),
|
||||
modifier = Modifier
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.size(size)
|
||||
.then(
|
||||
if (onLongClick != null || onClick != null) Modifier
|
||||
.combinedClickable(
|
||||
onClick = { onClick?.invoke() },
|
||||
onLongClick = { onLongClick?.invoke() }
|
||||
)
|
||||
else Modifier
|
||||
)
|
||||
)
|
||||
} else {
|
||||
Box(
|
||||
modifier = Modifier
|
||||
.size(size)
|
||||
.then(
|
||||
if (onLongClick != null || onClick != null) Modifier
|
||||
.combinedClickable(
|
||||
onClick = { onClick?.invoke() },
|
||||
onLongClick = { onLongClick?.invoke() }
|
||||
)
|
||||
else Modifier
|
||||
)
|
||||
.clip(MaterialTheme.shapes.small)
|
||||
.background(MaterialTheme.colorScheme.primary)
|
||||
) {
|
||||
Text(
|
||||
text = name.first().toString(),
|
||||
style = MaterialTheme.typography.labelMedium,
|
||||
color = MaterialTheme.colorScheme.onPrimary,
|
||||
modifier = Modifier.align(Alignment.Center)
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Composable
|
||||
fun UserAvatarWidthPlaceholder(
|
||||
size: Dp = 40.dp,
|
||||
|
|
|
|||
|
|
@ -22,7 +22,9 @@ import androidx.compose.ui.text.font.FontWeight
|
|||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.revolt.R
|
||||
import chat.revolt.api.internals.ChannelUtils
|
||||
import chat.revolt.api.schemas.Channel
|
||||
import chat.revolt.api.schemas.ChannelType
|
||||
|
||||
@Composable
|
||||
fun ChannelHeader(
|
||||
|
|
@ -64,7 +66,13 @@ fun ChannelHeader(
|
|||
verticalAlignment = Alignment.CenterVertically,
|
||||
) {
|
||||
Text(
|
||||
text = channel.name ?: "Ch #${channel.id}",
|
||||
text = channel.name
|
||||
?: ChannelUtils.resolveDMName(channel)
|
||||
?: if (channel.channelType == ChannelType.SavedMessages) {
|
||||
stringResource(R.string.channel_notes)
|
||||
} else {
|
||||
stringResource(R.string.unknown)
|
||||
},
|
||||
fontWeight = FontWeight.Medium,
|
||||
maxLines = 1,
|
||||
overflow = TextOverflow.Ellipsis,
|
||||
|
|
|
|||
|
|
@ -3,12 +3,12 @@ package chat.revolt.components.screens.chat.drawer.channel
|
|||
import androidx.compose.foundation.layout.Arrangement
|
||||
import androidx.compose.foundation.layout.Column
|
||||
import androidx.compose.foundation.layout.RowScope
|
||||
import androidx.compose.foundation.layout.fillMaxSize
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.height
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.rememberScrollState
|
||||
import androidx.compose.foundation.lazy.LazyColumn
|
||||
import androidx.compose.foundation.shape.RoundedCornerShape
|
||||
import androidx.compose.foundation.verticalScroll
|
||||
import androidx.compose.material3.DrawerState
|
||||
import androidx.compose.material3.ExperimentalMaterial3Api
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
import androidx.compose.material3.ModalBottomSheet
|
||||
|
|
@ -19,7 +19,6 @@ import androidx.compose.runtime.Composable
|
|||
import androidx.compose.runtime.getValue
|
||||
import androidx.compose.runtime.mutableStateOf
|
||||
import androidx.compose.runtime.remember
|
||||
import androidx.compose.runtime.rememberCoroutineScope
|
||||
import androidx.compose.runtime.setValue
|
||||
import androidx.compose.ui.Alignment
|
||||
import androidx.compose.ui.Modifier
|
||||
|
|
@ -30,21 +29,21 @@ import androidx.compose.ui.unit.dp
|
|||
import androidx.compose.ui.unit.sp
|
||||
import chat.revolt.R
|
||||
import chat.revolt.api.RevoltAPI
|
||||
import chat.revolt.api.internals.ChannelUtils
|
||||
import chat.revolt.api.schemas.ChannelType
|
||||
import chat.revolt.components.generic.presenceFromStatus
|
||||
import chat.revolt.components.screens.chat.drawer.server.DrawerChannel
|
||||
import chat.revolt.sheets.ChannelContextSheet
|
||||
import kotlinx.coroutines.launch
|
||||
|
||||
@OptIn(ExperimentalMaterial3Api::class)
|
||||
@Composable
|
||||
fun RowScope.ChannelList(
|
||||
serverId: String,
|
||||
drawerState: DrawerState,
|
||||
currentDestination: String?,
|
||||
currentChannel: String?,
|
||||
onChannelClick: (String) -> Unit,
|
||||
onSpecialClick: (String) -> Unit,
|
||||
) {
|
||||
val coroutineScope = rememberCoroutineScope()
|
||||
|
||||
var channelContextSheetShown by remember { mutableStateOf(false) }
|
||||
var channelContextSheetTarget by remember { mutableStateOf("") }
|
||||
|
||||
|
|
@ -67,6 +66,13 @@ fun RowScope.ChannelList(
|
|||
}
|
||||
}
|
||||
|
||||
val dmAbleChannels =
|
||||
RevoltAPI.channelCache.values
|
||||
.filter { it.channelType == ChannelType.DirectMessage || it.channelType == ChannelType.Group }
|
||||
.filter { if (it.channelType == ChannelType.DirectMessage) it.active == true else true }
|
||||
.sortedBy { it.lastMessageID ?: it.id }
|
||||
.reversed()
|
||||
|
||||
Surface(
|
||||
tonalElevation = 1.dp,
|
||||
modifier = Modifier
|
||||
|
|
@ -74,82 +80,153 @@ fun RowScope.ChannelList(
|
|||
.clip(RoundedCornerShape(16.dp))
|
||||
.fillMaxWidth(),
|
||||
) {
|
||||
Column(
|
||||
LazyColumn(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.fillMaxSize(),
|
||||
) {
|
||||
if (serverId == "home") {
|
||||
Column(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.verticalScroll(rememberScrollState())
|
||||
item(
|
||||
key = "header"
|
||||
) {
|
||||
RevoltAPI.channelCache.values.filter { it.channelType == ChannelType.Group }
|
||||
.forEach { channel ->
|
||||
DrawerChannel(
|
||||
name = channel.name
|
||||
?: "GDM #${channel.id}",
|
||||
channelType = ChannelType.Group,
|
||||
selected = currentChannel == channel.id,
|
||||
hasUnread = channel.lastMessageID?.let { lastMessageID ->
|
||||
RevoltAPI.unreads.hasUnread(
|
||||
channel.id!!,
|
||||
lastMessageID
|
||||
)
|
||||
} ?: false,
|
||||
onClick = {
|
||||
onChannelClick(channel.id ?: return@DrawerChannel)
|
||||
coroutineScope.launch { drawerState.close() }
|
||||
},
|
||||
onLongClick = {
|
||||
channelContextSheetTarget = channel.id ?: return@DrawerChannel
|
||||
channelContextSheetShown = true
|
||||
}
|
||||
Text(
|
||||
text = stringResource(R.string.direct_messages),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
item(
|
||||
key = "home"
|
||||
) {
|
||||
DrawerChannel(
|
||||
name = stringResource(R.string.home),
|
||||
channelType = ChannelType.TextChannel,
|
||||
selected = currentDestination == "home",
|
||||
hasUnread = false,
|
||||
onClick = {
|
||||
onSpecialClick("home")
|
||||
},
|
||||
large = true,
|
||||
)
|
||||
}
|
||||
|
||||
item(
|
||||
key = "notes"
|
||||
) {
|
||||
val notesChannelId =
|
||||
RevoltAPI.channelCache.values.firstOrNull { it.channelType == ChannelType.SavedMessages }?.id
|
||||
|
||||
DrawerChannel(
|
||||
name = stringResource(R.string.channel_notes),
|
||||
channelType = ChannelType.SavedMessages,
|
||||
selected = currentDestination == "channel/{channelId}" && currentChannel == notesChannelId,
|
||||
hasUnread = false,
|
||||
onClick = {
|
||||
onChannelClick(notesChannelId ?: return@DrawerChannel)
|
||||
},
|
||||
large = true,
|
||||
)
|
||||
}
|
||||
|
||||
item(
|
||||
key = "divider"
|
||||
) {
|
||||
Surface(
|
||||
Modifier
|
||||
.padding(vertical = 8.dp)
|
||||
.fillMaxWidth()
|
||||
.height(1.dp),
|
||||
color = MaterialTheme.colorScheme.onSurface.copy(alpha = 0.1f)
|
||||
) {}
|
||||
}
|
||||
|
||||
items(
|
||||
dmAbleChannels.size,
|
||||
key = { index ->
|
||||
val channel = dmAbleChannels.getOrNull(index)
|
||||
channel?.id ?: index
|
||||
}
|
||||
) {
|
||||
val channel = dmAbleChannels.getOrNull(it) ?: return@items
|
||||
|
||||
val partner =
|
||||
if (channel.channelType == ChannelType.DirectMessage) RevoltAPI.userCache[ChannelUtils.resolveDMPartner(
|
||||
channel
|
||||
)] else null
|
||||
|
||||
DrawerChannel(
|
||||
name = partner?.username ?: channel.name
|
||||
?: stringResource(R.string.unknown),
|
||||
channelType = channel.channelType ?: ChannelType.TextChannel,
|
||||
selected = currentDestination == "channel/{channelId}" && currentChannel == channel.id,
|
||||
hasUnread = channel.lastMessageID?.let { lastMessageID ->
|
||||
RevoltAPI.unreads.hasUnread(
|
||||
channel.id!!,
|
||||
lastMessageID
|
||||
)
|
||||
} ?: false,
|
||||
dmPartnerIcon = partner?.avatar ?: channel.icon,
|
||||
dmPartnerId = partner?.id,
|
||||
dmPartnerName = partner?.username,
|
||||
dmPartnerStatus = presenceFromStatus(
|
||||
partner?.status?.presence ?: "Offline"
|
||||
),
|
||||
onClick = {
|
||||
onChannelClick(channel.id ?: return@DrawerChannel)
|
||||
},
|
||||
onLongClick = {
|
||||
channelContextSheetTarget = channel.id ?: return@DrawerChannel
|
||||
channelContextSheetShown = true
|
||||
}
|
||||
)
|
||||
}
|
||||
} else {
|
||||
val server = RevoltAPI.serverCache[serverId]
|
||||
|
||||
Text(
|
||||
text = server?.name
|
||||
?: stringResource(R.string.unknown),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
item {
|
||||
Text(
|
||||
text = server?.name
|
||||
?: stringResource(R.string.unknown),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier.padding(16.dp)
|
||||
)
|
||||
}
|
||||
|
||||
if (server?.channels?.isEmpty() == true) {
|
||||
Column(
|
||||
Modifier.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.no_channels_heading),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.no_channels_body),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
item {
|
||||
Column(
|
||||
Modifier.weight(1f),
|
||||
horizontalAlignment = Alignment.CenterHorizontally,
|
||||
verticalArrangement = Arrangement.Center
|
||||
) {
|
||||
Text(
|
||||
text = stringResource(R.string.no_channels_heading),
|
||||
style = MaterialTheme.typography.labelLarge,
|
||||
textAlign = TextAlign.Center,
|
||||
fontSize = 24.sp,
|
||||
modifier = Modifier.padding(bottom = 16.dp)
|
||||
)
|
||||
Text(
|
||||
text = stringResource(R.string.no_channels_body),
|
||||
style = MaterialTheme.typography.bodyMedium,
|
||||
textAlign = TextAlign.Center,
|
||||
)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Column(
|
||||
Modifier
|
||||
.weight(1f)
|
||||
.verticalScroll(rememberScrollState())
|
||||
items(
|
||||
server?.channels?.size ?: 0,
|
||||
key = { server?.channels?.get(it) ?: "" }
|
||||
) {
|
||||
server?.channels?.forEach { channelId ->
|
||||
server?.channels?.get(it)?.let { channelId ->
|
||||
RevoltAPI.channelCache[channelId]?.let { ch ->
|
||||
DrawerChannel(
|
||||
name = ch.name!!,
|
||||
channelType = ch.channelType!!,
|
||||
selected = currentChannel == ch.id,
|
||||
selected = currentDestination == "channel/{channelId}" && currentChannel == ch.id,
|
||||
hasUnread = ch.lastMessageID?.let { lastMessageID ->
|
||||
RevoltAPI.unreads.hasUnread(
|
||||
ch.id!!,
|
||||
|
|
@ -158,7 +235,6 @@ fun RowScope.ChannelList(
|
|||
} ?: true,
|
||||
onClick = {
|
||||
onChannelClick(ch.id ?: return@DrawerChannel)
|
||||
coroutineScope.launch { drawerState.close() }
|
||||
},
|
||||
onLongClick = {
|
||||
channelContextSheetTarget = ch.id ?: return@DrawerChannel
|
||||
|
|
|
|||
|
|
@ -6,7 +6,13 @@ import androidx.compose.animation.core.spring
|
|||
import androidx.compose.foundation.ExperimentalFoundationApi
|
||||
import androidx.compose.foundation.background
|
||||
import androidx.compose.foundation.combinedClickable
|
||||
import androidx.compose.foundation.layout.*
|
||||
import androidx.compose.foundation.layout.Box
|
||||
import androidx.compose.foundation.layout.Row
|
||||
import androidx.compose.foundation.layout.Spacer
|
||||
import androidx.compose.foundation.layout.fillMaxWidth
|
||||
import androidx.compose.foundation.layout.offset
|
||||
import androidx.compose.foundation.layout.padding
|
||||
import androidx.compose.foundation.layout.size
|
||||
import androidx.compose.foundation.shape.CircleShape
|
||||
import androidx.compose.material3.LocalContentColor
|
||||
import androidx.compose.material3.MaterialTheme
|
||||
|
|
@ -20,7 +26,11 @@ import androidx.compose.ui.graphics.Color
|
|||
import androidx.compose.ui.text.font.FontWeight
|
||||
import androidx.compose.ui.text.style.TextOverflow
|
||||
import androidx.compose.ui.unit.dp
|
||||
import chat.revolt.api.schemas.AutumnResource
|
||||
import chat.revolt.api.schemas.ChannelType
|
||||
import chat.revolt.components.generic.GroupIcon
|
||||
import chat.revolt.components.generic.Presence
|
||||
import chat.revolt.components.generic.UserAvatar
|
||||
import chat.revolt.components.screens.chat.ChannelIcon
|
||||
|
||||
@OptIn(ExperimentalFoundationApi::class)
|
||||
|
|
@ -32,6 +42,11 @@ fun DrawerChannel(
|
|||
hasUnread: Boolean,
|
||||
onClick: () -> Unit,
|
||||
onLongClick: () -> Unit = {},
|
||||
dmPartnerStatus: Presence? = null,
|
||||
dmPartnerName: String? = null,
|
||||
dmPartnerIcon: AutumnResource? = null,
|
||||
dmPartnerId: String? = null,
|
||||
large: Boolean = false,
|
||||
) {
|
||||
val backgroundColor = animateColorAsState(
|
||||
if (selected) MaterialTheme.colorScheme.background
|
||||
|
|
@ -66,7 +81,37 @@ fun DrawerChannel(
|
|||
.padding(vertical = 8.dp, horizontal = 16.dp),
|
||||
verticalAlignment = Alignment.CenterVertically
|
||||
) {
|
||||
ChannelIcon(channelType = channelType, modifier = Modifier.padding(end = 8.dp))
|
||||
when (channelType) {
|
||||
ChannelType.DirectMessage -> UserAvatar(
|
||||
username = dmPartnerName ?: "",
|
||||
avatar = dmPartnerIcon,
|
||||
userId = dmPartnerId ?: "",
|
||||
presence = dmPartnerStatus,
|
||||
size = 32.dp,
|
||||
presenceSize = 16.dp,
|
||||
modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
|
||||
ChannelType.Group -> GroupIcon(
|
||||
name = name,
|
||||
icon = dmPartnerIcon,
|
||||
size = 32.dp,
|
||||
modifier = Modifier.padding(end = 8.dp)
|
||||
)
|
||||
|
||||
else -> ChannelIcon(
|
||||
channelType = channelType,
|
||||
modifier = Modifier.then(
|
||||
if (large) Modifier.padding(
|
||||
end = 12.dp,
|
||||
start = 4.dp,
|
||||
top = 4.dp,
|
||||
bottom = 4.dp
|
||||
) else Modifier.padding(end = 8.dp)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
Text(
|
||||
text = name,
|
||||
fontWeight = FontWeight.Medium,
|
||||
|
|
|
|||
|
|
@ -153,6 +153,14 @@ class ChatRouterViewModel @Inject constructor(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun navigateToSpecial(destination: String, navController: NavController) {
|
||||
navController.navigate(destination) {
|
||||
navController.graph.startDestinationRoute?.let { route ->
|
||||
popUpTo(route)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(
|
||||
|
|
@ -379,11 +387,16 @@ fun ChatRouterScreen(topNav: NavController, viewModel: ChatRouterViewModel = hil
|
|||
) {
|
||||
ChannelList(
|
||||
serverId = it,
|
||||
drawerState = drawerState,
|
||||
currentDestination = navController.currentDestination?.route,
|
||||
currentChannel = viewModel.currentChannel,
|
||||
onChannelClick = { channelId ->
|
||||
viewModel.navigateToChannel(channelId, navController)
|
||||
}
|
||||
scope.launch { drawerState.close() }
|
||||
},
|
||||
onSpecialClick = { destination ->
|
||||
viewModel.navigateToSpecial(destination, navController)
|
||||
scope.launch { drawerState.close() }
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -54,6 +54,7 @@ import chat.revolt.activities.RevoltTweenDp
|
|||
import chat.revolt.activities.RevoltTweenFloat
|
||||
import chat.revolt.activities.RevoltTweenInt
|
||||
import chat.revolt.api.RevoltAPI
|
||||
import chat.revolt.api.internals.ChannelUtils
|
||||
import chat.revolt.api.routes.microservices.autumn.FileArgs
|
||||
import chat.revolt.components.chat.Message
|
||||
import chat.revolt.components.chat.MessageField
|
||||
|
|
@ -390,7 +391,9 @@ fun ChannelScreen(
|
|||
pickFileLauncher.launch(arrayOf("*/*"))
|
||||
},
|
||||
channelType = channel.channelType,
|
||||
channelName = channel.name ?: channel.id!!,
|
||||
channelName = channel.name ?: ChannelUtils.resolveDMName(channel) ?: stringResource(
|
||||
R.string.unknown
|
||||
),
|
||||
forceSendButton = viewModel.attachments.isNotEmpty(),
|
||||
disabled = viewModel.attachments.isNotEmpty() && viewModel.sendingMessage
|
||||
)
|
||||
|
|
|
|||
|
|
@ -109,6 +109,8 @@
|
|||
|
||||
<string name="avatar_alt">%1$s\'s avatar</string>
|
||||
|
||||
<string name="direct_messages">Direct Messages</string>
|
||||
|
||||
<string name="channel_dm">Direct Message</string>
|
||||
<string name="channel_text">Text Channel</string>
|
||||
<string name="channel_voice">Voice Channel</string>
|
||||
|
|
|
|||
Loading…
Reference in New Issue