From a7f0771ca90ffec1be74c66b82d77dfefcd16b00 Mon Sep 17 00:00:00 2001 From: Enrico Ros Date: Fri, 25 Apr 2025 11:50:16 -0700 Subject: [PATCH] Attachments: support image-only --- .../attachment-drafts/useAttachmentDrafts.tsx | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/src/common/attachment-drafts/useAttachmentDrafts.tsx b/src/common/attachment-drafts/useAttachmentDrafts.tsx index 685d7e041..f9b649b6c 100644 --- a/src/common/attachment-drafts/useAttachmentDrafts.tsx +++ b/src/common/attachment-drafts/useAttachmentDrafts.tsx @@ -20,13 +20,20 @@ import type { AttachmentDraftsStoreApi } from './store-attachment-drafts_slice'; const ATTACHMENTS_DEBUG_INTAKE = false; +function notifyOnlyImages(item: any) { + if (ATTACHMENTS_DEBUG_INTAKE) console.log('useAttachmentDrafts: Filtered out non-image clipboard item.', { item }); + addSnackbar({ key: 'attach-filtered', message: `Only image attachments are allowed right now.`, type: 'precondition-fail' }); +} + + /** * @param attachmentsStoreApi A Per-Chat or standalone Attachment Drafts store. * @param enableLoadURLsOnPaste Only used if invoking attachAppendDataTransfer or attachAppendClipboardItems. * @param hintAddImages Attach an additional image representation of the attachment; only if Release.Features.ENABLE_TEXT_AND_IMAGES. - * @param onFilterAGIFile If defined, run this async functiion on '.agi.json' files to decide whether to load them (if returns true) or attach them (if returns false). + * @param onFilterAGIFile If defined, run this async function on '.agi.json' files to decide whether to load them (if returns true) or attach them (if returns false). + * @param filterOnlyImages If true, only image attachments are allowed. */ -export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreApi | null, enableLoadURLsOnPaste: boolean, hintAddImages: boolean, onFilterAGIFile?: (file: File) => Promise) { +export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreApi | null, enableLoadURLsOnPaste: boolean, hintAddImages: boolean, onFilterAGIFile?: (file: File) => Promise, filterOnlyImages?: boolean) { // state const { _createAttachmentDraft, attachmentDrafts, attachmentsRemoveAll, attachmentsTakeAllFragments, attachmentsTakeFragmentsByType } = useChatAttachmentsStore(attachmentsStoreApi, useShallow(state => ({ @@ -52,10 +59,14 @@ export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreAp if (onFilterAGIFile && await onFilterAGIFile(fileWithHandle)) return; + // only-images: ignore by mime + if (filterOnlyImages && !fileWithHandle.type.startsWith('image/')) + return notifyOnlyImages(fileWithHandle); + return _createAttachmentDraft({ media: 'file', origin, fileWithHandle, refPath: overrideFileName || fileWithHandle.name, }, { hintAddImages }); - }, [_createAttachmentDraft, hintAddImages, onFilterAGIFile]); + }, [_createAttachmentDraft, filterOnlyImages, hintAddImages, onFilterAGIFile]); /** * Append a URL, likely a web page or youtube transcript, to the attachments. @@ -68,10 +79,16 @@ export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreAp if (!validUrl) return false; + // only-images: ignore URLs as they are not direct images in this flow + if (filterOnlyImages) { + notifyOnlyImages(url); + return false; + } + return _createAttachmentDraft({ media: 'url', origin, url: validUrl, refUrl: refUrl || url, }, { hintAddImages }); - }, [_createAttachmentDraft, hintAddImages]); + }, [_createAttachmentDraft, filterOnlyImages, hintAddImages]); /** * Append data transfer to the attachments. @@ -238,6 +255,12 @@ export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreAp if (imageAttached) continue; + // only-images: skip the rest + if (filterOnlyImages) { + notifyOnlyImages(clipboardItem); + continue; + } + // get the Plain text const textPlain = clipboardItem.types.includes('text/plain') ? await clipboardItem.getType('text/plain').then(blob => blob.text()) : ''; @@ -260,7 +283,7 @@ export function useAttachmentDrafts(attachmentsStoreApi: AttachmentDraftsStoreAp console.warn('Clipboard item has no text/html or text/plain item.', clipboardItem.types, clipboardItem); } - }, [_createAttachmentDraft, attachAppendFile, attachAppendUrl, enableLoadURLsOnPaste, hintAddImages]); + }, [_createAttachmentDraft, attachAppendFile, attachAppendUrl, enableLoadURLsOnPaste, filterOnlyImages, hintAddImages]); /** * Append ego content to the attachments.