Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 81 additions & 1 deletion packages/react/src/lib/createPendingMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,84 @@ const createPendingMessage = (
};
};

export default createPendingMessage;
const createPendingAttachmentMessage = (
file,
user = { _id: undefined, username: undefined, name: undefined },
description = '',
fileType = 'file',
additionalFields = {}
) => {
const now = new Date();

const fileProps = {
_id: file._id || '',
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
};

const attachment = {
ts: '1970-01-01T00:00:00.000Z',
title: file.name,
title_link: `/file-upload/${file._id || file.name}/${encodeURIComponent(
file.name
)}`,
title_link_download: true,
type: 'file',
description,
descriptionMd: [
{
type: 'PARAGRAPH',
value: [
{
type: 'PLAIN_TEXT',
value: description,
},
],
},
],
};

if (fileType === 'audio') {
attachment.audio_url = `/file-upload/${
file._id || file.name
}/${encodeURIComponent(file.name)}`;
attachment.audio_type = file.type;
attachment.audio_size = file.size;
} else if (fileType === 'video') {
attachment.video_url = `/file-upload/${
file._id || file.name
}/${encodeURIComponent(file.name)}`;
attachment.video_type = file.type;
attachment.video_size = file.size;
} else if (fileType === 'image') {
attachment.image_preview = file.image_preview || '';
attachment.image_url = file.image_url;
attachment.image_type = file.type;
attachment.image_size = file.size;
}

return {
isPending: true,
_id: `ec_${createRandomId()}`,
rid: 'GENERAL',
msg: '',
ts: now.toISOString(),
u: {
_id: user._id,
username: user.username,
name: user.name,
},
_updatedAt: now.toISOString(),
urls: [],
mentions: [],
channels: [],
file: fileProps,
files: [fileProps],
attachments: [attachment],
md: [],
};
};

export { createPendingMessage, createPendingAttachmentMessage };
35 changes: 32 additions & 3 deletions packages/react/src/views/AttachmentPreview/AttachmentPreview.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@ import { Box, Icon, Button, Input, Modal } from '@embeddedchat/ui-elements';
import useAttachmentWindowStore from '../../store/attachmentwindow';
import CheckPreviewType from './CheckPreviewType';
import RCContext from '../../context/RCInstance';
import { useMessageStore, useMemberStore } from '../../store';
import { useMessageStore, useMemberStore, useUserStore } from '../../store';
import { createPendingAttachmentMessage } from '../../lib/createPendingMessage';
import getAttachmentPreviewStyles from './AttachmentPreview.styles';
import { parseEmoji } from '../../lib/emoji';
import MembersList from '../Mentions/MembersList';
Expand Down Expand Up @@ -51,15 +52,43 @@ const AttachmentPreview = () => {
searchMentionUser(description);
};

const upsertMessage = useMessageStore((state) => state.upsertMessage);
const removeMessage = useMessageStore((state) => state.removeMessage);
const { username, userId, name } = useUserStore((state) => ({
username: state.username,
userId: state.userId,
name: state.name,
}));
const userInfo = { _id: userId, username, name };

const submit = async () => {
setIsPending(true);
await RCInstance.sendAttachment(

const type = data ? data.type.split('/')[0] : '';
const pendingFileMessage = createPendingAttachmentMessage(
data,
userInfo,
messageRef.current.value,
type
);

upsertMessage(pendingFileMessage, ECOptions.enableThreads);
if (isPending) {
setIsPending(false);
}
toggle();

const res = await RCInstance.sendAttachment(
data,
fileName,
messageRef.current.value,
ECOptions?.enableThreads ? threadId : undefined
);
toggle();

if (res.success) {
removeMessage(pendingFileMessage._id);
}

setData(null);
if (isPending) {
setIsPending(false);
Expand Down
57 changes: 55 additions & 2 deletions packages/react/src/views/ChatInput/ChatInput.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useRef, useEffect } from 'react';
import React, { useState, useRef, useEffect, useContext } from 'react';
import { css } from '@emotion/react';
import {
Box,
Expand All @@ -24,7 +24,7 @@ import ChatInputFormattingToolbar from './ChatInputFormattingToolbar';
import useAttachmentWindowStore from '../../store/attachmentwindow';
import MembersList from '../Mentions/MembersList';
import { TypingUsers } from '../TypingUsers';
import createPendingMessage from '../../lib/createPendingMessage';
import { createPendingMessage } from '../../lib/createPendingMessage';
import { CommandsList } from '../CommandList';
import useSettingsStore from '../../store/settingsStore';
import ChannelState from '../ChannelState/ChannelState';
Expand Down Expand Up @@ -57,6 +57,7 @@ const ChatInput = ({ scrollToBottom }) => {
const [showCommandList, setShowCommandList] = useState(false);
const [filteredCommands, setFilteredCommands] = useState([]);
const [isMsgLong, setIsMsgLong] = useState(false);
const [messageQueue, setMessageQueue] = useState([]);

const {
isUserAuthenticated,
Expand Down Expand Up @@ -164,6 +165,43 @@ const ChatInput = ({ scrollToBottom }) => {
}
}, [editMessage]);

useEffect(() => {
const handleOnline = async () => {
if (navigator.onLine && messageQueue.length > 0) {
for (let i = 0; i < messageQueue.length; i += 1) {
const pendingMessage = JSON.parse(messageQueue[i]);
// eslint-disable-next-line no-await-in-loop
const res = await RCInstance.sendMessage(
{
msg: pendingMessage.msg,
_id: pendingMessage._id,
},
ECOptions.enableThreads ? threadId : undefined
);
if (res.success) {
clearQuoteMessages();
replaceMessage(pendingMessage, res.message);
}
}
setMessageQueue([]);
localStorage.removeItem('pendingMessage');
}
};

window.addEventListener('online', handleOnline);
return () => {
window.removeEventListener('online', handleOnline);
};
}, [messageQueue]);

useEffect(() => {
const pendingMessage = localStorage.getItem('pendingMessage');
if (pendingMessage) {
messageRef.current.value = JSON.parse(pendingMessage).msg || '';
localStorage.removeItem('pendingMessage');
}
}, []);

const getMessageLink = async (id) => {
const host = RCInstance.getHost();
const res = await RCInstance.channelInfo();
Expand Down Expand Up @@ -262,6 +300,16 @@ const ChatInput = ({ scrollToBottom }) => {
}
};

const handleOffline = (pendingMessage) => {
localStorage.removeItem('pendingMessage');
localStorage.setItem('pendingMessage', JSON.stringify(pendingMessage));

setMessageQueue((prevQueue) => [
...prevQueue,
JSON.stringify(pendingMessage),
]);
};

const handleSendNewMessage = async (message) => {
messageRef.current.value = '';
setDisableButton(true);
Expand Down Expand Up @@ -303,6 +351,11 @@ const ChatInput = ({ scrollToBottom }) => {

upsertMessage(pendingMessage, ECOptions.enableThreads);

if (!navigator.onLine) {
handleOffline(pendingMessage);
return;
}

const res = await RCInstance.sendMessage(
{
msg: pendingMessage.msg,
Expand Down
Loading