Уведомления
Напомним о ТО, страховке и регулярном внесении пробега.
+
diff --git a/web/static/app.js b/web/static/app.js
index 34d100c..c9b2197 100644
--- a/web/static/app.js
+++ b/web/static/app.js
@@ -354,14 +354,71 @@ function updateNotificationStatus(message) {
if (node) node.textContent = t(message);
}
-async function enableNotifications() {
+function updateNotificationHelp(message = "") {
+ const node = document.querySelector("#notificationHelp");
+ if (!node) return;
+ node.textContent = message ? t(message) : "";
+ node.classList.toggle("hidden", !message);
+}
+
+function notificationBlockedMessage() {
+ const isIos = /iPhone|iPad|iPod/i.test(navigator.userAgent);
+ const isAndroid = /Android/i.test(navigator.userAgent);
+ if (isIos) {
+ return "Браузерные уведомления заблокированы. Открой настройки iOS: Settings → Notifications → браузер или Telegram, разреши уведомления и вернись сюда. Сервисные уведомления в Telegram продолжают работать.";
+ }
+ if (isAndroid) {
+ return "Браузерные уведомления заблокированы. Открой настройки сайта в браузере или настройки приложения Telegram/браузера на Android и разреши уведомления. Сервисные уведомления в Telegram продолжают работать.";
+ }
+ return "Браузерные уведомления заблокированы. Нажми на значок замка рядом с адресом сайта, открой Site settings / Настройки сайта и разреши Notifications. Сервисные уведомления в Telegram продолжают работать.";
+}
+
+function refreshNotificationUi() {
+ const button = document.querySelector("#enableNotificationsBtn");
if (!("Notification" in window)) {
updateNotificationStatus("Браузер не поддерживает уведомления");
+ updateNotificationHelp("Важные события по СТО и заказ-нарядам все равно отправляются через Telegram-бота.");
+ if (button) button.disabled = true;
+ return;
+ }
+ if (Notification.permission === "granted") {
+ updateNotificationStatus("Уведомления включены");
+ updateNotificationHelp("");
+ if (button) {
+ button.disabled = false;
+ button.textContent = t("Проверить уведомления");
+ }
+ return;
+ }
+ if (Notification.permission === "denied") {
+ updateNotificationStatus("Уведомления запрещены в настройках браузера");
+ updateNotificationHelp(notificationBlockedMessage());
+ if (button) {
+ button.disabled = false;
+ button.textContent = t("Проверить снова");
+ }
+ return;
+ }
+ updateNotificationStatus("Напомним о ТО, страховке и регулярном внесении пробега.");
+ updateNotificationHelp("Если браузерный запрос будет отклонен, включить уведомления можно только вручную в настройках сайта.");
+ if (button) {
+ button.disabled = false;
+ button.textContent = t("Включить уведомления");
+ }
+}
+
+async function enableNotifications() {
+ if (!("Notification" in window)) {
+ refreshNotificationUi();
+ return;
+ }
+ if (Notification.permission === "denied") {
+ refreshNotificationUi();
return;
}
const permission = await Notification.requestPermission();
if (permission !== "granted") {
- updateNotificationStatus("Уведомления запрещены в настройках браузера");
+ refreshNotificationUi();
return;
}
const registration = state.serviceWorkerRegistration || (await navigator.serviceWorker?.ready);
@@ -383,6 +440,8 @@ async function enableNotifications() {
});
}
updateNotificationStatus("Уведомления включены");
+ updateNotificationHelp("");
+ refreshNotificationUi();
}
async function showDueReminders(registration) {
@@ -2631,11 +2690,7 @@ async function openDrawerSection(sectionId, options = {}) {
document.querySelector("#currencySelect").value = state.user?.currency || "RUB";
}
if (sectionId === "notificationsSection") {
- updateNotificationStatus(
- "Notification" in window && Notification.permission === "granted"
- ? "Уведомления включены"
- : "Напомним о ТО, страховке и регулярном внесении пробега.",
- );
+ refreshNotificationUi();
}
if (sectionId === "confirmationsSection") await loadConfirmations();
if (sectionId === "connectedServicesSection") await loadConnectedServices();