|
@@ -55,7 +55,12 @@ import { SheetManager } from 'react-native-actions-sheet';
|
|
|
import { NAVIGATION_PAGES } from 'src/types';
|
|
import { NAVIGATION_PAGES } from 'src/types';
|
|
|
import { usePushNotification } from 'src/contexts/PushNotificationContext';
|
|
import { usePushNotification } from 'src/contexts/PushNotificationContext';
|
|
|
import ReactionsListModal from '../Components/ReactionsListModal';
|
|
import ReactionsListModal from '../Components/ReactionsListModal';
|
|
|
-import { dismissChatNotifications, isMessageEdited } from '../utils';
|
|
|
|
|
|
|
+import {
|
|
|
|
|
+ compressImageWithProgress,
|
|
|
|
|
+ compressVideoWithProgress,
|
|
|
|
|
+ dismissChatNotifications,
|
|
|
|
|
+ isMessageEdited
|
|
|
|
|
+} from '../utils';
|
|
|
import { useMessagesStore } from 'src/stores/unreadMessagesStore';
|
|
import { useMessagesStore } from 'src/stores/unreadMessagesStore';
|
|
|
import FileViewer from 'react-native-file-viewer';
|
|
import FileViewer from 'react-native-file-viewer';
|
|
|
import * as FileSystem from 'expo-file-system/legacy';
|
|
import * as FileSystem from 'expo-file-system/legacy';
|
|
@@ -130,7 +135,8 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
const {
|
|
const {
|
|
|
data: chatData,
|
|
data: chatData,
|
|
|
refetch,
|
|
refetch,
|
|
|
- isFetching
|
|
|
|
|
|
|
+ isFetching,
|
|
|
|
|
+ isFetched
|
|
|
} = usePostGetChatWithQuery(token, id, 50, prevThenMessageId, true);
|
|
} = usePostGetChatWithQuery(token, id, 50, prevThenMessageId, true);
|
|
|
|
|
|
|
|
const swipeableRowRef = useRef<Swipeable | null>(null);
|
|
const swipeableRowRef = useRef<Swipeable | null>(null);
|
|
@@ -378,22 +384,17 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
|
|
|
|
|
const onSendMedia = useCallback(
|
|
const onSendMedia = useCallback(
|
|
|
async (files: { uri: string; type: 'image' | 'video' }[]) => {
|
|
async (files: { uri: string; type: 'image' | 'video' }[]) => {
|
|
|
- for (const file of files) {
|
|
|
|
|
- // if (file.type === 'image') {
|
|
|
|
|
- // const compressedUri = await compressImage(file.uri);
|
|
|
|
|
- // file.uri = compressedUri;
|
|
|
|
|
- // }
|
|
|
|
|
-
|
|
|
|
|
- const formatedReply = replyMessage
|
|
|
|
|
- ? {
|
|
|
|
|
- text: replyMessage.text,
|
|
|
|
|
- id: replyMessage._id,
|
|
|
|
|
- name: replyMessage.user._id === id ? userName : 'Me',
|
|
|
|
|
- sender: replyMessage.user._id
|
|
|
|
|
- }
|
|
|
|
|
- : null;
|
|
|
|
|
|
|
+ const formatedReply = replyMessage
|
|
|
|
|
+ ? {
|
|
|
|
|
+ text: replyMessage.text,
|
|
|
|
|
+ id: replyMessage._id,
|
|
|
|
|
+ name: replyMessage.user._id === id ? userName : 'Me',
|
|
|
|
|
+ sender: replyMessage.user._id
|
|
|
|
|
+ }
|
|
|
|
|
+ : null;
|
|
|
|
|
|
|
|
- await createOptimisticMessage({
|
|
|
|
|
|
|
+ for (const file of files) {
|
|
|
|
|
+ const optimisticId = await createOptimisticMessage({
|
|
|
chatUid: id,
|
|
chatUid: id,
|
|
|
currentUserId: +currentUserId,
|
|
currentUserId: +currentUserId,
|
|
|
uiAttachment: {
|
|
uiAttachment: {
|
|
@@ -409,12 +410,52 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
type: file.type,
|
|
type: file.type,
|
|
|
name: file.uri.split('/').pop()
|
|
name: file.uri.split('/').pop()
|
|
|
},
|
|
},
|
|
|
- replyMessage: formatedReply
|
|
|
|
|
|
|
+ replyMessage: formatedReply,
|
|
|
|
|
+ shouldAddDirty: false
|
|
|
});
|
|
});
|
|
|
|
|
+
|
|
|
|
|
+ const updateProgress = async (progress: number) => {};
|
|
|
|
|
+
|
|
|
|
|
+ let compressedUri = file.uri;
|
|
|
|
|
+
|
|
|
|
|
+ if (file.type === 'image') {
|
|
|
|
|
+ compressedUri = await compressImageWithProgress(file.uri, updateProgress);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ if (file.type === 'video') {
|
|
|
|
|
+ compressedUri = await compressVideoWithProgress(file.uri, updateProgress);
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ const optimisticMessage = await findMsgRecord(optimisticId, id);
|
|
|
|
|
+
|
|
|
|
|
+ if (optimisticMessage) {
|
|
|
|
|
+ await database.write(async () => {
|
|
|
|
|
+ optimisticMessage.update((m) => {
|
|
|
|
|
+ m.attachment = JSON.stringify({
|
|
|
|
|
+ ...JSON.parse(m.attachment ?? '{}'),
|
|
|
|
|
+ local_uri: compressedUri
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ addMessageDirtyAction(optimisticMessage, {
|
|
|
|
|
+ type: 'send',
|
|
|
|
|
+ value: {
|
|
|
|
|
+ text,
|
|
|
|
|
+ currentUid: currentUserId,
|
|
|
|
|
+ attachment: {
|
|
|
|
|
+ uri: compressedUri,
|
|
|
|
|
+ type: file.type,
|
|
|
|
|
+ name: file.uri.split('/').pop()
|
|
|
|
|
+ },
|
|
|
|
|
+ reply_to_id: formatedReply ? formatedReply.id : -1,
|
|
|
|
|
+ replyMessage: formatedReply
|
|
|
|
|
+ }
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ });
|
|
|
|
|
+ }
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
clearReplyMessage();
|
|
clearReplyMessage();
|
|
|
-
|
|
|
|
|
await triggerMessagePush(token, sendWsEvent);
|
|
await triggerMessagePush(token, sendWsEvent);
|
|
|
},
|
|
},
|
|
|
[replyMessage]
|
|
[replyMessage]
|
|
@@ -1041,7 +1082,10 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
}, []);
|
|
}, []);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- if (!chatData?.messages?.length) return;
|
|
|
|
|
|
|
+ if (!chatData?.messages?.length) {
|
|
|
|
|
+ setHasMoreMessages(false);
|
|
|
|
|
+ return;
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
upsertMessagesIntoDB({ chatUid: id, apiMessages: chatData.messages });
|
|
upsertMessagesIntoDB({ chatUid: id, apiMessages: chatData.messages });
|
|
|
|
|
|
|
@@ -1055,7 +1099,7 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
}, [chatData]);
|
|
}, [chatData]);
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
useEffect(() => {
|
|
|
- if (isFetching) return;
|
|
|
|
|
|
|
+ if (!isFetched || isFetching) return;
|
|
|
if (
|
|
if (
|
|
|
giftedMessages?.length === 0 &&
|
|
giftedMessages?.length === 0 &&
|
|
|
!modalInfo.visible &&
|
|
!modalInfo.visible &&
|
|
@@ -1065,7 +1109,7 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
textInputRef.current?.focus();
|
|
textInputRef.current?.focus();
|
|
|
}, 500);
|
|
}, 500);
|
|
|
}
|
|
}
|
|
|
- }, [modalInfo, isFetching]);
|
|
|
|
|
|
|
+ }, [isFetched]);
|
|
|
|
|
|
|
|
const loadEarlierMessages = async () => {
|
|
const loadEarlierMessages = async () => {
|
|
|
if (isLoadingEarlier || !hasMoreMessages || !giftedMessages) return;
|
|
if (isLoadingEarlier || !hasMoreMessages || !giftedMessages) return;
|
|
@@ -1108,47 +1152,50 @@ const ChatScreen = ({ route }: { route: any }) => {
|
|
|
|
|
|
|
|
const sentToServer = useRef<Set<number>>(new Set());
|
|
const sentToServer = useRef<Set<number>>(new Set());
|
|
|
|
|
|
|
|
- const handleViewableItemsChanged = async ({ viewableItems }: { viewableItems: any[] }) => {
|
|
|
|
|
- const newViewableUnreadMessages = viewableItems
|
|
|
|
|
- .filter(
|
|
|
|
|
- (item) =>
|
|
|
|
|
- !item.item.received &&
|
|
|
|
|
- !item.item.deleted &&
|
|
|
|
|
- !item.item.system &&
|
|
|
|
|
- item.item.user._id === id &&
|
|
|
|
|
- !sentToServer.current.has(item.item._id)
|
|
|
|
|
- )
|
|
|
|
|
- .map((item) => item.item._id);
|
|
|
|
|
-
|
|
|
|
|
- if (newViewableUnreadMessages.length > 0) {
|
|
|
|
|
- const messagesToUpdate = await database
|
|
|
|
|
- .get<Message>('messages')
|
|
|
|
|
- .query(
|
|
|
|
|
- Q.where('chat_key', 'u:' + id),
|
|
|
|
|
- Q.where('message_id', Q.oneOf(newViewableUnreadMessages))
|
|
|
|
|
|
|
+ const handleViewableItemsChanged = _.throttle(
|
|
|
|
|
+ async ({ viewableItems }: { viewableItems: any[] }) => {
|
|
|
|
|
+ const newViewableUnreadMessages = viewableItems
|
|
|
|
|
+ .filter(
|
|
|
|
|
+ (item) =>
|
|
|
|
|
+ !item.item.received &&
|
|
|
|
|
+ !item.item.deleted &&
|
|
|
|
|
+ !item.item.system &&
|
|
|
|
|
+ item.item.user._id === id &&
|
|
|
|
|
+ !sentToServer.current.has(item.item._id)
|
|
|
)
|
|
)
|
|
|
- .fetch();
|
|
|
|
|
-
|
|
|
|
|
- if (messagesToUpdate.length > 0) {
|
|
|
|
|
- await database.write(async () => {
|
|
|
|
|
- messagesToUpdate.forEach((msg: Message) => {
|
|
|
|
|
- msg.update((r) => {
|
|
|
|
|
- r.status = 3;
|
|
|
|
|
- addMessageDirtyAction(r, {
|
|
|
|
|
- type: 'read',
|
|
|
|
|
- value: { messagesIds: [msg.messageId] }
|
|
|
|
|
|
|
+ .map((item) => item.item._id);
|
|
|
|
|
+
|
|
|
|
|
+ if (newViewableUnreadMessages.length > 0) {
|
|
|
|
|
+ const messagesToUpdate = await database
|
|
|
|
|
+ .get<Message>('messages')
|
|
|
|
|
+ .query(
|
|
|
|
|
+ Q.where('chat_key', 'u:' + id),
|
|
|
|
|
+ Q.where('message_id', Q.oneOf(newViewableUnreadMessages))
|
|
|
|
|
+ )
|
|
|
|
|
+ .fetch();
|
|
|
|
|
+
|
|
|
|
|
+ if (messagesToUpdate.length > 0) {
|
|
|
|
|
+ await database.write(async () => {
|
|
|
|
|
+ messagesToUpdate.forEach((msg: Message) => {
|
|
|
|
|
+ msg.update((r) => {
|
|
|
|
|
+ r.status = 3;
|
|
|
|
|
+ addMessageDirtyAction(r, {
|
|
|
|
|
+ type: 'read',
|
|
|
|
|
+ value: { messagesIds: [msg.messageId] }
|
|
|
|
|
+ });
|
|
|
});
|
|
});
|
|
|
|
|
+ sentToServer.current.add(msg.messageId as number);
|
|
|
});
|
|
});
|
|
|
- sentToServer.current.add(msg.messageId as number);
|
|
|
|
|
});
|
|
});
|
|
|
- });
|
|
|
|
|
|
|
|
|
|
- await triggerMessagePush(token, sendWsEvent);
|
|
|
|
|
- }
|
|
|
|
|
|
|
+ await triggerMessagePush(token, sendWsEvent);
|
|
|
|
|
+ }
|
|
|
|
|
|
|
|
- sendWebSocketMessage('messages_read', null, null, newViewableUnreadMessages);
|
|
|
|
|
- }
|
|
|
|
|
- };
|
|
|
|
|
|
|
+ sendWebSocketMessage('messages_read', null, null, newViewableUnreadMessages);
|
|
|
|
|
+ }
|
|
|
|
|
+ },
|
|
|
|
|
+ 1000
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
const renderSystemMessage = (props: any) => {
|
|
const renderSystemMessage = (props: any) => {
|
|
|
if (props.currentMessage._id === 'unreadMarker') {
|
|
if (props.currentMessage._id === 'unreadMarker') {
|