Files
kit-ui/lib/favicon/faviconService.ts

87 lines
2.5 KiB
TypeScript

import { resizeImage } from '../media/converters/imagemagickService';
import type { FaviconIcon, FaviconSet, FaviconOptions } from '@/types/favicon';
export const ICON_CONFIGS = [
{ name: 'favicon-16x16.png', width: 16, height: 16 },
{ name: 'favicon-32x32.png', width: 32, height: 32 },
{ name: 'apple-touch-icon.png', width: 180, height: 180 },
{ name: 'android-chrome-192x192.png', width: 192, height: 192 },
{ name: 'android-chrome-512x512.png', width: 512, height: 512 },
{ name: 'favicon.ico', width: 48, height: 48 }, // Simple ICO fallback
];
export async function generateFaviconSet(
file: File,
options: FaviconOptions,
onProgress?: (progress: number) => void
): Promise<FaviconSet> {
const icons: FaviconIcon[] = [];
const totalSteps = ICON_CONFIGS.length;
for (let i = 0; i < ICON_CONFIGS.length; i++) {
const config = ICON_CONFIGS[i];
const format = config.name.endsWith('.ico') ? 'ico' : 'png';
const result = await resizeImage(file, config.width, config.height, format);
if (result.success && result.blob) {
icons.push({
name: config.name,
width: config.width,
height: config.height,
size: result.blob.size,
blob: result.blob,
previewUrl: URL.createObjectURL(result.blob),
});
}
if (onProgress) {
onProgress(Math.round(((i + 1) / totalSteps) * 100));
}
}
const manifest = generateManifest(options);
const htmlCode = generateHtmlCode(options);
return {
icons,
manifest,
htmlCode,
};
}
function generateManifest(options: FaviconOptions): string {
const manifest = {
name: options.name,
short_name: options.shortName,
icons: [
{
src: '/android-chrome-192x192.png',
sizes: '192x192',
type: 'image/png',
},
{
src: '/android-chrome-512x512.png',
sizes: '512x512',
type: 'image/png',
},
],
theme_color: options.themeColor,
background_color: options.backgroundColor,
display: 'standalone',
};
return JSON.stringify(manifest, null, 2);
}
function generateHtmlCode(options: FaviconOptions): string {
return `
<link rel="apple-touch-icon" sizes="180x180" href="/apple-touch-icon.png">
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png">
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png">
<link rel="manifest" href="/site.webmanifest">
<meta name="msapplication-TileColor" content="${options.backgroundColor}">
<meta name="theme-color" content="${options.themeColor}">
`.trim();
}