From 05727c637f3835f578101465d4c5716e001312a1 Mon Sep 17 00:00:00 2001 From: Wang Jiyuan <59059173+EurFelux@users.noreply.github.com> Date: Mon, 16 Jun 2025 00:05:25 +0800 Subject: [PATCH] refactor: Encapsulate image display related components (#7211) --- src/renderer/src/pages/files/FileList.tsx | 105 +-------------------- src/renderer/src/pages/files/ImageItem.tsx | 105 +++++++++++++++++++++ src/renderer/src/pages/files/ImageList.tsx | 21 +++++ 3 files changed, 130 insertions(+), 101 deletions(-) create mode 100644 src/renderer/src/pages/files/ImageItem.tsx create mode 100644 src/renderer/src/pages/files/ImageList.tsx diff --git a/src/renderer/src/pages/files/FileList.tsx b/src/renderer/src/pages/files/FileList.tsx index cdb0421439..166ff1eaa2 100644 --- a/src/renderer/src/pages/files/FileList.tsx +++ b/src/renderer/src/pages/files/FileList.tsx @@ -1,15 +1,12 @@ -import FileManager from '@renderer/services/FileManager' import { FileType, FileTypes } from '@renderer/types' -import { formatFileSize } from '@renderer/utils' -import { Col, Image, Row, Spin } from 'antd' import { t } from 'i18next' import VirtualList from 'rc-virtual-list' import React, { memo } from 'react' -import styled from 'styled-components' import FileItem from './FileItem' +import ImageList from './ImageList' -interface FileItemProps { +interface FileListProps { id: FileTypes | 'all' | string list: { key: FileTypes | 'all' | string @@ -24,37 +21,9 @@ interface FileItemProps { files?: FileType[] } -const FileList: React.FC = ({ id, list, files }) => { +const FileList: React.FC = ({ id, list, files }) => { if (id === FileTypes.IMAGE && files?.length && files?.length > 0) { - return ( -
- - - {files?.map((file) => ( - - - - - - { - const img = e.target as HTMLImageElement - img.parentElement?.classList.add('loaded') - }} - /> - -
{formatFileSize(file.size)}
-
-
- - ))} -
-
-
- ) + return } return ( @@ -93,70 +62,4 @@ const FileList: React.FC = ({ id, list, files }) => { ) } -const ImageWrapper = styled.div` - position: relative; - aspect-ratio: 1; - overflow: hidden; - border-radius: 8px; - background-color: var(--color-background-soft); - display: flex; - align-items: center; - justify-content: center; - border: 0.5px solid var(--color-border); - - .ant-image { - height: 100%; - width: 100%; - opacity: 0; - transition: - opacity 0.3s ease, - transform 0.3s ease; - - &.loaded { - opacity: 1; - } - } - - &:hover { - .ant-image.loaded { - transform: scale(1.05); - } - - div:last-child { - opacity: 1; - } - } -` - -const LoadingWrapper = styled.div` - position: absolute; - top: 0; - left: 0; - right: 0; - bottom: 0; - display: flex; - align-items: center; - justify-content: center; - background-color: var(--color-background-soft); -` - -const ImageInfo = styled.div` - position: absolute; - bottom: 0; - left: 0; - right: 0; - background: rgba(0, 0, 0, 0.6); - color: white; - padding: 5px 8px; - opacity: 0; - transition: opacity 0.3s ease; - font-size: 12px; - - > div:first-child { - white-space: nowrap; - overflow: hidden; - text-overflow: ellipsis; - } -` - export default memo(FileList) diff --git a/src/renderer/src/pages/files/ImageItem.tsx b/src/renderer/src/pages/files/ImageItem.tsx new file mode 100644 index 0000000000..5d81062c3f --- /dev/null +++ b/src/renderer/src/pages/files/ImageItem.tsx @@ -0,0 +1,105 @@ +import FileManager from '@renderer/services/FileManager' +import { FileType } from '@renderer/types' +import { formatFileSize } from '@renderer/utils' +import { Col, Image, Spin } from 'antd' +import { memo, useState } from 'react' +import styled from 'styled-components' + +interface ImageItemProps { + file: FileType +} + +const ImageItem: React.FC = ({ file }) => { + const [loading, setLoading] = useState(true) + return ( + + + {loading && ( + + + + )} + { + const img = e.target as HTMLImageElement + img.parentElement?.classList.add('loaded') + setLoading(false) + }} + /> + +
{formatFileSize(file.size)}
+
+
+ + ) +} +const ImageWrapper = styled.div` + position: relative; + aspect-ratio: 1; + overflow: hidden; + border-radius: 8px; + background-color: var(--color-background-soft); + display: flex; + align-items: center; + justify-content: center; + border: 0.5px solid var(--color-border); + + .ant-image { + height: 100%; + width: 100%; + opacity: 0; + transition: + opacity 0.3s ease, + transform 0.3s ease; + + &.loaded { + opacity: 1; + } + } + + &:hover { + .ant-image.loaded { + transform: scale(1.05); + } + + div:last-child { + opacity: 1; + } + } +` + +const LoadingWrapper = styled.div` + position: absolute; + top: 0; + left: 0; + right: 0; + bottom: 0; + display: flex; + align-items: center; + justify-content: center; + background-color: var(--color-background-soft); +` + +const ImageInfo = styled.div` + position: absolute; + bottom: 0; + left: 0; + right: 0; + background: rgba(0, 0, 0, 0.6); + color: white; + padding: 5px 8px; + opacity: 0; + transition: opacity 0.3s ease; + font-size: 12px; + + > div:first-child { + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + } +` + +export default memo(ImageItem) diff --git a/src/renderer/src/pages/files/ImageList.tsx b/src/renderer/src/pages/files/ImageList.tsx new file mode 100644 index 0000000000..4914fca34a --- /dev/null +++ b/src/renderer/src/pages/files/ImageList.tsx @@ -0,0 +1,21 @@ +import { FileType } from '@renderer/types' +import { Image, Row } from 'antd' +import { memo } from 'react' + +import ImageItem from './ImageItem' + +interface ImageListProps { + files?: FileType[] +} + +const ImageList: React.FC = ({ files }) => { + return ( +
+ + {files?.map((file) => )} + +
+ ) +} + +export default memo(ImageList)