Felipe97/llama-cpp-compiled
01.2k
1import {2 APPLE_DEVICES,3 BUILD_CONFIG,4 REGEX_PATTERNS,5 SPLASH_LINK6} from '../src/lib/constants/pwa.constants';7import { NEWLINE, TAB } from '../src/lib/constants/special-characters.constants';8import { SplashOrientation } from '../src/lib/enums/splash.enums';9import type { SplashDimensions } from '../src/lib/types';10import { existsSync, readdirSync, readFileSync, writeFileSync } from 'node:fs';11import { resolve } from 'path';12import type { Plugin } from 'vite';13 14let processed = false;15 16const OUTPUT_DIR = process.env.LLAMA_UI_OUT_DIR ?? BUILD_CONFIG.OUTPUT_DIR;17 18/**19 * Generate iOS splash screen <link> tags from generated apple-splash-*.png files.20 * Returns an array of HTML link strings to be injected into the page head.21 */22export function generateSplashScreenLinks(outDir: string): string[] {23 const files = readdirSync(outDir).filter((f) => f.match(REGEX_PATTERNS.SPLASH_FILE));24 25 if (files.length === 0) return [];26 27 const dimMap = new Map<string, SplashDimensions>();28 29 for (const [dims, spec] of Object.entries(APPLE_DEVICES)) {30 const [w, h] = dims.split('x').map(Number);31 32 // logical-point dimensions33 dimMap.set(`${w}x${h}`, { deviceH: spec.height, deviceW: spec.width, dpr: spec.dpr });34 dimMap.set(`${h}x${w}`, { deviceH: spec.height, deviceW: spec.width, dpr: spec.dpr });35 // pixel dimensions (used by actual generated splash files)36 dimMap.set(`${w * spec.dpr}x${h * spec.dpr}`, {37 deviceH: spec.height,38 deviceW: spec.width,39 dpr: spec.dpr40 });41 dimMap.set(`${h * spec.dpr}x${w * spec.dpr}`, {42 deviceH: spec.height,43 deviceW: spec.width,44 dpr: spec.dpr45 });46 }47 48 const lightLinks: string[] = [];49 const darkLinks: string[] = [];50 51 for (const file of files) {52 const match = file.match(REGEX_PATTERNS.SPLASH_FILE);53 54 if (!match) continue;55 56 const orientation = match[1] as SplashOrientation;57 const isDark = !!match[2];58 const pixelW = parseInt(match[3]);59 const pixelH = parseInt(match[4]);60 const key = `${pixelW}x${pixelH}`;61 const spec = dimMap.get(key);62 63 if (!spec) {64 console.warn(`Unknown splash screen dimensions: ${key} (${file})`);65 66 continue;67 }68 69 const { deviceH, deviceW, dpr } = spec;70 const media = `screen and (device-width: ${deviceW}px) and (device-height: ${deviceH}px) and (-webkit-device-pixel-ratio: ${dpr}) and (orientation: ${orientation})`;71 const href = `./${file}`;72 73 if (isDark) {74 darkLinks.push(75 `${SPLASH_LINK.HTML} media="${media}${SPLASH_LINK.DARK_MEDIA_SUFFIX}" href="${href}">`76 );77 } else {78 lightLinks.push(`${SPLASH_LINK.HTML} media="${media}" href="${href}">`);79 }80 }81 82 return [...lightLinks, ...darkLinks];83}84 85export function splashScreenPlugin(): Plugin {86 return {87 apply: 'build',88 closeBundle() {89 setTimeout(() => {90 try {91 if (processed) return;92 93 processed = true;94 95 const outDir = resolve(OUTPUT_DIR);96 const indexPath = resolve(outDir, 'index.html');97 98 if (!existsSync(indexPath)) return;99 100 let content = readFileSync(indexPath, 'utf-8');101 102 // Inject iOS splash screen <link> tags into <head>.103 // The @vite-pwa/assets-generator generates apple-splash-*.png files;104 // this scans them and creates the <link> tags SvelteKit needs.105 const splashLinks = generateSplashScreenLinks(outDir);106 107 if (splashLinks.length > 0) {108 console.log(`Generated ${splashLinks.length} apple-splash link tags`);109 const splashHtml = splashLinks.map((l) => TAB + TAB + l).join(NEWLINE);110 111 content = content.replace(112 REGEX_PATTERNS.HEAD_CLOSE,113 splashHtml + NEWLINE + TAB + TAB + '</head>'114 );115 }116 117 // Remove trailing \r from Windows line endings118 content = content.replace(/\r/g, '');119 content = BUILD_CONFIG.GUIDE_COMMENT + NEWLINE + content;120 121 writeFileSync(indexPath, content, 'utf-8');122 console.log('Updated index.html');123 } catch (error) {124 console.error('Failed to process build output:', error);125 }126 }, 100);127 },128 name: 'llamacpp:splash-screen'129 };130}131 