// InstallPrompt — add-to-home-screen entry points: cabinet banner,
// header icon button, iOS instructions sheet.
// State machine lives in /a2hs.js (plain JS, loaded before React).
const { useState: useA2hsState, useEffect: useA2hsEffect } = React;
function useA2HS() {
const [, force] = useA2hsState(0);
useA2hsEffect(() => {
if (!window.a2hs) return undefined;
const unsub = window.a2hs.subscribe(() => force(x => x + 1));
// Re-check once: beforeinstallprompt may have fired in the gap between
// the first render and this effect — that notify() had no subscribers.
force(x => x + 1);
return unsub;
}, []);
// No hard dependency on the plain script: if /a2hs.js failed to load
// (partial deploy, blocking extension), render no install UI instead of
// throwing and blanking the whole SPA.
if (!window.a2hs) return { state: 'unavailable', dismissed: true };
return { state: window.a2hs.getState(), dismissed: window.a2hs.isDismissed() };
}
function a2hsActivate(state) {
if (state === 'installable') window.a2hs.prompt(); // never rejects (caught inside a2hs.js)
else if (state === 'ios') window.dispatchEvent(new CustomEvent('a2hs-open-guide'));
}
function InstallBanner() {
const { state, dismissed } = useA2HS();
if (dismissed || (state !== 'installable' && state !== 'ios')) return null;
return (
Добавьте авито.пф на главный экран
Быстрый доступ к заказам и балансу — в одно касание
);
}
function InstallHeaderButton() {
const { state, dismissed } = useA2HS();
// Same gate as the banner: ✕ / «Готово, добавил» set the dismissed flag and
// both entry points disappear together. appinstalled clears the flag, so
// after an uninstall the icon can return.
if (dismissed || (state !== 'installable' && state !== 'ios')) return null;
return (
);
}
function InstallGuideSheet() {
const [open, setOpen] = useA2hsState(false);
// Permanent listener: opens the sheet on the CustomEvent from a2hsActivate.
useA2hsEffect(() => {
const h = () => setOpen(true);
window.addEventListener('a2hs-open-guide', h);
return () => window.removeEventListener('a2hs-open-guide', h);
}, []);
// Escape + body scroll-lock only while the sheet is actually open, so the
// global keydown handler isn't bound for the whole session.
useA2hsEffect(() => {
if (!open) return undefined;
const onKey = e => { if (e.key === 'Escape') setOpen(false); };
window.addEventListener('keydown', onKey);
const prevOverflow = document.body.style.overflow;
document.body.style.overflow = 'hidden';
return () => {
window.removeEventListener('keydown', onKey);
document.body.style.overflow = prevOverflow;
};
}, [open]);
if (!open) return null;
const done = () => { if (window.a2hs) window.a2hs.dismiss(); setOpen(false); };
return (
setOpen(false)}>
e.stopPropagation()}>
Добавить на главный экран
Нажмите «Поделиться»{' '}
{' '}в панели браузера
Выберите «На экран “Домой”»
Нажмите «Добавить» — значок появится на главном экране