✨ Обновлены файлы PWA и улучшена функциональность
- Добавлены новые мета-теги и улучшены существующие для поддержки PWA. - Обновлен manifest.json с новыми полями для совместимости с Brave. - Улучшен Service Worker для кэширования манифеста и обработки ошибок. - Обновлены инструкции по тестированию PWA, включая новую тестовую страницу для Brave. - Оптимизирован код для обработки установки PWA на мобильных устройствах и в Brave.
This commit is contained in:
parent
091fc6cc1e
commit
02be77d790
@ -3,6 +3,7 @@
|
|||||||
## Что было сделано
|
## Что было сделано
|
||||||
|
|
||||||
✅ **Созданы файлы PWA:**
|
✅ **Созданы файлы PWA:**
|
||||||
|
|
||||||
- `manifest.json` - манифест приложения
|
- `manifest.json` - манифест приложения
|
||||||
- `sw.js` - сервис-воркер для кэширования
|
- `sw.js` - сервис-воркер для кэширования
|
||||||
- `pwa.js` - JavaScript класс для управления PWA
|
- `pwa.js` - JavaScript класс для управления PWA
|
||||||
@ -12,64 +13,88 @@
|
|||||||
- `browserconfig.xml` - конфигурация для Windows
|
- `browserconfig.xml` - конфигурация для Windows
|
||||||
|
|
||||||
✅ **Обновлены HTML страницы:**
|
✅ **Обновлены HTML страницы:**
|
||||||
|
|
||||||
- Добавлены PWA мета-теги
|
- Добавлены PWA мета-теги
|
||||||
- Подключены иконки и манифест
|
- Подключены иконки и манифест
|
||||||
- Добавлен скрипт регистрации Service Worker
|
- Добавлен скрипт регистрации Service Worker
|
||||||
|
|
||||||
✅ **Настроен сервер:**
|
✅ **Настроен сервер:**
|
||||||
|
|
||||||
- Правильные заголовки для PWA файлов
|
- Правильные заголовки для PWA файлов
|
||||||
- Поддержка кэширования
|
- Поддержка кэширования
|
||||||
|
|
||||||
## Как протестировать
|
## Как протестировать
|
||||||
|
|
||||||
### 1. Откройте диагностическую страницу PWA
|
### 1. Откройте диагностическую страницу PWA
|
||||||
|
|
||||||
```
|
```
|
||||||
http://localhost:3000/pwa-debug.html
|
http://localhost:3000/pwa-debug.html
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2. Откройте тестовую страницу для мобильных устройств
|
### 2. Откройте тестовую страницу для мобильных устройств
|
||||||
|
|
||||||
```
|
```
|
||||||
http://localhost:3000/mobile-pwa-test.html
|
http://localhost:3000/mobile-pwa-test.html
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3. Откройте обычную тестовую страницу
|
### 3. Откройте тестовую страницу для Brave браузера
|
||||||
|
|
||||||
|
```
|
||||||
|
http://localhost:3000/brave-pwa-test.html
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Откройте обычную тестовую страницу
|
||||||
|
|
||||||
```
|
```
|
||||||
http://localhost:3000/test-pwa.html
|
http://localhost:3000/test-pwa.html
|
||||||
```
|
```
|
||||||
|
|
||||||
### 4. Проверьте требования PWA
|
### 5. Проверьте требования PWA
|
||||||
|
|
||||||
На мобильной тестовой странице автоматически проверяются все требования:
|
На мобильной тестовой странице автоматически проверяются все требования:
|
||||||
|
|
||||||
- ✅ HTTPS или localhost
|
- ✅ HTTPS или localhost
|
||||||
- ✅ Service Worker
|
- ✅ Service Worker
|
||||||
- ✅ Manifest
|
- ✅ Manifest
|
||||||
- ✅ Иконки
|
- ✅ Иконки
|
||||||
- ❌ Уже установлено (должно быть красным, если не установлено)
|
- ❌ Уже установлено (должно быть красным, если не установлено)
|
||||||
|
|
||||||
### 5. Установка приложения
|
### 6. Установка приложения
|
||||||
|
|
||||||
- Если все проверки пройдены, появится кнопка "Установить приложение"
|
- Если все проверки пройдены, появится кнопка "Установить приложение"
|
||||||
- Нажмите на неё для установки PWA
|
- Нажмите на неё для установки PWA
|
||||||
- Следуйте инструкциям браузера или используйте инструкции на странице
|
- Следуйте инструкциям браузера или используйте инструкции на странице
|
||||||
|
|
||||||
### 6. Проверка в разных браузерах
|
### 7. Проверка в разных браузерах
|
||||||
|
|
||||||
#### Chrome/Edge:
|
#### Chrome/Edge:
|
||||||
|
|
||||||
- Откройте DevTools (F12)
|
- Откройте DevTools (F12)
|
||||||
- Перейдите в Application → Manifest
|
- Перейдите в Application → Manifest
|
||||||
- Проверьте, что манифест загружается без ошибок
|
- Проверьте, что манифест загружается без ошибок
|
||||||
- В Application → Service Workers проверьте статус SW
|
- В Application → Service Workers проверьте статус SW
|
||||||
|
|
||||||
#### Firefox:
|
#### Firefox:
|
||||||
|
|
||||||
- Откройте DevTools (F12)
|
- Откройте DevTools (F12)
|
||||||
- Перейдите в Application → Manifest
|
- Перейдите в Application → Manifest
|
||||||
- Проверьте манифест
|
- Проверьте манифест
|
||||||
|
|
||||||
|
#### Brave:
|
||||||
|
|
||||||
|
- Откройте `http://localhost:3000/brave-pwa-test.html` для диагностики
|
||||||
|
- Проверьте настройки PWA в браузере
|
||||||
|
- Используйте меню браузера для установки
|
||||||
|
|
||||||
#### Safari (iOS):
|
#### Safari (iOS):
|
||||||
|
|
||||||
- Откройте сайт в Safari
|
- Откройте сайт в Safari
|
||||||
- Нажмите кнопку "Поделиться"
|
- Нажмите кнопку "Поделиться"
|
||||||
- Выберите "На экран Домой"
|
- Выберите "На экран Домой"
|
||||||
- Приложение установится как PWA
|
- Приложение установится как PWA
|
||||||
|
|
||||||
#### ПК/Десктоп (Chrome, Edge, Firefox):
|
#### ПК/Десктоп (Chrome, Edge, Firefox):
|
||||||
|
|
||||||
- Откройте сайт в браузере
|
- Откройте сайт в браузере
|
||||||
- Нажмите на иконку установки в адресной строке (если доступна)
|
- Нажмите на иконку установки в адресной строке (если доступна)
|
||||||
- Или используйте меню браузера → "Установить приложение"
|
- Или используйте меню браузера → "Установить приложение"
|
||||||
@ -78,24 +103,28 @@ http://localhost:3000/test-pwa.html
|
|||||||
## Новые улучшения для мобильных устройств
|
## Новые улучшения для мобильных устройств
|
||||||
|
|
||||||
✅ **Улучшенный manifest.json:**
|
✅ **Улучшенный manifest.json:**
|
||||||
|
|
||||||
- Добавлены все необходимые размеры иконок (72x72, 96x96, 128x128, 144x144, 152x152, 192x192, 384x384, 512x512)
|
- Добавлены все необходимые размеры иконок (72x72, 96x96, 128x128, 144x144, 152x152, 192x192, 384x384, 512x512)
|
||||||
- Добавлены maskable иконки для Android
|
- Добавлены maskable иконки для Android
|
||||||
- Добавлены категории и скриншоты
|
- Добавлены категории и скриншоты
|
||||||
- Улучшена совместимость с мобильными устройствами
|
- Улучшена совместимость с мобильными устройствами
|
||||||
|
|
||||||
✅ **Улучшенные мета-теги:**
|
✅ **Улучшенные мета-теги:**
|
||||||
|
|
||||||
- Добавлены все необходимые apple-touch-icon размеры
|
- Добавлены все необходимые apple-touch-icon размеры
|
||||||
- Улучшена поддержка iOS Safari
|
- Улучшена поддержка iOS Safari
|
||||||
- Добавлены мета-теги для Windows
|
- Добавлены мета-теги для Windows
|
||||||
- Настроен правильный статус-бар для iOS
|
- Настроен правильный статус-бар для iOS
|
||||||
|
|
||||||
✅ **Улучшенный Service Worker:**
|
✅ **Улучшенный Service Worker:**
|
||||||
|
|
||||||
- Кэширование всех иконок
|
- Кэширование всех иконок
|
||||||
- Улучшенная обработка ошибок
|
- Улучшенная обработка ошибок
|
||||||
- Fallback для различных типов ресурсов
|
- Fallback для различных типов ресурсов
|
||||||
- Лучшая поддержка мобильных устройств
|
- Лучшая поддержка мобильных устройств
|
||||||
|
|
||||||
✅ **Улучшенный PWA Manager:**
|
✅ **Улучшенный PWA Manager:**
|
||||||
|
|
||||||
- Определение мобильного Safari
|
- Определение мобильного Safari
|
||||||
- Разные инструкции для разных браузеров
|
- Разные инструкции для разных браузеров
|
||||||
- Улучшенная проверка установки PWA
|
- Улучшенная проверка установки PWA
|
||||||
@ -108,51 +137,83 @@ http://localhost:3000/test-pwa.html
|
|||||||
## Возможные проблемы и решения
|
## Возможные проблемы и решения
|
||||||
|
|
||||||
### 1. Кнопка установки не появляется
|
### 1. Кнопка установки не появляется
|
||||||
|
|
||||||
**Причины:**
|
**Причины:**
|
||||||
|
|
||||||
- Приложение уже установлено
|
- Приложение уже установлено
|
||||||
- Браузер не поддерживает PWA
|
- Браузер не поддерживает PWA
|
||||||
- Не выполнены требования PWA
|
- Не выполнены требования PWA
|
||||||
- **Вы используете ПК/десктоп (кнопка скрыта для ПК)**
|
- **Вы используете ПК/десктоп (кнопка скрыта для ПК)**
|
||||||
|
- **Проблемы с Brave браузером**
|
||||||
|
|
||||||
**Решение:**
|
**Решение:**
|
||||||
|
|
||||||
- Проверьте статус на мобильной тестовой странице
|
- Проверьте статус на мобильной тестовой странице
|
||||||
- Убедитесь, что используете HTTPS или localhost
|
- Убедитесь, что используете HTTPS или localhost
|
||||||
- Проверьте консоль браузера на ошибки
|
- Проверьте консоль браузера на ошибки
|
||||||
- Для iOS Safari используйте инструкции "Добавить на главный экран"
|
- Для iOS Safari используйте инструкции "Добавить на главный экран"
|
||||||
- **На ПК используйте меню браузера для установки PWA**
|
- **На ПК используйте меню браузера для установки PWA**
|
||||||
|
- **Для Brave: проверьте настройки PWA в браузере**
|
||||||
|
|
||||||
|
### 1.1. Проблемы с Brave браузером
|
||||||
|
|
||||||
|
**Причины:**
|
||||||
|
|
||||||
|
- Brave может блокировать PWA по умолчанию
|
||||||
|
- Неправильная конфигурация manifest.json
|
||||||
|
- Проблемы с Service Worker в Brave
|
||||||
|
|
||||||
|
**Решение:**
|
||||||
|
|
||||||
|
- Откройте `http://localhost:3000/brave-pwa-test.html` для диагностики
|
||||||
|
- В Brave перейдите в **Настройки → Дополнительно → Сайты и разрешения → PWA**
|
||||||
|
- Убедитесь, что PWA включены
|
||||||
|
- Попробуйте установить через меню браузера (три точки → "Установить приложение")
|
||||||
|
- Обновите manifest.json с новыми полями для Brave совместимости
|
||||||
|
|
||||||
### 2. Service Worker не регистрируется
|
### 2. Service Worker не регистрируется
|
||||||
|
|
||||||
**Причины:**
|
**Причины:**
|
||||||
|
|
||||||
- Ошибки в коде SW
|
- Ошибки в коде SW
|
||||||
- Проблемы с кэшированием файлов
|
- Проблемы с кэшированием файлов
|
||||||
|
|
||||||
**Решение:**
|
**Решение:**
|
||||||
|
|
||||||
- Откройте DevTools → Application → Service Workers
|
- Откройте DevTools → Application → Service Workers
|
||||||
- Проверьте ошибки в консоли
|
- Проверьте ошибки в консоли
|
||||||
- Попробуйте очистить кэш
|
- Попробуйте очистить кэш
|
||||||
|
|
||||||
### 3. Ошибка "Download error or resource isn't a valid image"
|
### 3. Ошибка "Download error or resource isn't a valid image"
|
||||||
|
|
||||||
**Причины:**
|
**Причины:**
|
||||||
|
|
||||||
- PNG иконки повреждены или имеют неправильный размер
|
- PNG иконки повреждены или имеют неправильный размер
|
||||||
- Иконки не являются валидными PNG файлами
|
- Иконки не являются валидными PNG файлами
|
||||||
|
|
||||||
**Решение:**
|
**Решение:**
|
||||||
|
|
||||||
- ✅ **ИСПРАВЛЕНО**: Созданы правильные PNG иконки с помощью pngjs
|
- ✅ **ИСПРАВЛЕНО**: Созданы правильные PNG иконки с помощью pngjs
|
||||||
- Проверьте, что иконки имеют правильные размеры (192x192, 512x512)
|
- Проверьте, что иконки имеют правильные размеры (192x192, 512x512)
|
||||||
- Убедитесь, что файлы иконок валидные PNG
|
- Убедитесь, что файлы иконок валидные PNG
|
||||||
|
|
||||||
### 4. Предупреждение о deprecated meta tag
|
### 4. Предупреждение о deprecated meta tag
|
||||||
|
|
||||||
**Причины:**
|
**Причины:**
|
||||||
|
|
||||||
- Использование устаревшего `apple-mobile-web-app-capable`
|
- Использование устаревшего `apple-mobile-web-app-capable`
|
||||||
|
|
||||||
**Решение:**
|
**Решение:**
|
||||||
|
|
||||||
- ✅ **ИСПРАВЛЕНО**: Добавлен современный `mobile-web-app-capable`
|
- ✅ **ИСПРАВЛЕНО**: Добавлен современный `mobile-web-app-capable`
|
||||||
- Оба тега теперь присутствуют для совместимости
|
- Оба тега теперь присутствуют для совместимости
|
||||||
|
|
||||||
## Отладка
|
## Отладка
|
||||||
|
|
||||||
### Консоль браузера
|
### Консоль браузера
|
||||||
|
|
||||||
Откройте DevTools (F12) и проверьте консоль на ошибки:
|
Откройте DevTools (F12) и проверьте консоль на ошибки:
|
||||||
|
|
||||||
```javascript
|
```javascript
|
||||||
// Проверить статус PWA
|
// Проверить статус PWA
|
||||||
window.debugPWA();
|
window.debugPWA();
|
||||||
@ -168,7 +229,9 @@ window.forceInstall();
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Диагностическая страница
|
### Диагностическая страница
|
||||||
|
|
||||||
Используйте `http://localhost:3000/pwa-debug.html` для:
|
Используйте `http://localhost:3000/pwa-debug.html` для:
|
||||||
|
|
||||||
- Детальной диагностики всех требований PWA
|
- Детальной диагностики всех требований PWA
|
||||||
- Проверки загрузки манифеста и Service Worker
|
- Проверки загрузки манифеста и Service Worker
|
||||||
- Отображения информации о браузере и устройстве
|
- Отображения информации о браузере и устройстве
|
||||||
@ -176,7 +239,9 @@ window.forceInstall();
|
|||||||
- Тестирования установки PWA
|
- Тестирования установки PWA
|
||||||
|
|
||||||
### Lighthouse
|
### Lighthouse
|
||||||
|
|
||||||
Запустите аудит Lighthouse в Chrome DevTools:
|
Запустите аудит Lighthouse в Chrome DevTools:
|
||||||
|
|
||||||
1. Откройте DevTools (F12)
|
1. Откройте DevTools (F12)
|
||||||
2. Перейдите в Lighthouse
|
2. Перейдите в Lighthouse
|
||||||
3. Выберите "Progressive Web App"
|
3. Выберите "Progressive Web App"
|
||||||
@ -190,11 +255,13 @@ window.forceInstall();
|
|||||||
- ✅ `http://localhost:3000/icons/icon-512x512.png` - должен возвращать PNG
|
- ✅ `http://localhost:3000/icons/icon-512x512.png` - должен возвращать PNG
|
||||||
- ✅ `http://localhost:3000/pwa-debug.html` - диагностическая страница PWA
|
- ✅ `http://localhost:3000/pwa-debug.html` - диагностическая страница PWA
|
||||||
- ✅ `http://localhost:3000/mobile-pwa-test.html` - мобильная тестовая страница
|
- ✅ `http://localhost:3000/mobile-pwa-test.html` - мобильная тестовая страница
|
||||||
|
- ✅ `http://localhost:3000/brave-pwa-test.html` - тестовая страница для Brave браузера
|
||||||
- ✅ `http://localhost:3000/test-pwa.html` - обычная тестовая страница
|
- ✅ `http://localhost:3000/test-pwa.html` - обычная тестовая страница
|
||||||
|
|
||||||
## Следующие шаги
|
## Следующие шаги
|
||||||
|
|
||||||
После успешного тестирования:
|
После успешного тестирования:
|
||||||
|
|
||||||
1. Удалите тестовую страницу `test-pwa.html`
|
1. Удалите тестовую страницу `test-pwa.html`
|
||||||
2. Настройте HTTPS для продакшена
|
2. Настройте HTTPS для продакшена
|
||||||
3. Добавьте реальные скриншоты в манифест
|
3. Добавьте реальные скриншоты в манифест
|
||||||
|
|||||||
333
public/brave-pwa-test.html
Normal file
333
public/brave-pwa-test.html
Normal file
@ -0,0 +1,333 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="ru">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8" />
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||||
|
<title>Тест PWA для Brave - NoteJS</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
|
||||||
|
sans-serif;
|
||||||
|
max-width: 800px;
|
||||||
|
margin: 0 auto;
|
||||||
|
padding: 20px;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
.status {
|
||||||
|
padding: 10px;
|
||||||
|
margin: 10px 0;
|
||||||
|
border-radius: 5px;
|
||||||
|
border-left: 4px solid;
|
||||||
|
}
|
||||||
|
.success {
|
||||||
|
background: #d4edda;
|
||||||
|
border-color: #28a745;
|
||||||
|
color: #155724;
|
||||||
|
}
|
||||||
|
.error {
|
||||||
|
background: #f8d7da;
|
||||||
|
border-color: #dc3545;
|
||||||
|
color: #721c24;
|
||||||
|
}
|
||||||
|
.warning {
|
||||||
|
background: #fff3cd;
|
||||||
|
border-color: #ffc107;
|
||||||
|
color: #856404;
|
||||||
|
}
|
||||||
|
.info {
|
||||||
|
background: #d1ecf1;
|
||||||
|
border-color: #17a2b8;
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
.test-section {
|
||||||
|
margin: 20px 0;
|
||||||
|
padding: 15px;
|
||||||
|
border: 1px solid #ddd;
|
||||||
|
border-radius: 5px;
|
||||||
|
}
|
||||||
|
.browser-info {
|
||||||
|
background: #f8f9fa;
|
||||||
|
padding: 15px;
|
||||||
|
border-radius: 5px;
|
||||||
|
margin: 10px 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1>🔍 Диагностика PWA для Brave браузера</h1>
|
||||||
|
|
||||||
|
<div class="browser-info">
|
||||||
|
<h3>Информация о браузере:</h3>
|
||||||
|
<div id="browserInfo"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>📋 Проверка требований PWA</h2>
|
||||||
|
<div id="pwaRequirements"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>🔧 Тестирование установки</h2>
|
||||||
|
<button id="installBtn" style="display: none">
|
||||||
|
Установить приложение
|
||||||
|
</button>
|
||||||
|
<button id="checkInstallBtn">Проверить возможность установки</button>
|
||||||
|
<div id="installStatus"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>📱 Инструкции для Brave</h2>
|
||||||
|
<div id="braveInstructions"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="test-section">
|
||||||
|
<h2>🐛 Отладочная информация</h2>
|
||||||
|
<button id="debugBtn">Показать отладочную информацию</button>
|
||||||
|
<div id="debugInfo" style="display: none"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
let deferredPrompt;
|
||||||
|
let isBrave = false;
|
||||||
|
|
||||||
|
// Определяем браузер
|
||||||
|
function detectBrowser() {
|
||||||
|
const userAgent = navigator.userAgent;
|
||||||
|
isBrave =
|
||||||
|
userAgent.includes("Brave") ||
|
||||||
|
(navigator.brave && navigator.brave.isBrave);
|
||||||
|
|
||||||
|
const browserInfo = document.getElementById("browserInfo");
|
||||||
|
browserInfo.innerHTML = `
|
||||||
|
<p><strong>User Agent:</strong> ${userAgent}</p>
|
||||||
|
<p><strong>Браузер:</strong> ${isBrave ? "Brave" : "Другой"}</p>
|
||||||
|
<p><strong>Платформа:</strong> ${navigator.platform}</p>
|
||||||
|
<p><strong>Мобильное устройство:</strong> ${
|
||||||
|
isMobile() ? "Да" : "Нет"
|
||||||
|
}</p>
|
||||||
|
<p><strong>HTTPS:</strong> ${
|
||||||
|
location.protocol === "https:" ? "Да" : "Нет"
|
||||||
|
}</p>
|
||||||
|
<p><strong>Localhost:</strong> ${
|
||||||
|
location.hostname === "localhost" ? "Да" : "Нет"
|
||||||
|
}</p>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
function isMobile() {
|
||||||
|
return (
|
||||||
|
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
||||||
|
navigator.userAgent
|
||||||
|
) ||
|
||||||
|
(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) ||
|
||||||
|
window.matchMedia("(max-width: 768px)").matches
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка требований PWA
|
||||||
|
function checkPWARequirements() {
|
||||||
|
const requirements = document.getElementById("pwaRequirements");
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
// HTTPS или localhost
|
||||||
|
const isSecure =
|
||||||
|
location.protocol === "https:" || location.hostname === "localhost";
|
||||||
|
html += `<div class="status ${isSecure ? "success" : "error"}">
|
||||||
|
${isSecure ? "✅" : "❌"} HTTPS или localhost: ${
|
||||||
|
isSecure ? "Да" : "Нет"
|
||||||
|
}
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
// Service Worker
|
||||||
|
const hasSW = "serviceWorker" in navigator;
|
||||||
|
html += `<div class="status ${hasSW ? "success" : "error"}">
|
||||||
|
${hasSW ? "✅" : "❌"} Service Worker API: ${
|
||||||
|
hasSW ? "Поддерживается" : "Не поддерживается"
|
||||||
|
}
|
||||||
|
</div>`;
|
||||||
|
|
||||||
|
// Manifest
|
||||||
|
fetch("/manifest.json")
|
||||||
|
.then((response) => response.ok)
|
||||||
|
.then((manifestOk) => {
|
||||||
|
html += `<div class="status ${manifestOk ? "success" : "error"}">
|
||||||
|
${manifestOk ? "✅" : "❌"} Manifest.json: ${
|
||||||
|
manifestOk ? "Загружается" : "Ошибка загрузки"
|
||||||
|
}
|
||||||
|
</div>`;
|
||||||
|
requirements.innerHTML = html;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
html += `<div class="status error">
|
||||||
|
❌ Manifest.json: Ошибка загрузки
|
||||||
|
</div>`;
|
||||||
|
requirements.innerHTML = html;
|
||||||
|
});
|
||||||
|
|
||||||
|
// Иконки
|
||||||
|
fetch("/icons/icon-192x192.png")
|
||||||
|
.then((response) => response.ok)
|
||||||
|
.then((iconOk) => {
|
||||||
|
html += `<div class="status ${iconOk ? "success" : "error"}">
|
||||||
|
${iconOk ? "✅" : "❌"} Иконки: ${
|
||||||
|
iconOk ? "Доступны" : "Не найдены"
|
||||||
|
}
|
||||||
|
</div>`;
|
||||||
|
requirements.innerHTML = html;
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
html += `<div class="status error">
|
||||||
|
❌ Иконки: Не найдены
|
||||||
|
</div>`;
|
||||||
|
requirements.innerHTML = html;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверка возможности установки
|
||||||
|
function checkInstallability() {
|
||||||
|
const status = document.getElementById("installStatus");
|
||||||
|
status.innerHTML =
|
||||||
|
'<div class="status info">Проверяем возможность установки...</div>';
|
||||||
|
|
||||||
|
// Проверяем, установлено ли уже приложение
|
||||||
|
if (
|
||||||
|
window.matchMedia("(display-mode: standalone)").matches ||
|
||||||
|
window.navigator.standalone === true
|
||||||
|
) {
|
||||||
|
status.innerHTML =
|
||||||
|
'<div class="status warning">⚠️ Приложение уже установлено</div>';
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Проверяем beforeinstallprompt
|
||||||
|
if (deferredPrompt) {
|
||||||
|
status.innerHTML =
|
||||||
|
'<div class="status success">✅ Приложение можно установить</div>';
|
||||||
|
document.getElementById("installBtn").style.display = "inline-block";
|
||||||
|
} else {
|
||||||
|
status.innerHTML =
|
||||||
|
'<div class="status warning">⚠️ Событие beforeinstallprompt не сработало</div>';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Инструкции для Brave
|
||||||
|
function showBraveInstructions() {
|
||||||
|
const instructions = document.getElementById("braveInstructions");
|
||||||
|
let html = "";
|
||||||
|
|
||||||
|
if (isBrave) {
|
||||||
|
html += `
|
||||||
|
<div class="status info">
|
||||||
|
<h4>Инструкции для Brave браузера:</h4>
|
||||||
|
<ol>
|
||||||
|
<li>Убедитесь, что у вас включены PWA в настройках Brave</li>
|
||||||
|
<li>Перейдите в <strong>Настройки → Дополнительно → Сайты и разрешения → PWA</strong></li>
|
||||||
|
<li>Убедитесь, что PWA включены</li>
|
||||||
|
<li>Попробуйте установить приложение через меню браузера</li>
|
||||||
|
</ol>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
html += `
|
||||||
|
<div class="status info">
|
||||||
|
<h4>Общие инструкции для установки PWA:</h4>
|
||||||
|
<ul>
|
||||||
|
<li><strong>Android:</strong> Нажмите на меню браузера (три точки) → "Установить приложение"</li>
|
||||||
|
<li><strong>iOS:</strong> Нажмите кнопку "Поделиться" → "На экран Домой"</li>
|
||||||
|
<li><strong>Desktop:</strong> Нажмите на иконку установки в адресной строке</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
|
||||||
|
instructions.innerHTML = html;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Отладочная информация
|
||||||
|
function showDebugInfo() {
|
||||||
|
const debugInfo = document.getElementById("debugInfo");
|
||||||
|
debugInfo.style.display =
|
||||||
|
debugInfo.style.display === "none" ? "block" : "none";
|
||||||
|
|
||||||
|
if (debugInfo.style.display === "block") {
|
||||||
|
debugInfo.innerHTML = `
|
||||||
|
<h4>Отладочная информация:</h4>
|
||||||
|
<pre>${JSON.stringify(
|
||||||
|
{
|
||||||
|
userAgent: navigator.userAgent,
|
||||||
|
isBrave: isBrave,
|
||||||
|
isMobile: isMobile(),
|
||||||
|
protocol: location.protocol,
|
||||||
|
hostname: location.hostname,
|
||||||
|
standalone: window.navigator.standalone,
|
||||||
|
displayMode: window.matchMedia(
|
||||||
|
"(display-mode: standalone)"
|
||||||
|
).matches,
|
||||||
|
serviceWorker: "serviceWorker" in navigator,
|
||||||
|
beforeinstallprompt: !!deferredPrompt,
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
2
|
||||||
|
)}</pre>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Обработчики событий
|
||||||
|
window.addEventListener("beforeinstallprompt", (e) => {
|
||||||
|
console.log("beforeinstallprompt event fired");
|
||||||
|
e.preventDefault();
|
||||||
|
deferredPrompt = e;
|
||||||
|
checkInstallability();
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("appinstalled", () => {
|
||||||
|
console.log("PWA installed successfully");
|
||||||
|
document.getElementById("installStatus").innerHTML =
|
||||||
|
'<div class="status success">✅ Приложение успешно установлено!</div>';
|
||||||
|
});
|
||||||
|
|
||||||
|
// Инициализация
|
||||||
|
document.addEventListener("DOMContentLoaded", () => {
|
||||||
|
detectBrowser();
|
||||||
|
checkPWARequirements();
|
||||||
|
showBraveInstructions();
|
||||||
|
|
||||||
|
document
|
||||||
|
.getElementById("checkInstallBtn")
|
||||||
|
.addEventListener("click", checkInstallability);
|
||||||
|
document
|
||||||
|
.getElementById("installBtn")
|
||||||
|
.addEventListener("click", async () => {
|
||||||
|
if (deferredPrompt) {
|
||||||
|
deferredPrompt.prompt();
|
||||||
|
const choiceResult = await deferredPrompt.userChoice;
|
||||||
|
if (choiceResult.outcome === "accepted") {
|
||||||
|
console.log("User accepted the install prompt");
|
||||||
|
}
|
||||||
|
deferredPrompt = null;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
document
|
||||||
|
.getElementById("debugBtn")
|
||||||
|
.addEventListener("click", showDebugInfo);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
@ -160,7 +160,11 @@
|
|||||||
// Обработка установки PWA
|
// Обработка установки PWA
|
||||||
let deferredPrompt;
|
let deferredPrompt;
|
||||||
window.addEventListener("beforeinstallprompt", (e) => {
|
window.addEventListener("beforeinstallprompt", (e) => {
|
||||||
// На мобильных устройствах позволяем браузеру показать нативный баннер
|
console.log("beforeinstallprompt event fired");
|
||||||
|
|
||||||
|
// Определяем браузер
|
||||||
|
const isBrave = navigator.userAgent.includes('Brave') ||
|
||||||
|
(navigator.brave && await navigator.brave.isBrave());
|
||||||
const isMobile =
|
const isMobile =
|
||||||
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(
|
||||||
navigator.userAgent
|
navigator.userAgent
|
||||||
@ -168,28 +172,30 @@
|
|||||||
(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) ||
|
(navigator.maxTouchPoints && navigator.maxTouchPoints > 2) ||
|
||||||
window.matchMedia("(max-width: 768px)").matches;
|
window.matchMedia("(max-width: 768px)").matches;
|
||||||
|
|
||||||
if (!isMobile) {
|
// Для Brave на мобильных устройствах не предотвращаем стандартное поведение
|
||||||
|
if (!isMobile && !isBrave) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
}
|
}
|
||||||
deferredPrompt = e;
|
deferredPrompt = e;
|
||||||
|
|
||||||
// Показываем кнопку установки только на мобильных устройствах
|
// Показываем кнопку установки на мобильных устройствах или в Brave
|
||||||
if (isMobile) {
|
if (isMobile || isBrave) {
|
||||||
const installButton = document.createElement("button");
|
const installButton = document.createElement("button");
|
||||||
installButton.textContent = "Установить приложение";
|
installButton.textContent = "Установить приложение";
|
||||||
installButton.className = "btnSave";
|
installButton.className = "btnSave";
|
||||||
installButton.style.marginTop = "10px";
|
installButton.style.marginTop = "10px";
|
||||||
installButton.style.width = "100%";
|
installButton.style.width = "100%";
|
||||||
|
|
||||||
installButton.addEventListener("click", () => {
|
installButton.addEventListener("click", async () => {
|
||||||
deferredPrompt.prompt();
|
if (deferredPrompt) {
|
||||||
deferredPrompt.userChoice.then((choiceResult) => {
|
deferredPrompt.prompt();
|
||||||
|
const choiceResult = await deferredPrompt.userChoice;
|
||||||
if (choiceResult.outcome === "accepted") {
|
if (choiceResult.outcome === "accepted") {
|
||||||
console.log("Пользователь установил приложение");
|
console.log("Пользователь установил приложение");
|
||||||
}
|
}
|
||||||
deferredPrompt = null;
|
deferredPrompt = null;
|
||||||
installButton.remove();
|
installButton.remove();
|
||||||
});
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
document.querySelector(".auth-link").appendChild(installButton);
|
document.querySelector(".auth-link").appendChild(installButton);
|
||||||
|
|||||||
@ -11,6 +11,8 @@
|
|||||||
"lang": "ru",
|
"lang": "ru",
|
||||||
"id": "/",
|
"id": "/",
|
||||||
"categories": ["productivity", "utilities"],
|
"categories": ["productivity", "utilities"],
|
||||||
|
"prefer_related_applications": false,
|
||||||
|
"display_override": ["window-controls-overlay", "standalone"],
|
||||||
"screenshots": [
|
"screenshots": [
|
||||||
{
|
{
|
||||||
"src": "/icons/icon-512x512.png",
|
"src": "/icons/icon-512x512.png",
|
||||||
|
|||||||
11
public/sw.js
11
public/sw.js
@ -1,11 +1,11 @@
|
|||||||
// Service Worker для NoteJS
|
// Service Worker для NoteJS
|
||||||
const APP_VERSION = "1.0.5";
|
const APP_VERSION = "1.0.6";
|
||||||
const CACHE_NAME = `notejs-v${APP_VERSION}`;
|
const CACHE_NAME = `notejs-v${APP_VERSION}`;
|
||||||
const STATIC_CACHE_NAME = `notejs-static-v${APP_VERSION}`;
|
const STATIC_CACHE_NAME = `notejs-static-v${APP_VERSION}`;
|
||||||
|
|
||||||
// Файлы для кэширования при установке (только изображения, иконки, логотипы)
|
// Файлы для кэширования при установке (включая манифест для Brave)
|
||||||
// Манифест убран - не нужен для офлайн работы
|
|
||||||
const STATIC_FILES = [
|
const STATIC_FILES = [
|
||||||
|
"/manifest.json",
|
||||||
"/icons/icon-72x72.png",
|
"/icons/icon-72x72.png",
|
||||||
"/icons/icon-96x96.png",
|
"/icons/icon-96x96.png",
|
||||||
"/icons/icon-128x128.png",
|
"/icons/icon-128x128.png",
|
||||||
@ -141,7 +141,7 @@ async function handleRequest(request) {
|
|||||||
function shouldCache(request) {
|
function shouldCache(request) {
|
||||||
const url = new URL(request.url);
|
const url = new URL(request.url);
|
||||||
|
|
||||||
// Кэшируем только изображения, иконки и логотипы (без манифеста для офлайн работы)
|
// Кэшируем изображения, иконки, логотипы и манифест (для Brave совместимости)
|
||||||
return (
|
return (
|
||||||
url.pathname.includes("/icons/") ||
|
url.pathname.includes("/icons/") ||
|
||||||
url.pathname.endsWith(".png") ||
|
url.pathname.endsWith(".png") ||
|
||||||
@ -149,7 +149,8 @@ function shouldCache(request) {
|
|||||||
url.pathname.endsWith(".jpeg") ||
|
url.pathname.endsWith(".jpeg") ||
|
||||||
url.pathname.endsWith(".gif") ||
|
url.pathname.endsWith(".gif") ||
|
||||||
url.pathname.endsWith(".webp") ||
|
url.pathname.endsWith(".webp") ||
|
||||||
url.pathname.endsWith(".svg")
|
url.pathname.endsWith(".svg") ||
|
||||||
|
url.pathname.endsWith("manifest.json")
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user