76 lines
2.9 KiB
JavaScript
76 lines
2.9 KiB
JavaScript
import React from "react";
|
||
|
||
/**
|
||
* Compact PWA install button for the header.
|
||
* - Shows 📲 icon when install prompt is available (Chrome/Edge on Android & desktop).
|
||
* - Shows iOS Safari instructions tooltip on click when on iOS.
|
||
* - Hidden when app is already installed (standalone mode).
|
||
* - After install: auto-hidden via appinstalled event.
|
||
*/
|
||
export const PwaInstallButton = ({ onInstall, isInstalled, isInstallAvailable }) => {
|
||
const [showTip, setShowTip] = React.useState(false);
|
||
const tipRef = React.useRef(null);
|
||
|
||
// Detect iOS (no beforeinstallprompt, but can be added to home screen)
|
||
const isIOS = typeof navigator !== "undefined" && /iPad|iPhone|iPod/.test(navigator.userAgent) && !window.MSStream;
|
||
|
||
const handleInstallClick = async () => {
|
||
if (isInstallAvailable && onInstall) {
|
||
await onInstall();
|
||
} else {
|
||
// Show instruction tip for iOS or unsupported browsers
|
||
setShowTip((prev) => !prev);
|
||
}
|
||
};
|
||
|
||
// Close tip on outside click
|
||
React.useEffect(() => {
|
||
if (!showTip) return;
|
||
const handler = (e) => {
|
||
if (tipRef.current && !tipRef.current.contains(e.target)) {
|
||
setShowTip(false);
|
||
}
|
||
};
|
||
document.addEventListener("click", handler);
|
||
return () => document.removeEventListener("click", handler);
|
||
}, [showTip]);
|
||
|
||
// Don't render if already installed as PWA — AFTER all hooks
|
||
if (isInstalled) return null;
|
||
|
||
return (
|
||
<div className="relative inline-flex" ref={tipRef}>
|
||
<button
|
||
type="button"
|
||
onClick={handleInstallClick}
|
||
className="inline-flex h-8 w-8 items-center justify-center rounded-full text-base transition hover:bg-[var(--color-accent-soft)]"
|
||
aria-label="Установить приложение"
|
||
title="Установить приложение"
|
||
>
|
||
📲
|
||
</button>
|
||
|
||
{showTip && (
|
||
<div className="absolute right-0 top-full z-50 mt-2 w-60 rounded-xl border border-[var(--color-border)] bg-[var(--color-surface)] p-3 text-sm shadow-lg">
|
||
{isIOS ? (
|
||
<>
|
||
<p className="font-medium">Установка на iOS</p>
|
||
<ol className="mt-1.5 list-decimal pl-4 leading-relaxed text-[var(--color-text-muted)]">
|
||
<li>Откройте в <strong>Safari</strong></li>
|
||
<li>Нажмите <strong>Поделиться</strong> ⬆️</li>
|
||
<li>Выберите <strong>«На экран Домой»</strong></li>
|
||
</ol>
|
||
</>
|
||
) : (
|
||
<>
|
||
<p className="font-medium">Установка</p>
|
||
<p className="mt-1 leading-relaxed text-[var(--color-text-muted)]">
|
||
Нажмите значок 📲 в адресной строке браузера или используйте меню <strong>«Установить приложение»</strong>.
|
||
</p>
|
||
</>
|
||
)}
|
||
</div>
|
||
)}
|
||
</div>
|
||
);
|
||
}; |