@lobehub/chat
Version:
Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.
99 lines (89 loc) • 2.33 kB
text/typescript
import qs from 'query-string';
import { BRANDING_LOGO_URL } from '@/const/branding';
import { getCanonicalUrl } from '@/server/utils/url';
const MAX_AGE = 31_536_000;
const COLOR = '#000000';
interface IconItem {
purpose: 'any' | 'maskable';
sizes: string;
url: string;
version?: number;
}
interface ScreenshotItem {
form_factor: 'wide' | 'narrow';
sizes?: string;
url: string;
version?: number;
}
export class Manifest {
public generate({
color = COLOR,
description,
name,
id,
icons,
screenshots,
}: {
color?: string;
description: string;
icons: IconItem[];
id: string;
name: string;
screenshots: ScreenshotItem[];
}) {
return {
background_color: color,
cache_busting_mode: 'all',
categories: ['productivity', 'design', 'development', 'education'],
description: description,
display: 'standalone',
display_override: ['tabbed'],
edge_side_panel: {
preferred_width: 480,
},
handle_links: 'auto',
icons: icons.map((item) => this._getIcon(item)),
id: id,
immutable: 'true',
max_age: MAX_AGE,
name: name,
orientation: 'portrait',
related_applications: [
{
platform: 'webapp',
url: getCanonicalUrl('manifest.webmanifest'),
},
],
scope: '/',
screenshots: screenshots.map((item) => this._getScreenshot(item)),
short_name: name,
splash_pages: null,
start_url: '/chat',
tab_strip: {
new_tab_button: {
url: '/chat',
},
},
theme_color: color,
};
}
private _getImage = (url: string, version: number = 1) => ({
cache_busting_mode: 'query',
immutable: 'true',
max_age: MAX_AGE,
src: qs.stringifyUrl({ query: { v: version }, url: BRANDING_LOGO_URL || url }),
});
private _getIcon = ({ url, version, sizes, purpose }: IconItem) => ({
...this._getImage(url, version),
purpose,
sizes,
type: 'image/png',
});
private _getScreenshot = ({ form_factor, url, version, sizes }: ScreenshotItem) => ({
...this._getImage(url, version),
form_factor,
sizes: sizes || form_factor === 'wide' ? '1280x676' : '640x1138',
type: 'image/png',
});
}
export const manifestModule = new Manifest();