134 lines
5.0 KiB
HTML
Executable File
134 lines
5.0 KiB
HTML
Executable File
<!doctype html>
|
|
<html lang="ko">
|
|
<head>
|
|
<meta charset="UTF-8" />
|
|
<meta
|
|
name="viewport"
|
|
content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no, viewport-fit=cover"
|
|
/>
|
|
<meta name="theme-color" content="#165dff" />
|
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
|
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
|
|
<link rel="icon" href="/favicon.svg" type="image/svg+xml" />
|
|
<link rel="apple-touch-icon" href="/apple-touch-icon.svg" />
|
|
<title>AI Code App</title>
|
|
<script>
|
|
(() => {
|
|
const { pathname, search, hash, origin } = window.location;
|
|
const searchParams = new URLSearchParams(search);
|
|
const playAppInstallMetadata = {
|
|
'baseball-ticket-bay': { title: 'Baseball Ticket Bay', themeColor: '#1b3f91' },
|
|
photoprism: { title: 'PhotoPrism', themeColor: '#0f766e' },
|
|
'photo-puzzle': { title: 'Photo Puzzle', themeColor: '#d97706' },
|
|
'the-quest': { title: 'The Quest', themeColor: '#7c3aed' },
|
|
tetris: { title: 'Tetris', themeColor: '#0f172a' },
|
|
'e-reader': { title: 'E-Reader', themeColor: '#165dff' },
|
|
};
|
|
|
|
let installMetadata = null;
|
|
let staticManifestHref = null;
|
|
|
|
if (pathname === '/play/apps') {
|
|
const appId = searchParams.get('app')?.trim() ?? '';
|
|
const appMetadata = playAppInstallMetadata[appId];
|
|
|
|
if (appMetadata) {
|
|
installMetadata = {
|
|
title: appMetadata.title,
|
|
shortName: appMetadata.title,
|
|
description: `${appMetadata.title} 앱을 홈 화면에서 바로 엽니다.`,
|
|
themeColor: appMetadata.themeColor,
|
|
scope: pathname,
|
|
};
|
|
}
|
|
} else if (pathname === '/plans/shared-resource') {
|
|
installMetadata = {
|
|
title: '공유 리소스 관리',
|
|
shortName: '공유 리소스',
|
|
description: '공유 리소스 관리 화면을 홈 화면 앱으로 바로 엽니다.',
|
|
themeColor: '#0f766e',
|
|
scope: pathname,
|
|
};
|
|
} else if (pathname.startsWith('/chat/share/') || pathname.startsWith('/shares/')) {
|
|
installMetadata = {
|
|
title: '리소스 공유 채팅방',
|
|
shortName: '공유채팅',
|
|
description: '리소스 공유 채팅방을 홈 화면 앱으로 바로 엽니다.',
|
|
themeColor: '#165dff',
|
|
scope: pathname,
|
|
};
|
|
staticManifestHref = '/chat-share.webmanifest';
|
|
}
|
|
|
|
if (!installMetadata) {
|
|
return;
|
|
}
|
|
|
|
const startUrl = new URL(`${pathname}${search}${hash}`, origin).toString();
|
|
const scopeUrl = new URL(installMetadata.scope, origin).toString();
|
|
const manifest = {
|
|
id: startUrl,
|
|
name: installMetadata.title,
|
|
short_name: installMetadata.shortName,
|
|
description: installMetadata.description,
|
|
theme_color: installMetadata.themeColor,
|
|
background_color: '#eff5ff',
|
|
display: 'standalone',
|
|
lang: 'ko',
|
|
scope: scopeUrl,
|
|
start_url: startUrl,
|
|
icons: [
|
|
{
|
|
src: new URL('/pwa-192x192.svg', origin).toString(),
|
|
sizes: '192x192',
|
|
type: 'image/svg+xml',
|
|
},
|
|
{
|
|
src: new URL('/pwa-512x512.svg', origin).toString(),
|
|
sizes: '512x512',
|
|
type: 'image/svg+xml',
|
|
purpose: 'any maskable',
|
|
},
|
|
],
|
|
};
|
|
|
|
const manifestHref = staticManifestHref ?? URL.createObjectURL(
|
|
new Blob([JSON.stringify(manifest, null, 2)], {
|
|
type: 'application/manifest+json',
|
|
}),
|
|
);
|
|
let manifestLink = document.querySelector('link[rel="manifest"]');
|
|
|
|
if (!manifestLink) {
|
|
manifestLink = document.createElement('link');
|
|
manifestLink.rel = 'manifest';
|
|
document.head.appendChild(manifestLink);
|
|
}
|
|
|
|
manifestLink.href = manifestHref;
|
|
document.title = installMetadata.title;
|
|
|
|
let appleTitleMeta = document.querySelector('meta[name="apple-mobile-web-app-title"]');
|
|
if (!appleTitleMeta) {
|
|
appleTitleMeta = document.createElement('meta');
|
|
appleTitleMeta.name = 'apple-mobile-web-app-title';
|
|
document.head.appendChild(appleTitleMeta);
|
|
}
|
|
appleTitleMeta.content = installMetadata.title;
|
|
|
|
let themeColorMeta = document.querySelector('meta[name="theme-color"]');
|
|
if (!themeColorMeta) {
|
|
themeColorMeta = document.createElement('meta');
|
|
themeColorMeta.name = 'theme-color';
|
|
document.head.appendChild(themeColorMeta);
|
|
}
|
|
themeColorMeta.content = installMetadata.themeColor;
|
|
})();
|
|
</script>
|
|
</head>
|
|
<body>
|
|
<div id="root"></div>
|
|
<script type="module" src="/src/main.tsx"></script>
|
|
</body>
|
|
</html>
|