diff --git a/src/App.tsx b/src/App.tsx index 558cd01..ad1f496 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -3219,7 +3219,7 @@ function App() { onClick={onOkUnsavedChanges} autoFocus > - {t('core:action.decline', { + {t('core:action.continue_logout', { postProcess: 'capitalize', })} diff --git a/src/components/Chat/ChatGroup.tsx b/src/components/Chat/ChatGroup.tsx index 0dd626e..2af7c2d 100644 --- a/src/components/Chat/ChatGroup.tsx +++ b/src/components/Chat/ChatGroup.tsx @@ -42,7 +42,7 @@ import CloseIcon from '@mui/icons-material/Close'; import { throttle } from 'lodash'; const uid = new ShortUniqueId({ length: 5 }); - +const uidImages = new ShortUniqueId({ length: 12 }); export const ChatGroup = ({ selectedGroup, secretKey, @@ -74,6 +74,7 @@ export const ChatGroup = ({ const [isOpenQManager, setIsOpenQManager] = useState(null); const [messageSize, setMessageSize] = useState(0); + const [chatImagesToSave, setChatImagesToSave] = useState([]); const hasInitializedWebsocket = useRef(false); const socketRef = useRef(null); // WebSocket reference const timeoutIdRef = useRef(null); // Timeout ID reference @@ -778,11 +779,45 @@ export const ChatGroup = ({ : { isEdited: chatReference ? true : false, }; + const imagesToPublish = []; + if (!chatReference && chatImagesToSave?.length > 0) { + chatImagesToSave.forEach((base64Img) => { + const identifier = `qchat_1_group_${selectedGroup}_${uidImages.rnd()}`; + imagesToPublish.push({ + service: 'IMAGE', + identifier, + name: myName, + base64: base64Img, + }); + }); + + const res = await window.sendMessage( + 'PUBLISH_MULTIPLE_QDN_RESOURCES', + + { + resources: imagesToPublish, + }, + 240000, + true + ); + console.log('res', res); + if (res !== true) throw new Error('Unable to publish images'); + } + const otherData = { repliedTo, ...(onEditMessage?.decryptedData || {}), type: chatReference ? 'edit' : '', specialId: uid.rnd(), + images: + onEditMessage?.images || + imagesToPublish.map((item) => { + return { + name: item.name, + identifier: item.identifier, + service: item.service, + }; + }), ...publicData, }; const objectMessage = { @@ -824,6 +859,7 @@ export const ChatGroup = ({ clearEditorContent(); setReplyMessage(null); setOnEditMessage(null); + setChatImagesToSave([]); } // send chat message } catch (error) { @@ -986,6 +1022,10 @@ export const ChatGroup = ({ const theme = useTheme(); + const insertImage = useCallback((img) => { + setChatImagesToSave((prev) => [...prev, img]); + }, []); + return (
+ + {chatImagesToSave?.map((imgBase64) => { + return ( + + ); + })} + {replyMessage && ( {messageSize > 750 && ( { - if (editor) { + if (editor && !isChat) { editor.view.dom.addEventListener('paste', handlePaste); return () => { editor.view.dom.removeEventListener('paste', handlePaste); @@ -366,12 +367,46 @@ export default ({ customEditorHeight, membersWithNames, enableMentions, + insertImage, }) => { const theme = useTheme(); const [isDisabledEditorEnter, setIsDisabledEditorEnter] = useAtom( isDisabledEditorEnterAtom ); + const handleImageUpload = async (file) => { + try { + if (!file.type.includes('image')) return; + let compressedFile = file; + if (file.type !== 'image/gif') { + await new Promise((resolve) => { + new Compressor(file, { + quality: 0.6, + maxWidth: 1200, + mimeType: 'image/webp', + success(result) { + compressedFile = new File([result], 'image.webp', { + type: 'image/webp', + }); + resolve(); + }, + error(err) { + console.error('Image compression error:', err); + }, + }); + }); + } + + if (compressedFile) { + const toBase64 = await fileToBase64(compressedFile); + insertImage(toBase64); + console.log('toBase64', toBase64); + } + } catch (error) { + console.error(error); + } + }; + const extensionsFiltered = isChat ? extensions.filter((item) => item?.name !== 'image') : extensions; @@ -543,6 +578,24 @@ export default ({ } return false; }, + handlePaste(view, event) { + if (!isChat) return; + const items = event.clipboardData?.items; + if (!items) return false; + + for (const item of items) { + if (item.type.startsWith('image/')) { + const file = item.getAsFile(); + if (file) { + event.preventDefault(); // Block the default paste + handleImageUpload(file); // Custom handler + return true; // Let ProseMirror know we handled it + } + } + } + + return false; // fallback to default behavior otherwise + }, }} /> diff --git a/src/qortalRequests/get.ts b/src/qortalRequests/get.ts index a160305..37ef736 100644 --- a/src/qortalRequests/get.ts +++ b/src/qortalRequests/get.ts @@ -1218,6 +1218,7 @@ export const publishMultipleQDNResources = async ( sender, isFromExtension ) => { + console.log('data', data); const requiredFields = ['resources']; const missingFields: string[] = []; let feeAmount = null;