supersam/src/components/UI/PwaInstallButton.jsx

76 lines
2.9 KiB
JavaScript
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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>
);
};