diff --git a/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentThumbnailFile.svelte b/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentThumbnailFile.svelte index cecdc784c9..73ef7852e1 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentThumbnailFile.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentThumbnailFile.svelte @@ -145,7 +145,9 @@
{name} diff --git a/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList.svelte b/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList.svelte index 46fc2d4313..7e29df60b0 100644 --- a/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList.svelte +++ b/tools/server/webui/src/lib/components/app/chat/ChatAttachments/ChatAttachmentsList.svelte @@ -2,10 +2,8 @@ import { ChatAttachmentThumbnailImage, ChatAttachmentThumbnailFile } from '$lib/components/app'; import { Button } from '$lib/components/ui/button'; import { ChevronLeft, ChevronRight } from '@lucide/svelte'; - import { getFileTypeCategory } from '$lib/utils/file-type'; - import { FileTypeCategory } from '$lib/enums'; - import { isImageFile } from '$lib/utils/attachment-type'; import { DialogChatAttachmentPreview, DialogChatAttachmentsViewAll } from '$lib/components/app'; + import { getAttachmentDisplayItems } from '$lib/utils/attachment-display'; import type { ChatAttachmentDisplayItem, ChatAttachmentPreviewItem } from '$lib/types/chat'; import type { DatabaseMessageExtra } from '$lib/types/database'; @@ -40,7 +38,7 @@ limitToSingleRow = false }: Props = $props(); - let displayItems = $derived(getDisplayItems()); + let displayItems = $derived(getAttachmentDisplayItems({ uploadedFiles, attachments })); let canScrollLeft = $state(false); let canScrollRight = $state(false); @@ -51,40 +49,6 @@ let showViewAll = $derived(limitToSingleRow && displayItems.length > 0 && isScrollable); let viewAllDialogOpen = $state(false); - function getDisplayItems(): ChatAttachmentDisplayItem[] { - const items: ChatAttachmentDisplayItem[] = []; - - // Add uploaded files (ChatForm) - for (const file of uploadedFiles) { - items.push({ - id: file.id, - name: file.name, - size: file.size, - preview: file.preview, - isImage: getFileTypeCategory(file.type) === FileTypeCategory.IMAGE, - uploadedFile: file, - textContent: file.textContent - }); - } - - // Add stored attachments (ChatMessage) - for (const [index, attachment] of attachments.entries()) { - const isImage = isImageFile(attachment); - - items.push({ - id: `attachment-${index}`, - name: attachment.name, - preview: isImage && 'base64Url' in attachment ? attachment.base64Url : undefined, - isImage, - attachment, - attachmentIndex: index, - textContent: 'content' in attachment ? attachment.content : undefined - }); - } - - return items.reverse(); - } - function openPreview(item: ChatAttachmentDisplayItem, event?: MouseEvent) { event?.stopPropagation(); event?.preventDefault(); @@ -218,7 +182,7 @@
{/if} {:else} -
+
{#each displayItems as item (item.id)} {#if item.isImage && item.preview} (null); - let displayItems = $derived(getDisplayItems()); + let displayItems = $derived(getAttachmentDisplayItems({ uploadedFiles, attachments })); let imageItems = $derived(displayItems.filter((item) => item.isImage)); let fileItems = $derived(displayItems.filter((item) => !item.isImage)); - function getDisplayItems(): ChatAttachmentDisplayItem[] { - const items: ChatAttachmentDisplayItem[] = []; - - for (const file of uploadedFiles) { - items.push({ - id: file.id, - name: file.name, - size: file.size, - preview: file.preview, - isImage: getFileTypeCategory(file.type) === FileTypeCategory.IMAGE, - uploadedFile: file, - textContent: file.textContent - }); - } - - for (const [index, attachment] of attachments.entries()) { - const isImage = isImageFile(attachment); - - items.push({ - id: `attachment-${index}`, - name: attachment.name, - preview: isImage && 'base64Url' in attachment ? attachment.base64Url : undefined, - isImage, - attachment, - attachmentIndex: index, - textContent: 'content' in attachment ? attachment.content : undefined - }); - } - - return items.reverse(); - } - function openPreview(item: (typeof displayItems)[0], event?: Event) { if (event) { event.preventDefault(); diff --git a/tools/server/webui/src/lib/utils/attachment-display.ts b/tools/server/webui/src/lib/utils/attachment-display.ts new file mode 100644 index 0000000000..1fc166a881 --- /dev/null +++ b/tools/server/webui/src/lib/utils/attachment-display.ts @@ -0,0 +1,51 @@ +import { FileTypeCategory } from '$lib/enums'; +import type { ChatAttachmentDisplayItem } from '$lib/types/chat'; +import type { DatabaseMessageExtra } from '$lib/types/database'; +import { isImageFile } from '$lib/utils/attachment-type'; +import { getFileTypeCategory } from '$lib/utils/file-type'; + +export interface AttachmentDisplayItemsOptions { + uploadedFiles?: ChatUploadedFile[]; + attachments?: DatabaseMessageExtra[]; +} + +/** + * Creates a unified list of display items from uploaded files and stored attachments. + * Items are returned in reverse order (newest first). + */ +export function getAttachmentDisplayItems( + options: AttachmentDisplayItemsOptions +): ChatAttachmentDisplayItem[] { + const { uploadedFiles = [], attachments = [] } = options; + const items: ChatAttachmentDisplayItem[] = []; + + // Add uploaded files (ChatForm) + for (const file of uploadedFiles) { + items.push({ + id: file.id, + name: file.name, + size: file.size, + preview: file.preview, + isImage: getFileTypeCategory(file.type) === FileTypeCategory.IMAGE, + uploadedFile: file, + textContent: file.textContent + }); + } + + // Add stored attachments (ChatMessage) + for (const [index, attachment] of attachments.entries()) { + const isImage = isImageFile(attachment); + + items.push({ + id: `attachment-${index}`, + name: attachment.name, + preview: isImage && 'base64Url' in attachment ? attachment.base64Url : undefined, + isImage, + attachment, + attachmentIndex: index, + textContent: 'content' in attachment ? attachment.content : undefined + }); + } + + return items.reverse(); +}