mirror of
https://github.com/infinilabs/coco-app.git
synced 2025-12-16 03:27:43 +01:00
refactor: refactored file icon retrieval logic (#757)
* refactor: refactored file icon retrieval logic * update * update * update
This commit is contained in:
@@ -18,7 +18,6 @@
|
||||
"release-beta": "release-it --preRelease=beta --preReleaseBase=1"
|
||||
},
|
||||
"dependencies": {
|
||||
"@ant-design/icons": "^6.0.0",
|
||||
"@headlessui/react": "^2.2.2",
|
||||
"@tauri-apps/api": "^2.5.0",
|
||||
"@tauri-apps/plugin-autostart": "~2.2.0",
|
||||
|
||||
59
pnpm-lock.yaml
generated
59
pnpm-lock.yaml
generated
@@ -8,9 +8,6 @@ importers:
|
||||
|
||||
.:
|
||||
dependencies:
|
||||
'@ant-design/icons':
|
||||
specifier: ^6.0.0
|
||||
version: 6.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
'@headlessui/react':
|
||||
specifier: ^2.2.2
|
||||
version: 2.2.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -239,23 +236,6 @@ packages:
|
||||
resolution: {integrity: sha512-30iZtAPgz+LTIYoeivqYo853f02jBYSd5uGnGpkFV0M3xOt9aN73erkgYAmZU43x4VfqcnLxW9Kpg3R5LC4YYw==}
|
||||
engines: {node: '>=6.0.0'}
|
||||
|
||||
'@ant-design/colors@8.0.0':
|
||||
resolution: {integrity: sha512-6YzkKCw30EI/E9kHOIXsQDHmMvTllT8STzjMb4K2qzit33RW2pqCJP0sk+hidBntXxE+Vz4n1+RvCTfBw6OErw==}
|
||||
|
||||
'@ant-design/fast-color@3.0.0':
|
||||
resolution: {integrity: sha512-eqvpP7xEDm2S7dUzl5srEQCBTXZMmY3ekf97zI+M2DHOYyKdJGH0qua0JACHTqbkRnD/KHFQP9J1uMJ/XWVzzA==}
|
||||
engines: {node: '>=8.x'}
|
||||
|
||||
'@ant-design/icons-svg@4.4.2':
|
||||
resolution: {integrity: sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==}
|
||||
|
||||
'@ant-design/icons@6.0.0':
|
||||
resolution: {integrity: sha512-o0aCCAlHc1o4CQcapAwWzHeaW2x9F49g7P3IDtvtNXgHowtRWYb7kiubt8sQPFvfVIVU/jLw2hzeSlNt0FU+Uw==}
|
||||
engines: {node: '>=8'}
|
||||
peerDependencies:
|
||||
react: '>=16.0.0'
|
||||
react-dom: '>=16.0.0'
|
||||
|
||||
'@antfu/install-pkg@1.1.0':
|
||||
resolution: {integrity: sha512-MGQsmw10ZyI+EJo45CdSER4zEb+p31LpDAFp2Z3gkSd1yqVZGi0Ebx++YTEMonJy4oChEMLsxZ64j8FH6sSqtQ==}
|
||||
|
||||
@@ -1005,12 +985,6 @@ packages:
|
||||
resolution: {integrity: sha512-c83qWb22rNRuB0UaVCI0uRPNRr8Z0FWnEIvT47jiHAmOIUHbBOg5XvV7pM5x+rKn9HRpjxquDbXYSXr3fAKFcw==}
|
||||
engines: {node: '>=12'}
|
||||
|
||||
'@rc-component/util@1.2.1':
|
||||
resolution: {integrity: sha512-AUVu6jO+lWjQnUOOECwu8iR0EdElQgWW5NBv5vP/Uf9dWbAX3udhMutRlkVXjuac2E40ghkFy+ve00mc/3Fymg==}
|
||||
peerDependencies:
|
||||
react: '>=18.0.0'
|
||||
react-dom: '>=18.0.0'
|
||||
|
||||
'@react-aria/focus@3.20.2':
|
||||
resolution: {integrity: sha512-Q3rouk/rzoF/3TuH6FzoAIKrl+kzZi9LHmr8S5EqLAOyP9TXIKG34x2j42dZsAhrw7TbF9gA8tBKwnCNH4ZV+Q==}
|
||||
peerDependencies:
|
||||
@@ -1679,9 +1653,6 @@ packages:
|
||||
resolution: {integrity: sha512-cYY9mypksY8NRqgDB1XD1RiJL338v/551niynFTGkZOO2LHuB2OmOYxDIe/ttN9AHwrqdum1360G3ald0W9kCg==}
|
||||
engines: {node: '>=8'}
|
||||
|
||||
classnames@2.5.1:
|
||||
resolution: {integrity: sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==}
|
||||
|
||||
cli-boxes@3.0.0:
|
||||
resolution: {integrity: sha512-/lzGpEWL/8PfI0BmBOPRwp0c/wFNX1RdUML3jK/RcSBA9T8mZDdQpqYBKtCFTOfQbwPqWEOpjqW+Fnayc0969g==}
|
||||
engines: {node: '>=10'}
|
||||
@@ -3161,9 +3132,6 @@ packages:
|
||||
typescript:
|
||||
optional: true
|
||||
|
||||
react-is@18.3.1:
|
||||
resolution: {integrity: sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==}
|
||||
|
||||
react-markdown@9.1.0:
|
||||
resolution: {integrity: sha512-xaijuJB0kzGiUdG7nc2MOMDUDBWPyGAjZtUrow9XxUeua8IqeP+VlIfAZ3bphpcLTnSZXz6z9jcVC/TCwbfgdw==}
|
||||
peerDependencies:
|
||||
@@ -3809,23 +3777,6 @@ snapshots:
|
||||
'@jridgewell/gen-mapping': 0.3.8
|
||||
'@jridgewell/trace-mapping': 0.3.25
|
||||
|
||||
'@ant-design/colors@8.0.0':
|
||||
dependencies:
|
||||
'@ant-design/fast-color': 3.0.0
|
||||
|
||||
'@ant-design/fast-color@3.0.0': {}
|
||||
|
||||
'@ant-design/icons-svg@4.4.2': {}
|
||||
|
||||
'@ant-design/icons@6.0.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@ant-design/colors': 8.0.0
|
||||
'@ant-design/icons-svg': 4.4.2
|
||||
'@rc-component/util': 1.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
classnames: 2.5.1
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
|
||||
'@antfu/install-pkg@1.1.0':
|
||||
dependencies:
|
||||
package-manager-detector: 1.3.0
|
||||
@@ -4468,12 +4419,6 @@ snapshots:
|
||||
'@pnpm/network.ca-file': 1.0.2
|
||||
config-chain: 1.1.13
|
||||
|
||||
'@rc-component/util@1.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
react: 18.3.1
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
react-is: 18.3.1
|
||||
|
||||
'@react-aria/focus@3.20.2(react-dom@18.3.1(react@18.3.1))(react@18.3.1)':
|
||||
dependencies:
|
||||
'@react-aria/interactions': 3.25.0(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -5132,8 +5077,6 @@ snapshots:
|
||||
|
||||
ci-info@4.2.0: {}
|
||||
|
||||
classnames@2.5.1: {}
|
||||
|
||||
cli-boxes@3.0.0: {}
|
||||
|
||||
cli-cursor@5.0.0:
|
||||
@@ -6881,8 +6824,6 @@ snapshots:
|
||||
react-dom: 18.3.1(react@18.3.1)
|
||||
typescript: 5.8.3
|
||||
|
||||
react-is@18.3.1: {}
|
||||
|
||||
react-markdown@9.1.0(@types/react@18.3.21)(react@18.3.1):
|
||||
dependencies:
|
||||
'@types/hast': 3.0.4
|
||||
|
||||
@@ -6,9 +6,9 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useChatStore, UploadFile } from "@/stores/chatStore";
|
||||
import { useConnectStore } from "@/stores/connectStore";
|
||||
import FileIcon from "../Common/Icons/FileIcon";
|
||||
import platformAdapter from "@/utils/platformAdapter";
|
||||
import Tooltip2 from "../Common/Tooltip2";
|
||||
import FileIcon from "../Common/Icons/FileIcon";
|
||||
|
||||
interface FileListProps {
|
||||
sessionId: string;
|
||||
@@ -87,6 +87,7 @@ const FileList = (props: FileListProps) => {
|
||||
const {
|
||||
id,
|
||||
name,
|
||||
path,
|
||||
extname,
|
||||
size,
|
||||
uploaded,
|
||||
@@ -109,7 +110,7 @@ const FileList = (props: FileListProps) => {
|
||||
</div>
|
||||
)}
|
||||
|
||||
<FileIcon extname={extname} />
|
||||
<FileIcon path={path} />
|
||||
|
||||
<div className="flex flex-col justify-between overflow-hidden">
|
||||
<div className="truncate text-[#333333] dark:text-[#D8D8D8]">
|
||||
|
||||
@@ -6,10 +6,10 @@ import { useTranslation } from "react-i18next";
|
||||
|
||||
import { useConnectStore } from "@/stores/connectStore";
|
||||
import Checkbox from "@/components/Common/Checkbox";
|
||||
import FileIcon from "@/components/Common/Icons/FileIcon";
|
||||
import { AttachmentHit } from "@/types/commands";
|
||||
import { useAppStore } from "@/stores/appStore";
|
||||
import platformAdapter from "@/utils/platformAdapter";
|
||||
import FileIcon from "../Common/Icons/FileIcon";
|
||||
|
||||
interface SessionFileProps {
|
||||
sessionId: string;
|
||||
@@ -44,8 +44,6 @@ const SessionFile = (props: SessionFileProps) => {
|
||||
sessionId,
|
||||
});
|
||||
|
||||
console.log("get_attachment response", response);
|
||||
|
||||
setUploadedFiles(response?.hits?.hits ?? []);
|
||||
} else {
|
||||
}
|
||||
@@ -138,16 +136,16 @@ const SessionFile = (props: SessionFileProps) => {
|
||||
key={id}
|
||||
className="flex items-center justify-between min-h-12 px-2 rounded-[4px] bg-[#ededed] dark:bg-[#202126]"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<FileIcon extname={icon} />
|
||||
<div className="flex items-center gap-1">
|
||||
<FileIcon path={name} />
|
||||
|
||||
<div>
|
||||
<div className="text-sm leading-4 text-[#333] dark:text-[#D8D8D8]">
|
||||
{name}
|
||||
</div>
|
||||
<div className="text-xs text-[#999]">
|
||||
<span>{icon}</span>
|
||||
<span className="pl-2">
|
||||
{icon && <span className="pr-2">{icon}</span>}
|
||||
<span>
|
||||
{filesize(size, { standard: "jedec", spacer: "" })}
|
||||
</span>
|
||||
</div>
|
||||
|
||||
24
src/components/Common/Icons/FileIcon.tsx
Normal file
24
src/components/Common/Icons/FileIcon.tsx
Normal file
@@ -0,0 +1,24 @@
|
||||
import platformAdapter from "@/utils/platformAdapter";
|
||||
import { FC, useEffect, useState } from "react";
|
||||
import FontIcon from "./FontIcon";
|
||||
import { twMerge } from "tailwind-merge";
|
||||
|
||||
interface FileIconProps {
|
||||
path: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const FileIcon: FC<FileIconProps> = (props) => {
|
||||
const { path, className } = props;
|
||||
const [iconName, setIconName] = useState("");
|
||||
|
||||
useEffect(() => {
|
||||
platformAdapter
|
||||
.invokeBackend<string>("get_file_icon", { path })
|
||||
.then(setIconName);
|
||||
});
|
||||
|
||||
return <FontIcon name={iconName} className={twMerge("size-8", className)} />;
|
||||
};
|
||||
|
||||
export default FileIcon;
|
||||
@@ -1,21 +0,0 @@
|
||||
const AudioIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<title>audio</title>
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M14.1178571,4.0125 C14.225,4.11964286 14.2857143,4.26428571 14.2857143,4.41607143 L14.2857143,15.4285714 C14.2857143,15.7446429 14.0303571,16 13.7142857,16 L2.28571429,16 C1.96964286,16 1.71428571,15.7446429 1.71428571,15.4285714 L1.71428571,0.571428571 C1.71428571,0.255357143 1.96964286,0 2.28571429,0 L9.86964286,0 C10.0214286,0 10.1678571,0.0607142857 10.275,0.167857143 L14.1178571,4.0125 Z M10.7315824,7.11216117 C10.7428131,7.15148751 10.7485063,7.19218979 10.7485063,7.23309113 L10.7485063,8.07742614 C10.7484199,8.27364959 10.6183424,8.44607275 10.4296853,8.50003683 L8.32984514,9.09986306 L8.32984514,11.7071803 C8.32986605,12.5367078 7.67249692,13.217028 6.84345686,13.2454634 L6.79068592,13.2463395 C6.12766108,13.2463395 5.53916361,12.8217001 5.33010655,12.1924966 C5.1210495,11.563293 5.33842118,10.8709227 5.86959669,10.4741173 C6.40077221,10.0773119 7.12636292,10.0652587 7.67042486,10.4442027 L7.67020842,7.74937024 L7.68449368,7.74937024 C7.72405122,7.59919041 7.83988806,7.48101083 7.98924584,7.4384546 L10.1880418,6.81004755 C10.42156,6.74340323 10.6648954,6.87865515 10.7315824,7.11216117 Z M9.60714286,1.31785714 L12.9678571,4.67857143 L9.60714286,4.67857143 L9.60714286,1.31785714 Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default AudioIcon;
|
||||
@@ -1,21 +0,0 @@
|
||||
const VideoIcon = () => {
|
||||
return (
|
||||
<svg
|
||||
width="1em"
|
||||
height="1em"
|
||||
viewBox="0 0 16 16"
|
||||
version="1.1"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<title>video</title>
|
||||
<g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
|
||||
<path
|
||||
d="M14.1178571,4.0125 C14.225,4.11964286 14.2857143,4.26428571 14.2857143,4.41607143 L14.2857143,15.4285714 C14.2857143,15.7446429 14.0303571,16 13.7142857,16 L2.28571429,16 C1.96964286,16 1.71428571,15.7446429 1.71428571,15.4285714 L1.71428571,0.571428571 C1.71428571,0.255357143 1.96964286,0 2.28571429,0 L9.86964286,0 C10.0214286,0 10.1678571,0.0607142857 10.275,0.167857143 L14.1178571,4.0125 Z M12.9678571,4.67857143 L9.60714286,1.31785714 L9.60714286,4.67857143 L12.9678571,4.67857143 Z M10.5379461,10.3101106 L6.68957555,13.0059749 C6.59910784,13.0693494 6.47439406,13.0473861 6.41101953,12.9569184 C6.3874624,12.9232903 6.37482581,12.8832269 6.37482581,12.8421686 L6.37482581,7.45043999 C6.37482581,7.33998304 6.46436886,7.25043999 6.57482581,7.25043999 C6.61588409,7.25043999 6.65594753,7.26307658 6.68957555,7.28663371 L10.5379461,9.98249803 C10.6284138,10.0458726 10.6503772,10.1705863 10.5870027,10.2610541 C10.5736331,10.2801392 10.5570312,10.2967411 10.5379461,10.3101106 Z"
|
||||
fill="currentColor"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoIcon;
|
||||
@@ -1,154 +0,0 @@
|
||||
import {
|
||||
FileExcelFilled,
|
||||
FileImageFilled,
|
||||
FileMarkdownFilled,
|
||||
FilePdfFilled,
|
||||
FilePptFilled,
|
||||
FileTextFilled,
|
||||
FileWordFilled,
|
||||
FileZipFilled,
|
||||
} from "@ant-design/icons";
|
||||
|
||||
import AudioIcon from "./AudioIcon";
|
||||
import VideoIcon from "./VideoIcon";
|
||||
import { FC, useMemo } from "react";
|
||||
import clsx from "clsx";
|
||||
|
||||
interface FileIconProps {
|
||||
extname: string;
|
||||
className?: string;
|
||||
}
|
||||
|
||||
const FileIcon: FC<FileIconProps> = (props) => {
|
||||
const { extname, className } = props;
|
||||
|
||||
const presetFileIcons = [
|
||||
{
|
||||
icon: <FileExcelFilled />,
|
||||
color: "#22b35e",
|
||||
extnames: ["xlsx", "xls", "csv", "xlsm", "xltx", "xltm", "xlsb"],
|
||||
},
|
||||
{
|
||||
icon: <FileImageFilled />,
|
||||
color: "#13c2c2",
|
||||
extnames: [
|
||||
"png",
|
||||
"jpg",
|
||||
"jpeg",
|
||||
"gif",
|
||||
"bmp",
|
||||
"webp",
|
||||
"svg",
|
||||
"ico",
|
||||
"tiff",
|
||||
"raw",
|
||||
"heic",
|
||||
"psd",
|
||||
"ai",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: <FileMarkdownFilled />,
|
||||
color: "#722ed1",
|
||||
extnames: ["md", "mdx", "markdown", "mdown", "mkd", "mkdn"],
|
||||
},
|
||||
{
|
||||
icon: <FilePdfFilled />,
|
||||
color: "#ff4d4f",
|
||||
extnames: ["pdf", "xps", "oxps"],
|
||||
},
|
||||
{
|
||||
icon: <FilePptFilled />,
|
||||
color: "#d04423",
|
||||
extnames: [
|
||||
"ppt",
|
||||
"pptx",
|
||||
"pps",
|
||||
"ppsx",
|
||||
"pot",
|
||||
"potx",
|
||||
"pptm",
|
||||
"potm",
|
||||
"ppsm",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: <FileWordFilled />,
|
||||
color: "#1677ff",
|
||||
extnames: ["doc", "docx", "dot", "dotx", "docm", "dotm", "rtf", "odt"],
|
||||
},
|
||||
{
|
||||
icon: <FileZipFilled />,
|
||||
color: "#fab714",
|
||||
extnames: [
|
||||
"zip",
|
||||
"rar",
|
||||
"7z",
|
||||
"tar",
|
||||
"gz",
|
||||
"bz2",
|
||||
"xz",
|
||||
"tgz",
|
||||
"iso",
|
||||
"dmg",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: <VideoIcon />,
|
||||
color: "#7b61ff",
|
||||
extnames: [
|
||||
"mp4",
|
||||
"avi",
|
||||
"mov",
|
||||
"wmv",
|
||||
"flv",
|
||||
"mkv",
|
||||
"webm",
|
||||
"m4v",
|
||||
"mpeg",
|
||||
"mpg",
|
||||
"3gp",
|
||||
"rmvb",
|
||||
"ts",
|
||||
],
|
||||
},
|
||||
{
|
||||
icon: <AudioIcon />,
|
||||
color: "#eb2f96",
|
||||
extnames: [
|
||||
"mp3",
|
||||
"wav",
|
||||
"flac",
|
||||
"ape",
|
||||
"aac",
|
||||
"ogg",
|
||||
"wma",
|
||||
"m4a",
|
||||
"opus",
|
||||
"ac3",
|
||||
"mid",
|
||||
"midi",
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const [icon, iconColor] = useMemo(() => {
|
||||
for (const item of presetFileIcons) {
|
||||
const { icon, color, extnames } = item;
|
||||
|
||||
if (extnames.includes(extname)) {
|
||||
return [icon, color];
|
||||
}
|
||||
}
|
||||
|
||||
return [<FileTextFilled key="defaultIcon" />, "#8c8c8c"];
|
||||
}, [extname]);
|
||||
|
||||
return (
|
||||
<div className={clsx("text-3xl", className)} style={{ color: iconColor }}>
|
||||
{icon}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default FileIcon;
|
||||
@@ -59,7 +59,6 @@ const InputUpload: FC<InputUploadProps> = (props) => {
|
||||
captureWindowScreenshot,
|
||||
openFileDialog,
|
||||
getFileMetadata,
|
||||
getFileIcon,
|
||||
} = props;
|
||||
const { t, i18n } = useTranslation();
|
||||
const { uploadFiles, setUploadFiles } = useChatStore();
|
||||
@@ -105,7 +104,6 @@ const InputUpload: FC<InputUploadProps> = (props) => {
|
||||
...stat,
|
||||
id: nanoid(),
|
||||
path,
|
||||
icon: await getFileIcon(path, 256),
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -8,7 +8,6 @@ import { Metadata } from "tauri-plugin-fs-pro-api";
|
||||
export interface UploadFile extends Metadata {
|
||||
id: string;
|
||||
path: string;
|
||||
icon: string;
|
||||
uploaded?: boolean;
|
||||
attachmentId?: string;
|
||||
uploadFailed?: boolean;
|
||||
|
||||
Reference in New Issue
Block a user