refactor icon cache logic

This commit is contained in:
pompurin404 2024-09-24 20:57:14 +08:00
parent 41d3b4fbba
commit 9165b3abb7
No known key found for this signature in database
4 changed files with 43 additions and 24 deletions

17
src/main/utils/image.ts Normal file
View File

@ -0,0 +1,17 @@
import axios from 'axios'
import { getControledMihomoConfig } from '../config'
export async function getImageDataURL(url: string): Promise<string> {
const { 'mixed-port': port = 7890 } = await getControledMihomoConfig()
const res = await axios.get(url, {
responseType: 'arraybuffer',
proxy: {
protocol: 'http',
host: '127.0.0.1',
port
}
})
const mimeType = res.headers['content-type']
const dataURL = `data:${mimeType};base64,${Buffer.from(res.data).toString('base64')}`
return dataURL
}

View File

@ -78,6 +78,7 @@ import { logDir } from './dirs'
import path from 'path'
import v8 from 'v8'
import { getGistUrl } from '../resolve/gistApi'
import { getImageDataURL } from './image'
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
@ -211,6 +212,7 @@ export function registerIpcMainHandlers(): void {
ipcMain.handle('createHeapSnapshot', () => {
v8.writeHeapSnapshot(path.join(logDir(), `${Date.now()}.heapsnapshot`))
})
ipcMain.handle('getImageDataURL', (_e, url) => ipcErrorWrapper(getImageDataURL)(url))
ipcMain.handle('resolveThemes', () => ipcErrorWrapper(resolveThemes)())
ipcMain.handle('fetchThemes', () => ipcErrorWrapper(fetchThemes)())
ipcMain.handle('importThemes', (_e, file) => ipcErrorWrapper(importThemes)(file))

View File

@ -1,7 +1,12 @@
import { Avatar, Button, Card, CardBody, Chip } from '@nextui-org/react'
import BasePage from '@renderer/components/base/base-page'
import { useAppConfig } from '@renderer/hooks/use-app-config'
import { mihomoChangeProxy, mihomoCloseAllConnections, mihomoProxyDelay } from '@renderer/utils/ipc'
import {
getImageDataURL,
mihomoChangeProxy,
mihomoCloseAllConnections,
mihomoProxyDelay
} from '@renderer/utils/ipc'
import { CgDetailsLess, CgDetailsMore } from 'react-icons/cg'
import { TbCircleLetterD } from 'react-icons/tb'
import { FaLocationCrosshairs } from 'react-icons/fa6'
@ -197,6 +202,17 @@ const Proxies: React.FC = () => {
ref={virtuosoRef}
groupCounts={groupCounts}
groupContent={(index) => {
if (
groups[index] &&
groups[index].icon &&
groups[index].icon.startsWith('http') &&
!localStorage.getItem(groups[index].icon)
) {
getImageDataURL(groups[index].icon).then((dataURL) => {
localStorage.setItem(groups[index].icon, dataURL)
mutate()
})
}
return groups[index] ? (
<div
className={`w-full pt-2 ${index === groupCounts.length - 1 && !isOpen[index] ? 'pb-2' : ''} px-2`}
@ -219,31 +235,11 @@ const Proxies: React.FC = () => {
<Avatar
className="bg-transparent mr-2"
size="sm"
onLoad={() => {
if (!groups[index].icon.startsWith('http')) return
if (localStorage.getItem(groups[index].icon)) return
// canvas 只支持静态图片
if (groups[index].icon.endsWith('gif')) return
const img = new Image()
img.crossOrigin = 'anonymous'
img.onload = (): void => {
const canvas = document.createElement('canvas')
const ctx = canvas.getContext('2d')
canvas.width = img.width
canvas.height = img.height
ctx?.drawImage(img, 0, 0)
const data = canvas.toDataURL('image/png')
localStorage.setItem(groups[index].icon, data)
}
img.src = groups[index].icon
}}
radius="sm"
src={
groups[index].icon.startsWith('http')
? localStorage.getItem(groups[index].icon) || groups[index].icon
: groups[index].icon.startsWith('<svg')
? `data:image/svg+xml;utf8,${groups[index].icon}`
: groups[index].icon
groups[index].icon.startsWith('<svg')
? `data:image/svg+xml;utf8,${groups[index].icon}`
: localStorage.getItem(groups[index].icon) || groups[index].icon
}
/>
) : null}

View File

@ -335,6 +335,10 @@ export async function createHeapSnapshot(): Promise<void> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('createHeapSnapshot'))
}
export async function getImageDataURL(url: string): Promise<string> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('getImageDataURL', url))
}
export async function resolveThemes(): Promise<{ key: string; label: string; content: string }[]> {
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('resolveThemes'))
}