let USER = {}; let page = "Home"; let swRegistration = null; // Реєструємо CustomElements const Notifier = document.getElementById('notif-manager'); // Определение ID главного блока let app = document.getElementById('app'); // Конфигурация роутера Router.config({ mode: 'history' }); async function appReload() { location.reload(); // Router.navigate(window.location.pathname, false).check(); // // Закрытие старого соединения WebSocket // if (socket) socket.close(1000, "Перезапуск соединения"); // listEntrances = [] // listApartment = [] } // Функция загрузки приложения window.addEventListener('load', async function () { console.log('[OS] ', detectOS()); if (window.matchMedia('(display-mode: standalone)').matches) { if (detectOS() == 'Android') { document.getElementById('navigation').dataset.state = ''; } else if (detectOS() == 'iOS') { document.getElementById('navigation').dataset.state = 'ios'; localStorage.setItem('backToTop', 'false'); } else if (detectOS() == 'MacOS') { document.getElementById('navigation').dataset.state = 'ios'; localStorage.setItem('backToTop', 'false'); } else { document.getElementById('navigation').dataset.state = ''; } } if (Router.getParams().uuid) { localStorage.setItem("uuid", Router.getParams().uuid) } let uuid = localStorage.getItem("uuid"); if (!uuid) { Router.navigate(`/auth`).check().listen().delegateLinks(); } else { const URL = `${CONFIG.api}auth`; USER = await fetch(URL, { method: 'GET', headers: { "Content-Type": "application/json, text/plain, */*", "Authorization": uuid } }).then(response => { if (response.status === 401) { localStorage.removeItem("uuid"); Router.navigate(`/auth`); } return response.json(); }); console.log("[APP] USER Info: ", USER); if (USER.possibilities.can_view_sheeps) document.getElementById("li-sheeps").style.display = ""; if (USER.possibilities.can_view_schedule) document.getElementById("li-schedule").style.display = ""; if (USER.possibilities.can_manager_territory) document.getElementById("li-territory").style.display = ""; if (USER.possibilities.can_view_stand) document.getElementById("li-stand").style.display = ""; document.getElementById("li-options").style.display = ""; if (USER.possibilities.can_view_sheeps) await Sheeps.sheeps_list.loadAPI(); if (Cloud.socket) Cloud.socket.close(1000, "Перезапуск з'єднання"); Cloud.start(); editFontStyle(); Router.check().listen().delegateLinks(); setupFrontendMetrics(); } }); let offlineNode = null; window.addEventListener("offline", () => { console.log("[APP] Інтернет зник"); offlineNode = Notifier.error({ title: 'Оффлайн', text: 'Втрачено з\'єднання з інтернетом' }, { timeout: 0, lock: true }); }); window.addEventListener("online", () => { console.log("[APP] Інтернет з'явився"); if (offlineNode) { Notifier._removeNode(offlineNode); offlineNode = null; } Notifier.success({ title: 'Онлайн', text: 'Інтернет знову працює' }, { timeout: 3000 }); if (Cloud.socket) Cloud.socket.close(1000, "Перезапуск з'єднання"); Cloud.start(); }); function editFontStyle() { let fontSize = localStorage.getItem("fontSize") ? localStorage.getItem("fontSize") : 'medium'; applyFontMode(fontSize); } function applyFontMode(mode) { const options = { "small": { "--FontSize1": "10px", "--FontSize2": "11px", "--FontSize3": "12px", "--FontSize4": "13px", "--FontSize5": "14px" }, "medium": { "--FontSize1": "12px", "--FontSize2": "13px", "--FontSize3": "14px", "--FontSize4": "15px", "--FontSize5": "16px" }, "large": { "--FontSize1": "15px", "--FontSize2": "16px", "--FontSize3": "17px", "--FontSize4": "18px", "--FontSize5": "19px" } }; const root = document.documentElement; const config = options[mode]; if (!config) return; Object.keys(config).forEach(key => { if (key.startsWith("--")) { root.style.setProperty(key, config[key]); } }); } // Банер з прохання встановлення PWA let deferredPrompt; const isInStandaloneMode = () => ('standalone' in window.navigator && window.navigator.standalone === true); if (detectOS() == 'iOS' && !isInStandaloneMode()) { setTimeout(() => { document.getElementById('blur-backdrop').classList.remove('pwa-hidden'); document.getElementById('pwa-ios-overlay').classList.remove('pwa-hidden'); document.body.classList.add('modal-open'); }, 1000); } window.addEventListener("beforeinstallprompt", (e) => { if (localStorage.getItem('modal') != "false") { e.preventDefault(); deferredPrompt = e; document.getElementById("blur-backdrop").classList.remove("pwa-hidden"); document.getElementById("pwa-install-overlay").classList.remove("pwa-hidden"); document.body.classList.add("modal-open"); } }); document.getElementById("pwa-install-button").addEventListener("click", async () => { if (!deferredPrompt) return; deferredPrompt.prompt(); const { outcome } = await deferredPrompt.userChoice; console.log(`[APP] Результат встановлення PWA: ${outcome}`); closePopup(); }); document.getElementById("pwa-close-button").addEventListener("click", closePopup); document.getElementById('pwa-ios-close-button').addEventListener('click', closePopup); function closePopup() { document.getElementById("pwa-install-overlay").classList.add("pwa-hidden"); document.getElementById("blur-backdrop").classList.add("pwa-hidden"); document.getElementById('pwa-ios-overlay').classList.add('pwa-hidden'); document.body.classList.remove("modal-open"); deferredPrompt = null; } if ('serviceWorker' in navigator) { let refreshing = false; let updateNode = null; const updateCache = sw => { if (updateNode) { Notifier._removeNode(updateNode); updateNode = null; } Notifier.warn({ title: `Завантаження оновлення`, text: `Додаток буде перезавантажено!` }, { timeout: 3000 }); sw.postMessage('skipWaiting'); // активує новий SW sw.postMessage('updateCache'); // оновлює кеш }; navigator.serviceWorker.register('/sw.js').then(reg => { // якщо є waiting SW, показуємо банер if (reg.waiting) { updateNode = Notifier.click({ title: `Доступне оновлення`, text: `Натисніть, щоб оновити додаток до останньої версії!` }, { type: 'info', f: () => updateCache(reg.waiting), timeout: 0 }); } // слідкуємо за новим воркером reg.addEventListener('updatefound', () => { const newWorker = reg.installing; if (!newWorker) return; newWorker.addEventListener('statechange', () => { if (newWorker.state === 'installed' && reg.waiting) { updateNode = Notifier.click({ title: `Доступне оновлення`, text: `Натисніть, щоб оновити додаток до останньої версії!` }, { type: 'info', f: () => updateCache(reg.waiting), timeout: 0 }); } }); }); navigator.serviceWorker.addEventListener('controllerchange', () => { if (refreshing) return; refreshing = true; window.location.reload(); // відбувається ТІЛЬКИ після skipWaiting }); }).catch(err => console.error('[ServiceWorker] Помилка реєстрації SW:', err)); }