chore(deps): add icon library and update preset configurations
Add dependencies and utility scripts for icon system: ## Dependencies (package.json) - Add @lobehub/icons-static-svg@1.73.0 - High-quality SVG icon library for AI providers - Source for extracted icons in src/icons/extracted/ - Update pnpm-lock.yaml accordingly ## Provider Preset Updates (src/config/claudeProviderPresets.ts) - Add optional `icon` and `iconColor` fields to ProviderPreset interface - Apply to Anthropic Official preset as example: - icon: "anthropic" - iconColor: "#D4915D" - Future presets can include default icon configurations ## Utility Script (scripts/filter-icons.js) [NEW] - Helper script for filtering and managing icon assets - Supports icon discovery and validation workflow - Complements extract-icons.js and generate-icon-index.js This completes the icon system infrastructure, providing all necessary tools and dependencies for icon customization.
This commit is contained in:
@@ -46,6 +46,7 @@
|
||||
"@dnd-kit/sortable": "^10.0.0",
|
||||
"@dnd-kit/utilities": "^3.2.2",
|
||||
"@hookform/resolvers": "^5.2.2",
|
||||
"@lobehub/icons-static-svg": "^1.73.0",
|
||||
"@radix-ui/react-checkbox": "^1.3.3",
|
||||
"@radix-ui/react-dialog": "^1.1.15",
|
||||
"@radix-ui/react-dropdown-menu": "^2.1.16",
|
||||
|
||||
8
pnpm-lock.yaml
generated
8
pnpm-lock.yaml
generated
@@ -41,6 +41,9 @@ importers:
|
||||
'@hookform/resolvers':
|
||||
specifier: ^5.2.2
|
||||
version: 5.2.2(react-hook-form@7.65.0(react@18.3.1))
|
||||
'@lobehub/icons-static-svg':
|
||||
specifier: ^1.73.0
|
||||
version: 1.73.0
|
||||
'@radix-ui/react-checkbox':
|
||||
specifier: ^1.3.3
|
||||
version: 1.3.3(@types/react-dom@18.3.7(@types/react@18.3.23))(@types/react@18.3.23)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)
|
||||
@@ -609,6 +612,9 @@ packages:
|
||||
'@lezer/markdown@1.6.0':
|
||||
resolution: {integrity: sha512-AXb98u3M6BEzTnreBnGtQaF7xFTiMA92Dsy5tqEjpacbjRxDSFdN4bKJo9uvU4cEEOS7D2B9MT7kvDgOEIzJSw==}
|
||||
|
||||
'@lobehub/icons-static-svg@1.73.0':
|
||||
resolution: {integrity: sha512-ydKUCDoopdmulbjDZo/gppaODd5Ju5nPneVcN9A5dAz9IJZUMkLms8bqostMLrqcdMQ8resKjLuV9RhJaWhaag==}
|
||||
|
||||
'@marijn/find-cluster-break@1.0.2':
|
||||
resolution: {integrity: sha512-l0h88YhZFyKdXIFNfSWpyjStDjGHwZ/U7iobcK1cQQD8sejsONdQtTVU+1wVN1PBw40PiiHB1vA5S7VTfQiP9g==}
|
||||
|
||||
@@ -2839,6 +2845,8 @@ snapshots:
|
||||
'@lezer/common': 1.2.3
|
||||
'@lezer/highlight': 1.2.1
|
||||
|
||||
'@lobehub/icons-static-svg@1.73.0': {}
|
||||
|
||||
'@marijn/find-cluster-break@1.0.2': {}
|
||||
|
||||
'@mswjs/interceptors@0.40.0':
|
||||
|
||||
95
scripts/filter-icons.js
Normal file
95
scripts/filter-icons.js
Normal file
@@ -0,0 +1,95 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ICONS_DIR = path.join(__dirname, '../src/icons/extracted');
|
||||
|
||||
// List of "Famous" icons to keep
|
||||
// Based on common AI providers and tools
|
||||
const KEEP_LIST = [
|
||||
// AI Providers
|
||||
'openai', 'anthropic', 'claude', 'google', 'gemini', 'gemma', 'palm',
|
||||
'microsoft', 'azure', 'copilot', 'meta', 'llama',
|
||||
'alibaba', 'qwen', 'tencent', 'hunyuan', 'baidu', 'wenxin',
|
||||
'bytedance', 'doubao', 'deepseek', 'moonshot', 'kimi',
|
||||
'zhipu', 'chatglm', 'glm', 'minimax', 'mistral', 'cohere',
|
||||
'perplexity', 'huggingface', 'midjourney', 'stability',
|
||||
'xai', 'grok', 'yi', 'zeroone', 'ollama',
|
||||
|
||||
// Cloud/Tools
|
||||
'aws', 'googlecloud', 'huawei', 'cloudflare',
|
||||
'github', 'githubcopilot', 'vercel', 'notion', 'discord',
|
||||
'gitlab', 'docker', 'kubernetes', 'vscode', 'settings', 'folder', 'file', 'link'
|
||||
];
|
||||
|
||||
// Get all SVG files
|
||||
const files = fs.readdirSync(ICONS_DIR).filter(file => file.endsWith('.svg'));
|
||||
|
||||
console.log(`Scanning ${files.length} files...`);
|
||||
|
||||
let keptCount = 0;
|
||||
let deletedCount = 0;
|
||||
let renamedCount = 0;
|
||||
|
||||
// First pass: Identify files to keep and prefer color versions
|
||||
const fileMap = {}; // name -> { hasColor: bool, hasMono: bool }
|
||||
|
||||
files.forEach(file => {
|
||||
const isColor = file.endsWith('-color.svg');
|
||||
const baseName = isColor ? file.replace('-color.svg', '') : file.replace('.svg', '');
|
||||
|
||||
if (!fileMap[baseName]) {
|
||||
fileMap[baseName] = { hasColor: false, hasMono: false };
|
||||
}
|
||||
|
||||
if (isColor) {
|
||||
fileMap[baseName].hasColor = true;
|
||||
} else {
|
||||
fileMap[baseName].hasMono = true;
|
||||
}
|
||||
});
|
||||
|
||||
// Second pass: Process files
|
||||
Object.keys(fileMap).forEach(baseName => {
|
||||
const info = fileMap[baseName];
|
||||
const shouldKeep = KEEP_LIST.includes(baseName);
|
||||
|
||||
if (!shouldKeep) {
|
||||
// Delete both versions if not in keep list
|
||||
if (info.hasColor) {
|
||||
fs.unlinkSync(path.join(ICONS_DIR, `${baseName}-color.svg`));
|
||||
deletedCount++;
|
||||
}
|
||||
if (info.hasMono) {
|
||||
fs.unlinkSync(path.join(ICONS_DIR, `${baseName}.svg`));
|
||||
deletedCount++;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// If keeping, prefer color
|
||||
if (info.hasColor) {
|
||||
// Rename color version to base version (overwrite mono if exists)
|
||||
const colorPath = path.join(ICONS_DIR, `${baseName}-color.svg`);
|
||||
const targetPath = path.join(ICONS_DIR, `${baseName}.svg`);
|
||||
|
||||
try {
|
||||
// If mono exists, it will be overwritten/replaced
|
||||
fs.renameSync(colorPath, targetPath);
|
||||
renamedCount++;
|
||||
keptCount++;
|
||||
} catch (e) {
|
||||
console.error(`Error renaming ${baseName}:`, e);
|
||||
}
|
||||
} else if (info.hasMono) {
|
||||
// Keep mono if no color version
|
||||
keptCount++;
|
||||
}
|
||||
});
|
||||
|
||||
console.log(`\nCleanup complete:`);
|
||||
console.log(`- Kept: ${keptCount}`);
|
||||
console.log(`- Deleted: ${deletedCount}`);
|
||||
console.log(`- Renamed (Color -> Standard): ${renamedCount}`);
|
||||
|
||||
// Regenerate index and metadata
|
||||
require('./generate-icon-index.js');
|
||||
@@ -40,6 +40,9 @@ export interface ProviderPreset {
|
||||
endpointCandidates?: string[];
|
||||
// 新增:视觉主题配置
|
||||
theme?: PresetTheme;
|
||||
// 图标配置
|
||||
icon?: string; // 图标名称
|
||||
iconColor?: string; // 图标颜色
|
||||
}
|
||||
|
||||
export const providerPresets: ProviderPreset[] = [
|
||||
@@ -56,6 +59,8 @@ export const providerPresets: ProviderPreset[] = [
|
||||
backgroundColor: "#D97757",
|
||||
textColor: "#FFFFFF",
|
||||
},
|
||||
icon: "anthropic",
|
||||
iconColor: "#D4915D",
|
||||
},
|
||||
{
|
||||
name: "DeepSeek",
|
||||
|
||||
Reference in New Issue
Block a user