Fix PWA mobile UX and modal button handlers

- Fixed iOS Safari modal buttons not working (removed inline onclick)
- Added 10-second auto-popup for install instructions
- Removed floating install buttons on mobile devices
- Enhanced mobile experience with modal-only approach
- Added proper event listeners for all modal buttons
- Improved cross-platform PWA installation flow

Mobile UX: Modal-only, Desktop: Button + Modal
This commit is contained in:
lockbitchat
2025-08-23 17:40:32 -04:00
parent 959e137171
commit a28aacbe6e
2 changed files with 62 additions and 40 deletions

View File

@@ -4208,19 +4208,26 @@ window.PWAUtils = {
} }
}, },
// Метод для отмены отложенного промпта
cancelDelayedPrompt: () => {
if (window.pwaInstallPrompt) {
return window.pwaInstallPrompt.cancelDelayedPrompt();
}
return false;
},
// Метод для перезапуска отложенного промпта // Метод для перезапуска отложенного промпта
rescheduleDelayedPrompt: () => { rescheduleDelayedPrompt: () => {
if (window.pwaInstallPrompt) { if (window.pwaInstallPrompt && window.pwaInstallPrompt.scheduleDelayedPrompt) {
window.pwaInstallPrompt.rescheduleDelayedPrompt(); // Отменяем существующий таймер и запускаем новый
if (window.pwaInstallPrompt.delayedPromptTimeout) {
clearTimeout(window.pwaInstallPrompt.delayedPromptTimeout);
}
window.pwaInstallPrompt.scheduleDelayedPrompt();
} }
},
// Метод для отмены отложенного промпта
cancelDelayedPrompt: () => {
if (window.pwaInstallPrompt && window.pwaInstallPrompt.delayedPromptTimeout) {
clearTimeout(window.pwaInstallPrompt.delayedPromptTimeout);
window.pwaInstallPrompt.delayedPromptTimeout = null;
console.log('⏰ Delayed install prompt cancelled via PWAUtils');
return true;
}
return false;
} }
}; };

View File

@@ -25,7 +25,7 @@ class PWAInstallPrompt {
this.startInstallationMonitoring(); this.startInstallationMonitoring();
} }
// Автоматический показ через 10 секунд для новых пользователей // Автоматический показ модального окна через 10 секунд для новых пользователей
this.scheduleDelayedPrompt(); this.scheduleDelayedPrompt();
console.log('✅ PWA Install Prompt initialized'); console.log('✅ PWA Install Prompt initialized');
@@ -100,14 +100,21 @@ class PWAInstallPrompt {
} }
scheduleDelayedPrompt() { scheduleDelayedPrompt() {
// Автоматический показ промпта через 10 секунд для новых пользователей // Автоматический показ модального окна через 10 секунд для новых пользователей
this.delayedPromptTimeout = setTimeout(() => { this.delayedPromptTimeout = setTimeout(() => {
console.log('⏰ Checking if delayed install prompt should be shown...'); console.log('⏰ Checking if delayed install prompt should be shown...');
// Проверяем, нужно ли показывать промпт // Проверяем, нужно ли показывать промпт
if (!this.isInstalled && this.shouldShowPrompt()) { if (!this.isInstalled && this.shouldShowPrompt()) {
console.log('💿 Showing delayed install prompt after 10 seconds'); console.log('💿 Showing delayed install modal after 10 seconds');
this.showInstallOptions();
// Для iOS Safari показываем модальное окно с инструкциями
if (this.isIOSSafari()) {
this.showIOSInstallInstructions();
} else {
// Для других устройств показываем fallback инструкции
this.showFallbackInstructions();
}
} else { } else {
console.log('💿 Delayed install prompt not shown - app is installed or dismissed'); console.log('💿 Delayed install prompt not shown - app is installed or dismissed');
} }
@@ -251,11 +258,14 @@ class PWAInstallPrompt {
console.log('⏰ Delayed install prompt cancelled - showing prompt now'); console.log('⏰ Delayed install prompt cancelled - showing prompt now');
} }
// Для мобильных устройств показываем модальные окна, а не кнопки
if (this.isIOSSafari()) { if (this.isIOSSafari()) {
this.showInstallButton(); this.showIOSInstallInstructions();
} else if (this.isMobileDevice()) { } else if (this.isMobileDevice()) {
this.showInstallBanner(); // Для мобильных показываем fallback инструкции вместо баннера
this.showFallbackInstructions();
} else { } else {
// Для десктопа показываем кнопку
this.showInstallButton(); this.showInstallButton();
} }
} }
@@ -417,18 +427,35 @@ class PWAInstallPrompt {
</div> </div>
<div class="flex space-x-3"> <div class="flex space-x-3">
<button onclick="this.parentElement.parentElement.remove(); localStorage.setItem('ios_install_shown', Date.now());" <button class="got-it-btn flex-1 bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg font-medium transition-colors">
class="flex-1 bg-blue-500 hover:bg-blue-600 text-white py-3 px-4 rounded-lg font-medium transition-colors">
Got it Got it
</button> </button>
<button onclick="this.parentElement.parentElement.remove(); localStorage.setItem('ios_install_dismissed', Date.now());" <button class="later-btn flex-1 bg-gray-600 hover:bg-gray-500 text-white py-3 px-4 rounded-lg font-medium transition-colors">
class="flex-1 bg-gray-600 hover:bg-gray-500 text-white py-3 px-4 rounded-lg font-medium transition-colors">
Later Later
</button> </button>
</div> </div>
</div> </div>
`; `;
// Добавляем обработчики событий для кнопок
const gotItBtn = modal.querySelector('.got-it-btn');
const laterBtn = modal.querySelector('.later-btn');
gotItBtn.addEventListener('click', () => {
modal.remove();
localStorage.setItem('ios_install_shown', Date.now());
this.saveInstallPreference('ios_instructions_shown', Date.now());
console.log('✅ iOS install instructions acknowledged');
});
laterBtn.addEventListener('click', () => {
modal.remove();
localStorage.setItem('ios_install_dismissed', Date.now());
this.dismissedCount++;
this.saveInstallPreference('dismissed', this.dismissedCount);
console.log('❌ iOS install instructions dismissed');
});
document.body.appendChild(modal); document.body.appendChild(modal);
this.saveInstallPreference('ios_instructions_shown', Date.now()); this.saveInstallPreference('ios_instructions_shown', Date.now());
@@ -463,13 +490,19 @@ class PWAInstallPrompt {
</div> </div>
</div> </div>
<button onclick="this.parentElement.parentElement.remove()" <button class="close-btn w-full bg-orange-500 hover:bg-orange-600 text-white py-3 px-4 rounded-lg font-medium transition-colors mt-6">
class="w-full bg-orange-500 hover:bg-orange-600 text-white py-3 px-4 rounded-lg font-medium transition-colors mt-6">
Close Close
</button> </button>
</div> </div>
`; `;
// Добавляем обработчик события для кнопки Close
const closeBtn = modal.querySelector('.close-btn');
closeBtn.addEventListener('click', () => {
modal.remove();
console.log('📱 Fallback install instructions closed');
});
document.body.appendChild(modal); document.body.appendChild(modal);
} }
@@ -684,24 +717,6 @@ class PWAInstallPrompt {
this.saveInstallPreference('dismissed', 0); this.saveInstallPreference('dismissed', 0);
console.log('💿 Install dismissals reset'); console.log('💿 Install dismissals reset');
} }
// Метод для отмены отложенного промпта
cancelDelayedPrompt() {
if (this.delayedPromptTimeout) {
clearTimeout(this.delayedPromptTimeout);
this.delayedPromptTimeout = null;
console.log('⏰ Delayed install prompt manually cancelled');
return true;
}
return false;
}
// Метод для перезапуска отложенного промпта
rescheduleDelayedPrompt() {
this.cancelDelayedPrompt();
this.scheduleDelayedPrompt();
console.log('⏰ Delayed install prompt rescheduled');
}
// Method for setting service worker registration // Method for setting service worker registration
setServiceWorkerRegistration(registration) { setServiceWorkerRegistration(registration) {