mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-02-14 11:15:49 +00:00
optimizations, see ui direct chat, fixes
This commit is contained in:
parent
5327c79543
commit
eebcd8c36f
26
package-lock.json
generated
26
package-lock.json
generated
@ -18,9 +18,11 @@
|
||||
"@testing-library/jest-dom": "^6.4.6",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@tiptap/extension-color": "^2.5.9",
|
||||
"@tiptap/extension-highlight": "^2.6.6",
|
||||
"@tiptap/extension-image": "^2.6.6",
|
||||
"@tiptap/extension-placeholder": "^2.6.2",
|
||||
"@tiptap/extension-text-style": "^2.5.9",
|
||||
"@tiptap/extension-underline": "^2.6.6",
|
||||
"@tiptap/pm": "^2.5.9",
|
||||
"@tiptap/react": "^2.5.9",
|
||||
"@tiptap/starter-kit": "^2.5.9",
|
||||
@ -2300,6 +2302,18 @@
|
||||
"@tiptap/core": "^2.5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-highlight": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-highlight/-/extension-highlight-2.6.6.tgz",
|
||||
"integrity": "sha512-Z02AYWm1AJAfhmfT4fGCI3YitijF4uNu+eiuq7OxhCiVf9IYaq8xlH2YMxa09QvMUo70ovklxk97+vQUUHeqfQ==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.6.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-history": {
|
||||
"version": "2.5.9",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-history/-/extension-history-2.5.9.tgz",
|
||||
@ -2435,6 +2449,18 @@
|
||||
"@tiptap/core": "^2.5.9"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/extension-underline": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/extension-underline/-/extension-underline-2.6.6.tgz",
|
||||
"integrity": "sha512-3A4HqsDM/AFb2VaeWACpGexjgI257kz0yU4jNV8uyydDR2KhqeinuEnoSoOmx9T3pL006TWfPg4vaQYPO3qvrQ==",
|
||||
"funding": {
|
||||
"type": "github",
|
||||
"url": "https://github.com/sponsors/ueberdosis"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"@tiptap/core": "^2.6.6"
|
||||
}
|
||||
},
|
||||
"node_modules/@tiptap/pm": {
|
||||
"version": "2.6.6",
|
||||
"resolved": "https://registry.npmjs.org/@tiptap/pm/-/pm-2.6.6.tgz",
|
||||
|
@ -22,9 +22,11 @@
|
||||
"@testing-library/jest-dom": "^6.4.6",
|
||||
"@testing-library/user-event": "^14.5.2",
|
||||
"@tiptap/extension-color": "^2.5.9",
|
||||
"@tiptap/extension-highlight": "^2.6.6",
|
||||
"@tiptap/extension-image": "^2.6.6",
|
||||
"@tiptap/extension-placeholder": "^2.6.2",
|
||||
"@tiptap/extension-text-style": "^2.5.9",
|
||||
"@tiptap/extension-underline": "^2.6.6",
|
||||
"@tiptap/pm": "^2.5.9",
|
||||
"@tiptap/react": "^2.5.9",
|
||||
"@tiptap/starter-kit": "^2.5.9",
|
||||
|
@ -1263,6 +1263,7 @@ function App() {
|
||||
<CustomButton
|
||||
onClick={() => {
|
||||
setExtstate("send-qort");
|
||||
setIsOpenDrawerProfile(false)
|
||||
}}
|
||||
>
|
||||
Transfer QORT
|
||||
@ -1291,6 +1292,7 @@ function App() {
|
||||
<img
|
||||
onClick={() => {
|
||||
setExtstate("download-wallet");
|
||||
setIsOpenDrawerProfile(false)
|
||||
}}
|
||||
src={Download}
|
||||
style={{
|
||||
@ -1300,7 +1302,10 @@ function App() {
|
||||
<Spacer height="20px" />
|
||||
<img
|
||||
src={Logout}
|
||||
onClick={logoutFunc}
|
||||
onClick={()=> {
|
||||
logoutFunc()
|
||||
setIsOpenDrawerProfile(false)
|
||||
}}
|
||||
style={{
|
||||
cursor: "pointer",
|
||||
}}
|
||||
@ -1554,7 +1559,7 @@ function App() {
|
||||
<Group
|
||||
balance={balance}
|
||||
userInfo={userInfo}
|
||||
myAddress={userInfo?.address}
|
||||
myAddress={address}
|
||||
isFocused={isFocused}
|
||||
isMain={isMain}
|
||||
isOpenDrawerProfile={isOpenDrawerProfile}
|
||||
|
@ -237,7 +237,7 @@ const handleNotificationDirect = async (directs)=> {
|
||||
const address = wallet.address0;
|
||||
const dataDirects = directs.filter((direct)=> direct?.sender !== address)
|
||||
try {
|
||||
|
||||
if(!dataDirects || dataDirects?.length === 0) return
|
||||
isFocused = await checkWebviewFocus()
|
||||
|
||||
if(isFocused){
|
||||
@ -264,7 +264,7 @@ if (!oldestLatestTimestamp || oldChat?.timestamp > oldestLatestTimestamp?.timest
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
console.log('newestLatestTimestamp', newestLatestTimestamp)
|
||||
if(checkDifference(newestLatestTimestamp.timestamp) && !oldestLatestTimestamp || (newestLatestTimestamp && newestLatestTimestamp?.timestamp > oldestLatestTimestamp?.timestamp)){
|
||||
const notificationId = 'chat_notification_' + Date.now() + '_type=direct' + `_from=${newestLatestTimestamp.address}`;
|
||||
chrome.notifications.create(notificationId, {
|
||||
@ -1062,7 +1062,7 @@ async function getNameOrAddress(receiver) {
|
||||
}
|
||||
}
|
||||
|
||||
async function getPublicKey(receiver) {
|
||||
export async function getPublicKey(receiver) {
|
||||
try {
|
||||
const validApi = await getBaseApi()
|
||||
|
||||
@ -1326,8 +1326,8 @@ async function sendChatGroup({
|
||||
privateKey: uint8PrivateKey,
|
||||
publicKey: uint8PublicKey,
|
||||
};
|
||||
const balance = await getBalanceInfo();
|
||||
const hasEnoughBalance = +balance < 4 ? false : true;
|
||||
// const balance = await getBalanceInfo();
|
||||
// const hasEnoughBalance = +balance < 4 ? false : true;
|
||||
const difficulty = 8;
|
||||
|
||||
const tx = await createTransaction(181, keyPair, {
|
||||
@ -1343,9 +1343,9 @@ async function sendChatGroup({
|
||||
isText: 1,
|
||||
});
|
||||
|
||||
if (!hasEnoughBalance) {
|
||||
throw new Error("Must have at least 4 QORT to send a chat message");
|
||||
}
|
||||
// if (!hasEnoughBalance) {
|
||||
// throw new Error("Must have at least 4 QORT to send a chat message");
|
||||
// }
|
||||
const path = chrome.runtime.getURL("memory-pow.wasm.full");
|
||||
|
||||
const { nonce, chatBytesArray } = await computePow({
|
||||
@ -1366,15 +1366,27 @@ async function sendChatGroup({
|
||||
}
|
||||
|
||||
async function sendChatDirect({
|
||||
address,
|
||||
directTo,
|
||||
typeMessage,
|
||||
chatReference,
|
||||
messageText,
|
||||
publicKeyOfRecipient
|
||||
}) {
|
||||
|
||||
let recipientPublicKey
|
||||
let recipientAddress = address
|
||||
if(publicKeyOfRecipient){
|
||||
recipientPublicKey = publicKeyOfRecipient
|
||||
} else {
|
||||
recipientAddress = await getNameOrAddress(directTo)
|
||||
recipientPublicKey = await getPublicKey(recipientAddress)
|
||||
}
|
||||
if(!recipientAddress){
|
||||
recipientAddress = await getNameOrAddress(directTo)
|
||||
}
|
||||
|
||||
const recipientAddress = await getNameOrAddress(directTo)
|
||||
const recipientPublicKey = await getPublicKey(recipientAddress)
|
||||
|
||||
|
||||
if(!recipientPublicKey) throw new Error('Cannot retrieve publickey')
|
||||
|
||||
@ -1390,8 +1402,8 @@ async function sendChatDirect({
|
||||
privateKey: uint8PrivateKey,
|
||||
publicKey: uint8PublicKey,
|
||||
};
|
||||
const balance = await getBalanceInfo();
|
||||
const hasEnoughBalance = +balance < 4 ? false : true;
|
||||
// const balance = await getBalanceInfo();
|
||||
// const hasEnoughBalance = +balance < 4 ? false : true;
|
||||
|
||||
const difficulty = 8;
|
||||
|
||||
@ -1412,9 +1424,9 @@ async function sendChatDirect({
|
||||
isText: 1,
|
||||
});
|
||||
|
||||
if (!hasEnoughBalance) {
|
||||
throw new Error("Must have at least 4 QORT to send a chat message");
|
||||
}
|
||||
// if (!hasEnoughBalance) {
|
||||
// throw new Error("Must have at least 4 QORT to send a chat message");
|
||||
// }
|
||||
const path = chrome.runtime.getURL("memory-pow.wasm.full");
|
||||
|
||||
|
||||
@ -1490,6 +1502,7 @@ async function decryptDirectFunc({ messages, involvingAddress }) {
|
||||
publicKey: uint8PublicKey,
|
||||
};
|
||||
for (const message of messages) {
|
||||
console.log('messagedep', message)
|
||||
try {
|
||||
const decodedMessage = decryptChatMessage(
|
||||
message.data,
|
||||
@ -3607,9 +3620,11 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||
typeMessage = undefined,
|
||||
chatReference = undefined,
|
||||
messageText,
|
||||
publicKeyOfRecipient,
|
||||
address
|
||||
} = request.payload;
|
||||
|
||||
sendChatDirect({ directTo, chatReference, messageText, typeMessage })
|
||||
sendChatDirect({ directTo, chatReference, messageText, typeMessage, publicKeyOfRecipient, address })
|
||||
.then((res) => {
|
||||
|
||||
sendResponse(res);
|
||||
@ -3669,8 +3684,9 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||
const wallet = await getSaveWallet();
|
||||
const address = wallet.address0;
|
||||
const key1 = `tempPublish-${address}`
|
||||
|
||||
chrome.storage.local.remove(["keyPair", "walletInfo", "apiKey", "active-groups-directs", key1], () => {
|
||||
const key2 = `group-data-${address}`
|
||||
|
||||
chrome.storage.local.remove(["keyPair", "walletInfo", "apiKey", "active-groups-directs", key1, key2], () => {
|
||||
if (chrome.runtime.lastError) {
|
||||
// Handle error
|
||||
console.error(chrome.runtime.lastError.message);
|
||||
@ -4009,7 +4025,7 @@ chrome.runtime?.onInstalled.addListener((details) => {
|
||||
chrome.alarms?.get("checkForNotifications", (existingAlarm) => {
|
||||
if (!existingAlarm) {
|
||||
// If the alarm does not exist, create it
|
||||
chrome.alarms.create("checkForNotifications", { periodInMinutes: 4 });
|
||||
chrome.alarms.create("checkForNotifications", { periodInMinutes: 10 });
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -11,13 +11,18 @@ import { LoadingSnackbar } from '../Snackbar/LoadingSnackbar';
|
||||
import { getNameInfo } from '../Group/Group';
|
||||
import { Spacer } from '../../common/Spacer';
|
||||
import { CustomizedSnackbars } from '../Snackbar/Snackbar';
|
||||
import { getBaseApiReactSocket, isMobile } from '../../App';
|
||||
import { getBaseApiReactSocket, isMobile, pauseAllQueues, resumeAllQueues } from '../../App';
|
||||
import { getPublicKey } from '../../background';
|
||||
import { useMessageQueue } from '../../MessageQueueContext';
|
||||
import { executeEvent } from '../../utils/events';
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName}) => {
|
||||
export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDirect, setNewChat, getTimestampEnterChat, myName, balance}) => {
|
||||
const { queueChats, addToQueue, } = useMessageQueue();
|
||||
|
||||
const [messages, setMessages] = useState([])
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
const [directToValue, setDirectToValue] = useState('')
|
||||
@ -25,14 +30,41 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
const [openSnack, setOpenSnack] = React.useState(false);
|
||||
const [infoSnack, setInfoSnack] = React.useState(null);
|
||||
const [publicKeyOfRecipient, setPublicKeyOfRecipient] = React.useState("")
|
||||
const hasInitializedWebsocket = useRef(false)
|
||||
const editorRef = useRef(null);
|
||||
const socketRef = useRef(null);
|
||||
const timeoutIdRef = useRef(null);
|
||||
const groupSocketTimeoutRef = useRef(null);
|
||||
|
||||
const setEditorRef = (editorInstance) => {
|
||||
editorRef.current = editorInstance;
|
||||
};
|
||||
|
||||
const publicKeyOfRecipientRef = useRef(null)
|
||||
|
||||
const getPublicKeyFunc = async (address)=> {
|
||||
try {
|
||||
const publicKey = await getPublicKey(address)
|
||||
if(publicKeyOfRecipientRef.current !== selectedDirect?.address) return
|
||||
setPublicKeyOfRecipient(publicKey)
|
||||
} catch (error) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
const tempMessages = useMemo(()=> {
|
||||
if(!selectedDirect?.address) return []
|
||||
if(queueChats[selectedDirect?.address]){
|
||||
return queueChats[selectedDirect?.address]
|
||||
}
|
||||
return []
|
||||
}, [selectedDirect?.address, queueChats])
|
||||
useEffect(()=> {
|
||||
if(selectedDirect?.address){
|
||||
publicKeyOfRecipientRef.current = selectedDirect?.address
|
||||
getPublicKeyFunc(publicKeyOfRecipientRef.current)
|
||||
}
|
||||
}, [selectedDirect?.address])
|
||||
|
||||
|
||||
|
||||
@ -54,7 +86,7 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
||||
...item,
|
||||
id: item.signature,
|
||||
text: item.message,
|
||||
unread: true
|
||||
unread: item?.sender === myAddress ? false : true
|
||||
}
|
||||
} )
|
||||
setMessages((prev)=> [...prev, ...formatted])
|
||||
@ -80,78 +112,106 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
||||
}
|
||||
}
|
||||
|
||||
const forceCloseWebSocket = () => {
|
||||
if (socketRef.current) {
|
||||
console.log('Force closing the WebSocket');
|
||||
clearTimeout(timeoutIdRef.current);
|
||||
clearTimeout(groupSocketTimeoutRef.current);
|
||||
socketRef.current.close(1000, 'forced');
|
||||
socketRef.current = null;
|
||||
}
|
||||
};
|
||||
|
||||
const pingWebSocket = () => {
|
||||
try {
|
||||
if (socketRef.current?.readyState === WebSocket.OPEN) {
|
||||
socketRef.current.send('ping');
|
||||
timeoutIdRef.current = setTimeout(() => {
|
||||
if (socketRef.current) {
|
||||
socketRef.current.close();
|
||||
clearTimeout(groupSocketTimeoutRef.current);
|
||||
}
|
||||
}, 5000); // Close if no pong in 5 seconds
|
||||
}
|
||||
} catch (error) {
|
||||
console.error('Error during ping:', error);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
const initWebsocketMessageGroup = () => {
|
||||
let timeoutId
|
||||
let groupSocketTimeout
|
||||
|
||||
let socketTimeout: any
|
||||
let socketLink = `${getBaseApiReactSocket()}/websockets/chat/messages?involving=${selectedDirect?.address}&involving=${myAddress}&encoding=BASE64&limit=100`
|
||||
const socket = new WebSocket(socketLink)
|
||||
|
||||
const pingGroupSocket = () => {
|
||||
socket.send('ping')
|
||||
timeoutId = setTimeout(() => {
|
||||
socket.close()
|
||||
clearTimeout(groupSocketTimeout)
|
||||
}, 5000) // Close the WebSocket connection if no pong message is received within 5 seconds.
|
||||
}
|
||||
socket.onopen = () => {
|
||||
|
||||
setTimeout(pingGroupSocket, 50)
|
||||
}
|
||||
socket.onmessage = (e) => {
|
||||
forceCloseWebSocket(); // Close any existing connection
|
||||
|
||||
if (!selectedDirect?.address || !myAddress) return;
|
||||
|
||||
const socketLink = `${getBaseApiReactSocket()}/websockets/chat/messages?involving=${selectedDirect?.address}&involving=${myAddress}&encoding=BASE64&limit=100`;
|
||||
socketRef.current = new WebSocket(socketLink);
|
||||
|
||||
socketRef.current.onopen = () => {
|
||||
console.log('WebSocket connection opened');
|
||||
setTimeout(pingWebSocket, 50); // Initial ping
|
||||
};
|
||||
|
||||
socketRef.current.onmessage = (e) => {
|
||||
try {
|
||||
if (e.data === 'pong') {
|
||||
|
||||
clearTimeout(timeoutId)
|
||||
groupSocketTimeout = setTimeout(pingGroupSocket, 45000)
|
||||
return
|
||||
clearTimeout(timeoutIdRef.current);
|
||||
groupSocketTimeoutRef.current = setTimeout(pingWebSocket, 45000); // Ping every 45 seconds
|
||||
} else {
|
||||
decryptMessages(JSON.parse(e.data))
|
||||
setIsLoading(false)
|
||||
decryptMessages(JSON.parse(e.data));
|
||||
setIsLoading(false);
|
||||
}
|
||||
|
||||
} catch (error) {
|
||||
|
||||
console.error('Error handling WebSocket message:', error);
|
||||
}
|
||||
|
||||
}
|
||||
socket.onclose = () => {
|
||||
console.log('closed')
|
||||
clearTimeout(socketTimeout)
|
||||
setTimeout(() => initWebsocketMessageGroup(), 50)
|
||||
|
||||
}
|
||||
socket.onerror = (e) => {
|
||||
clearTimeout(groupSocketTimeout)
|
||||
socket.close()
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
socketRef.current.onclose = (event) => {
|
||||
clearTimeout(groupSocketTimeoutRef.current);
|
||||
clearTimeout(timeoutIdRef.current);
|
||||
console.warn(`WebSocket closed: ${event.reason || 'unknown reason'}`);
|
||||
if (event.reason !== 'forced' && event.code !== 1000) {
|
||||
setTimeout(() => initWebsocketMessageGroup(), 10000); // Retry after 10 seconds
|
||||
}
|
||||
};
|
||||
|
||||
socketRef.current.onerror = (error) => {
|
||||
console.error('WebSocket error:', error);
|
||||
clearTimeout(groupSocketTimeoutRef.current);
|
||||
clearTimeout(timeoutIdRef.current);
|
||||
if (socketRef.current) {
|
||||
socketRef.current.close();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
|
||||
useEffect(()=> {
|
||||
if(hasInitializedWebsocket.current) return
|
||||
setIsLoading(true)
|
||||
initWebsocketMessageGroup()
|
||||
hasInitializedWebsocket.current = true
|
||||
}, [])
|
||||
useEffect(() => {
|
||||
if (hasInitializedWebsocket.current || isNewChat) return;
|
||||
setIsLoading(true);
|
||||
initWebsocketMessageGroup();
|
||||
hasInitializedWebsocket.current = true;
|
||||
|
||||
return () => {
|
||||
forceCloseWebSocket(); // Clean up WebSocket on component unmount
|
||||
};
|
||||
}, [selectedDirect?.address, myAddress, isNewChat]);
|
||||
|
||||
|
||||
|
||||
const sendChatDirect = async ({ chatReference = undefined, messageText}: any)=> {
|
||||
const sendChatDirect = async ({ chatReference = undefined, messageText}: any, address, publicKeyOfRecipient, isNewChatVar)=> {
|
||||
try {
|
||||
const directTo = isNewChat ? directToValue : selectedDirect.address
|
||||
const directTo = isNewChatVar ? directToValue : address
|
||||
|
||||
if(!directTo) return
|
||||
return new Promise((res, rej)=> {
|
||||
chrome?.runtime?.sendMessage({ action: "sendChatDirect", payload: {
|
||||
directTo, chatReference, messageText
|
||||
directTo, chatReference, messageText, publicKeyOfRecipient, address: directTo
|
||||
}}, async (response) => {
|
||||
|
||||
if (!response?.error) {
|
||||
if(isNewChat){
|
||||
if(isNewChatVar){
|
||||
|
||||
let getRecipientName = null
|
||||
try {
|
||||
@ -186,6 +246,7 @@ const sendChatDirect = async ({ chatReference = undefined, messageText}: any)=>
|
||||
})
|
||||
} catch (error) {
|
||||
throw new Error(error)
|
||||
} finally {
|
||||
}
|
||||
}
|
||||
const clearEditorContent = () => {
|
||||
@ -197,33 +258,60 @@ const clearEditorContent = () => {
|
||||
|
||||
const sendMessage = async ()=> {
|
||||
try {
|
||||
if(+balance < 4) throw new Error('You need at least 4 QORT to send a message')
|
||||
if(isSending) return
|
||||
if (editorRef.current) {
|
||||
const htmlContent = editorRef.current.getHTML();
|
||||
|
||||
if(!htmlContent?.trim() || htmlContent?.trim() === '<p></p>') return
|
||||
setIsSending(true)
|
||||
pauseAllQueues()
|
||||
const message = JSON.stringify(htmlContent)
|
||||
|
||||
const res = await sendChatDirect({ messageText: htmlContent})
|
||||
|
||||
if(isNewChat){
|
||||
await sendChatDirect({ messageText: htmlContent}, null, null, true)
|
||||
return
|
||||
}
|
||||
const sendMessageFunc = async () => {
|
||||
await sendChatDirect({ messageText: htmlContent}, selectedDirect?.address, publicKeyOfRecipient, false)
|
||||
};
|
||||
|
||||
// Add the function to the queue
|
||||
const messageObj = {
|
||||
message: {
|
||||
text: htmlContent,
|
||||
timestamp: Date.now(),
|
||||
senderName: myName,
|
||||
sender: myAddress
|
||||
},
|
||||
|
||||
}
|
||||
addToQueue(sendMessageFunc, messageObj, 'chat-direct',
|
||||
selectedDirect?.address );
|
||||
setTimeout(() => {
|
||||
executeEvent("sent-new-message-group", {})
|
||||
}, 150);
|
||||
clearEditorContent()
|
||||
clearEditorContent()
|
||||
}
|
||||
// send chat message
|
||||
} catch (error) {
|
||||
const errorMsg = error?.message || error
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error,
|
||||
message: errorMsg === 'invalid signature' ? 'You need at least 4 QORT to send a message' : errorMsg,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
console.error(error)
|
||||
} finally {
|
||||
setIsSending(false)
|
||||
resumeAllQueues()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
height: isMobile ? '100%' : '100vh',
|
||||
@ -241,7 +329,7 @@ const clearEditorContent = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<ChatList initialMessages={messages} myAddress={myAddress} tempMessages={[]}/>
|
||||
<ChatList initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
|
||||
|
||||
|
||||
<div style={{
|
||||
|
@ -20,7 +20,7 @@ import { executeEvent } from '../../utils/events'
|
||||
|
||||
|
||||
|
||||
export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey, myAddress, handleNewEncryptionNotification, hide, handleSecretKeyCreationInProgress, triedToFetchSecretKey, myName}) => {
|
||||
export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey, myAddress, handleNewEncryptionNotification, hide, handleSecretKeyCreationInProgress, triedToFetchSecretKey, myName, balance}) => {
|
||||
const [messages, setMessages] = useState([])
|
||||
const [isSending, setIsSending] = useState(false)
|
||||
const [isLoading, setIsLoading] = useState(false)
|
||||
@ -277,6 +277,7 @@ const clearEditorContent = () => {
|
||||
const sendMessage = async ()=> {
|
||||
try {
|
||||
if(isSending) return
|
||||
if(+balance < 4) throw new Error('You need at least 4 QORT to send a message')
|
||||
pauseAllQueues()
|
||||
if (editorRef.current) {
|
||||
const htmlContent = editorRef.current.getHTML();
|
||||
@ -313,9 +314,10 @@ const clearEditorContent = () => {
|
||||
}
|
||||
// send chat message
|
||||
} catch (error) {
|
||||
const errorMsg = error?.message || error
|
||||
setInfoSnack({
|
||||
type: "error",
|
||||
message: error,
|
||||
message: errorMsg,
|
||||
});
|
||||
setOpenSnack(true);
|
||||
console.error(error)
|
||||
|
@ -335,11 +335,11 @@ export const GroupAnnouncements = ({
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (selectedGroup && secretKey && !hasInitialized.current) {
|
||||
if (selectedGroup && secretKey && !hasInitialized.current && !hide) {
|
||||
getAnnouncements(selectedGroup);
|
||||
hasInitialized.current = true
|
||||
}
|
||||
}, [selectedGroup, secretKey]);
|
||||
}, [selectedGroup, secretKey, hide]);
|
||||
|
||||
|
||||
const loadMore = async()=> {
|
||||
@ -428,14 +428,14 @@ export const GroupAnnouncements = ({
|
||||
}, [checkNewMessages])
|
||||
|
||||
useEffect(() => {
|
||||
if(!secretKey) return
|
||||
if(!secretKey || hide) return
|
||||
checkNewMessagesFunc()
|
||||
return () => {
|
||||
if (interval?.current) {
|
||||
clearInterval(interval.current)
|
||||
}
|
||||
}
|
||||
}, [checkNewMessagesFunc])
|
||||
}, [checkNewMessagesFunc, hide])
|
||||
|
||||
|
||||
|
||||
|
@ -46,7 +46,7 @@ export const GroupForum = ({
|
||||
left: hide && '-1000px'
|
||||
}}
|
||||
>
|
||||
<GroupMail getSecretKey={getSecretKey} selectedGroup={selectedGroup} userInfo={userInfo} secretKey={secretKey} defaultThread={defaultThread} setDefaultThread={setDefaultThread} />
|
||||
<GroupMail hide={hide} getSecretKey={getSecretKey} selectedGroup={selectedGroup} userInfo={userInfo} secretKey={secretKey} defaultThread={defaultThread} setDefaultThread={setDefaultThread} />
|
||||
|
||||
</div>
|
||||
);
|
||||
|
@ -6,7 +6,10 @@ import { Avatar, Box, Typography } from "@mui/material";
|
||||
import { formatTimestamp } from "../../utils/time";
|
||||
import { getBaseApi } from "../../background";
|
||||
import { getBaseApiReact } from "../../App";
|
||||
|
||||
import { generateHTML } from "@tiptap/react";
|
||||
import Highlight from '@tiptap/extension-highlight'
|
||||
import StarterKit from '@tiptap/starter-kit'
|
||||
import Underline from '@tiptap/extension-underline'
|
||||
export const MessageItem = ({ message, onSeen, isLast, isTemp }) => {
|
||||
|
||||
const { ref, inView } = useInView({
|
||||
@ -60,6 +63,9 @@ export const MessageItem = ({ message, onSeen, isLast, isTemp }) => {
|
||||
>
|
||||
{message?.senderName || message?.sender}
|
||||
</Typography>
|
||||
{message?.messageText && (
|
||||
<MessageDisplay htmlContent={generateHTML(message?.messageText, [StarterKit, Underline, Highlight])} />
|
||||
)}
|
||||
{message?.text?.type === "notification" ? (
|
||||
<MessageDisplay htmlContent={message.text?.data?.message} />
|
||||
) : (
|
||||
|
@ -63,7 +63,8 @@ export const GroupMail = ({
|
||||
getSecretKey,
|
||||
secretKey,
|
||||
defaultThread,
|
||||
setDefaultThread
|
||||
setDefaultThread,
|
||||
hide
|
||||
}) => {
|
||||
const [viewedThreads, setViewedThreads] = React.useState<any>({});
|
||||
const [filterMode, setFilterMode] = useState<string>("Recently active");
|
||||
@ -353,6 +354,7 @@ export const GroupMail = ({
|
||||
const filterModeRef = useRef("");
|
||||
|
||||
useEffect(() => {
|
||||
if(hide) return
|
||||
if (filterModeRef.current !== filterMode) {
|
||||
firstMount.current = false;
|
||||
}
|
||||
@ -368,7 +370,7 @@ export const GroupMail = ({
|
||||
setTempData()
|
||||
firstMount.current = true;
|
||||
}
|
||||
}, [groupId, members, filterMode]);
|
||||
}, [groupId, members, filterMode, hide]);
|
||||
|
||||
const closeThread = useCallback(() => {
|
||||
setCurrentThread(null);
|
||||
|
@ -332,7 +332,6 @@ export const Group = ({
|
||||
const [directs, setDirects] = useState([]);
|
||||
const [admins, setAdmins] = useState([]);
|
||||
const [adminsWithNames, setAdminsWithNames] = useState([]);
|
||||
console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
const [members, setMembers] = useState([]);
|
||||
const [groupOwner, setGroupOwner] = useState(null);
|
||||
const [triedToFetchSecretKey, setTriedToFetchSecretKey] = useState(false);
|
||||
@ -574,7 +573,6 @@ console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
let publishFromStorage
|
||||
let adminsFromStorage
|
||||
const groupData = await getGroupDataSingle(selectedGroup?.groupId)
|
||||
console.log('groupData', groupData)
|
||||
if(groupData?.secretKeyData && Date.now() - groupData?.timestampLastSet < 3600000 ){
|
||||
|
||||
dataFromStorage = groupData.secretKeyData
|
||||
@ -1518,27 +1516,42 @@ console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
setMemberCountFromSecretKeyData(null);
|
||||
setTriedToFetchSecretKey(false);
|
||||
setFirstSecretKeyInCreation(false);
|
||||
setGroupSection("announcement");
|
||||
// setGroupSection("announcement");
|
||||
setGroupSection("chat");
|
||||
setIsOpenDrawer(false)
|
||||
setTimeout(() => {
|
||||
setSelectedGroup(group);
|
||||
|
||||
getTimestampEnterChat();
|
||||
// getTimestampEnterChat();
|
||||
}, 200);
|
||||
|
||||
if (groupSectionRef.current === "announcement") {
|
||||
|
||||
chrome?.runtime?.sendMessage({
|
||||
action: "addGroupNotificationTimestamp",
|
||||
action: "addTimestampEnterChat",
|
||||
payload: {
|
||||
timestamp: Date.now(),
|
||||
groupId: group.groupId,
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
setTimeout(() => {
|
||||
getTimestampEnterChat();
|
||||
}, 200);
|
||||
|
||||
|
||||
setTimeout(() => {
|
||||
getGroupAnnouncements();
|
||||
}, 600);
|
||||
// if (groupSectionRef.current === "announcement") {
|
||||
// chrome?.runtime?.sendMessage({
|
||||
// action: "addGroupNotificationTimestamp",
|
||||
// payload: {
|
||||
// timestamp: Date.now(),
|
||||
// groupId: group.groupId,
|
||||
// },
|
||||
// });
|
||||
// }
|
||||
|
||||
// setTimeout(() => {
|
||||
// getGroupAnnouncements();
|
||||
// }, 600);
|
||||
}}
|
||||
sx={{
|
||||
display: "flex",
|
||||
@ -1700,6 +1713,7 @@ console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
setSelectedDirect={setSelectedDirect}
|
||||
setNewChat={setNewChat}
|
||||
getTimestampEnterChat={getTimestampEnterChat}
|
||||
balance={balance}
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
@ -1727,6 +1741,7 @@ console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
}
|
||||
triedToFetchSecretKey={triedToFetchSecretKey}
|
||||
myName={userInfo?.name}
|
||||
balance={balance}
|
||||
/>
|
||||
)}
|
||||
{firstSecretKeyInCreation &&
|
||||
@ -1892,6 +1907,7 @@ console.log('adminsWithNames', {adminsWithNames}, {admins})
|
||||
setSelectedDirect={setSelectedDirect}
|
||||
setNewChat={setNewChat}
|
||||
getTimestampEnterChat={getTimestampEnterChat}
|
||||
myName={userInfo?.name}
|
||||
/>
|
||||
</Box>
|
||||
</>
|
||||
|
Loading…
x
Reference in New Issue
Block a user