Skip to content

Commit 8091b12

Browse files
authored
feat: add a loader to show when decrypting messgaes (#646)
1 parent d026ece commit 8091b12

5 files changed

Lines changed: 189 additions & 152 deletions

File tree

client/package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

client/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@
3535
"react-loading-icons": "^1.1.0",
3636
"react-router-dom": "^6.15.0",
3737
"react-scroll-to-bottom": "^4.2.0",
38+
"react-spinners": "^0.14.1",
3839
"rsuite": "^5.37.4",
3940
"socket.io-client": "^4.7.2",
4041
"styled-components": "^5.3.5",

client/src/components/Chat.jsx

Lines changed: 33 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -19,28 +19,28 @@ import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
1919

2020
import BadWordsNext from 'bad-words-next';
2121
import DropDownOptions from './Chat/DropDownOption';
22+
import Loading from './Loading';
2223
import MarkdownIt from 'markdown-it';
2324
import MessageInput from './Chat/MessageInput';
2425
import MessageSeen from './Chat/MessageSeen';
2526
import MessageStatus from './MessageStatus';
2627
import PreviousMessages from './Chat/PreviousMessages';
2728
import ScrollToBottom from 'react-scroll-to-bottom';
28-
import { socket } from 'src/lib/socketConnection';
2929
import { createBrowserNotification } from 'src/lib/browserNotification';
3030
import decryptMessage from 'src/lib/decryptMessage';
3131
import en from 'bad-words-next/data/en.json';
32+
import { socket } from 'src/lib/socketConnection';
3233
import { throttle } from 'lodash';
3334
import { useApp } from 'src/context/AppContext';
3435
import { useAuth } from 'src/context/AuthContext';
3536
import { useChat } from 'src/context/ChatContext';
3637
import useChatUtils from 'src/lib/chatSocket';
38+
import useCryptoKeys from 'src/hooks/useCryptoKeys';
3739
import useInactiveChat from 'src/hooks/useInactiveChat';
3840
import { useKindeAuth } from '@kinde-oss/kinde-auth-react';
3941
import { useNotification } from 'src/lib/notification';
4042
import { v4 as uuid } from 'uuid';
4143

42-
import useCryptoKeys from 'src/hooks/useCryptoKeys';
43-
4444
let senderId;
4545

4646
const Chat = () => {
@@ -55,7 +55,7 @@ const Chat = () => {
5555
const [decryptedMessages, setDecryptedMessages] = useState();
5656
// use the id so we can track what message's previousMessage is open
5757
const [openPreviousMessages, setOpenPreviousMessages] = useState(null);
58-
const [badwordChoices, setBadwordChoices] = useState({});
58+
const [badwordChoices, setBadwordChoices] = useState({});
5959

6060
const {
6161
messages: state,
@@ -67,9 +67,7 @@ const Chat = () => {
6767
currentReplyMessageId,
6868
cancelReply,
6969
} = useChat();
70-
const {importedPublicKey, importedPrivateKey, cryptoKey, importKey, generateKeyPair
71-
72-
} = useCryptoKeys(app.currentChatId);
70+
const { importedPublicKey, importedPrivateKey, cryptoKey, messageIsDecrypting, generateKeyPair, importKey } = useCryptoKeys(app.currentChatId);
7371
const { authState, dispatchAuth } = useAuth();
7472
const { logout } = useKindeAuth();
7573

@@ -288,13 +286,14 @@ const Chat = () => {
288286
receiveMessage(messageId, chatId);
289287
}, []);
290288

291-
const onPublicStringHandler = useCallback(({ pemPublicKeyString, pemPrivateKeyString }) => {
292-
const pemPublicKeyArrayBuffer = pemToArrayBuffer(pemPublicKeyString);
293-
const pemPrivateKeyArrayBuffer = pemToArrayBuffer(pemPrivateKeyString);
294-
295-
// Import PEM-formatted public key as CryptoKey
296-
importKey(pemPublicKeyArrayBuffer, pemPrivateKeyArrayBuffer);
297-
}, []);
289+
const onPublicStringHandler = useCallback(({ pemPublicKeyString, pemPrivateKeyString }) => {
290+
const pemPublicKeyArrayBuffer = pemToArrayBuffer(pemPublicKeyString);
291+
const pemPrivateKeyArrayBuffer = pemToArrayBuffer(pemPrivateKeyString);
292+
293+
// Import PEM-formatted public key as CryptoKey
294+
importKey(pemPublicKeyArrayBuffer, pemPrivateKeyArrayBuffer);
295+
}, []);
296+
298297

299298
// Clear chat when escape is pressed
300299
useEffect(() => {
@@ -324,12 +323,12 @@ const Chat = () => {
324323
inputRef.current.focus();
325324
}, [currentReplyMessageId]);
326325

327-
useEffect(() => {
328-
const fetchData = async () => {
326+
useEffect(() => {
327+
const fetchData = async (importedPrivateKey, cryptoKey) => {
329328
const decryptedPromises = sortedMessages.map(
330-
async ({ message, senderId: sender, ...rest }) => {
329+
async ({ message, senderId: sender, ...rest }) => {
331330
try {
332-
if (sender.toString() === senderId.toString()) {
331+
if (sender.toString() === senderId.toString()) {
333332
const decryptedMessage = await decryptMessage(message, importedPrivateKey);
334333
return {
335334
...rest,
@@ -356,15 +355,17 @@ const Chat = () => {
356355
);
357356

358357
const decryptedMessages = await Promise.all(decryptedPromises);
359-
setDecryptedMessages(decryptedMessages);
358+
setDecryptedMessages(decryptedMessages);
360359
};
361360

362-
fetchData();
363-
}, [sortedMessages, cryptoKey]);
361+
if (cryptoKey && importedPrivateKey) {
362+
fetchData(importedPrivateKey, cryptoKey)
363+
}
364+
}, [sortedMessages, cryptoKey, importedPrivateKey]);
364365

365-
useEffect(() => {
366-
generateKeyPair()
367-
socket.on('publicKey', onPublicStringHandler);
366+
useEffect(() => {
367+
generateKeyPair();
368+
socket.on('publicKey', onPublicStringHandler);
368369
socket.on(NEW_EVENT_RECEIVE_MESSAGE, onNewMessageHandler);
369370
socket.on(NEW_EVENT_DELETE_MESSAGE, onDeleteMessageHandler);
370371
socket.on(NEW_EVENT_EDIT_MESSAGE, onEditMessageHandler);
@@ -376,8 +377,9 @@ const Chat = () => {
376377
socket.off(NEW_EVENT_DELETE_MESSAGE, onDeleteMessageHandler);
377378
socket.off(NEW_EVENT_EDIT_MESSAGE, onEditMessageHandler);
378379
socket.off(NEW_EVENT_READ_MESSAGE, onReadMessageHandler);
379-
socket.off(NEW_EVENT_SEND_FAILED, onLimitMessageHandler);
380-
socket.off('publicKey', onPublicStringHandler);
380+
socket.off(NEW_EVENT_SEND_FAILED, onLimitMessageHandler);
381+
socket.off('publicKey', onPublicStringHandler);
382+
381383
};
382384
}, []);
383385

@@ -392,7 +394,7 @@ const Chat = () => {
392394
initialScrollBehavior="auto"
393395
className="h-[100%] md:max-h-full overflow-y-auto w-full scroll-smooth"
394396
>
395-
{decryptedMessages &&
397+
{!messageIsDecrypting ? (decryptedMessages &&
396398
decryptedMessages.map(
397399
({
398400
senderId: sender,
@@ -571,7 +573,10 @@ const Chat = () => {
571573
</div>
572574
);
573575
}
574-
)}
576+
)) : (
577+
<div className='w-full h-full flex flex-col items-center justify-center'><Loading loading={messageIsDecrypting} />
578+
</div>
579+
)}
575580
</ScrollToBottom>
576581
</div>
577582

client/src/components/Loading.jsx

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import MoonLoader from "react-spinners/MoonLoader";
2+
import { PropTypes } from 'prop-types';
3+
import React from 'react'
4+
5+
const Loading = ({ loading }) => {
6+
return (
7+
<MoonLoader size={60} color='#FF9F1C' loading={loading} />
8+
)
9+
}
10+
11+
export default Loading
12+
13+
Loading.propTypes = {
14+
loading: PropTypes.bool
15+
}

0 commit comments

Comments
 (0)