mirror of
https://github.com/Qortal/chrome-extension.git
synced 2025-02-11 17:55:49 +00:00
added reply
This commit is contained in:
parent
c8fb4974a7
commit
bcf22ca5e0
@ -129,7 +129,7 @@ const defaultValues: MyContextInterface = {
|
||||
message: "",
|
||||
},
|
||||
};
|
||||
export let isMobile = false
|
||||
export let isMobile = true
|
||||
|
||||
const isMobileDevice = () => {
|
||||
const userAgent = navigator.userAgent || navigator.vendor || window.opera;
|
||||
|
@ -1622,17 +1622,22 @@ async function sendChatDirect({
|
||||
...(otherData || {})
|
||||
};
|
||||
const messageStringified = JSON.stringify(finalJson);
|
||||
const tx = await createTransaction(18, keyPair, {
|
||||
console.log('chatReferencefinal', chatReference)
|
||||
const txBody = {
|
||||
timestamp: Date.now(),
|
||||
recipient: recipientAddress,
|
||||
recipientPublicKey: recipientPublicKey,
|
||||
hasChatReference: 0,
|
||||
hasChatReference: chatReference ? 1 : 0,
|
||||
message: messageStringified,
|
||||
lastReference: reference,
|
||||
proofOfWorkNonce: 0,
|
||||
isEncrypted: 1,
|
||||
isText: 1,
|
||||
});
|
||||
}
|
||||
if(chatReference){
|
||||
txBody['chatReference'] = chatReference
|
||||
}
|
||||
const tx = await createTransaction(18, keyPair, txBody);
|
||||
|
||||
// if (!hasEnoughBalance) {
|
||||
// throw new Error("Must have at least 4 QORT to send a chat message");
|
||||
@ -4000,7 +4005,7 @@ chrome?.runtime?.onMessage.addListener((request, sender, sendResponse) => {
|
||||
address,
|
||||
otherData
|
||||
} = request.payload;
|
||||
|
||||
console.log('chatReferencebg', chatReference)
|
||||
sendChatDirect({
|
||||
directTo,
|
||||
chatReference,
|
||||
|
@ -19,6 +19,7 @@ import ArrowBackIcon from '@mui/icons-material/ArrowBack';
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { ReturnIcon } from '../../assets/Icons/ReturnIcon';
|
||||
import { ExitIcon } from '../../assets/Icons/ExitIcon';
|
||||
import { MessageItem, ReplyPreview } from './MessageItem';
|
||||
|
||||
|
||||
const uid = new ShortUniqueId({ length: 5 });
|
||||
@ -41,12 +42,12 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
||||
const socketRef = useRef(null);
|
||||
const timeoutIdRef = useRef(null);
|
||||
const groupSocketTimeoutRef = useRef(null);
|
||||
|
||||
const [replyMessage, setReplyMessage] = useState(null)
|
||||
const setEditorRef = (editorInstance) => {
|
||||
editorRef.current = editorInstance;
|
||||
};
|
||||
const publicKeyOfRecipientRef = useRef(null)
|
||||
|
||||
console.log({messages})
|
||||
const getPublicKeyFunc = async (address)=> {
|
||||
try {
|
||||
const publicKey = await getPublicKey(address)
|
||||
@ -219,6 +220,7 @@ export const ChatDirect = ({ myAddress, isNewChat, selectedDirect, setSelectedDi
|
||||
|
||||
const sendChatDirect = async ({ chatReference = undefined, messageText, otherData}: any, address, publicKeyOfRecipient, isNewChatVar)=> {
|
||||
try {
|
||||
console.log('chatReferencedirect', chatReference)
|
||||
const directTo = isNewChatVar ? directToValue : address
|
||||
|
||||
if(!directTo) return
|
||||
@ -282,6 +284,8 @@ 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) {
|
||||
@ -297,12 +301,20 @@ const clearEditorContent = () => {
|
||||
await sendChatDirect({ messageText: htmlContent}, null, null, true)
|
||||
return
|
||||
}
|
||||
let repliedTo = replyMessage?.signature
|
||||
|
||||
if (replyMessage?.chatReference) {
|
||||
repliedTo = replyMessage?.chatReference
|
||||
}
|
||||
const otherData = {
|
||||
specialId: uid.rnd()
|
||||
specialId: uid.rnd(),
|
||||
repliedTo
|
||||
}
|
||||
const sendMessageFunc = async () => {
|
||||
await sendChatDirect({ messageText: htmlContent, otherData}, selectedDirect?.address, publicKeyOfRecipient, false)
|
||||
await sendChatDirect({ chatReference: undefined, messageText: htmlContent, otherData}, selectedDirect?.address, publicKeyOfRecipient, false)
|
||||
};
|
||||
|
||||
|
||||
|
||||
// Add the function to the queue
|
||||
const messageObj = {
|
||||
@ -321,6 +333,7 @@ const clearEditorContent = () => {
|
||||
executeEvent("sent-new-message-group", {})
|
||||
}, 150);
|
||||
clearEditorContent()
|
||||
setReplyMessage(null)
|
||||
}
|
||||
// send chat message
|
||||
} catch (error) {
|
||||
@ -337,6 +350,9 @@ const clearEditorContent = () => {
|
||||
}
|
||||
}
|
||||
|
||||
const onReply = useCallback((message)=> {
|
||||
setReplyMessage(message)
|
||||
}, [])
|
||||
|
||||
|
||||
return (
|
||||
@ -444,7 +460,7 @@ const clearEditorContent = () => {
|
||||
</>
|
||||
)}
|
||||
|
||||
<ChatList chatId={selectedDirect?.address} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
|
||||
<ChatList onReply={onReply} chatId={selectedDirect?.address} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
|
||||
|
||||
|
||||
<div style={{
|
||||
@ -470,7 +486,24 @@ const clearEditorContent = () => {
|
||||
flexGrow: isMobile && 1,
|
||||
overflow: !isMobile && "auto",
|
||||
}}>
|
||||
{replyMessage && (
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '5px',
|
||||
alignItems: 'flex-start',
|
||||
width: '100%'
|
||||
}}>
|
||||
<ReplyPreview message={replyMessage} />
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setReplyMessage(null)
|
||||
}}
|
||||
>
|
||||
<ExitIcon />
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
<Tiptap isFocusedParent={isFocusedParent} setEditorRef={setEditorRef} onEnter={sendMessage} isChat disableEnter={isMobile ? true : false} setIsFocusedParent={setIsFocusedParent}/>
|
||||
</div>
|
||||
|
@ -15,8 +15,10 @@ import { CustomizedSnackbars } from '../Snackbar/Snackbar'
|
||||
import { PUBLIC_NOTIFICATION_CODE_FIRST_SECRET_KEY } from '../../constants/codes'
|
||||
import { useMessageQueue } from '../../MessageQueueContext'
|
||||
import { executeEvent } from '../../utils/events'
|
||||
import { Box } from '@mui/material'
|
||||
import { Box, ButtonBase } from '@mui/material'
|
||||
import ShortUniqueId from "short-unique-id";
|
||||
import { ReplyPreview } from './MessageItem'
|
||||
import { ExitIcon } from '../../assets/Icons/ExitIcon'
|
||||
|
||||
|
||||
const uid = new ShortUniqueId({ length: 5 });
|
||||
@ -34,6 +36,7 @@ export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey,
|
||||
const [infoSnack, setInfoSnack] = React.useState(null);
|
||||
const hasInitialized = useRef(false)
|
||||
const [isFocusedParent, setIsFocusedParent] = useState(false);
|
||||
const [replyMessage, setReplyMessage] = useState(null)
|
||||
|
||||
const hasInitializedWebsocket = useRef(false)
|
||||
const socketRef = useRef(null); // WebSocket reference
|
||||
@ -111,6 +114,7 @@ export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey,
|
||||
...item,
|
||||
id: item.signature,
|
||||
text: item?.decryptedData?.message || "",
|
||||
repliedTo: item?.decryptedData?.repliedTo,
|
||||
unread: item?.sender === myAddress ? false : true
|
||||
}
|
||||
} )
|
||||
@ -121,6 +125,7 @@ export const ChatGroup = ({selectedGroup, secretKey, setSecretKey, getSecretKey,
|
||||
...item,
|
||||
id: item.signature,
|
||||
text: item?.decryptedData?.message || "",
|
||||
repliedTo: item?.decryptedData?.repliedTo,
|
||||
unread: false
|
||||
}
|
||||
} )
|
||||
@ -305,8 +310,15 @@ const clearEditorContent = () => {
|
||||
setIsSending(true)
|
||||
const message = htmlContent
|
||||
const secretKeyObject = await getSecretKey(false, true)
|
||||
|
||||
let repliedTo = replyMessage?.signature
|
||||
|
||||
if (replyMessage?.chatReference) {
|
||||
repliedTo = replyMessage?.chatReference
|
||||
}
|
||||
const otherData = {
|
||||
specialId: uid.rnd()
|
||||
specialId: uid.rnd(),
|
||||
repliedTo
|
||||
}
|
||||
const objectMessage = {
|
||||
message,
|
||||
@ -338,6 +350,7 @@ const clearEditorContent = () => {
|
||||
executeEvent("sent-new-message-group", {})
|
||||
}, 150);
|
||||
clearEditorContent()
|
||||
setReplyMessage(null)
|
||||
}
|
||||
// send chat message
|
||||
} catch (error) {
|
||||
@ -362,6 +375,9 @@ const clearEditorContent = () => {
|
||||
}
|
||||
}, [hide]);
|
||||
|
||||
const onReply = useCallback((message)=> {
|
||||
setReplyMessage(message)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<div style={{
|
||||
@ -374,7 +390,7 @@ const clearEditorContent = () => {
|
||||
left: hide && '-100000px',
|
||||
}}>
|
||||
|
||||
<ChatList chatId={selectedGroup} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
|
||||
<ChatList onReply={onReply} chatId={selectedGroup} initialMessages={messages} myAddress={myAddress} tempMessages={tempMessages}/>
|
||||
|
||||
|
||||
<div style={{
|
||||
@ -400,7 +416,25 @@ const clearEditorContent = () => {
|
||||
flexGrow: isMobile && 1,
|
||||
overflow: !isMobile && "auto",
|
||||
}}>
|
||||
{replyMessage && (
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
gap: '5px',
|
||||
alignItems: 'flex-start',
|
||||
width: '100%'
|
||||
}}>
|
||||
<ReplyPreview message={replyMessage} />
|
||||
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
setReplyMessage(null)
|
||||
}}
|
||||
>
|
||||
<ExitIcon />
|
||||
</ButtonBase>
|
||||
</Box>
|
||||
)}
|
||||
|
||||
|
||||
<Tiptap setEditorRef={setEditorRef} onEnter={sendMessage} isChat disableEnter={isMobile ? true : false} isFocusedParent={isFocusedParent} setIsFocusedParent={setIsFocusedParent} />
|
||||
</div>
|
||||
|
@ -8,7 +8,7 @@ import { subscribeToEvent, unsubscribeFromEvent } from '../../utils/events';
|
||||
// defaultHeight: 50,
|
||||
// });
|
||||
|
||||
export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) => {
|
||||
export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId, onReply }) => {
|
||||
|
||||
const hasLoadedInitialRef = useRef(false);
|
||||
const listRef = useRef();
|
||||
@ -18,7 +18,7 @@ export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) =
|
||||
fixedWidth: true,
|
||||
defaultHeight: 50,
|
||||
}), [chatId]); // Recreate cache when chatId changes
|
||||
|
||||
console.log('messages2', messages)
|
||||
useEffect(() => {
|
||||
cache.clearAll();
|
||||
}, []);
|
||||
@ -68,6 +68,10 @@ export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) =
|
||||
}
|
||||
};
|
||||
|
||||
const scrollToItem = useCallback((index) => {
|
||||
listRef.current.scrollToRow(index); // This scrolls to the specific index
|
||||
}, []);
|
||||
|
||||
const recomputeListHeights = () => {
|
||||
if (listRef.current) {
|
||||
listRef.current.recomputeRowHeights();
|
||||
@ -93,7 +97,18 @@ export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) =
|
||||
let message = messages[index];
|
||||
const isLargeMessage = message.text?.length > 200; // Adjust based on your message size threshold
|
||||
|
||||
// const reply = message?.repliedTo ? messages.find((msg)=> msg?.signature === message?.repliedTo) : undefined
|
||||
let replyIndex = messages.findIndex((msg)=> msg?.signature === message?.repliedTo)
|
||||
let reply
|
||||
if(message?.repliedTo && replyIndex !== -1){
|
||||
reply = messages[replyIndex]
|
||||
}
|
||||
if(message?.message && message?.groupDirectId){
|
||||
replyIndex = messages.findIndex((msg)=> msg?.signature === message?.message?.repliedTo)
|
||||
reply
|
||||
if(message?.message?.repliedTo && replyIndex !== -1){
|
||||
reply = messages[replyIndex]
|
||||
}
|
||||
message = {
|
||||
...(message?.message || {}),
|
||||
isTemp: true,
|
||||
@ -130,6 +145,10 @@ export const ChatList = ({ initialMessages, myAddress, tempMessages, chatId }) =
|
||||
onSeen={handleMessageSeen}
|
||||
isTemp={!!message?.isTemp}
|
||||
myAddress={myAddress}
|
||||
onReply={onReply}
|
||||
reply={reply}
|
||||
scrollToItem={scrollToItem}
|
||||
replyIndex={replyIndex}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
|
||||
import DOMPurify from 'dompurify';
|
||||
import './styles.css'; // Ensure this CSS file is imported
|
||||
|
||||
export const MessageDisplay = ({ htmlContent }) => {
|
||||
export const MessageDisplay = ({ htmlContent , isReply}) => {
|
||||
|
||||
const linkify = (text) => {
|
||||
// Regular expression to find URLs starting with https://, http://, or www.
|
||||
@ -53,7 +53,7 @@ export const MessageDisplay = ({ htmlContent }) => {
|
||||
};
|
||||
return (
|
||||
<div
|
||||
className="tiptap"
|
||||
className={`tiptap ${isReply ? 'isReply' : ''}`}
|
||||
dangerouslySetInnerHTML={{ __html: sanitizedContent }}
|
||||
onClick={(e) => {
|
||||
// Delegate click handling to the parent div
|
||||
|
@ -2,18 +2,30 @@ import { Message } from "@chatscope/chat-ui-kit-react";
|
||||
import React, { useEffect } from "react";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { MessageDisplay } from "./MessageDisplay";
|
||||
import { Avatar, Box, Typography } from "@mui/material";
|
||||
import { Avatar, Box, ButtonBase, 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'
|
||||
import Highlight from "@tiptap/extension-highlight";
|
||||
import StarterKit from "@tiptap/starter-kit";
|
||||
import Underline from "@tiptap/extension-underline";
|
||||
import { executeEvent } from "../../utils/events";
|
||||
import { WrapperUserAction } from "../WrapperUserAction";
|
||||
export const MessageItem = ({ message, onSeen, isLast, isTemp, myAddress }) => {
|
||||
import ReplyIcon from "@mui/icons-material/Reply";
|
||||
|
||||
export const MessageItem = ({
|
||||
message,
|
||||
onSeen,
|
||||
isLast,
|
||||
isTemp,
|
||||
myAddress,
|
||||
onReply,
|
||||
isShowingAsReply,
|
||||
reply,
|
||||
replyIndex,
|
||||
scrollToItem
|
||||
}) => {
|
||||
const { ref, inView } = useInView({
|
||||
threshold: 0.7, // Fully visible
|
||||
triggerOnce: true, // Only trigger once when it becomes visible
|
||||
@ -34,70 +46,169 @@ export const MessageItem = ({ message, onSeen, isLast, isTemp, myAddress }) => {
|
||||
borderRadius: "7px",
|
||||
width: "95%",
|
||||
display: "flex",
|
||||
gap: '7px',
|
||||
opacity: isTemp ? 0.5 : 1
|
||||
gap: "7px",
|
||||
opacity: isTemp ? 0.5 : 1,
|
||||
}}
|
||||
id={message?.signature}
|
||||
>
|
||||
<WrapperUserAction disabled={myAddress === message?.sender} address={message?.sender} name={message?.senderName}>
|
||||
<Avatar
|
||||
sx={{
|
||||
backgroundColor: '#27282c',
|
||||
color: 'white'
|
||||
}}
|
||||
alt={message?.senderName}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${message?.senderName}/qortal_avatar?async=true`}
|
||||
>
|
||||
{message?.senderName?.charAt(0)}
|
||||
</Avatar>
|
||||
</WrapperUserAction>
|
||||
{isShowingAsReply ? (
|
||||
<ReplyIcon
|
||||
sx={{
|
||||
fontSize: "30px",
|
||||
}}
|
||||
/>
|
||||
) : (
|
||||
<WrapperUserAction
|
||||
disabled={myAddress === message?.sender}
|
||||
address={message?.sender}
|
||||
name={message?.senderName}
|
||||
>
|
||||
<Avatar
|
||||
sx={{
|
||||
backgroundColor: "#27282c",
|
||||
color: "white",
|
||||
}}
|
||||
alt={message?.senderName}
|
||||
src={`${getBaseApiReact()}/arbitrary/THUMBNAIL/${
|
||||
message?.senderName
|
||||
}/qortal_avatar?async=true`}
|
||||
>
|
||||
{message?.senderName?.charAt(0)}
|
||||
</Avatar>
|
||||
</WrapperUserAction>
|
||||
)}
|
||||
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
gap: "7px",
|
||||
width: '100%'
|
||||
width: "100%",
|
||||
height: isShowingAsReply && "40px",
|
||||
}}
|
||||
>
|
||||
<WrapperUserAction disabled={myAddress === message?.sender} address={message?.sender} name={message?.senderName}>
|
||||
<Typography
|
||||
<Box
|
||||
sx={{
|
||||
fontWight: 600,
|
||||
fontFamily: "Inter",
|
||||
color: "cadetBlue",
|
||||
display: "flex",
|
||||
width: "100%",
|
||||
justifyContent: "space-between",
|
||||
}}
|
||||
|
||||
>
|
||||
{message?.senderName || message?.sender}
|
||||
</Typography>
|
||||
</WrapperUserAction>
|
||||
<WrapperUserAction
|
||||
disabled={myAddress === message?.sender}
|
||||
address={message?.sender}
|
||||
name={message?.senderName}
|
||||
>
|
||||
<Typography
|
||||
sx={{
|
||||
fontWight: 600,
|
||||
fontFamily: "Inter",
|
||||
color: "cadetBlue",
|
||||
}}
|
||||
>
|
||||
{message?.senderName || message?.sender}
|
||||
</Typography>
|
||||
</WrapperUserAction>
|
||||
{!isShowingAsReply && (
|
||||
<ButtonBase
|
||||
onClick={() => {
|
||||
onReply(message);
|
||||
}}
|
||||
>
|
||||
<ReplyIcon />
|
||||
</ButtonBase>
|
||||
)}
|
||||
</Box>
|
||||
{reply && (
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: '20px',
|
||||
width: "100%",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
maxHeight: '90px',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
onClick={()=> {
|
||||
scrollToItem(replyIndex)
|
||||
|
||||
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
height: '100%',
|
||||
width: '5px',
|
||||
background: 'white'
|
||||
}} />
|
||||
<Box sx={{
|
||||
padding: '5px'
|
||||
}}>
|
||||
<Typography sx={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 600
|
||||
}}>Replied to {reply?.senderName || reply?.senderAddress}</Typography>
|
||||
{reply?.messageText && (
|
||||
<MessageDisplay
|
||||
htmlContent={generateHTML(reply?.messageText, [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Highlight,
|
||||
])}
|
||||
/>
|
||||
)}
|
||||
{reply?.text?.type === "notification" ? (
|
||||
<MessageDisplay htmlContent={reply.text?.data?.message} />
|
||||
) : (
|
||||
<MessageDisplay isReply htmlContent={reply.text} />
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)}
|
||||
{message?.messageText && (
|
||||
<MessageDisplay htmlContent={generateHTML(message?.messageText, [StarterKit, Underline, Highlight])} />
|
||||
<MessageDisplay
|
||||
htmlContent={generateHTML(message?.messageText, [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Highlight,
|
||||
])}
|
||||
/>
|
||||
)}
|
||||
{message?.text?.type === "notification" ? (
|
||||
<MessageDisplay htmlContent={message.text?.data?.message} />
|
||||
) : (
|
||||
<MessageDisplay htmlContent={message.text} />
|
||||
)}
|
||||
<Box sx={{
|
||||
display: 'flex',
|
||||
justifyContent: 'flex-end',
|
||||
width: '100%',
|
||||
|
||||
}}>
|
||||
<Box
|
||||
sx={{
|
||||
display: "flex",
|
||||
justifyContent: "flex-end",
|
||||
width: "100%",
|
||||
}}
|
||||
>
|
||||
{isTemp ? (
|
||||
<Typography sx={{
|
||||
fontSize: '14px',
|
||||
color: 'gray',
|
||||
fontFamily: 'Inter'
|
||||
}}>Sending...</Typography>
|
||||
): (
|
||||
<Typography sx={{
|
||||
fontSize: '14px',
|
||||
color: 'gray',
|
||||
fontFamily: 'Inter'
|
||||
}}>{formatTimestamp(message.timestamp)}</Typography>
|
||||
) }
|
||||
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
color: "gray",
|
||||
fontFamily: "Inter",
|
||||
}}
|
||||
>
|
||||
Sending...
|
||||
</Typography>
|
||||
) : (
|
||||
<Typography
|
||||
sx={{
|
||||
fontSize: "14px",
|
||||
color: "gray",
|
||||
fontFamily: "Inter",
|
||||
}}
|
||||
>
|
||||
{formatTimestamp(message.timestamp)}
|
||||
</Typography>
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
|
||||
@ -115,3 +226,51 @@ export const MessageItem = ({ message, onSeen, isLast, isTemp, myAddress }) => {
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export const ReplyPreview = ({message})=> {
|
||||
|
||||
return (
|
||||
<Box
|
||||
sx={{
|
||||
marginTop: '20px',
|
||||
width: "100%",
|
||||
borderRadius: "5px",
|
||||
backgroundColor: "var(--bg-primary)",
|
||||
overflow: 'hidden',
|
||||
display: 'flex',
|
||||
gap: '20px',
|
||||
maxHeight: '90px',
|
||||
cursor: 'pointer'
|
||||
}}
|
||||
>
|
||||
<Box sx={{
|
||||
height: '100%',
|
||||
width: '5px',
|
||||
background: 'white'
|
||||
}} />
|
||||
<Box sx={{
|
||||
padding: '5px'
|
||||
}}>
|
||||
<Typography sx={{
|
||||
fontSize: '12px',
|
||||
fontWeight: 600
|
||||
}}>Replied to {message?.senderName || message?.senderAddress}</Typography>
|
||||
{message?.messageText && (
|
||||
<MessageDisplay
|
||||
htmlContent={generateHTML(message?.messageText, [
|
||||
StarterKit,
|
||||
Underline,
|
||||
Highlight,
|
||||
])}
|
||||
/>
|
||||
)}
|
||||
{message?.text?.type === "notification" ? (
|
||||
<MessageDisplay htmlContent={message.text?.data?.message} />
|
||||
) : (
|
||||
<MessageDisplay isReply htmlContent={message.text} />
|
||||
)}
|
||||
</Box>
|
||||
</Box>
|
||||
)
|
||||
}
|
@ -120,3 +120,6 @@
|
||||
max-width: 100%;
|
||||
}
|
||||
|
||||
.isReply p {
|
||||
font-size: 12px !important;
|
||||
}
|
||||
|
@ -31,6 +31,7 @@ const IconWrapper = ({ children, label, color }) => {
|
||||
fontSize: "12px",
|
||||
fontWeight: 500,
|
||||
color: color,
|
||||
wordBreak: 'normal'
|
||||
}}
|
||||
>
|
||||
{label}
|
||||
|
Loading…
x
Reference in New Issue
Block a user