@@ -34,7 +34,6 @@ import android.provider.MediaStore
3434import android.provider.Settings
3535import android.text.SpannableStringBuilder
3636import android.text.TextUtils
37- import android.text.format.DateFormat
3837import android.util.Log
3938import android.view.Gravity
4039import android.view.Menu
@@ -60,39 +59,11 @@ import androidx.activity.result.contract.ActivityResultContracts.PickVisualMedia
6059import androidx.appcompat.app.AlertDialog
6160import androidx.appcompat.view.ContextThemeWrapper
6261import androidx.cardview.widget.CardView
63- import androidx.compose.foundation.background
64- import androidx.compose.foundation.clickable
65- import androidx.compose.foundation.layout.Arrangement
66- import androidx.compose.foundation.layout.Box
67- import androidx.compose.foundation.layout.Column
68- import androidx.compose.foundation.layout.heightIn
69- import androidx.compose.foundation.layout.offset
70- import androidx.compose.foundation.layout.padding
71- import androidx.compose.foundation.layout.size
72- import androidx.compose.foundation.rememberScrollState
73- import androidx.compose.foundation.shape.RoundedCornerShape
74- import androidx.compose.foundation.verticalScroll
75- import androidx.compose.material.icons.Icons
76- import androidx.compose.material.icons.filled.Menu
77- import androidx.compose.material3.Divider
78- import androidx.compose.material3.DropdownMenu
79- import androidx.compose.material3.DropdownMenuItem
80- import androidx.compose.material3.Icon
81- import androidx.compose.material3.IconButton
8262import androidx.compose.material3.MaterialTheme
83- import androidx.compose.material3.Text
84- import androidx.compose.runtime.Composable
8563import androidx.compose.runtime.getValue
8664import androidx.compose.runtime.mutableStateOf
87- import androidx.compose.runtime.remember
8865import androidx.compose.runtime.setValue
89- import androidx.compose.ui.Modifier
90- import androidx.compose.ui.draw.shadow
91- import androidx.compose.ui.graphics.Color
9266import androidx.compose.ui.platform.ComposeView
93- import androidx.compose.ui.res.painterResource
94- import androidx.compose.ui.res.stringResource
95- import androidx.compose.ui.unit.dp
9667import androidx.coordinatorlayout.widget.CoordinatorLayout
9768import androidx.core.content.ContextCompat
9869import androidx.core.content.FileProvider
@@ -196,7 +167,7 @@ import com.nextcloud.talk.signaling.SignalingMessageReceiver
196167import com.nextcloud.talk.signaling.SignalingMessageSender
197168import com.nextcloud.talk.threadsoverview.ThreadsOverviewActivity
198169import com.nextcloud.talk.translate.ui.TranslateActivity
199- import com.nextcloud.talk.ui.ComposeChatAdapter
170+ import com.nextcloud.talk.ui.PinnedMessageView
200171import com.nextcloud.talk.ui.PlaybackSpeed
201172import com.nextcloud.talk.ui.PlaybackSpeedControl
202173import com.nextcloud.talk.ui.StatusDrawable
@@ -720,7 +691,14 @@ class ChatActivity :
720691 message?.let {
721692 binding.pinnedMessageContainer.visibility = View .VISIBLE
722693 binding.pinnedMessageComposeView.setContent {
723- PinnedMessageView (message)
694+ PinnedMessageView (
695+ message,
696+ viewThemeUtils,
697+ currentConversation,
698+ scrollToMessageWithIdWithOffset = ::scrollToMessageWithIdWithOffset,
699+ hidePinnedMessage = ::hidePinnedMessage,
700+ unPinMessage = ::unPinMessage
701+ )
724702 }
725703 }
726704 }
@@ -1381,160 +1359,6 @@ class ChatActivity :
13811359 }
13821360 }
13831361
1384- @Composable
1385- private fun PinnedMessageView (message : ChatMessage ) {
1386- message.incoming = true
1387-
1388- val pinnedBy = stringResource(R .string.pinned_by)
1389-
1390- message.actorDisplayName = remember(message.pinnedActorDisplayName) {
1391- " ${message.actorDisplayName} \n $pinnedBy ${message.pinnedActorDisplayName} "
1392- }
1393- val scrollState = rememberScrollState()
1394-
1395- val outgoingBubbleColor = remember {
1396- val colorInt = viewThemeUtils.talk
1397- .getOutgoingMessageBubbleColor(context, message.isDeleted, false )
1398-
1399- Color (colorInt)
1400- }
1401-
1402- val incomingBubbleColor = remember {
1403- val colorInt = resources
1404- .getColor(R .color.bg_message_list_incoming_bubble, null )
1405-
1406- Color (colorInt)
1407- }
1408-
1409- val canPin = remember {
1410- message.isOneToOneConversation ||
1411- ConversationUtils .isParticipantOwnerOrModerator(currentConversation!! )
1412- }
1413-
1414- Column (
1415- verticalArrangement = Arrangement .spacedBy((- 16 ).dp),
1416- modifier = Modifier
1417- ) {
1418- Box (
1419- modifier = Modifier
1420- .shadow(4 .dp, shape = RoundedCornerShape (16 .dp))
1421- .background(incomingBubbleColor, RoundedCornerShape (16 .dp))
1422- .padding(16 .dp)
1423- .heightIn(max = 100 .dp)
1424- .verticalScroll(scrollState)
1425- .clickable {
1426- scrollToMessageWithIdWithOffset(message.id)
1427- }
1428-
1429- ) {
1430- ComposeChatAdapter ().GetComposableForMessage (message)
1431- }
1432-
1433- var expanded by remember { mutableStateOf(false ) }
1434-
1435- val pinnedText = remember(message.pinnedUntil) {
1436- val pinnedUntilStr = context.getString(R .string.pinned_until)
1437- val untilUnpin = context.getString(R .string.until_unpin)
1438-
1439- message.pinnedUntil?.let {
1440- val format = if (DateFormat .is24HourFormat(context)) {
1441- " MMM dd yyyy, HH:mm"
1442- } else {
1443- " MMM dd yyyy, hh:mm a"
1444- }
1445-
1446- val localDateTime = Instant .ofEpochSecond(it)
1447- .atZone(ZoneId .systemDefault())
1448- .toLocalDateTime()
1449-
1450- val timeString = localDateTime.format(DateTimeFormatter .ofPattern(format))
1451-
1452- " $pinnedUntilStr $timeString "
1453- } ? : untilUnpin
1454- }
1455-
1456- Box (
1457- modifier = Modifier
1458- .offset(16 .dp, 0 .dp)
1459- .background(outgoingBubbleColor, RoundedCornerShape (16 .dp))
1460- ) {
1461- IconButton (onClick = { expanded = true }) {
1462- Icon (
1463- imageVector = Icons .Default .Menu , // Or use a Pin icon here
1464- contentDescription = " Pinned Message Options"
1465- )
1466- }
1467-
1468- DropdownMenu (
1469- expanded = expanded,
1470- onDismissRequest = { expanded = false },
1471- modifier = Modifier .background(outgoingBubbleColor)
1472- ) {
1473- DropdownMenuItem (
1474- text = {
1475- Text (
1476- text = pinnedText,
1477- style = MaterialTheme .typography.bodySmall,
1478- color = MaterialTheme .colorScheme.onSurfaceVariant
1479- )
1480- },
1481- onClick = { /* No-op or toggle expansion */ },
1482- enabled = false // Visually distinct as information, not action
1483- )
1484-
1485- Divider ()
1486-
1487- DropdownMenuItem (
1488- text = { Text (" Go to message" ) },
1489- leadingIcon = {
1490- Icon (
1491- painter = painterResource(R .drawable.baseline_chat_bubble_outline_24),
1492- contentDescription = null ,
1493- modifier = Modifier .size(24 .dp)
1494- )
1495- },
1496- onClick = {
1497- expanded = false
1498- scrollToMessageWithIdWithOffset(message.id)
1499- }
1500- )
1501-
1502- DropdownMenuItem (
1503- text = { Text (" Dismiss" ) },
1504- leadingIcon = {
1505- Icon (
1506- painter = painterResource(R .drawable.ic_eye_off),
1507- contentDescription = null ,
1508- modifier = Modifier .size(24 .dp)
1509- )
1510- },
1511- onClick = {
1512- expanded = false
1513- hidePinnedMessage(message)
1514- }
1515- )
1516-
1517- if (canPin) {
1518- DropdownMenuItem (
1519- text = { Text (" Unpin" ) },
1520- leadingIcon = {
1521- Icon (
1522- painter = painterResource(R .drawable.keep_off_24px),
1523- contentDescription = null ,
1524- modifier = Modifier .size(24 .dp)
1525- )
1526- },
1527- onClick = {
1528- expanded = false
1529- unPinMessage(message)
1530- }
1531- )
1532- }
1533- }
1534- }
1535- }
1536- }
1537-
15381362 private fun removeUnreadMessagesMarker () {
15391363 removeMessageById(UNREAD_MESSAGES_MARKER_ID .toString())
15401364 }
0 commit comments