From b148c5adf5de0934fc3b42a900df7679ba05393b Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Wed, 30 Oct 2024 20:45:48 +0800 Subject: [PATCH] feat: files ui improvements --- src/renderer/src/i18n/en-us.json | 7 +- src/renderer/src/i18n/zh-cn.json | 9 +- src/renderer/src/i18n/zh-tw.json | 7 +- src/renderer/src/pages/files/FilesPage.tsx | 182 +++++++++++++++++---- 4 files changed, 173 insertions(+), 32 deletions(-) diff --git a/src/renderer/src/i18n/en-us.json b/src/renderer/src/i18n/en-us.json index 14821f45..bc31014d 100644 --- a/src/renderer/src/i18n/en-us.json +++ b/src/renderer/src/i18n/en-us.json @@ -162,7 +162,12 @@ "name": "Name", "size": "Size", "count": "Count", - "created_at": "Created At" + "created_at": "Created At", + "image": "Image", + "text": "Text", + "document": "Document", + "actions": "Actions", + "open": "Open" }, "agents": { "title": "Agents", diff --git a/src/renderer/src/i18n/zh-cn.json b/src/renderer/src/i18n/zh-cn.json index bdbbf5d4..e72e4f17 100644 --- a/src/renderer/src/i18n/zh-cn.json +++ b/src/renderer/src/i18n/zh-cn.json @@ -162,7 +162,12 @@ "name": "文件名", "size": "大小", "count": "文件数", - "created_at": "创建时间" + "created_at": "创建时间", + "image": "图片", + "text": "文本", + "document": "文档", + "actions": "操作", + "open": "打开" }, "agents": { "title": "智能体", @@ -336,7 +341,7 @@ "new_topic": "新建话题", "zoom_in": "放大界面", "zoom_out": "缩小界面", - "zoom_reset": "���置缩放" + "zoom_reset": "置缩放" } }, "translate": { diff --git a/src/renderer/src/i18n/zh-tw.json b/src/renderer/src/i18n/zh-tw.json index 24a66a80..7facc660 100644 --- a/src/renderer/src/i18n/zh-tw.json +++ b/src/renderer/src/i18n/zh-tw.json @@ -162,7 +162,12 @@ "name": "名稱", "size": "大小", "count": "數量", - "created_at": "建立時間" + "created_at": "建立時間", + "image": "圖片", + "text": "文本", + "document": "文檔", + "actions": "操作", + "open": "打開" }, "agents": { "title": "智能體", diff --git a/src/renderer/src/pages/files/FilesPage.tsx b/src/renderer/src/pages/files/FilesPage.tsx index 5fb0b0bd..2ed87cb4 100644 --- a/src/renderer/src/pages/files/FilesPage.tsx +++ b/src/renderer/src/pages/files/FilesPage.tsx @@ -1,45 +1,39 @@ +import { FileImageOutlined, FilePdfOutlined, FileTextOutlined } from '@ant-design/icons' import { Navbar, NavbarCenter } from '@renderer/components/app/Navbar' import Scrollbar from '@renderer/components/Scrollbar' import db from '@renderer/databases' import FileManager from '@renderer/services/FileManager' import { FileType, FileTypes } from '@renderer/types' import { formatFileSize } from '@renderer/utils' -import { Image, Table } from 'antd' +import { Col, Image, Menu, Row, Spin, Table } from 'antd' import dayjs from 'dayjs' import { useLiveQuery } from 'dexie-react-hooks' -import { FC } from 'react' +import { FC, useState } from 'react' import { useTranslation } from 'react-i18next' import styled from 'styled-components' const FilesPage: FC = () => { const { t } = useTranslation() - const files = useLiveQuery(() => db.files.orderBy('count').reverse().toArray()) + const [fileType, setFileType] = useState(FileTypes.IMAGE) + + const files = useLiveQuery(() => db.files.where('type').equals(fileType).sortBy('count'), [fileType]) const dataSource = files?.map((file) => { - const isImage = file.type === FileTypes.IMAGE - const ImageView = - console.log(FileManager.getFileUrl(file)) return { key: file.id, - file: isImage ? ImageView : {file.origin_name}, - name: {file.origin_name}, + file: {file.origin_name}, size: formatFileSize(file), count: file.count, - created_at: dayjs(file.created_at).format('MM-DD HH:mm') + created_at: dayjs(file.created_at).format('MM-DD HH:mm'), + actions: {t('files.open')} } }) const columns = [ - { - title: t('files.file'), - dataIndex: 'file', - key: 'file', - width: '300px' - }, { title: t('files.name'), - dataIndex: 'name', - key: 'name' + dataIndex: 'file', + key: 'file' }, { title: t('files.size'), @@ -58,23 +52,66 @@ const FilesPage: FC = () => { dataIndex: 'created_at', key: 'created_at', width: '120px' + }, + { + title: t('files.actions'), + dataIndex: 'actions', + key: 'actions', + width: '50px' } ] + const menuItems = [ + { key: FileTypes.IMAGE, label: t('files.image'), icon: }, + { key: FileTypes.TEXT, label: t('files.text'), icon: }, + { key: FileTypes.DOCUMENT, label: t('files.document'), icon: } + ] + return ( {t('files.title')} + + setFileType(key as FileTypes)} /> + - + {fileType === FileTypes.IMAGE ? ( + + + {files?.map((file) => ( + + + + + + { + const img = e.target as HTMLImageElement + img.parentElement?.classList.add('loaded') + }} + /> + +
{formatFileSize(file)}
+
+
+ + ))} + + + ) : ( +
+ )} @@ -92,9 +129,7 @@ const ContentContainer = styled.div` display: flex; flex: 1; flex-direction: row; - justify-content: center; - height: 100%; - padding: 0 2px; + min-height: 100%; ` const TableContainer = styled(Scrollbar)` @@ -107,7 +142,98 @@ const TableContainer = styled(Scrollbar)` const FileNameText = styled.div` font-size: 14px; color: var(--color-text); - max-width: 300px; +` + +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; + + .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; + } +` + +const SideNav = styled.div` + width: var(--assistants-width); + border-right: 0.5px solid var(--color-border); + padding: 15px; + + .ant-menu { + border-inline-end: none !important; + background: transparent; + } + + .ant-menu-item { + height: 40px; + line-height: 40px; + margin: 4px 0; + width: 100%; + + &:hover { + background-color: var(--color-background-soft); + } + + &.ant-menu-item-selected { + background-color: var(--color-background-soft); + color: var(--color-primary); + } + } ` export default FilesPage