Skip to content

Commit c74fd57

Browse files
committed
Add DeleteMessageForMeComponentFactory for user-specific message deletion
1 parent afcdf12 commit c74fd57

File tree

3 files changed

+154
-4
lines changed

3 files changed

+154
-4
lines changed

stream-chat-android-compose-sample/src/main/java/io/getstream/chat/android/compose/sample/feature/reminders/MessageRemindersComponentFactory.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,8 @@ import androidx.compose.ui.res.painterResource
2929
import io.getstream.chat.android.client.ChatClient
3030
import io.getstream.chat.android.client.utils.message.isDeleted
3131
import io.getstream.chat.android.compose.sample.R
32+
import io.getstream.chat.android.compose.sample.ui.component.DeleteMessageForMeComponentFactory
3233
import io.getstream.chat.android.compose.state.messageoptions.MessageOptionItemState
33-
import io.getstream.chat.android.compose.ui.components.selectedmessage.SelectedMessageMenu
3434
import io.getstream.chat.android.compose.ui.theme.ChatComponentFactory
3535
import io.getstream.chat.android.compose.ui.theme.ChatTheme
3636
import io.getstream.chat.android.models.Message
@@ -44,7 +44,7 @@ import java.util.Date
4444
* Factory for creating components related to message reminders.
4545
*/
4646
class MessageRemindersComponentFactory(
47-
private val delegate: ChatComponentFactory = object : ChatComponentFactory {},
47+
private val delegate: ChatComponentFactory = DeleteMessageForMeComponentFactory(),
4848
) : ChatComponentFactory by delegate {
4949

5050
/**
@@ -159,13 +159,13 @@ class MessageRemindersComponentFactory(
159159
messageOptions
160160
}
161161

162-
SelectedMessageMenu(
162+
delegate.MessageMenu(
163163
modifier = modifier,
164164
message = message,
165165
messageOptions = allOptions,
166166
ownCapabilities = ownCapabilities,
167167
onMessageAction = extendedAction,
168-
onShowMoreReactionsSelected = onShowMore,
168+
onShowMore = onShowMore,
169169
onDismiss = onDismiss,
170170
)
171171
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,148 @@
1+
/*
2+
* Copyright (c) 2014-2025 Stream.io Inc. All rights reserved.
3+
*
4+
* Licensed under the Stream License;
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://github.com/GetStream/stream-chat-android/blob/main/LICENSE
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package io.getstream.chat.android.compose.sample.ui.component
18+
19+
import androidx.compose.foundation.layout.Arrangement
20+
import androidx.compose.foundation.layout.Row
21+
import androidx.compose.foundation.layout.padding
22+
import androidx.compose.material3.Text
23+
import androidx.compose.runtime.Composable
24+
import androidx.compose.runtime.getValue
25+
import androidx.compose.runtime.mutableStateOf
26+
import androidx.compose.runtime.remember
27+
import androidx.compose.runtime.setValue
28+
import androidx.compose.ui.Alignment
29+
import androidx.compose.ui.Modifier
30+
import androidx.compose.ui.res.painterResource
31+
import androidx.compose.ui.unit.dp
32+
import io.getstream.chat.android.client.ChatClient
33+
import io.getstream.chat.android.compose.sample.R
34+
import io.getstream.chat.android.compose.state.messageoptions.MessageOptionItemState
35+
import io.getstream.chat.android.compose.ui.components.SimpleDialog
36+
import io.getstream.chat.android.compose.ui.theme.ChatComponentFactory
37+
import io.getstream.chat.android.compose.ui.theme.ChatTheme
38+
import io.getstream.chat.android.models.Message
39+
import io.getstream.chat.android.ui.common.state.messages.CustomAction
40+
import io.getstream.chat.android.ui.common.state.messages.Delete
41+
import io.getstream.chat.android.ui.common.state.messages.MessageAction
42+
import io.getstream.chat.android.ui.common.state.messages.list.MessageItemState
43+
import io.getstream.chat.android.ui.common.utils.canDeleteMessage
44+
45+
/**
46+
* Factory for creating components related to deleting messages for the current user.
47+
*/
48+
class DeleteMessageForMeComponentFactory : ChatComponentFactory {
49+
50+
/**
51+
* Creates a message menu with option for deleting messages for the current user.
52+
*/
53+
@Suppress("LongMethod")
54+
@Composable
55+
override fun MessageMenu(
56+
modifier: Modifier,
57+
message: Message,
58+
messageOptions: List<MessageOptionItemState>,
59+
ownCapabilities: Set<String>,
60+
onMessageAction: (MessageAction) -> Unit,
61+
onShowMore: () -> Unit,
62+
onDismiss: () -> Unit,
63+
) {
64+
val chatClient = ChatClient.instance()
65+
66+
val visibility = ChatTheme.messageOptionsTheme.optionVisibility
67+
68+
val canDeleteMessage = canDeleteMessage(
69+
deleteMessageEnabled = visibility.isDeleteMessageVisible,
70+
currentUser = chatClient.getCurrentUser(),
71+
message = message,
72+
ownCapabilities = ownCapabilities,
73+
)
74+
75+
var showDeleteForMeConfirmationDialog by remember { mutableStateOf(false) }
76+
77+
val allOptions = if (canDeleteMessage) {
78+
buildList {
79+
messageOptions.forEach { option ->
80+
add(option)
81+
if (option.action is Delete) {
82+
add(
83+
MessageOptionItemState(
84+
title = R.string.message_option_delete_for_me,
85+
titleColor = ChatTheme.colors.errorAccent,
86+
iconPainter = painterResource(R.drawable.stream_compose_ic_delete),
87+
iconColor = ChatTheme.colors.errorAccent,
88+
action = CustomAction(message, mapOf("delete_for_me" to true)),
89+
),
90+
)
91+
}
92+
}
93+
}
94+
} else {
95+
messageOptions
96+
}
97+
98+
val extendedOnMessageAction: (MessageAction) -> Unit = { action ->
99+
when {
100+
action is CustomAction && action.extraProperties.contains("delete_for_me") ->
101+
showDeleteForMeConfirmationDialog = true
102+
103+
else -> onMessageAction(action)
104+
}
105+
}
106+
107+
if (showDeleteForMeConfirmationDialog) {
108+
SimpleDialog(
109+
modifier = Modifier.padding(16.dp),
110+
title = "Delete for me",
111+
message = "Are you sure you want to delete this message for you?",
112+
onPositiveAction = {
113+
chatClient.deleteMessageForMe(message.id).enqueue()
114+
onDismiss()
115+
},
116+
onDismiss = { showDeleteForMeConfirmationDialog = false },
117+
)
118+
}
119+
120+
super.MessageMenu(
121+
modifier = modifier,
122+
message = message,
123+
messageOptions = allOptions,
124+
ownCapabilities = ownCapabilities,
125+
onMessageAction = extendedOnMessageAction,
126+
onShowMore = onShowMore,
127+
onDismiss = onDismiss,
128+
)
129+
}
130+
131+
@Composable
132+
override fun MessageFooterContent(messageItem: MessageItemState) {
133+
Row(
134+
verticalAlignment = Alignment.CenterVertically,
135+
horizontalArrangement = Arrangement.spacedBy(8.dp),
136+
) {
137+
super.MessageFooterContent(messageItem)
138+
if (messageItem.message.deletedForMe) {
139+
Text(
140+
modifier = Modifier.padding(vertical = 4.dp),
141+
text = "Deleted only for me",
142+
style = ChatTheme.typography.footnote,
143+
color = ChatTheme.colors.textHighEmphasis,
144+
)
145+
}
146+
}
147+
}
148+
}

stream-chat-android-compose-sample/src/main/res/values/strings.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,8 @@
121121
<item quantity="other">%d seconds</item>
122122
</plurals>
123123

124+
<string name="message_option_delete_for_me">Delete Message For Me</string>
125+
124126
<!-- Channel Attachments -->
125127
<string name="channel_attachments_media_loading_more_error">Failed to load more media attachments</string>
126128
<string name="channel_attachments_files_loading_more_error">Failed to load more files attachments</string>

0 commit comments

Comments
 (0)