From 5c944719564b2ff675eb858550d0c3615560b2f4 Mon Sep 17 00:00:00 2001
From: Ajay Bura <32841439+ajbura@users.noreply.github.com>
Date: Wed, 26 Feb 2025 21:43:43 +1100
Subject: [PATCH] Show image preview in upload window (#2231)
* memoize metadata callback properly
* add image preview on upload
* show spoiler image button inside image preview
---
.../upload-card/UploadCardRenderer.tsx | 89 ++++++++++++-------
src/app/features/room/RoomInput.tsx | 20 +++--
2 files changed, 71 insertions(+), 38 deletions(-)
diff --git a/src/app/components/upload-card/UploadCardRenderer.tsx b/src/app/components/upload-card/UploadCardRenderer.tsx
index 4cc8a00c..4383e204 100644
--- a/src/app/components/upload-card/UploadCardRenderer.tsx
+++ b/src/app/components/upload-card/UploadCardRenderer.tsx
@@ -1,5 +1,5 @@
-import React, { useCallback, useEffect } from 'react';
-import { Chip, Icon, IconButton, Icons, Text, Tooltip, TooltipProvider, color } from 'folds';
+import React, { useEffect } from 'react';
+import { Box, Chip, Icon, IconButton, Icons, Text, color, config, toRem } from 'folds';
import { UploadCard, UploadCardError, UploadCardProgress } from './UploadCard';
import { UploadStatus, UploadSuccess, useBindUploadAtom } from '../../state/upload';
import { useMatrixClient } from '../../hooks/useMatrixClient';
@@ -10,11 +10,60 @@ import {
TUploadItem,
TUploadMetadata,
} from '../../state/room/roomInputDrafts';
+import { useObjectURL } from '../../hooks/useObjectURL';
+
+type ImagePreviewProps = { fileItem: TUploadItem; onSpoiler: (marked: boolean) => void };
+function ImagePreview({ fileItem, onSpoiler }: ImagePreviewProps) {
+ const { originalFile, metadata } = fileItem;
+ const fileUrl = useObjectURL(originalFile);
+
+ return fileUrl ? (
+
+
+
+ }
+ onClick={() => onSpoiler(!metadata.markedAsSpoiler)}
+ >
+ Spoiler
+
+
+
+ ) : null;
+}
type UploadCardRendererProps = {
isEncrypted?: boolean;
fileItem: TUploadItem;
- setMetadata: (metadata: TUploadMetadata) => void;
+ setMetadata: (fileItem: TUploadItem, metadata: TUploadMetadata) => void;
onRemove: (file: TUploadContent) => void;
onComplete?: (upload: UploadSuccess) => void;
};
@@ -33,9 +82,9 @@ export function UploadCardRenderer({
if (upload.status === UploadStatus.Idle) startUpload();
- const toggleSpoiler = useCallback(() => {
- setMetadata({ ...metadata, markedAsSpoiler: !metadata.markedAsSpoiler });
- }, [setMetadata, metadata]);
+ const handleSpoiler = (marked: boolean) => {
+ setMetadata(fileItem, { ...metadata, markedAsSpoiler: marked });
+ };
const removeUpload = () => {
cancelUpload();
@@ -66,31 +115,6 @@ export function UploadCardRenderer({
Retry
)}
- {file.type.startsWith('image') && (
-
- Mark as Spoiler
-
- }
- position="Top"
- align="Center"
- >
- {(triggerRef) => (
-
-
-
- )}
-
- )}
+ {fileItem.originalFile.type.startsWith('image') && (
+
+ )}
{upload.status === UploadStatus.Idle && (
)}
diff --git a/src/app/features/room/RoomInput.tsx b/src/app/features/room/RoomInput.tsx
index 3141a5d5..faaba90c 100644
--- a/src/app/features/room/RoomInput.tsx
+++ b/src/app/features/room/RoomInput.tsx
@@ -70,6 +70,7 @@ import { useFilePasteHandler } from '../../hooks/useFilePasteHandler';
import { useFileDropZone } from '../../hooks/useFileDrop';
import {
TUploadItem,
+ TUploadMetadata,
roomIdToMsgDraftAtomFamily,
roomIdToReplyDraftAtomFamily,
roomIdToUploadItemsAtomFamily,
@@ -220,6 +221,17 @@ export const RoomInput = forwardRef(
[roomId, editor, setMsgDraft]
);
+ const handleFileMetadata = useCallback(
+ (fileItem: TUploadItem, metadata: TUploadMetadata) => {
+ setSelectedFiles({
+ type: 'REPLACE',
+ item: fileItem,
+ replacement: { ...fileItem, metadata },
+ });
+ },
+ [setSelectedFiles]
+ );
+
const handleRemoveUpload = useCallback(
(upload: TUploadContent | TUploadContent[]) => {
const uploads = Array.isArray(upload) ? upload : [upload];
@@ -433,13 +445,7 @@ export const RoomInput = forwardRef(
key={index}
isEncrypted={!!fileItem.encInfo}
fileItem={fileItem}
- setMetadata={(metadata) =>
- setSelectedFiles({
- type: 'REPLACE',
- item: fileItem,
- replacement: { ...fileItem, metadata },
- })
- }
+ setMetadata={handleFileMetadata}
onRemove={handleRemoveUpload}
/>
))}