import {
BsFileEarmarkWordFill,
BsFileEarmarkExcelFill,
BsFileEarmarkPptFill,
BsFileEarmarkPdfFill,
BsFileEarmarkPlayFill,
BsFileEarmarkMusicFill,
BsFileEarmarkFontFill,
BsFileEarmarkImageFill,
BsFileEarmarkMinusFill,
BsApple,
BsWindows,
BsFileEarmarkZipFill,
BsMarkdownFill,
} from "solid-icons/bs"
import {
FaSolidDatabase,
FaSolidBook,
FaSolidCompactDisc,
FaSolidLink,
} from "solid-icons/fa"
import { IoFolder } from "solid-icons/io"
import { ImAndroid } from "solid-icons/im"
import { Obj, ObjType } from "~/types"
import { ext } from "./path"
import { joinBase } from "."
import {
VscodeIconsFileTypeAi2,
VscodeIconsFileTypePhotoshop2,
} from "~/components"
import { SiAsciinema } from "solid-icons/si"
import { isArchive } from "~/store/archive"
import { IconProps, IconTemplate } from "solid-icons/lib"
import { getSetting } from "~/store/settings"
// 通用自定义图标组件
export function createCustomIcon(imagePath: string, fallbackIcon: any) {
return (props: IconProps) => {
// 检查是否启用了新UI
const useNewUI = getSetting("use_newui") === "true"
if (useNewUI) {
// 使用自定义图片图标
return IconTemplate(
{
a: {
viewBox: "0 0 32 32",
},
c: ``,
},
props,
)
} else {
// 当 use_newui 为 false 时,使用备用图标
return fallbackIcon(props)
}
}
}
// 自定义图标配置类型
interface CustomIconConfig {
imagePath: string
fallbackIcon: any
}
// 自定义图标管理器
class CustomIconManager {
private customIcons: Map = new Map()
// 注册自定义图标
register(extension: string, config: CustomIconConfig) {
this.customIcons.set(extension.toLowerCase(), config)
}
// 获取自定义图标组件
getIcon(extension: string) {
const config = this.customIcons.get(extension.toLowerCase())
if (config) {
return createCustomIcon(config.imagePath, config.fallbackIcon)
}
return null
}
// 检查是否有自定义图标
hasCustomIcon(extension: string) {
return this.customIcons.has(extension.toLowerCase())
}
// 获取所有已注册的扩展名
getRegisteredExtensions() {
return Array.from(this.customIcons.keys())
}
}
// 创建全局图标管理器实例
export const customIconManager = new CustomIconManager()
// 注册默认的自定义图标
customIconManager.register("pdf", {
imagePath: "/images/filetypes/PDF.png",
fallbackIcon: BsFileEarmarkPdfFill,
})
// 便捷的注册函数
export function registerCustomIcon(
extension: string,
imagePath: string,
fallbackIcon: any,
) {
customIconManager.register(extension, { imagePath, fallbackIcon })
}
// 示例:如何注册更多自定义图标
// registerCustomIcon("doc", "/images/filetypes/DOC.png", BsFileEarmarkWordFill)
// registerCustomIcon("docx", "/images/filetypes/DOCX.png", BsFileEarmarkWordFill)
// registerCustomIcon("xls", "/images/filetypes/XLS.png", BsFileEarmarkExcelFill)
// registerCustomIcon("xlsx", "/images/filetypes/XLSX.png", BsFileEarmarkExcelFill)
// registerCustomIcon("ppt", "/images/filetypes/PPT.png", BsFileEarmarkPptFill)
// registerCustomIcon("pptx", "/images/filetypes/PPTX.png", BsFileEarmarkPptFill)
const iconMap = {
"dmg,ipa,plist,tipa": BsApple,
"exe,msi": BsWindows,
apk: ImAndroid,
db: FaSolidDatabase,
md: BsMarkdownFill,
epub: FaSolidBook,
iso: FaSolidCompactDisc,
m3u8: BsFileEarmarkPlayFill,
"doc,docx": BsFileEarmarkWordFill,
"xls,xlsx": BsFileEarmarkExcelFill,
"ppt,pptx": BsFileEarmarkPptFill,
pdf: BsFileEarmarkPdfFill, // 恢复为原始图标,让自定义逻辑在 getIconByTypeAndName 中处理
psd: VscodeIconsFileTypePhotoshop2,
ai: VscodeIconsFileTypeAi2,
url: FaSolidLink,
cast: SiAsciinema,
}
export const getIconByTypeAndName = (type: number, name: string) => {
if (type !== ObjType.FOLDER) {
// 首先检查是否有自定义图标
const fileExtension = ext(name).toLowerCase()
const customIcon = customIconManager.getIcon(fileExtension)
if (customIcon) {
return customIcon
}
// 然后检查 iconMap
for (const [extensions, icon] of Object.entries(iconMap)) {
if (extensions.split(",").includes(fileExtension)) {
return icon
}
}
if (isArchive(name)) {
return BsFileEarmarkZipFill
}
}
switch (type) {
case ObjType.FOLDER:
return IoFolder
case ObjType.VIDEO:
return BsFileEarmarkPlayFill
case ObjType.AUDIO:
return BsFileEarmarkMusicFill
case ObjType.TEXT:
return BsFileEarmarkFontFill
case ObjType.IMAGE:
return BsFileEarmarkImageFill
default:
return BsFileEarmarkMinusFill
}
}
export const getIconByObj = (obj: Pick) => {
return getIconByTypeAndName(obj.type, obj.name)
}