chore: redundant getters setters in channel ViMo
Signed-off-by: Infi <wingit@geist.ga>
This commit is contained in:
parent
bf8acdcb05
commit
add6f6d557
|
|
@ -88,7 +88,7 @@ fun ChannelScreen(
|
||||||
onToggleDrawer: () -> Unit,
|
onToggleDrawer: () -> Unit,
|
||||||
viewModel: ChannelScreenViewModel = viewModel()
|
viewModel: ChannelScreenViewModel = viewModel()
|
||||||
) {
|
) {
|
||||||
val channel = viewModel.channel
|
val channel = viewModel.activeChannel
|
||||||
|
|
||||||
val context = LocalContext.current
|
val context = LocalContext.current
|
||||||
val lazyListState = rememberLazyListState()
|
val lazyListState = rememberLazyListState()
|
||||||
|
|
@ -114,7 +114,7 @@ fun ChannelScreen(
|
||||||
context.contentResolver.openInputStream(it)?.copyTo(output)
|
context.contentResolver.openInputStream(it)?.copyTo(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
viewModel.addAttachment(
|
viewModel.pendingAttachments.add(
|
||||||
FileArgs(
|
FileArgs(
|
||||||
file = mFile,
|
file = mFile,
|
||||||
contentType = file.type ?: "application/octet-stream",
|
contentType = file.type ?: "application/octet-stream",
|
||||||
|
|
@ -376,22 +376,24 @@ fun ChannelScreen(
|
||||||
AnimatedVisibility(visible = viewModel.replies.isNotEmpty()) {
|
AnimatedVisibility(visible = viewModel.replies.isNotEmpty()) {
|
||||||
ReplyManager(
|
ReplyManager(
|
||||||
replies = viewModel.replies,
|
replies = viewModel.replies,
|
||||||
onRemove = viewModel::removeReply,
|
onRemove = { viewModel.replies.remove(it) },
|
||||||
onToggleMention = viewModel::toggleReplyMentionFor
|
onToggleMention = viewModel::toggleReplyMentionFor
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
AnimatedVisibility(visible = viewModel.attachments.isNotEmpty()) {
|
AnimatedVisibility(visible = viewModel.pendingAttachments.isNotEmpty()) {
|
||||||
AttachmentManager(
|
AttachmentManager(
|
||||||
attachments = viewModel.attachments,
|
attachments = viewModel.pendingAttachments,
|
||||||
uploading = viewModel.sendingMessage,
|
uploading = viewModel.sendingMessage,
|
||||||
onRemove = viewModel::removeAttachment
|
onRemove = { viewModel.pendingAttachments.remove(it) }
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageField(
|
MessageField(
|
||||||
messageContent = viewModel.messageContent,
|
messageContent = viewModel.messageContent,
|
||||||
onMessageContentChange = viewModel::setMessageContent,
|
onMessageContentChange = {
|
||||||
|
viewModel.messageContent = it
|
||||||
|
},
|
||||||
onSendMessage = viewModel::sendPendingMessage,
|
onSendMessage = viewModel::sendPendingMessage,
|
||||||
onAddAttachment = {
|
onAddAttachment = {
|
||||||
pickFileLauncher.launch(arrayOf("*/*"))
|
pickFileLauncher.launch(arrayOf("*/*"))
|
||||||
|
|
@ -400,8 +402,8 @@ fun ChannelScreen(
|
||||||
channelName = channel.name ?: ChannelUtils.resolveDMName(channel) ?: stringResource(
|
channelName = channel.name ?: ChannelUtils.resolveDMName(channel) ?: stringResource(
|
||||||
R.string.unknown
|
R.string.unknown
|
||||||
),
|
),
|
||||||
forceSendButton = viewModel.attachments.isNotEmpty(),
|
forceSendButton = viewModel.pendingAttachments.isNotEmpty(),
|
||||||
disabled = viewModel.attachments.isNotEmpty() && viewModel.sendingMessage
|
disabled = viewModel.pendingAttachments.isNotEmpty() && viewModel.sendingMessage
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ import androidx.compose.runtime.getValue
|
||||||
import androidx.compose.runtime.mutableStateListOf
|
import androidx.compose.runtime.mutableStateListOf
|
||||||
import androidx.compose.runtime.mutableStateOf
|
import androidx.compose.runtime.mutableStateOf
|
||||||
import androidx.compose.runtime.setValue
|
import androidx.compose.runtime.setValue
|
||||||
|
import androidx.compose.runtime.snapshots.SnapshotStateList
|
||||||
import androidx.lifecycle.ViewModel
|
import androidx.lifecycle.ViewModel
|
||||||
import androidx.lifecycle.viewModelScope
|
import androidx.lifecycle.viewModelScope
|
||||||
import chat.revolt.api.RevoltAPI
|
import chat.revolt.api.RevoltAPI
|
||||||
|
|
@ -42,97 +43,53 @@ import kotlinx.coroutines.withContext
|
||||||
import kotlinx.datetime.Instant
|
import kotlinx.datetime.Instant
|
||||||
|
|
||||||
class ChannelScreenViewModel : ViewModel() {
|
class ChannelScreenViewModel : ViewModel() {
|
||||||
private var _channel by mutableStateOf<Channel?>(null)
|
var activeChannel by mutableStateOf<Channel?>(null)
|
||||||
val channel: Channel?
|
|
||||||
get() = _channel
|
|
||||||
|
|
||||||
private var _renderableMessages = mutableStateListOf<Message>()
|
var renderableMessages = mutableStateListOf<Message>()
|
||||||
val renderableMessages: List<Message>
|
|
||||||
get() = _renderableMessages
|
|
||||||
|
|
||||||
private fun setRenderableMessages(messages: List<Message>) {
|
private fun setRenderableMessages(messages: List<Message>) {
|
||||||
_renderableMessages.clear()
|
renderableMessages.clear()
|
||||||
_renderableMessages.addAll(messages)
|
renderableMessages.addAll(messages)
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _typingUsers = mutableStateListOf<String>()
|
var typingUsers = mutableStateListOf<String>()
|
||||||
val typingUsers: List<String>
|
|
||||||
get() = _typingUsers
|
|
||||||
|
|
||||||
private var _messageContent by mutableStateOf("")
|
var messageContent by mutableStateOf("")
|
||||||
val messageContent: String
|
|
||||||
get() = _messageContent
|
|
||||||
|
|
||||||
fun setMessageContent(content: String) {
|
var pendingAttachments = mutableStateListOf<FileArgs>()
|
||||||
_messageContent = content
|
|
||||||
}
|
|
||||||
|
|
||||||
private var _attachments = mutableStateListOf<FileArgs>()
|
|
||||||
val attachments: List<FileArgs>
|
|
||||||
get() = _attachments
|
|
||||||
|
|
||||||
private fun setAttachments(attachments: List<FileArgs>) {
|
|
||||||
_attachments.clear()
|
|
||||||
_attachments.addAll(attachments)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun addAttachment(fileArgs: FileArgs) {
|
|
||||||
_attachments.add(fileArgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeAttachment(fileArgs: FileArgs) {
|
|
||||||
_attachments.remove(fileArgs)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun popAttachmentBatch() {
|
private fun popAttachmentBatch() {
|
||||||
setAttachments(_attachments.drop(MAX_ATTACHMENTS_PER_MESSAGE))
|
pendingAttachments =
|
||||||
|
pendingAttachments.drop(MAX_ATTACHMENTS_PER_MESSAGE) as SnapshotStateList<FileArgs>
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _sendingMessage by mutableStateOf(false)
|
var sendingMessage by mutableStateOf(false)
|
||||||
val sendingMessage: Boolean
|
|
||||||
get() = _sendingMessage
|
|
||||||
|
|
||||||
private fun setSendingMessage(sending: Boolean) {
|
var replies = mutableStateListOf<SendMessageReply>()
|
||||||
_sendingMessage = sending
|
|
||||||
}
|
|
||||||
|
|
||||||
private var _replies = mutableStateListOf<SendMessageReply>()
|
private fun addReply(reply: SendMessageReply) {
|
||||||
val replies: List<SendMessageReply>
|
if (replies.any { it.id == reply.id }) return
|
||||||
get() = _replies
|
replies.add(reply)
|
||||||
|
|
||||||
fun addInReplyTo(reply: SendMessageReply) {
|
|
||||||
if (_replies.any { it.id == reply.id }) return
|
|
||||||
_replies.add(reply)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun removeReply(reply: SendMessageReply) {
|
|
||||||
_replies.remove(reply)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun toggleReplyMentionFor(reply: SendMessageReply) {
|
fun toggleReplyMentionFor(reply: SendMessageReply) {
|
||||||
val index = _replies.indexOf(reply)
|
val index = replies.indexOf(reply)
|
||||||
val newReply = SendMessageReply(
|
val newReply = SendMessageReply(
|
||||||
reply.id,
|
reply.id,
|
||||||
!reply.mention
|
!reply.mention
|
||||||
)
|
)
|
||||||
|
|
||||||
_replies[index] = newReply
|
replies[index] = newReply
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun clearInReplyTo() {
|
private fun clearInReplyTo() {
|
||||||
_replies.clear()
|
replies.clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
private var _noMoreMessages by mutableStateOf(false)
|
var noMoreMessages by mutableStateOf(false)
|
||||||
val noMoreMessages: Boolean
|
|
||||||
get() = _noMoreMessages
|
|
||||||
|
|
||||||
private fun setNoMoreMessages() {
|
|
||||||
_noMoreMessages = true
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchOlderMessages() {
|
fun fetchOlderMessages() {
|
||||||
if (channel == null) {
|
if (activeChannel == null) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -140,7 +97,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
val messages = arrayListOf<Message>()
|
val messages = arrayListOf<Message>()
|
||||||
|
|
||||||
fetchMessagesFromChannel(
|
fetchMessagesFromChannel(
|
||||||
channel!!.id!!,
|
activeChannel!!.id!!,
|
||||||
limit = 50,
|
limit = 50,
|
||||||
true,
|
true,
|
||||||
before = if (renderableMessages.isNotEmpty()) {
|
before = if (renderableMessages.isNotEmpty()) {
|
||||||
|
|
@ -150,7 +107,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
).let {
|
).let {
|
||||||
if (it.messages.isNullOrEmpty() || it.messages.size < 50) {
|
if (it.messages.isNullOrEmpty() || it.messages.size < 50) {
|
||||||
setNoMoreMessages()
|
noMoreMessages = true
|
||||||
}
|
}
|
||||||
|
|
||||||
it.messages?.forEach { message ->
|
it.messages?.forEach { message ->
|
||||||
|
|
@ -170,13 +127,13 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
if (id !in RevoltAPI.channelCache) {
|
if (id !in RevoltAPI.channelCache) {
|
||||||
val channel = fetchSingleChannel(id)
|
val channel = fetchSingleChannel(id)
|
||||||
_channel = channel
|
activeChannel = channel
|
||||||
RevoltAPI.channelCache[id] = channel
|
RevoltAPI.channelCache[id] = channel
|
||||||
} else {
|
} else {
|
||||||
_channel = RevoltAPI.channelCache[id]
|
activeChannel = RevoltAPI.channelCache[id]
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_channel?.lastMessageID != null) {
|
if (activeChannel?.lastMessageID != null) {
|
||||||
ackNewest()
|
ackNewest()
|
||||||
} else {
|
} else {
|
||||||
Log.d("ChannelScreen", "No last message ID, not acking.")
|
Log.d("ChannelScreen", "No last message ID, not acking.")
|
||||||
|
|
@ -185,12 +142,12 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
fun sendPendingMessage() {
|
fun sendPendingMessage() {
|
||||||
setSendingMessage(true)
|
sendingMessage = true
|
||||||
|
|
||||||
viewModelScope.launch {
|
viewModelScope.launch {
|
||||||
val attachmentIds = arrayListOf<String>()
|
val attachmentIds = arrayListOf<String>()
|
||||||
|
|
||||||
attachments.take(MAX_ATTACHMENTS_PER_MESSAGE).forEach {
|
pendingAttachments.take(MAX_ATTACHMENTS_PER_MESSAGE).forEach {
|
||||||
try {
|
try {
|
||||||
val id = uploadToAutumn(
|
val id = uploadToAutumn(
|
||||||
it.file,
|
it.file,
|
||||||
|
|
@ -207,16 +164,16 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
sendMessage(
|
sendMessage(
|
||||||
channel!!.id!!,
|
activeChannel!!.id!!,
|
||||||
messageContent,
|
messageContent.trimIndent(),
|
||||||
attachments = if (attachmentIds.isEmpty()) null else attachmentIds,
|
attachments = if (attachmentIds.isEmpty()) null else attachmentIds,
|
||||||
replies = replies
|
replies = replies
|
||||||
)
|
)
|
||||||
|
|
||||||
_messageContent = ""
|
messageContent = ""
|
||||||
|
noMoreMessages = false
|
||||||
popAttachmentBatch()
|
popAttachmentBatch()
|
||||||
clearInReplyTo()
|
clearInReplyTo()
|
||||||
setSendingMessage(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -268,7 +225,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}.onEach {
|
}.onEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is MessageFrame -> {
|
is MessageFrame -> {
|
||||||
if (it.channel != channel?.id) return@onEach
|
if (it.channel != activeChannel?.id) return@onEach
|
||||||
|
|
||||||
addUserIfUnknown(it.author!!)
|
addUserIfUnknown(it.author!!)
|
||||||
regroupMessages(listOf(it) + renderableMessages)
|
regroupMessages(listOf(it) + renderableMessages)
|
||||||
|
|
@ -276,7 +233,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
is MessageUpdateFrame -> {
|
is MessageUpdateFrame -> {
|
||||||
if (it.channel != channel?.id) return@onEach
|
if (it.channel != activeChannel?.id) return@onEach
|
||||||
|
|
||||||
val messageFrame =
|
val messageFrame =
|
||||||
RevoltJson.decodeFromJsonElement(MessageFrame.serializer(), it.data)
|
RevoltJson.decodeFromJsonElement(MessageFrame.serializer(), it.data)
|
||||||
|
|
@ -298,7 +255,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
is MessageDeleteFrame -> {
|
is MessageDeleteFrame -> {
|
||||||
if (it.channel != channel?.id) return@onEach
|
if (it.channel != activeChannel?.id) return@onEach
|
||||||
|
|
||||||
val newRenderableMessages = renderableMessages.filter { currentMsg ->
|
val newRenderableMessages = renderableMessages.filter { currentMsg ->
|
||||||
currentMsg.id != it.id
|
currentMsg.id != it.id
|
||||||
|
|
@ -307,18 +264,18 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
}
|
}
|
||||||
|
|
||||||
is ChannelStartTypingFrame -> {
|
is ChannelStartTypingFrame -> {
|
||||||
if (it.id != channel?.id) return@onEach
|
if (it.id != activeChannel?.id) return@onEach
|
||||||
if (_typingUsers.contains(it.user)) return@onEach
|
if (typingUsers.contains(it.user)) return@onEach
|
||||||
|
|
||||||
addUserIfUnknown(it.user)
|
addUserIfUnknown(it.user)
|
||||||
_typingUsers.add(it.user)
|
typingUsers.add(it.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
is ChannelStopTypingFrame -> {
|
is ChannelStopTypingFrame -> {
|
||||||
if (it.id != channel?.id) return@onEach
|
if (it.id != activeChannel?.id) return@onEach
|
||||||
if (!_typingUsers.contains(it.user)) return@onEach
|
if (!typingUsers.contains(it.user)) return@onEach
|
||||||
|
|
||||||
_typingUsers.remove(it.user)
|
typingUsers.remove(it.user)
|
||||||
}
|
}
|
||||||
|
|
||||||
is RealtimeSocketFrames.Reconnected -> {
|
is RealtimeSocketFrames.Reconnected -> {
|
||||||
|
|
@ -337,7 +294,7 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
UiCallbacks.uiCallbackFlow.onEach {
|
UiCallbacks.uiCallbackFlow.onEach {
|
||||||
when (it) {
|
when (it) {
|
||||||
is UiCallback.ReplyToMessage -> {
|
is UiCallback.ReplyToMessage -> {
|
||||||
addInReplyTo(
|
addReply(
|
||||||
SendMessageReply(
|
SendMessageReply(
|
||||||
id = it.messageId,
|
id = it.messageId,
|
||||||
mention = false
|
mention = false
|
||||||
|
|
@ -359,21 +316,24 @@ class ChannelScreenViewModel : ViewModel() {
|
||||||
Log.d("ChannelScreen", "Cancelling channel ack")
|
Log.d("ChannelScreen", "Cancelling channel ack")
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel?.lastMessageID == null) return
|
if (activeChannel?.lastMessageID == null) return
|
||||||
|
|
||||||
RevoltAPI.unreads.processExternalAck(channel!!.id!!, channel!!.lastMessageID!!)
|
RevoltAPI.unreads.processExternalAck(
|
||||||
|
activeChannel!!.id!!,
|
||||||
|
activeChannel!!.lastMessageID!!
|
||||||
|
)
|
||||||
|
|
||||||
debouncedChannelAck = viewModelScope.launch {
|
debouncedChannelAck = viewModelScope.launch {
|
||||||
delay(1000)
|
delay(1000)
|
||||||
if (channel?.lastMessageID == null) return@launch
|
if (activeChannel?.lastMessageID == null) return@launch
|
||||||
ackChannel(channel!!.id!!, channel!!.lastMessageID!!)
|
ackChannel(activeChannel!!.id!!, activeChannel!!.lastMessageID!!)
|
||||||
|
|
||||||
Log.d("ChannelScreen", "Acking channel")
|
Log.d("ChannelScreen", "Acking channel")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun replyToMessage(message: Message) {
|
fun replyToMessage(message: Message) {
|
||||||
addInReplyTo(
|
addReply(
|
||||||
SendMessageReply(
|
SendMessageReply(
|
||||||
id = message.id!!,
|
id = message.id!!,
|
||||||
mention = false
|
mention = false
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue