From 68d8e62a5ca81110dbd419ac8921d70abcfd60cb Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Tue, 16 Dec 2025 12:32:52 +0530 Subject: [PATCH 1/3] fix: Share modal not working in year-in-review (#13079) --- .../components-next/year-in-review/ShareModal.vue | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/app/javascript/dashboard/components-next/year-in-review/ShareModal.vue b/app/javascript/dashboard/components-next/year-in-review/ShareModal.vue index 92f45a12b..12a556b0e 100644 --- a/app/javascript/dashboard/components-next/year-in-review/ShareModal.vue +++ b/app/javascript/dashboard/components-next/year-in-review/ShareModal.vue @@ -56,15 +56,19 @@ const generateImage = async () => { const bgColor = colorMap[props.slideBackground] || '#ffffff'; const dataUrl = await toPng(slideElement, { - quality: 2, pixelRatio: 1.2, backgroundColor: bgColor, + // Skip font/CSS embedding to avoid CORS issues with CDN stylesheets + // See: https://github.com/bubkoo/html-to-image/issues/49#issuecomment-762222100 + fontEmbedCSS: '', + cacheBust: true, }); const img = new Image(); img.src = dataUrl; - await new Promise(resolve => { + await new Promise((resolve, reject) => { img.onload = resolve; + img.onerror = reject; }); const finalCanvas = document.createElement('canvas'); From 02216471c3f2d91f1608c3ba99cb02f7f0a68dd6 Mon Sep 17 00:00:00 2001 From: Sivin Varghese <64252451+iamsivin@users.noreply.github.com> Date: Tue, 16 Dec 2025 14:35:42 +0530 Subject: [PATCH 2/3] feat: Enable attachment paste in new conversation modal (#13082) --- .../NewConversation/ComposeConversation.vue | 4 ++++ .../NewConversation/components/ActionButtons.vue | 15 +++++++++++++++ .../dashboard/components-next/sidebar/Sidebar.vue | 15 +++++++++++++-- .../components/widgets/conversation/ReplyBox.vue | 4 ++++ 4 files changed, 36 insertions(+), 2 deletions(-) diff --git a/app/javascript/dashboard/components-next/NewConversation/ComposeConversation.vue b/app/javascript/dashboard/components-next/NewConversation/ComposeConversation.vue index fa9102d59..ee71bf51a 100644 --- a/app/javascript/dashboard/components-next/NewConversation/ComposeConversation.vue +++ b/app/javascript/dashboard/components-next/NewConversation/ComposeConversation.vue @@ -9,6 +9,8 @@ import { useAlert } from 'dashboard/composables'; import { ExceptionWithMessage } from 'shared/helpers/CustomErrors'; import { debounce } from '@chatwoot/utils'; import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents'; +import { emitter } from 'shared/helpers/mitt'; +import { BUS_EVENTS } from 'shared/constants/busEvents'; import { searchContacts, createNewContact, @@ -226,6 +228,8 @@ const keyboardEvents = { action: () => { if (showComposeNewConversation.value) { showComposeNewConversation.value = false; + emit('close'); + emitter.emit(BUS_EVENTS.NEW_CONVERSATION_MODAL, false); } }, }, diff --git a/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue b/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue index cb1f9d99d..c2971c60d 100644 --- a/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue +++ b/app/javascript/dashboard/components-next/NewConversation/components/ActionButtons.vue @@ -4,6 +4,7 @@ import { useI18n } from 'vue-i18n'; import { useUISettings } from 'dashboard/composables/useUISettings'; import { useFileUpload } from 'dashboard/composables/useFileUpload'; import { vOnClickOutside } from '@vueuse/components'; +import { useEventListener } from '@vueuse/core'; import { ALLOWED_FILE_TYPES } from 'shared/constants/messages'; import { useKeyboardEvents } from 'dashboard/composables/useKeyboardEvents'; import FileUpload from 'vue-upload-component'; @@ -163,6 +164,20 @@ const keyboardEvents = { }, }; useKeyboardEvents(keyboardEvents); + +const onPaste = e => { + if (!props.isEmailOrWebWidgetInbox) return; + + const files = e.clipboardData?.files; + if (!files?.length) return; + + Array.from(files).forEach(file => { + const { name, type, size } = file; + onFileUpload({ file, name, type, size }); + }); +}; + +useEventListener(document, 'paste', onPaste);