@@ -9,6 +9,9 @@ package com.nextcloud.talk.chat
99
1010import android.content.Intent
1111import android.os.Bundle
12+ import android.text.method.LinkMovementMethod
13+ import android.text.util.Linkify
14+ import android.widget.TextView
1215import androidx.activity.compose.setContent
1316import androidx.compose.foundation.background
1417import androidx.compose.foundation.combinedClickable
@@ -38,12 +41,14 @@ import androidx.compose.material.icons.outlined.Check
3841import androidx.compose.material.icons.outlined.Close
3942import androidx.compose.material.icons.outlined.Delete
4043import androidx.compose.material.icons.outlined.Edit
44+ import androidx.compose.material.icons.outlined.Forum
4145import androidx.compose.material.icons.outlined.InsertEmoticon
4246import androidx.compose.material.icons.outlined.Keyboard
4347import androidx.compose.material.icons.outlined.NotificationsOff
4448import androidx.compose.material3.ExperimentalMaterial3Api
4549import androidx.compose.material3.Icon
4650import androidx.compose.material3.IconButton
51+ import androidx.compose.material3.LocalContentColor
4752import androidx.compose.material3.MaterialTheme
4853import androidx.compose.material3.ModalBottomSheet
4954import androidx.compose.material3.Scaffold
@@ -67,6 +72,7 @@ import androidx.compose.ui.draw.clip
6772import androidx.compose.ui.draw.drawBehind
6873import androidx.compose.ui.geometry.Offset
6974import androidx.compose.ui.graphics.Color
75+ import androidx.compose.ui.graphics.toArgb
7076import androidx.compose.ui.graphics.vector.ImageVector
7177import androidx.compose.ui.platform.LocalContext
7278import androidx.compose.ui.platform.LocalSoftwareKeyboardController
@@ -103,6 +109,7 @@ import com.nextcloud.talk.utils.DateUtils
103109import com.nextcloud.talk.utils.bundle.BundleKeys
104110import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_ROOM_TOKEN
105111import com.nextcloud.talk.utils.bundle.BundleKeys.KEY_THREAD_ID
112+ import com.nextcloud.talk.utils.message.MessageUtils
106113import com.vanniktech.emoji.EmojiEditText
107114import com.vanniktech.emoji.EmojiPopup
108115import java.time.Instant
@@ -166,15 +173,26 @@ class ScheduledMessagesActivity : BaseActivity() {
166173 edit(message, sendAt, user)
167174 },
168175 onDeleteScheduledMessage = { message -> deleteScheduledMessage(message, user) },
169- onOpenParentMessage = { messageId, threadId ->
170- openParentMessage(messageId, threadId)
176+ onOpenParentMessage = { messageId ->
177+ openParentMessage(messageId)
178+ },
179+ onOpenThread = { threadId ->
180+ openThread(threadId)
171181 }
172182 )
173183 }
174184 }
175185 }
176186 }
177187
188+ private fun openThread (threadId : Long ) {
189+ val intent = Intent (this , ChatActivity ::class .java).apply {
190+ putExtra(KEY_ROOM_TOKEN , roomToken)
191+ putExtra(KEY_THREAD_ID , threadId)
192+ }
193+ startActivity(intent)
194+ }
195+
178196 private fun loadScheduledMessages (user : User ) {
179197 scheduledMessagesViewModel.loadScheduledMessages(
180198 user.getCredentials(),
@@ -256,7 +274,8 @@ class ScheduledMessagesActivity : BaseActivity() {
256274 onReschedule : (ChatMessage , Int ) -> Unit ,
257275 onEdit : (ChatMessage , Int ) -> Unit ,
258276 onDeleteScheduledMessage : (ChatMessage ) -> Unit ,
259- onOpenParentMessage : (Long? , Long? ) -> Unit
277+ onOpenParentMessage : (Long? ) -> Unit ,
278+ onOpenThread : (Long ) -> Unit
260279 ) {
261280 val snackBarHostState = remember { SnackbarHostState () }
262281 val scheduledState by scheduledMessagesViewModel.getScheduledMessagesState.collectAsStateWithLifecycle()
@@ -424,20 +443,16 @@ class ScheduledMessagesActivity : BaseActivity() {
424443 )
425444 }
426445 }
427-
428446 val parentMessage = parentId?.let { parentMessages[it] }
429-
430447 ScheduledMessageBubble (
431448 message = message,
432449 parentMessage = parentMessage,
433450 dateUtils = dateUtils,
434451 viewThemeUtils = viewThemeUtils,
435452 onClick = {
436453 val parentId = message.parentMessageId
437- if (message.threadId != null ) {
438- onOpenParentMessage(parentId, message.threadId)
439- } else if (parentId != null ) {
440- onOpenParentMessage(parentId, message.threadId)
454+ if (parentId != null ) {
455+ onOpenParentMessage(parentId)
441456 }
442457 },
443458 onLongPress = {
@@ -520,6 +535,12 @@ class ScheduledMessagesActivity : BaseActivity() {
520535 val message = selectedMessage ? : return @ScheduledMessageActionsSheet
521536 onDeleteScheduledMessage(message)
522537 showActionsSheet = false
538+ },
539+ showOpenThreadAction = selectedMessage?.threadId != null && selectedMessage?.threadId!! > 0 ,
540+ onOpenThread = {
541+ val threadId = selectedMessage?.threadId ? : return @ScheduledMessageActionsSheet
542+ onOpenThread(threadId)
543+ showActionsSheet = false
523544 }
524545 )
525546 }
@@ -622,15 +643,16 @@ class ScheduledMessagesActivity : BaseActivity() {
622643 val context = LocalContext .current
623644 val scheduledAt = message.sendAt?.toLong() ? : message.timestamp
624645 val timeText = dateUtils.getLocalTimeStringFromTimestamp(scheduledAt)
625- val text = ChatUtils .getParsedMessage(message.message, message.messageParameters).orEmpty ()
646+ val messageTextColor = LocalContentColor .current.toArgb ()
626647
627648 val bubbleColor = remember(context, message.isDeleted, viewThemeUtils) {
628649 Color (viewThemeUtils.talk.getOutgoingMessageBubbleColor(context, message.isDeleted, false ))
629650 }
630651
631- val isClickable = remember(message.threadTitle, parentMessage) {
632- ! message.threadTitle.isNullOrBlank() || parentMessage != null
652+ val isClickable = remember(parentMessage) {
653+ parentMessage != null
633654 }
655+
634656 Row (
635657 modifier = Modifier
636658 .fillMaxWidth()
@@ -646,11 +668,13 @@ class ScheduledMessagesActivity : BaseActivity() {
646668 .then(
647669 if (isClickable) {
648670 Modifier .combinedClickable(
671+ enabled = true ,
649672 onClick = onClick,
650673 onLongClick = onLongPress
651674 )
652675 } else {
653676 Modifier .combinedClickable(
677+ enabled = true ,
654678 onClick = {},
655679 onLongClick = onLongPress
656680 )
@@ -660,7 +684,6 @@ class ScheduledMessagesActivity : BaseActivity() {
660684 val strokeColor = MaterialTheme .colorScheme.primary
661685 Column (modifier = Modifier .padding(8 .dp)) {
662686 parentMessage?.let { parent ->
663-
664687 if (! message.threadTitle.isNullOrBlank()) {
665688 Row (
666689 verticalAlignment = Alignment .CenterVertically ,
@@ -677,44 +700,79 @@ class ScheduledMessagesActivity : BaseActivity() {
677700 style = MaterialTheme .typography.labelSmall.copy(fontWeight = FontWeight .Bold )
678701 )
679702 }
680- } else {
681- Row (
682- modifier = Modifier
683- .fillMaxWidth()
684- .padding(bottom = 4 .dp)
685- .clip(RoundedCornerShape (4 .dp))
686- .background(MaterialTheme .colorScheme.background, MaterialTheme .shapes.small)
687- .drawBehind {
688- val strokeWidth = 3 .dp.toPx()
689- drawLine(
690- color = strokeColor,
691- start = Offset (strokeWidth / 2 , 0f ),
692- end = Offset (strokeWidth / 2 , size.height),
693- strokeWidth = strokeWidth
694- )
695- }
696- .padding(start = 12 .dp, top = 4 .dp, bottom = 4 .dp, end = 8 .dp)
697- ) {
698- Column (modifier = Modifier .weight(1f )) {
699- Text (
700- text = parent.actorDisplayName ? : " Unknown" ,
701- style = MaterialTheme .typography.labelSmall.copy(
702- fontWeight = FontWeight .Bold
703- )
704- )
705- Text (
706- text = ChatUtils .getParsedMessage(
707- parent.message,
708- parent.messageParameters
709- ).orEmpty(),
710- style = MaterialTheme .typography.bodySmall
703+ }
704+ Row (
705+ modifier = Modifier
706+ .fillMaxWidth()
707+ .padding(bottom = 4 .dp)
708+ .clip(RoundedCornerShape (4 .dp))
709+ .background(MaterialTheme .colorScheme.background, MaterialTheme .shapes.small)
710+ .drawBehind {
711+ val strokeWidth = 3 .dp.toPx()
712+ drawLine(
713+ color = strokeColor,
714+ start = Offset (strokeWidth / 2 , 0f ),
715+ end = Offset (strokeWidth / 2 , size.height),
716+ strokeWidth = strokeWidth
711717 )
712718 }
719+ .padding(start = 12 .dp, top = 4 .dp, bottom = 4 .dp, end = 8 .dp)
720+ ) {
721+ Column (modifier = Modifier .weight(1f )) {
722+ Text (
723+ text = parent.actorDisplayName ? : " Unknown" ,
724+ style = MaterialTheme .typography.labelSmall.copy(
725+ fontWeight = FontWeight .Bold
726+ )
727+ )
728+ val parentMessage = ChatUtils .getParsedMessage(
729+ parent.message,
730+ parent.messageParameters
731+ ).orEmpty()
732+
733+ AndroidView (
734+ factory = { androidContext ->
735+ TextView (androidContext).apply {
736+ movementMethod = LinkMovementMethod .getInstance()
737+ linksClickable = true
738+ }
739+ },
740+ update = { textView ->
741+ textView.setTextColor(messageTextColor)
742+ textView.text = MessageUtils (context).getRenderedMarkdownText(
743+ context,
744+ parentMessage,
745+ messageTextColor
746+ )
747+ Linkify .addLinks(textView, 0 )
748+ }
749+ )
713750 }
714751 }
715752 }
753+ val messageTextColor = LocalContentColor .current.toArgb()
754+ val chatMessage = ChatUtils .getParsedMessage(
755+ message.message,
756+ message.messageParameters
757+ ).orEmpty()
716758
717- Text (text = text, style = MaterialTheme .typography.bodyMedium)
759+ AndroidView (
760+ factory = { androidContext ->
761+ TextView (androidContext).apply {
762+ movementMethod = LinkMovementMethod .getInstance()
763+ linksClickable = true
764+ }
765+ },
766+ update = { textView ->
767+ textView.setTextColor(messageTextColor)
768+ textView.text = MessageUtils (context).getRenderedMarkdownText(
769+ context,
770+ chatMessage,
771+ messageTextColor
772+ )
773+ Linkify .addLinks(textView, Linkify .ALL )
774+ }
775+ )
718776 Spacer (Modifier .height(4 .dp))
719777
720778 Row (
@@ -860,7 +918,6 @@ class ScheduledMessagesActivity : BaseActivity() {
860918 if (it.text.toString() != editValue.text) {
861919 it.setText(editValue.text)
862920 }
863- it.setSelection(editValue.text.length)
864921 }
865922 )
866923
@@ -889,13 +946,16 @@ class ScheduledMessagesActivity : BaseActivity() {
889946 }
890947 }
891948
949+ @Suppress(" LongParameterList" )
892950 @Composable
893951 private fun ScheduledMessageActionsSheet (
894952 scheduledTime : String ,
895953 onReschedule : () -> Unit ,
896954 onSendNow : () -> Unit ,
897955 onEdit : () -> Unit ,
898- onDelete : () -> Unit
956+ onDelete : () -> Unit ,
957+ showOpenThreadAction : Boolean ,
958+ onOpenThread : () -> Unit
899959 ) {
900960 Column (modifier = Modifier .fillMaxWidth()) {
901961 Column (
@@ -925,19 +985,23 @@ class ScheduledMessagesActivity : BaseActivity() {
925985 text = stringResource(R .string.nc_send_now),
926986 onClick = onSendNow
927987 )
988+ if (showOpenThreadAction) {
989+ ActionRow (
990+ icon = Icons .Outlined .Forum ,
991+ text = stringResource(R .string.open_thread),
992+ onClick = onOpenThread
993+ )
994+ }
928995 ActionRow (icon = Icons .Outlined .Edit , text = stringResource(R .string.nc_edit), onClick = onEdit)
929996 ActionRow (icon = Icons .Outlined .Delete , text = stringResource(R .string.nc_delete), onClick = onDelete)
930997 }
931998 }
932999
933- private fun openParentMessage (messageId : Long? , threadId : Long? ) {
1000+ private fun openParentMessage (messageId : Long? ) {
9341001 val intent = Intent (this , ChatActivity ::class .java).apply {
9351002 putExtra(KEY_ROOM_TOKEN , roomToken)
936- if (threadId != null && threadId > 0 ) {
937- putExtra(KEY_THREAD_ID , threadId)
938- } else {
939- messageId?.let { putExtra(BundleKeys .KEY_MESSAGE_ID , it.toString()) }
940- }
1003+
1004+ messageId?.let { putExtra(BundleKeys .KEY_MESSAGE_ID , it.toString()) }
9411005 }
9421006 startActivity(intent)
9431007 }
0 commit comments