Расширение функционала загрузки файлов: Предпросмотр изображений и вставка через буфер обмена
Введение
В предыдущей статье мы разобрали, как создать кастомный интерфейс для загрузки файлов с поддержкой двух режимов: кнопки и drag-and-drop. Мы также добавили возможность вставки файлов из буфера обмена. Однако часто пользователям нужно не только загружать файлы, но и просматривать их содержимое до или после загрузки. В этой статье мы реализуем функцию предпросмотра изображений и интегрируем её в наш компонент `UiUploadDraggerField`.
Зачем нужен предпросмотр?
Предпросмотр изображений — это важная функция, которая улучшает пользовательский опыт:
- До загрузки: Пользователи могут убедиться, что выбранное изображение соответствует их ожиданиям.
- После загрузки: Пользователи могут быстро просмотреть загруженные файлы без необходимости скачивать их.
- Удобство работы: Предпросмотр особенно полезен для работы с изображениями, PDF-файлами и другими форматами. Мы реализуем предпросмотр с помощью компонента `FilePreviewer`, который будет интегрирован в наш основной компонент.
Создание компонента FilePreviewer
Компонент `FilePreviewer` позволяет пользователям просматривать изображения перед их загрузкой или после загрузки на сервер. Вот как он работает:
Код компонента FilePreviewer.tsx
import React, { useImperativeHandle, useState } from "react";
import { Image, message } from "antd";
import { downloadAttachment } from "../../services/attachment-service";
import { UploadFile } from "antd/lib";
export interface FileReviewerRef {
handlePreview: (file: UploadFile) => void;
}
export interface FilePreviewerProps {
handlerRef: React.RefObject<FileReviewerRef>;
}
const FilePreviewer: React.FC<FilePreviewerProps> = ({ handlerRef }) => {
const [previewImage, setPreviewImage] = useState<string>("");
const [previewOpen, setPreviewOpen] = useState(false);
const handlePreview = (file: UploadFile) => {
if (file.preview && file.preview !== '') {
// Если preview уже существует, используем его
setPreviewImage(file.preview);
setPreviewOpen(true);
} else {
// Если preview отсутствует, загружаем файл с сервера
downloadAttachment(file.response.id)
.then((response) => {
if (response && response.data) {
const fileReader = new FileReader();
fileReader.readAsDataURL(response.data);
fileReader.onload = () => {
if (typeof fileReader.result === "string") {
// Преобразуем Blob в строку
file.preview = fileReader.result;
setPreviewImage(fileReader.result);
setPreviewOpen(true);
}
};
} else {
console.error("No data in response", response);
message.error("Ошибка при загрузке файла для предварительного просмотра.");
}
});
}
};
// Экспорт метода handlePreview через ref
useImperativeHandle(handlerRef, () => ({
handlePreview: (file) => handlePreview(file),
}));
return (
<Image
preview={{
visible: previewOpen,
onVisibleChange: (visible) => {
setPreviewOpen(visible); // Закрытие предпросмотра
if (!visible) setPreviewImage(""); // Очистка изображения
},
}}
src={previewImage}
style={{ display: "none", cursor: 'pointer' }}
/>
);
};
export default FilePreviewer;
Как это работает?
1. Предпросмотр локальных файлов:
- Если файл ещё не загружен на сервер, он может быть предварительно просмотрен с помощью свойства `file.preview`.
- Это особенно полезно для изображений, которые пользователь выбирает через диалоговое окно или перетаскивает.
2. Предпросмотр загруженных файлов:
- Если файл уже загружен на сервер, компонент скачивает его через API (`downloadAttachment`) и преобразует в формат, подходящий для отображения (например, Base64).
3. Интерфейс предпросмотра:
- Для отображения изображений используется компонент `Image` из Ant Design.
- Пользователь может открывать и закрывать предпросмотр, а также увеличивать изображение.
Интеграция `FilePreviewer` в `UiUploadDraggerField`
Чтобы использовать `FilePreviewer`, мы добавляем его в наш основной компонент `UiUploadDraggerField`. Вот как это выглядит:
<UploadList className={classname} {...UploadListProps} onPreview={handlePreview} />
<FilePreviewer handlerRef={fileReviewerRef} />
- `onPreview`: Этот обработчик вызывает метод `handlePreview` из `FilePreviewer`.
- `handlerRef`: Мы передаём ссылку на `FilePreviewer`, чтобы вызывать его методы из родительского компонента.
Вставка файлов через буфер обмена
Мы уже добавили поддержку вставки файлов из буфера обмена в первой статье. Однако теперь эта функция становится ещё удобнее благодаря предпросмотру. После вставки файла пользователь сразу может увидеть его содержимое.
Пример использования:
const handleFilePasted = (file: any) => {
uploadAttachment(entityType, entityId, fileType, { files: [file] }).then((res) => {
setAttachments((prev) => [...prev, res.data]);
});
};
Итог
Мы реализовали функцию предпросмотра изображений с помощью компонента `FilePreviewer`. Теперь пользователи могут:
- Просматривать локальные файлы перед загрузкой.
- Просматривать загруженные файлы.
- Вставлять файлы из буфера обмена и сразу видеть их содержимое.
Теперь ваш интерфейс загрузки файлов стал ещё удобнее и функциональнее!
другие статьи
Смотреть всёСоздание современной PWA: Опыт Callisto
Как мы создали PWA-приложение Callisto с Workbox, Webpack и Service Worker — разбор ключевых решений и технологий.
Видеокурс Camunda 8: Создаем первый процесс
Видеокурс Camunda 8: User Tasks & Camunda Forms
Статья описывает, как управлять задачами пользователей в Camunda 8 или как сделать людей участниками исполняемого бизнес-процесса.