NoteJS/public/test-pwa.html
Fovway 091fc6cc1e Обновлены мета-теги и улучшена функциональность PWA
- Оптимизированы мета-теги в index.html и test-pwa.html для лучшей поддержки PWA.
- Улучшена структура кода с использованием многострочных атрибутов для мета-тегов.
- Обновлен сервисный работник для более эффективного кэширования и обработки запросов.
- Добавлены новые функции в pwa.js для управления установкой и обновлением PWA.
2025-10-20 12:29:43 +07:00

288 lines
9.2 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

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.

<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Тест PWA - NoteJS</title>
<!-- PWA Meta Tags -->
<meta name="description" content="Тест PWA для NoteJS" />
<meta name="theme-color" content="#007bff" />
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="default" />
<meta name="apple-mobile-web-app-title" content="NoteJS" />
<!-- Icons -->
<link rel="icon" type="image/svg+xml" href="/icon.svg" />
<link
rel="icon"
type="image/png"
sizes="32x32"
href="/icons/icon-32x32.png"
/>
<link
rel="icon"
type="image/png"
sizes="16x16"
href="/icons/icon-16x16.png"
/>
<link
rel="apple-touch-icon"
sizes="180x180"
href="/icons/icon-192x192.png"
/>
<!-- Manifest -->
<link rel="manifest" href="/manifest.json" />
<style>
body {
font-family: Arial, sans-serif;
max-width: 800px;
margin: 0 auto;
padding: 20px;
background: #f5f5f5;
}
.container {
background: white;
padding: 20px;
border-radius: 8px;
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
}
.status {
padding: 10px;
margin: 10px 0;
border-radius: 5px;
}
.success {
background: #d4edda;
color: #155724;
}
.error {
background: #f8d7da;
color: #721c24;
}
.info {
background: #d1ecf1;
color: #0c5460;
}
button {
background: #007bff;
color: white;
border: none;
padding: 10px 20px;
border-radius: 5px;
cursor: pointer;
margin: 5px;
}
button:hover {
background: #0056b3;
}
button:disabled {
background: #6c757d;
cursor: not-allowed;
}
</style>
</head>
<body>
<div class="container">
<h1>🔧 Тест PWA для NoteJS</h1>
<div id="status-container">
<div class="status info">Проверяем требования PWA...</div>
</div>
<div>
<button onclick="checkPWAStatus()">Проверить статус PWA</button>
<button onclick="installPWA()" id="install-btn" disabled>
Установить приложение
</button>
<button onclick="clearCache()">Очистить кэш</button>
</div>
<div
id="debug-info"
style="
margin-top: 20px;
padding: 15px;
background: #f8f9fa;
border-radius: 5px;
font-family: monospace;
font-size: 12px;
"
>
<h3>Отладочная информация:</h3>
<div id="debug-content"></div>
</div>
</div>
<!-- PWA Script -->
<script src="/pwa.js"></script>
<script>
let deferredPrompt;
// Проверка статуса PWA
function checkPWAStatus() {
const statusContainer = document.getElementById("status-container");
const debugContent = document.getElementById("debug-content");
// Очищаем предыдущие статусы
statusContainer.innerHTML = "";
debugContent.innerHTML = "";
// Проверяем требования PWA
const checks = [
{
name: "HTTPS или localhost",
status:
location.protocol === "https:" ||
location.hostname === "localhost",
description: `Протокол: ${location.protocol}, Хост: ${location.hostname}`,
},
{
name: "Service Worker",
status: "serviceWorker" in navigator,
description: "Поддержка Service Worker API",
},
{
name: "Manifest",
status: document.querySelector('link[rel="manifest"]') !== null,
description: "Манифест PWA подключен",
},
{
name: "Иконки",
status: document.querySelector('link[rel="icon"]') !== null,
description: "Иконки приложения подключены",
},
{
name: "Уже установлено",
status:
window.matchMedia("(display-mode: standalone)").matches ||
window.navigator.standalone === true,
description: "Приложение уже установлено как PWA",
},
];
let allPassed = true;
checks.forEach((check) => {
const statusDiv = document.createElement("div");
statusDiv.className = `status ${check.status ? "success" : "error"}`;
statusDiv.innerHTML = `${check.status ? "✅" : "❌"} ${check.name}: ${
check.description
}`;
statusContainer.appendChild(statusDiv);
if (!check.status) allPassed = false;
});
// Общая оценка
const overallDiv = document.createElement("div");
overallDiv.className = `status ${allPassed ? "success" : "error"}`;
overallDiv.innerHTML = `${allPassed ? "✅" : "❌"} Общий статус: ${
allPassed ? "PWA готово к установке" : "Есть проблемы с PWA"
}`;
statusContainer.appendChild(overallDiv);
// Отладочная информация
const debugInfo = {
userAgent: navigator.userAgent,
isOnline: navigator.onLine,
hasServiceWorker: "serviceWorker" in navigator,
isStandalone: window.matchMedia("(display-mode: standalone)").matches,
isIOSStandalone: window.navigator.standalone === true,
hasDeferredPrompt: deferredPrompt !== null,
pwaInfo: window.PWAManager
? window.PWAManager.getPWAInfo()
: "PWA Manager не доступен",
};
debugContent.innerHTML = JSON.stringify(debugInfo, null, 2);
// Активируем кнопку установки если доступно
const installBtn = document.getElementById("install-btn");
if (
deferredPrompt &&
!debugInfo.isStandalone &&
!debugInfo.isIOSStandalone
) {
installBtn.disabled = false;
}
}
// Установка PWA
function installPWA() {
if (deferredPrompt) {
deferredPrompt.prompt();
deferredPrompt.userChoice.then((choiceResult) => {
console.log("Результат установки:", choiceResult.outcome);
if (choiceResult.outcome === "accepted") {
alert("Приложение установлено!");
}
deferredPrompt = null;
document.getElementById("install-btn").disabled = true;
});
} else {
alert(
"Установка недоступна. Возможно, приложение уже установлено или браузер не поддерживает установку PWA."
);
}
}
// Очистка кэша
function clearCache() {
if ("caches" in window) {
caches
.keys()
.then((cacheNames) => {
return Promise.all(
cacheNames.map((cacheName) => {
console.log("Удаление кэша:", cacheName);
return caches.delete(cacheName);
})
);
})
.then(() => {
alert("Кэш очищен! Перезагрузите страницу.");
});
} else {
alert("Кэш не поддерживается в этом браузере.");
}
}
// Обработка события beforeinstallprompt
window.addEventListener("beforeinstallprompt", (e) => {
console.log("beforeinstallprompt событие получено");
// На мобильных устройствах позволяем браузеру показать нативный баннер
const isMobile =
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
navigator.userAgent
) ||
(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) ||
window.matchMedia("(max-width: 768px)").matches;
if (!isMobile) {
e.preventDefault();
}
deferredPrompt = e;
document.getElementById("install-btn").disabled = false;
});
// Обработка успешной установки
window.addEventListener("appinstalled", () => {
console.log("PWA установлено успешно");
alert("Приложение установлено успешно!");
document.getElementById("install-btn").disabled = true;
});
// Автоматическая проверка при загрузке
window.addEventListener("load", () => {
setTimeout(checkPWAStatus, 1000);
});
</script>
</body>
</html>