- Реализованы маршруты для обслуживания PWA файлов: manifest.json, sw.js и browserconfig.xml - Добавлены мета-теги и иконки для PWA в HTML страницах - Внедрена регистрация сервисного работника для кэширования и оффлайн-доступа - Обновлены страницы входа, регистрации, профиля и заметок для поддержки PWA
165 lines
5.2 KiB
JavaScript
165 lines
5.2 KiB
JavaScript
// PWA Service Worker Registration и установка
|
||
class PWAManager {
|
||
constructor() {
|
||
this.deferredPrompt = null;
|
||
this.init();
|
||
}
|
||
|
||
init() {
|
||
this.registerServiceWorker();
|
||
this.setupInstallPrompt();
|
||
this.setupAppInstalled();
|
||
}
|
||
|
||
// Регистрация Service Worker
|
||
registerServiceWorker() {
|
||
if ('serviceWorker' in navigator) {
|
||
window.addEventListener('load', () => {
|
||
navigator.serviceWorker.register('/sw.js')
|
||
.then((registration) => {
|
||
console.log('SW зарегистрирован успешно:', registration.scope);
|
||
|
||
// Проверяем обновления
|
||
registration.addEventListener('updatefound', () => {
|
||
const newWorker = registration.installing;
|
||
newWorker.addEventListener('statechange', () => {
|
||
if (newWorker.state === 'installed' && navigator.serviceWorker.controller) {
|
||
this.showUpdateNotification();
|
||
}
|
||
});
|
||
});
|
||
})
|
||
.catch((error) => {
|
||
console.log('Ошибка регистрации SW:', error);
|
||
});
|
||
});
|
||
}
|
||
}
|
||
|
||
// Показ уведомления об обновлении
|
||
showUpdateNotification() {
|
||
if (confirm('Доступна новая версия приложения. Обновить?')) {
|
||
if (navigator.serviceWorker.controller) {
|
||
navigator.serviceWorker.controller.postMessage({ type: 'SKIP_WAITING' });
|
||
}
|
||
window.location.reload();
|
||
}
|
||
}
|
||
|
||
// Настройка промпта установки
|
||
setupInstallPrompt() {
|
||
window.addEventListener('beforeinstallprompt', (e) => {
|
||
e.preventDefault();
|
||
this.deferredPrompt = e;
|
||
this.showInstallButton();
|
||
});
|
||
}
|
||
|
||
// Показ кнопки установки
|
||
showInstallButton() {
|
||
// Проверяем, не установлено ли уже приложение
|
||
if (window.matchMedia('(display-mode: standalone)').matches ||
|
||
window.navigator.standalone === true) {
|
||
return; // Приложение уже установлено
|
||
}
|
||
|
||
const installButton = this.createInstallButton();
|
||
this.addInstallButtonToPage(installButton);
|
||
}
|
||
|
||
// Создание кнопки установки
|
||
createInstallButton() {
|
||
const installButton = document.createElement('button');
|
||
installButton.textContent = '📱 Установить приложение';
|
||
installButton.className = 'btnSave';
|
||
installButton.style.marginTop = '10px';
|
||
installButton.style.width = '100%';
|
||
installButton.style.fontSize = '14px';
|
||
installButton.style.display = 'flex';
|
||
installButton.style.alignItems = 'center';
|
||
installButton.style.justifyContent = 'center';
|
||
installButton.style.gap = '8px';
|
||
|
||
installButton.addEventListener('click', () => {
|
||
this.installApp();
|
||
});
|
||
|
||
return installButton;
|
||
}
|
||
|
||
// Добавление кнопки на страницу
|
||
addInstallButtonToPage(installButton) {
|
||
// Ищем подходящее место для кнопки
|
||
const authLink = document.querySelector('.auth-link');
|
||
const footer = document.querySelector('.footer');
|
||
const container = document.querySelector('.container');
|
||
|
||
if (authLink) {
|
||
authLink.appendChild(installButton);
|
||
} else if (footer) {
|
||
footer.insertBefore(installButton, footer.firstChild);
|
||
} else if (container) {
|
||
container.appendChild(installButton);
|
||
}
|
||
}
|
||
|
||
// Установка приложения
|
||
installApp() {
|
||
if (this.deferredPrompt) {
|
||
this.deferredPrompt.prompt();
|
||
this.deferredPrompt.userChoice.then((choiceResult) => {
|
||
if (choiceResult.outcome === 'accepted') {
|
||
console.log('Пользователь установил приложение');
|
||
this.trackInstallation();
|
||
}
|
||
this.deferredPrompt = null;
|
||
this.removeInstallButton();
|
||
});
|
||
}
|
||
}
|
||
|
||
// Удаление кнопки установки
|
||
removeInstallButton() {
|
||
const installButton = document.querySelector('button[style*="Установить приложение"]');
|
||
if (installButton) {
|
||
installButton.remove();
|
||
}
|
||
}
|
||
|
||
// Отслеживание установки
|
||
trackInstallation() {
|
||
// Здесь можно добавить аналитику
|
||
console.log('PWA установлено успешно');
|
||
}
|
||
|
||
// Обработка успешной установки
|
||
setupAppInstalled() {
|
||
window.addEventListener('appinstalled', () => {
|
||
console.log('PWA установлено успешно');
|
||
this.removeInstallButton();
|
||
});
|
||
}
|
||
|
||
// Проверка статуса PWA
|
||
isPWAInstalled() {
|
||
return window.matchMedia('(display-mode: standalone)').matches ||
|
||
window.navigator.standalone === true;
|
||
}
|
||
|
||
// Получение информации о PWA
|
||
getPWAInfo() {
|
||
return {
|
||
isInstalled: this.isPWAInstalled(),
|
||
isOnline: navigator.onLine,
|
||
hasServiceWorker: 'serviceWorker' in navigator,
|
||
userAgent: navigator.userAgent
|
||
};
|
||
}
|
||
}
|
||
|
||
// Инициализация PWA Manager
|
||
const pwaManager = new PWAManager();
|
||
|
||
// Экспорт для использования в других скриптах
|
||
window.PWAManager = pwaManager;
|