diff --git a/examples/ExpoMessaging/app/index.tsx b/examples/ExpoMessaging/app/index.tsx
index 14742ae6ea..e484cccbfa 100644
--- a/examples/ExpoMessaging/app/index.tsx
+++ b/examples/ExpoMessaging/app/index.tsx
@@ -1,5 +1,5 @@
import { Alert, Image, Pressable, StyleSheet, View } from 'react-native';
-import { ChannelList } from 'stream-chat-expo';
+import { ChannelList, SqliteClient } from 'stream-chat-expo';
import { useCallback, useContext, useMemo } from 'react';
import { Stack, useRouter } from 'expo-router';
import { ChannelSort } from 'stream-chat';
@@ -19,7 +19,13 @@ const LogoutButton = () => {
const onLogoutHandler = useCallback(() => {
Alert.alert('Logout', 'Are you sure you want to logout?', [
{ text: 'Cancel', style: 'cancel' },
- { text: 'Logout', onPress: logOut },
+ {
+ text: 'Logout',
+ onPress: () => {
+ SqliteClient.resetDB();
+ logOut();
+ },
+ },
]);
}, [logOut]);
diff --git a/examples/ExpoMessaging/components/ChatWrapper.tsx b/examples/ExpoMessaging/components/ChatWrapper.tsx
index 4054f9edc6..d0bf6eff10 100644
--- a/examples/ExpoMessaging/components/ChatWrapper.tsx
+++ b/examples/ExpoMessaging/components/ChatWrapper.tsx
@@ -46,7 +46,7 @@ export const ChatWrapper = ({ children }: PropsWithChildren<{}>) => {
return (
-
+
{children}
diff --git a/examples/ExpoMessaging/yarn.lock b/examples/ExpoMessaging/yarn.lock
index e9c8f552bd..96f43cad27 100644
--- a/examples/ExpoMessaging/yarn.lock
+++ b/examples/ExpoMessaging/yarn.lock
@@ -6063,7 +6063,22 @@ stream-chat-react-native-core@8.1.0:
version "0.0.0"
uid ""
-stream-chat@^9.17.0, stream-chat@^9.9.0:
+stream-chat@^9.23.0:
+ version "9.23.0"
+ resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.23.0.tgz#e7e5cf729861597e7198907c1cab22a57d68a2fc"
+ integrity sha512-UW112HYsLnYb4RMIXBtAouNQCCe0weVzNivjezsw+JKK1b/TX0JLBi+wK25mBUEO+coOGKfXiye6IB3gao8ipw==
+ dependencies:
+ "@types/jsonwebtoken" "^9.0.8"
+ "@types/ws" "^8.5.14"
+ axios "^1.12.2"
+ base64-js "^1.5.1"
+ form-data "^4.0.4"
+ isomorphic-ws "^5.0.0"
+ jsonwebtoken "^9.0.2"
+ linkifyjs "^4.3.2"
+ ws "^8.18.1"
+
+stream-chat@^9.9.0:
version "9.20.3"
resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.20.3.tgz#5f47d6f46d146202c743282f5fb7350f4a640922"
integrity sha512-206Lea0ZAVWbfYZkIwLG5m+++ELD3f8EAEL/YzbMDL++E2vU2WhQ2d1HNb1ROXURZUF0Sy845htTw1rwnahomw==
diff --git a/examples/SampleApp/src/utils/messageActions.tsx b/examples/SampleApp/src/utils/messageActions.tsx
index e462763e22..7dafc4ff79 100644
--- a/examples/SampleApp/src/utils/messageActions.tsx
+++ b/examples/SampleApp/src/utils/messageActions.tsx
@@ -2,6 +2,7 @@ import { Alert } from 'react-native';
import { StreamChat } from 'stream-chat';
import {
Colors,
+ Delete,
messageActions,
MessageActionsParams,
Time,
@@ -20,7 +21,7 @@ export function channelMessageActions({
t: TranslationContextValue['t'];
colors?: typeof Colors;
}) {
- const { dismissOverlay } = params;
+ const { dismissOverlay, deleteForMeMessage } = params;
const actions = messageActions(params);
// We cannot use the useMessageReminder hook here because it is a hook.
@@ -88,6 +89,27 @@ export function channelMessageActions({
title: reminder ? 'Remove Reminder' : 'Remind Me',
icon: ,
});
+ actions.push({
+ action: async () => {
+ Alert.alert('Delete for me', 'Are you sure you want to delete this message for me?', [
+ {
+ text: 'Cancel',
+ style: 'cancel',
+ },
+ {
+ text: 'Delete',
+ onPress: async () => {
+ await deleteForMeMessage?.action();
+ dismissOverlay();
+ },
+ style: 'destructive',
+ },
+ ]);
+ },
+ actionType: 'deleteForMe',
+ icon: ,
+ title: t('Delete for me'),
+ });
return actions;
}
diff --git a/examples/SampleApp/yarn.lock b/examples/SampleApp/yarn.lock
index ff8c1c7832..f2a8f2a2f3 100644
--- a/examples/SampleApp/yarn.lock
+++ b/examples/SampleApp/yarn.lock
@@ -3474,6 +3474,15 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
+axios@^1.12.2:
+ version "1.12.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7"
+ integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==
+ dependencies:
+ follow-redirects "^1.15.6"
+ form-data "^4.0.4"
+ proxy-from-env "^1.1.0"
+
axios@^1.6.0:
version "1.7.9"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a"
@@ -8179,14 +8188,14 @@ stream-chat-react-native-core@8.1.0:
version "0.0.0"
uid ""
-stream-chat@^9.17.0:
- version "9.17.0"
- resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.17.0.tgz#540cf1ea03b08a394d6140696aae8528e9ba9ce2"
- integrity sha512-ys6K73wIVWs5+qsfPJ9wumEUtgbMXYVbH1dhmAZ1oYtQ01dY/avsvt25PYDakVjKeyrnT+y8T/xEzfeF/WDJsg==
+stream-chat@^9.23.0:
+ version "9.23.0"
+ resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.23.0.tgz#e7e5cf729861597e7198907c1cab22a57d68a2fc"
+ integrity sha512-UW112HYsLnYb4RMIXBtAouNQCCe0weVzNivjezsw+JKK1b/TX0JLBi+wK25mBUEO+coOGKfXiye6IB3gao8ipw==
dependencies:
"@types/jsonwebtoken" "^9.0.8"
"@types/ws" "^8.5.14"
- axios "^1.6.0"
+ axios "^1.12.2"
base64-js "^1.5.1"
form-data "^4.0.4"
isomorphic-ws "^5.0.0"
diff --git a/examples/TypeScriptMessaging/yarn.lock b/examples/TypeScriptMessaging/yarn.lock
index 46cd8ec3b9..e5cb3eef85 100644
--- a/examples/TypeScriptMessaging/yarn.lock
+++ b/examples/TypeScriptMessaging/yarn.lock
@@ -2734,6 +2734,15 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
+axios@^1.12.2:
+ version "1.12.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7"
+ integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==
+ dependencies:
+ follow-redirects "^1.15.6"
+ form-data "^4.0.4"
+ proxy-from-env "^1.1.0"
+
axios@^1.6.0:
version "1.7.9"
resolved "https://registry.yarnpkg.com/axios/-/axios-1.7.9.tgz#d7d071380c132a24accda1b2cfc1535b79ec650a"
@@ -7319,14 +7328,14 @@ stream-chat-react-native-core@8.1.0:
version "0.0.0"
uid ""
-stream-chat@^9.17.0:
- version "9.17.0"
- resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.17.0.tgz#540cf1ea03b08a394d6140696aae8528e9ba9ce2"
- integrity sha512-ys6K73wIVWs5+qsfPJ9wumEUtgbMXYVbH1dhmAZ1oYtQ01dY/avsvt25PYDakVjKeyrnT+y8T/xEzfeF/WDJsg==
+stream-chat@^9.23.0:
+ version "9.23.0"
+ resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.23.0.tgz#e7e5cf729861597e7198907c1cab22a57d68a2fc"
+ integrity sha512-UW112HYsLnYb4RMIXBtAouNQCCe0weVzNivjezsw+JKK1b/TX0JLBi+wK25mBUEO+coOGKfXiye6IB3gao8ipw==
dependencies:
"@types/jsonwebtoken" "^9.0.8"
"@types/ws" "^8.5.14"
- axios "^1.6.0"
+ axios "^1.12.2"
base64-js "^1.5.1"
form-data "^4.0.4"
isomorphic-ws "^5.0.0"
diff --git a/package/package.json b/package/package.json
index 99ba8839f6..5037c56ff2 100644
--- a/package/package.json
+++ b/package/package.json
@@ -79,7 +79,7 @@
"path": "0.12.7",
"react-native-markdown-package": "1.8.2",
"react-native-url-polyfill": "^2.0.0",
- "stream-chat": "^9.17.0",
+ "stream-chat": "^9.23.0",
"use-sync-external-store": "^1.5.0"
},
"peerDependencies": {
diff --git a/package/src/components/Channel/Channel.tsx b/package/src/components/Channel/Channel.tsx
index 523e2d7297..29ac2ca4b2 100644
--- a/package/src/components/Channel/Channel.tsx
+++ b/package/src/components/Channel/Channel.tsx
@@ -9,6 +9,7 @@ import {
Channel as ChannelClass,
ChannelState,
Channel as ChannelType,
+ DeleteMessageOptions,
EventHandler,
LocalMessage,
localMessageToNewMessagePayload,
@@ -322,6 +323,7 @@ export type ChannelPropsWithContext = Pick &
| 'handleBan'
| 'handleCopy'
| 'handleDelete'
+ | 'handleDeleteForMe'
| 'handleEdit'
| 'handleFlag'
| 'handleMarkUnread'
@@ -580,6 +582,7 @@ const ChannelWithContext = (props: PropsWithChildren) =
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
@@ -1509,7 +1512,15 @@ const ChannelWithContext = (props: PropsWithChildren) =
});
const deleteMessage: MessagesContextValue['deleteMessage'] = useStableCallback(
- async (message, hardDelete = false) => {
+ async (message, optionsOrHardDelete = false) => {
+ let options: DeleteMessageOptions = {};
+ if (typeof optionsOrHardDelete === 'boolean') {
+ options = optionsOrHardDelete ? { hardDelete: true } : {};
+ } else if (optionsOrHardDelete?.deleteForMe) {
+ options = { deleteForMe: true };
+ } else if (optionsOrHardDelete?.hardDelete) {
+ options = { hardDelete: true };
+ }
if (!channel.id) {
throw new Error('Channel has not been initialized yet');
}
@@ -1528,7 +1539,7 @@ const ChannelWithContext = (props: PropsWithChildren) =
threadInstance?.upsertReplyLocally({ message: updatedMessage });
- const data = await client.deleteMessage(message.id, hardDelete);
+ const data = await client.deleteMessage(message.id, options);
if (data?.message) {
updateMessage({ ...data.message });
@@ -1837,6 +1848,7 @@ const ChannelWithContext = (props: PropsWithChildren) =
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
diff --git a/package/src/components/Channel/hooks/useCreateMessagesContext.ts b/package/src/components/Channel/hooks/useCreateMessagesContext.ts
index 71f3e02795..3ac1e7236d 100644
--- a/package/src/components/Channel/hooks/useCreateMessagesContext.ts
+++ b/package/src/components/Channel/hooks/useCreateMessagesContext.ts
@@ -33,6 +33,7 @@ export const useCreateMessagesContext = ({
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
@@ -150,6 +151,7 @@ export const useCreateMessagesContext = ({
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
diff --git a/package/src/components/Message/Message.tsx b/package/src/components/Message/Message.tsx
index 1f10124150..6a677616ae 100644
--- a/package/src/components/Message/Message.tsx
+++ b/package/src/components/Message/Message.tsx
@@ -121,6 +121,7 @@ export type MessagePressableHandlerPayload = PressableHandlerPayload & {
export type MessageActionHandlers = {
copyMessage: () => void;
deleteMessage: () => void;
+ deleteForMeMessage: () => void;
editMessage: () => void;
flagMessage: () => void;
markUnread: () => Promise;
@@ -155,6 +156,7 @@ export type MessagePropsWithContext = Pick<
| 'handleBan'
| 'handleCopy'
| 'handleDelete'
+ | 'handleDeleteForMe'
| 'handleEdit'
| 'handleFlag'
| 'handleMarkUnread'
@@ -229,6 +231,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
@@ -487,6 +490,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
const {
handleCopyMessage,
handleDeleteMessage,
+ handleDeleteForMeMessage,
handleEditMessage,
handleFlagMessage,
handleMarkUnreadMessage,
@@ -514,6 +518,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
banUser,
copyMessage,
deleteMessage,
+ deleteForMeMessage,
editMessage,
flagMessage,
handleReaction,
@@ -534,6 +539,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
@@ -565,6 +571,7 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
: messageActionsProp({
banUser,
copyMessage,
+ deleteForMeMessage,
deleteMessage,
dismissOverlay,
editMessage,
@@ -582,10 +589,12 @@ const MessageWithContext = (props: MessagePropsWithContext) => {
showMessageReactions,
threadReply,
unpinMessage,
+ updateMessage,
});
const actionHandlers: MessageActionHandlers = {
copyMessage: handleCopyMessage,
+ deleteForMeMessage: handleDeleteForMeMessage,
deleteMessage: handleDeleteMessage,
editMessage: handleEditMessage,
flagMessage: handleFlagMessage,
diff --git a/package/src/components/Message/hooks/useMessageActionHandlers.ts b/package/src/components/Message/hooks/useMessageActionHandlers.ts
index 3f835dca3c..872cd5e6eb 100644
--- a/package/src/components/Message/hooks/useMessageActionHandlers.ts
+++ b/package/src/components/Message/hooks/useMessageActionHandlers.ts
@@ -66,6 +66,14 @@ export const useMessageActionHandlers = ({
);
};
+ const handleDeleteForMeMessage = async () => {
+ if (!message.id) {
+ return;
+ }
+
+ await deleteMessage(message, { deleteForMe: true });
+ };
+
const handleToggleMuteUser = async () => {
if (!message.user?.id) {
return;
@@ -182,6 +190,7 @@ export const useMessageActionHandlers = ({
return {
handleCopyMessage,
+ handleDeleteForMeMessage,
handleDeleteMessage,
handleEditMessage,
handleFlagMessage,
diff --git a/package/src/components/Message/hooks/useMessageActions.tsx b/package/src/components/Message/hooks/useMessageActions.tsx
index 7f45b451ec..9f307f56fd 100644
--- a/package/src/components/Message/hooks/useMessageActions.tsx
+++ b/package/src/components/Message/hooks/useMessageActions.tsx
@@ -39,6 +39,7 @@ export type MessageActionsHookProps = Pick<
| 'handleBan'
| 'handleCopy'
| 'handleDelete'
+ | 'handleDeleteForMe'
| 'handleEdit'
| 'handleFlag'
| 'handleQuotedReply'
@@ -73,6 +74,7 @@ export const useMessageActions = ({
handleBan,
handleCopy,
handleDelete,
+ handleDeleteForMe,
handleEdit,
handleFlag,
handleMarkUnread,
@@ -101,6 +103,7 @@ export const useMessageActions = ({
const {
handleCopyMessage,
handleDeleteMessage,
+ handleDeleteForMeMessage,
handleEditMessage,
handleFlagMessage,
handleMarkUnreadMessage,
@@ -182,6 +185,19 @@ export const useMessageActions = ({
titleStyle: { color: accent_red },
};
+ const deleteForMeMessage: MessageActionType = {
+ action: () => {
+ dismissOverlay();
+ if (handleDeleteForMe) {
+ handleDeleteForMe(message);
+ }
+ handleDeleteForMeMessage();
+ },
+ actionType: 'deleteForMeMessage',
+ icon: ,
+ title: t('Delete for me'),
+ };
+
const editMessage: MessageActionType = {
action: () => {
dismissOverlay();
@@ -319,6 +335,7 @@ export const useMessageActions = ({
return {
banUser,
copyMessage,
+ deleteForMeMessage,
deleteMessage,
editMessage,
flagMessage,
diff --git a/package/src/components/Message/utils/messageActions.ts b/package/src/components/Message/utils/messageActions.ts
index 8d019238b9..d7973cc2db 100644
--- a/package/src/components/Message/utils/messageActions.ts
+++ b/package/src/components/Message/utils/messageActions.ts
@@ -1,4 +1,5 @@
import type { MessageContextValue } from '../../../contexts/messageContext/MessageContext';
+import type { MessagesContextValue } from '../../../contexts/messagesContext/MessagesContext';
import type { OwnCapabilitiesContextValue } from '../../../contexts/ownCapabilitiesContext/OwnCapabilitiesContext';
import { isClipboardAvailable } from '../../../native';
@@ -25,7 +26,10 @@ export type MessageActionsParams = {
showMessageReactions: boolean;
threadReply: MessageActionType;
unpinMessage: MessageActionType;
-} & Pick;
+ // Optional Actions
+ deleteForMeMessage?: MessageActionType;
+} & Pick &
+ Pick;
export type MessageActionsProp = (param: MessageActionsParams) => MessageActionType[];
diff --git a/package/src/contexts/messagesContext/MessagesContext.tsx b/package/src/contexts/messagesContext/MessagesContext.tsx
index f919028760..3e5441292c 100644
--- a/package/src/contexts/messagesContext/MessagesContext.tsx
+++ b/package/src/contexts/messagesContext/MessagesContext.tsx
@@ -7,6 +7,7 @@ import type {
Channel,
ChannelState,
CommandSuggestion,
+ DeleteMessageOptions,
LocalMessage,
MessageResponse,
} from 'stream-chat';
@@ -114,7 +115,11 @@ export type MessagesContextValue = Pick;
- deleteMessage: (message: LocalMessage, hardDelete?: boolean) => Promise;
+ // FIXME: Remove the signature with optionsOrHardDelete boolean with the next major release
+ deleteMessage: (
+ message: LocalMessage,
+ optionsOrHardDelete?: boolean | DeleteMessageOptions,
+ ) => Promise;
deleteReaction: (type: string, messageId: string) => Promise;
/** Should keyboard be dismissed when messaged is touched */
@@ -404,6 +409,8 @@ export type MessagesContextValue = Pick Promise;
/** Handler to access when a copy message action is invoked */
handleCopy?: (message: LocalMessage) => Promise;
+ /** Handler to access when a delete for me message action is invoked */
+ handleDeleteForMe?: (message: LocalMessage) => Promise;
/** Handler to access when a delete message action is invoked */
handleDelete?: (message: LocalMessage) => Promise;
/** Handler to access when an edit message action is invoked */
diff --git a/package/src/i18n/en.json b/package/src/i18n/en.json
index 3e9465eda0..9837a87b65 100644
--- a/package/src/i18n/en.json
+++ b/package/src/i18n/en.json
@@ -23,6 +23,7 @@
"Create Poll": "Create Poll",
"Delete": "Delete",
"Delete Message": "Delete Message",
+ "Delete for me": "Delete for me",
"Device camera is used to take photos or videos.": "Device camera is used to take photos or videos.",
"Device gallery permissions is used to take photos or videos.": "Device gallery permissions is used to take photos or videos.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Do you want to send a copy of this message to a moderator for further investigation?",
diff --git a/package/src/i18n/es.json b/package/src/i18n/es.json
index 74657b6a1b..4daf4147d7 100644
--- a/package/src/i18n/es.json
+++ b/package/src/i18n/es.json
@@ -23,6 +23,7 @@
"Create Poll": "Crear encuesta",
"Delete": "Eliminar",
"Delete Message": "Eliminar mensaje",
+ "Delete for me": "Eliminar para mí",
"Device camera is used to take photos or videos.": "La cámara del dispositivo se utiliza para tomar fotografías o vídeos.",
"Device gallery permissions is used to take photos or videos.": "Los permisos de la galería del dispositivo se utilizan para tomar fotos o videos.",
"Do you want to send a copy of this message to a moderator for further investigation?": "¿Deseas enviar una copia de este mensaje a un moderador para una investigación adicional?",
diff --git a/package/src/i18n/fr.json b/package/src/i18n/fr.json
index 7ac6cfe1ea..3227ab9290 100644
--- a/package/src/i18n/fr.json
+++ b/package/src/i18n/fr.json
@@ -23,6 +23,7 @@
"Create Poll": "Créer un sondage",
"Delete": "Supprimer",
"Delete Message": "Supprimer un message",
+ "Delete for me": "Supprimer pour moi",
"Device camera is used to take photos or videos.": "L'appareil photo de l'appareil est utilisé pour prendre des photos ou des vidéos.",
"Device gallery permissions is used to take photos or videos.": "Les autorisations de la galerie de l'appareil sont utilisées pour prendre des photos ou des vidéos.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Voulez-vous envoyer une copie de ce message à un modérateur pour une enquête plus approfondie?",
diff --git a/package/src/i18n/he.json b/package/src/i18n/he.json
index 2e913471ee..376f6294eb 100644
--- a/package/src/i18n/he.json
+++ b/package/src/i18n/he.json
@@ -23,6 +23,7 @@
"Create Poll": "צור סקר",
"Delete": "מחק",
"Delete Message": "מחק/י הודעה",
+ "Delete for me": "מחק עבורי",
"Device camera is used to take photos or videos.": "מצלמת המכשיר משמשת לצילום תמונות או סרטונים.",
"Device gallery permissions is used to take photos or videos.": "הרשאות גלריית המכשיר משמשות לצילום תמונות או סרטונים.",
"Do you want to send a copy of this message to a moderator for further investigation?": "האם את/ה רוצה לשלוח עותק של הודעה זו למנחה להמשך חקירה?",
diff --git a/package/src/i18n/hi.json b/package/src/i18n/hi.json
index 5f2b5bcb4a..2ea6b2a80d 100644
--- a/package/src/i18n/hi.json
+++ b/package/src/i18n/hi.json
@@ -23,6 +23,7 @@
"Create Poll": "सर्वेक्षण बनाएं",
"Delete": "हटाएं",
"Delete Message": "मैसेज को डिलीट करे",
+ "Delete for me": "मुझे हटाएं",
"Device camera is used to take photos or videos.": "डिवाइस कैमरे का उपयोग फ़ोटो या वीडियो लेने के लिए किया जाता है।",
"Device gallery permissions is used to take photos or videos.": "डिवाइस गैलरी की अनुमतियों का उपयोग फोटो या वीडियो लेने के लिए किया जाता है।",
"Do you want to send a copy of this message to a moderator for further investigation?": "क्या आप इस संदेश की एक प्रति आगे की जाँच के लिए किसी मॉडरेटर को भेजना चाहते हैं?",
diff --git a/package/src/i18n/it.json b/package/src/i18n/it.json
index 728d8a44d5..e89c76d4ba 100644
--- a/package/src/i18n/it.json
+++ b/package/src/i18n/it.json
@@ -23,6 +23,7 @@
"Create Poll": "Crea sondaggio",
"Delete": "Elimina",
"Delete Message": "Cancella il Messaggio",
+ "Delete for me": "Elimina per me",
"Device camera is used to take photos or videos.": "La fotocamera del dispositivo viene utilizzata per scattare foto o video.",
"Device gallery permissions is used to take photos or videos.": "Le autorizzazioni della galleria del dispositivo vengono utilizzate per scattare foto o video.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Vuoi inviare una copia di questo messaggio a un moderatore per ulteriori indagini?",
diff --git a/package/src/i18n/ja.json b/package/src/i18n/ja.json
index 099a53591d..4394088f31 100644
--- a/package/src/i18n/ja.json
+++ b/package/src/i18n/ja.json
@@ -23,6 +23,7 @@
"Create Poll": "アンケートを作成",
"Delete": "消去",
"Delete Message": "メッセージを削除",
+ "Delete for me": "自分で削除",
"Device camera is used to take photos or videos.": "デバイスのカメラは写真やビデオの撮影に使用されます。",
"Device gallery permissions is used to take photos or videos.": "デバイスギャラリーの権限は写真やビデオを撮るために使用されます。",
"Do you want to send a copy of this message to a moderator for further investigation?": "このメッセージのコピーをモデレーターに送信して、さらに調査しますか?",
diff --git a/package/src/i18n/ko.json b/package/src/i18n/ko.json
index c297cbd67b..a9d61ef72a 100644
--- a/package/src/i18n/ko.json
+++ b/package/src/i18n/ko.json
@@ -23,6 +23,7 @@
"Create Poll": "투표 생성",
"Delete": "삭제",
"Delete Message": "메시지 삭제",
+ "Delete for me": "나 삭제",
"Device camera is used to take photos or videos.": "기기 카메라는 사진이나 동영상을 촬영하는 데 사용됩니다.",
"Device gallery permissions is used to take photos or videos.": "장치 갤러리 권한은 사진 또는 비디오를 촬영하는 데 사용됩니다.",
"Do you want to send a copy of this message to a moderator for further investigation?": "이 메시지의 복사본을 운영자에게 보내 추가 조사를합니까?",
diff --git a/package/src/i18n/nl.json b/package/src/i18n/nl.json
index 0c68500e11..eada070bd6 100644
--- a/package/src/i18n/nl.json
+++ b/package/src/i18n/nl.json
@@ -23,6 +23,7 @@
"Create Poll": "Peiling aanmaken",
"Delete": "Verwijderen",
"Delete Message": "Verwijder bericht",
+ "Delete for me": "Verwijder voor mij",
"Device camera is used to take photos or videos.": "De camera van het apparaat wordt gebruikt om foto's of video's te maken.",
"Device gallery permissions is used to take photos or videos.": "Apparaatgallerijmachtigingen worden gebruikt om foto’s of video’s te maken.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Wil je een kopie van dit bericht naar een moderator sturen voor verder onderzoek?",
diff --git a/package/src/i18n/pt-br.json b/package/src/i18n/pt-br.json
index d8e975f378..4fb3d21991 100644
--- a/package/src/i18n/pt-br.json
+++ b/package/src/i18n/pt-br.json
@@ -23,6 +23,7 @@
"Create Poll": "Criar enquete",
"Delete": "Excluir",
"Delete Message": "Excluir Mensagem",
+ "Delete for me": "Excluir para mim",
"Device camera is used to take photos or videos.": "A câmera do dispositivo é usada para tirar fotos ou vídeos.",
"Device gallery permissions is used to take photos or videos.": "As permissões da galeria do dispositivo são usadas para tirar fotos ou vídeos.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Deseja enviar uma cópia desta mensagem para um moderador para investigação adicional?",
diff --git a/package/src/i18n/ru.json b/package/src/i18n/ru.json
index ea29cf9806..5f4a81f7e5 100644
--- a/package/src/i18n/ru.json
+++ b/package/src/i18n/ru.json
@@ -24,6 +24,7 @@
"Create Poll": "Создать опрос",
"Delete": "удалять",
"Delete Message": "Удалить сообщение",
+ "Delete for me": "Удалить для себя",
"Device camera is used to take photos or videos.": "Камера устройства используется для съемки фотографий или видео.",
"Device gallery permissions is used to take photos or videos.": "Разрешения галереи устройства используются для съемки фото или видео.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Вы хотите отправить копию этого сообщения модератору для дальнейшего изучения?",
diff --git a/package/src/i18n/tr.json b/package/src/i18n/tr.json
index 3305b84b6a..6f2b955938 100644
--- a/package/src/i18n/tr.json
+++ b/package/src/i18n/tr.json
@@ -23,6 +23,7 @@
"Create Poll": "Anket oluştur",
"Delete": "Sil",
"Delete Message": "Mesajı Sil",
+ "Delete for me": "Benim için sil",
"Device camera is used to take photos or videos.": "Cihaz kamerası fotoğraf veya video çekmek için kullanılır.",
"Device gallery permissions is used to take photos or videos.": "Cihaz galerisi izinleri fotoğraf veya video çekmek için kullanılır.",
"Do you want to send a copy of this message to a moderator for further investigation?": "Detaylı inceleme için bu mesajın kopyasını moderatöre göndermek istiyor musunuz?",
diff --git a/package/src/store/SqliteClient.ts b/package/src/store/SqliteClient.ts
index 74380960c6..103eaa25e0 100644
--- a/package/src/store/SqliteClient.ts
+++ b/package/src/store/SqliteClient.ts
@@ -28,7 +28,7 @@ import type { PreparedBatchQueries, PreparedQueries, Scalar, Table } from './typ
* This way usage @op-engineering/op-sqlite package is scoped to a single class/file.
*/
export class SqliteClient {
- static dbVersion = 13;
+ static dbVersion = 14;
static dbName = DB_NAME;
static dbLocation = DB_LOCATION;
diff --git a/package/src/store/apis/softDeleteMessage.ts b/package/src/store/apis/softDeleteMessage.ts
index e88964f358..ce9c99a104 100644
--- a/package/src/store/apis/softDeleteMessage.ts
+++ b/package/src/store/apis/softDeleteMessage.ts
@@ -1,25 +1,25 @@
-import { MessageLabel } from 'stream-chat';
+import { DBDeleteMessageType, MessageLabel } from 'stream-chat';
import { createUpdateQuery } from '../sqlite-utils/createUpdateQuery';
import { SqliteClient } from '../SqliteClient';
export const softDeleteMessage = async ({
+ deleteForMe = false,
execute = true,
id,
-}: {
- id: string;
- execute?: boolean;
-}) => {
+}: DBDeleteMessageType) => {
const query = createUpdateQuery(
'messages',
{
- deletedAt: new Date().toISOString(),
+ deletedAt: deleteForMe ? undefined : new Date().toISOString(),
+ deletedForMe: deleteForMe,
type: 'deleted' as MessageLabel,
},
{ id },
);
SqliteClient.logger?.('info', 'softDeleteMessage', {
+ deleteForMe,
execute,
id,
});
diff --git a/package/src/store/mappers/mapMessageToStorable.ts b/package/src/store/mappers/mapMessageToStorable.ts
index f307355af2..ac166d7c98 100644
--- a/package/src/store/mappers/mapMessageToStorable.ts
+++ b/package/src/store/mappers/mapMessageToStorable.ts
@@ -12,6 +12,7 @@ export const mapMessageToStorable = (
cid,
created_at,
deleted_at,
+ deleted_for_me,
id,
// eslint-disable-next-line @typescript-eslint/no-unused-vars
latest_reactions,
@@ -37,6 +38,7 @@ export const mapMessageToStorable = (
cid: cid || '',
createdAt: mapDateTimeToStorable(created_at),
deletedAt: mapDateTimeToStorable(deleted_at),
+ deletedForMe: deleted_for_me,
extraData: JSON.stringify(extraData),
id,
messageTextUpdatedAt: mapDateTimeToStorable(message_text_updated_at),
diff --git a/package/src/store/mappers/mapStorableToMessage.ts b/package/src/store/mappers/mapStorableToMessage.ts
index 30ca649ee5..e4b6459466 100644
--- a/package/src/store/mappers/mapStorableToMessage.ts
+++ b/package/src/store/mappers/mapStorableToMessage.ts
@@ -24,6 +24,7 @@ export const mapStorableToMessage = ({
const {
createdAt,
deletedAt,
+ deletedForMe,
extraData,
messageTextUpdatedAt,
poll_id,
@@ -42,6 +43,7 @@ export const mapStorableToMessage = ({
attachments: messageRow.attachments ? JSON.parse(messageRow.attachments) : [],
created_at: createdAt,
deleted_at: deletedAt,
+ deleted_for_me: deletedForMe,
latest_reactions: latestReactions,
message_text_updated_at: messageTextUpdatedAt,
own_reactions: ownReactions,
diff --git a/package/src/store/schema.ts b/package/src/store/schema.ts
index 50ec7ee2aa..21de2afed4 100644
--- a/package/src/store/schema.ts
+++ b/package/src/store/schema.ts
@@ -170,6 +170,7 @@ export const tables: Tables = {
cid: 'TEXT NOT NULL',
createdAt: 'TEXT',
deletedAt: 'TEXT',
+ deletedForMe: 'BOOLEAN DEFAULT FALSE',
extraData: 'TEXT',
id: 'TEXT',
messageTextUpdatedAt: 'TEXT',
@@ -408,6 +409,7 @@ export type Schema = {
cid: string;
createdAt: string;
deletedAt: string;
+ deletedForMe?: boolean;
extraData: string;
id: string;
messageTextUpdatedAt: string;
diff --git a/package/yarn.lock b/package/yarn.lock
index b2258ec83a..855c6b8a95 100644
--- a/package/yarn.lock
+++ b/package/yarn.lock
@@ -2956,13 +2956,13 @@ available-typed-arrays@^1.0.7:
dependencies:
possible-typed-array-names "^1.0.0"
-axios@^1.6.0:
- version "1.8.1"
- resolved "https://registry.yarnpkg.com/axios/-/axios-1.8.1.tgz#7c118d2146e9ebac512b7d1128771cdd738d11e3"
- integrity sha512-NN+fvwH/kV01dYUQ3PTOZns4LWtWhOFCAhQ/pHb88WQ1hNe5V/dvFwc4VJcDL11LT9xSX0QtsR8sWUuyOuOq7g==
+axios@^1.12.2:
+ version "1.12.2"
+ resolved "https://registry.yarnpkg.com/axios/-/axios-1.12.2.tgz#6c307390136cf7a2278d09cec63b136dfc6e6da7"
+ integrity sha512-vMJzPewAlRyOgxV2dU0Cuz2O8zzzx9VYtbJOaBgXFeLc4IV/Eg50n4LowmehOOR61S8ZMpc2K5Sa7g6A4jfkUw==
dependencies:
follow-redirects "^1.15.6"
- form-data "^4.0.0"
+ form-data "^4.0.4"
proxy-from-env "^1.1.0"
b4a@^1.6.4:
@@ -4651,16 +4651,6 @@ foreground-child@^3.1.0:
cross-spawn "^7.0.6"
signal-exit "^4.0.1"
-form-data@^4.0.0:
- version "4.0.2"
- resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.2.tgz#35cabbdd30c3ce73deb2c42d3c8d3ed9ca51794c"
- integrity sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w==
- dependencies:
- asynckit "^0.4.0"
- combined-stream "^1.0.8"
- es-set-tostringtag "^2.1.0"
- mime-types "^2.1.12"
-
form-data@^4.0.4:
version "4.0.4"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-4.0.4.tgz#784cdcce0669a9d68e94d11ac4eea98088edd2c4"
@@ -8354,14 +8344,14 @@ statuses@~1.5.0:
resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.5.0.tgz#161c7dac177659fd9811f43771fa99381478628c"
integrity sha512-OpZ3zP+jT1PI7I8nemJX4AKmAX070ZkYPVWV/AaKTJl+tXCTGyVdC1a4SL8RUQYEwk/f34ZX8UTykN68FwrqAA==
-stream-chat@^9.17.0:
- version "9.17.0"
- resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.17.0.tgz#540cf1ea03b08a394d6140696aae8528e9ba9ce2"
- integrity sha512-ys6K73wIVWs5+qsfPJ9wumEUtgbMXYVbH1dhmAZ1oYtQ01dY/avsvt25PYDakVjKeyrnT+y8T/xEzfeF/WDJsg==
+stream-chat@^9.23.0:
+ version "9.23.0"
+ resolved "https://registry.yarnpkg.com/stream-chat/-/stream-chat-9.23.0.tgz#e7e5cf729861597e7198907c1cab22a57d68a2fc"
+ integrity sha512-UW112HYsLnYb4RMIXBtAouNQCCe0weVzNivjezsw+JKK1b/TX0JLBi+wK25mBUEO+coOGKfXiye6IB3gao8ipw==
dependencies:
"@types/jsonwebtoken" "^9.0.8"
"@types/ws" "^8.5.14"
- axios "^1.6.0"
+ axios "^1.12.2"
base64-js "^1.5.1"
form-data "^4.0.4"
isomorphic-ws "^5.0.0"