feat(pwa): add install orientation setting (#900)

This commit is contained in:
vhqtvn
2026-04-21 23:17:34 +03:00
committed by GitHub
parent 125094d371
commit 8e86891d8e
9 changed files with 197 additions and 14 deletions
+49 -6
View File
@@ -27,6 +27,7 @@
const defaultAppName = 'OpenChamber - AI Coding Assistant';
const defaultShortName = 'OpenChamber';
const pwaNameStorageKey = 'openchamber.pwaName';
const pwaOrientationStorageKey = 'openchamber.pwaOrientation';
const pwaRecentSessionsStorageKey = 'openchamber.pwaRecentSessions';
const normalizePwaName = (value, fallback) => {
@@ -47,6 +48,13 @@
return value.length > maxLength ? value.slice(0, maxLength) : value;
};
const normalizePwaOrientation = (value, fallback = 'system') => {
if (value === 'portrait' || value === 'landscape' || value === 'system') {
return value;
}
return fallback;
};
const getStoredInstallName = () => {
try {
const storedName = localStorage.getItem(pwaNameStorageKey);
@@ -70,6 +78,25 @@
return normalizedName || defaultAppName;
};
const getStoredOrientation = () => {
try {
const storedOrientation = localStorage.getItem(pwaOrientationStorageKey);
return normalizePwaOrientation(storedOrientation, 'system');
} catch {
return 'system';
}
};
const setStoredOrientation = (value) => {
const normalizedOrientation = normalizePwaOrientation(value, 'system');
try {
localStorage.setItem(pwaOrientationStorageKey, normalizedOrientation);
} catch {
return 'system';
}
return normalizedOrientation;
};
const getQueryInstallNameOverride = () => {
try {
const params = new URLSearchParams(location.search);
@@ -158,8 +185,13 @@
return shortcuts;
};
const buildManifest = (appName, recentSessions) => {
const buildManifest = (appName, recentSessions, orientationPreference) => {
const shortName = appName === defaultAppName ? defaultShortName : truncate(appName, 30);
const manifestOrientation = orientationPreference === 'portrait'
? 'portrait-primary'
: orientationPreference === 'landscape'
? 'landscape-primary'
: null;
return {
name: appName,
short_name: shortName,
@@ -168,7 +200,7 @@
start_url: `${baseUrl}/`,
scope: `${baseUrl}/`,
display: 'standalone',
orientation: 'portrait-primary',
...(manifestOrientation ? { orientation: manifestOrientation } : {}),
background_color: '#151313',
theme_color: '#edb449',
icons: [
@@ -187,11 +219,14 @@
};
};
const buildManifestEndpointUrl = (installNameOverride = null) => {
const buildManifestEndpointUrl = (installNameOverride = null, orientationOverride = null) => {
const params = new URLSearchParams();
if (typeof installNameOverride === 'string') {
params.set('appName', installNameOverride);
}
if (typeof orientationOverride === 'string') {
params.set('orientation', normalizePwaOrientation(orientationOverride, 'system'));
}
const search = params.toString();
return `${baseUrl}/manifest.webmanifest${search ? `?${search}` : ''}`;
};
@@ -257,11 +292,14 @@
}
};
const updateManifest = async (installNameOverride = null) => {
const updateManifest = async (installNameOverride = null, orientationOverride = null) => {
const resolvedFallbackName = typeof installNameOverride === 'string' ? installNameOverride : getStoredInstallName();
const resolvedOrientation = typeof orientationOverride === 'string'
? normalizePwaOrientation(orientationOverride, 'system')
: getStoredOrientation();
const recentSessions = parseRecentSessionShortcuts();
const manifest = buildManifest(resolvedFallbackName, recentSessions);
const manifestUrl = buildManifestEndpointUrl(installNameOverride);
const manifest = buildManifest(resolvedFallbackName, recentSessions, resolvedOrientation);
const manifestUrl = buildManifestEndpointUrl(installNameOverride, resolvedOrientation);
const requestVersion = ++manifestRequestVersion;
const useEndpoint = await canUseManifestEndpoint(manifestUrl, requestVersion);
@@ -290,6 +328,11 @@
void updateManifest(resolvedName);
return resolvedName;
};
window.__OPENCHAMBER_SET_PWA_ORIENTATION__ = (value) => {
const resolvedOrientation = setStoredOrientation(value);
void updateManifest(null, resolvedOrientation);
return resolvedOrientation;
};
window.__OPENCHAMBER_UPDATE_PWA_MANIFEST__ = () => {
refreshManifestFromStorage();
};