Skip to content

Commit

Permalink
added functionality to send message automatically once internet resto…
Browse files Browse the repository at this point in the history
…red and some validations
  • Loading branch information
dhairyashiil committed Dec 23, 2024
1 parent 94e0faf commit 5f1dc0c
Show file tree
Hide file tree
Showing 5 changed files with 445 additions and 12 deletions.
191 changes: 190 additions & 1 deletion packages/react/src/lib/createPendingMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,4 +53,193 @@ const createPendingMessage = (
};
};

export default createPendingMessage;
const createPendingAudioMessage = (
file,
user = {
_id: undefined,
username: undefined,
name: undefined,
}
) => {
const now = new Date();
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: {
_id: file._id,
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
files: [
{
_id: file._id,
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
],
attachments: [
{
ts: '1970-01-01T00:00:00.000Z',
title: file.name,
title_link: `/file-upload/${file._id}/${encodeURIComponent(file.name)}`,
title_link_download: true,
audio_url: `/file-upload/${file._id}/${encodeURIComponent(file.name)}`,
audio_type: file.type,
audio_size: file.size,
type: 'file',
description: '',
},
],
md: [],
};
};

const createPendingVideoMessage = (
file,
user = {
_id: undefined,
username: undefined,
name: undefined,
}
) => {
const now = new Date();
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: {
_id: file._id,
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
files: [
{
_id: file._id,
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
],
attachments: [
{
ts: '1970-01-01T00:00:00.000Z',
title: file.name,
title_link: `/file-upload/${file._id}/${encodeURIComponent(file.name)}`,
title_link_download: true,
video_url: `/file-upload/${file._id}/${encodeURIComponent(file.name)}`,
video_type: file.type,
video_size: file.size,
type: 'file',
description: '',
},
],
md: [],
};
};

const createPendingFileMessage = (
file,
user = {
_id: undefined,
username: undefined,
name: undefined,
},
description = 'Hahahaha'
) => {
const now = new Date();
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: {
_id: '',
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
files: [
{
_id: '',
name: file.name,
type: file.type,
size: file.size,
format: file.format || '',
},
],
attachments: [
{
ts: '1970-01-01T00:00:00.000Z',
title: file.name,
title_link: `/file-upload/${file.name}/${encodeURIComponent(
file.name
)}`,
title_link_download: true,
type: 'file',
description,
format: file.format || '',
size: file.size,
descriptionMd: [
{
type: 'PARAGRAPH',
value: [
{
type: 'PLAIN_TEXT',
value: description,
},
],
},
],
},
],
md: [],
};
};

export {
createPendingMessage,
createPendingAudioMessage,
createPendingVideoMessage,
createPendingFileMessage,
};
49 changes: 45 additions & 4 deletions packages/react/src/views/AttachmentPreview/AttachmentPreview.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,20 @@
import React, { useContext, useState } from 'react';
import { css } from '@emotion/react';
import { Box, Icon, Button, Input, Modal } from '@embeddedchat/ui-elements';
import {
Box,
Icon,
Button,
Input,
Modal,
useToastBarDispatch,
} from '@embeddedchat/ui-elements';
import useAttachmentWindowStore from '../../store/attachmentwindow';
import CheckPreviewType from './CheckPreviewType';
import RCContext from '../../context/RCInstance';
import { useMessageStore } from '../../store';
import { useUserStore, useMessageStore } from '../../store';
import getAttachmentPreviewStyles from './AttachmentPreview.styles';
import { parseEmoji } from '../../lib/emoji';
import { createPendingFileMessage } from '../../lib/createPendingMessage';

const AttachmentPreview = () => {
const { RCInstance, ECOptions } = useContext(RCContext);
Expand All @@ -29,15 +37,48 @@ const AttachmentPreview = () => {
setFileDescription(parseEmoji(e.target.value));
};

const upsertMessage = useMessageStore((state) => state.upsertMessage);
const removeMessage = useMessageStore((state) => state.removeMessage);
const dispatchToastMessage = useToastBarDispatch();

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(

let pendingFileMessage = createPendingFileMessage(
data,
userInfo,
fileDescription
);
upsertMessage(pendingFileMessage, ECOptions.enableThreads);
toggle();

if (!navigator.onLine) {
dispatchToastMessage({
type: 'error',
message: 'Please try again after connecting to internet!',
});
removeMessage(pendingFileMessage._id);
return;
}

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

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

setData(null);
setIsPending(false);
};
Expand Down
78 changes: 75 additions & 3 deletions packages/react/src/views/ChatInput/AudioMessageRecorder.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,18 @@ import React, {
useContext,
useRef,
} from 'react';
import { Box, Icon, ActionButton, useTheme } from '@embeddedchat/ui-elements';
import {
Box,
Icon,
ActionButton,
useTheme,
useToastBarDispatch,
} from '@embeddedchat/ui-elements';
import { useMediaRecorder } from '../../hooks/useMediaRecorder';
import RCContext from '../../context/RCInstance';
import useMessageStore from '../../store/messageStore';
import { useUserStore, useMessageStore } from '../../store';
import { getCommonRecorderStyles } from './ChatInput.styles';
import { createPendingAudioMessage } from '../../lib/createPendingMessage';

const AudioMessageRecorder = () => {
const videoRef = useRef(null);
Expand All @@ -26,6 +33,22 @@ const AudioMessageRecorder = () => {
const [file, setFile] = useState(null);
const [isRecorded, setIsRecorded] = useState(false);
const threadId = useMessageStore((_state) => _state.threadMainMessage?._id);
const upsertMessage = useMessageStore((state) => state.upsertMessage);
const removeMessage = useMessageStore((state) => state.removeMessage);
const dispatchToastMessage = useToastBarDispatch();

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

const [messageQueue, setMessageQueue] = useState([]);
const addMessageInMessageQueue = (key, value) => {
setMessageQueue((prevState) => [...prevState, { key, value }]);
};

const onStop = (audioChunks) => {
const audioBlob = new Blob(audioChunks, { type: 'audio/mpeg' });
const fileName = 'Audio record.mp3';
Expand Down Expand Up @@ -119,14 +142,63 @@ const AudioMessageRecorder = () => {
handleMount();
}, [handleMount]);

useEffect(() => {
const handleOnline = async () => {
if (navigator.onLine && messageQueue.length > 0) {
for (let i = 0; i < messageQueue.length; i++) {
const { key, value } = messageQueue[i];
const pendingAudioMessage = JSON.parse(value);

const res = await RCInstance.sendAttachment(
key,
undefined,
undefined,
ECOptions.enableThreads ? threadId : undefined
);

if (res.success) {
removeMessage(pendingAudioMessage._id);
}
}
setMessageQueue([]);
}
};

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

const handleOffline = (file, pendingAudioMessage) => {
addMessageInMessageQueue(file, JSON.stringify(pendingAudioMessage));

dispatchToastMessage({
type: 'info',
message: 'Audio will be sent automatically once you are back online!',
});
};

useEffect(() => {
const sendRecording = async () => {
await RCInstance.sendAttachment(
let pendingAudioMessage = createPendingAudioMessage(file, userInfo);
upsertMessage(pendingAudioMessage, ECOptions.enableThreads);

if (!navigator.onLine) {
handleOffline(file, pendingAudioMessage);
return;
}

const res = await RCInstance.sendAttachment(
file,
undefined,
undefined,
ECOptions.enableThreads ? threadId : undefined
);

if (res.success) {
removeMessage(pendingAudioMessage._id);
}
};
if (isRecorded && file) {
sendRecording();
Expand Down
Loading

0 comments on commit 5f1dc0c

Please sign in to comment.