Added onboarding + a lightweight install banner to both the mobile login screen and the settings screen, with Android/Chromium

install prompt support and iOS “Share → Add to Home Screen” guidance. Also added a small helper + tests to decide
  when/which banner variant should show, and shared copy in common.json.
This commit is contained in:
Codex Agent
2025-12-28 18:26:17 +01:00
parent b780d82d62
commit d5f038d098
17 changed files with 831 additions and 8 deletions

View File

@@ -21,6 +21,9 @@ import { adminPath } from '../constants';
import { useAdminPushSubscription } from './hooks/useAdminPushSubscription';
import { useDevicePermissions } from './hooks/useDevicePermissions';
import { type PermissionStatus, type StorageStatus } from './lib/devicePermissions';
import { useInstallPrompt } from './hooks/useInstallPrompt';
import { resolveInstallBannerState } from './lib/installBanner';
import { MobileInstallBanner } from './components/MobileInstallBanner';
type PreferenceKey = keyof NotificationPreferences;
@@ -54,6 +57,13 @@ export default function MobileSettingsPage() {
const [storageError, setStorageError] = React.useState<string | null>(null);
const pushState = useAdminPushSubscription();
const devicePermissions = useDevicePermissions();
const installPrompt = useInstallPrompt();
const installBanner = resolveInstallBannerState({
isInstalled: installPrompt.isInstalled,
isStandalone: installPrompt.isStandalone,
canInstall: installPrompt.canInstall,
isIos: installPrompt.isIos,
});
const pushDescription = React.useMemo(() => {
if (!pushState.supported) {
@@ -172,6 +182,10 @@ export default function MobileSettingsPage() {
</Text>
</MobileCard>
) : null}
<MobileInstallBanner
state={installBanner}
onInstall={installPrompt.canInstall ? () => void installPrompt.promptInstall() : undefined}
/>
<MobileCard space="$3">
<XStack alignItems="center" space="$2">