feat: add pause button to notifs

This commit is contained in:
Matt Pumarlo
2026-06-24 15:54:14 -05:00
parent d1ca40a539
commit bf12f5e36d
9 changed files with 102 additions and 2 deletions

View File

@@ -848,6 +848,7 @@ class KobraXBridge:
self._print_active: bool = False
self._notify_every_minutes: int = 0
self._notify_every_layers: int = 0
self._notifications_paused: bool = False
self._last_progress_notif_time: float = 0.0
self._last_progress_notif_layer: int = 0
try:
@@ -860,6 +861,7 @@ class KobraXBridge:
_ncfg.read(_np, encoding="utf-8")
self._notify_every_minutes = _ncfg.getint("notifications", "notify_every_minutes", fallback=0)
self._notify_every_layers = _ncfg.getint("notifications", "notify_every_layers", fallback=0)
self._notifications_paused = _ncfg.getboolean("notifications", "paused", fallback=False)
except Exception:
self._notification_urls = []
@@ -1107,6 +1109,8 @@ class KobraXBridge:
# -------------------------------------------------------------------------
def _notify(self, event: str, filename: str = ""):
if self._notifications_paused:
return
matching = [e for e in self._notification_urls if event in e.get("events", [])]
if not matching:
return
@@ -4370,6 +4374,7 @@ class KobraXBridge:
"notifications": self._notification_urls,
"notify_every_minutes": self._notify_every_minutes,
"notify_every_layers": self._notify_every_layers,
"notifications_paused": self._notifications_paused,
})
async def handle_api_settings_post(self, request):
@@ -4463,6 +4468,9 @@ class KobraXBridge:
cfg.set("notifications", "notify_every_layers", str(notify_every_layers))
self._notify_every_minutes = notify_every_minutes
self._notify_every_layers = notify_every_layers
if "notifications_paused" in data:
self._notifications_paused = bool(data.get("notifications_paused"))
cfg.set("notifications", "paused", "true" if self._notifications_paused else "false")
with open(config_path, "w", encoding="utf-8") as f:
f.write("# KX-Bridge Konfigurationsdatei\n\n")
@@ -4473,6 +4481,34 @@ class KobraXBridge:
asyncio.get_event_loop().call_later(0.3, self._restart_bridge)
return response
async def handle_api_notifications_pause(self, request):
"""Toggle or set the global notifications-paused flag without restarting."""
try:
data = await request.json()
except Exception:
data = {}
if isinstance(data, dict) and "paused" in data:
self._notifications_paused = bool(data.get("paused"))
else:
self._notifications_paused = not self._notifications_paused
try:
import configparser
config_path = self._find_config_path()
config_path.parent.mkdir(parents=True, exist_ok=True)
cfg = configparser.ConfigParser()
if config_path.is_file():
cfg.read(config_path, encoding="utf-8")
if not cfg.has_section("notifications"):
cfg.add_section("notifications")
cfg.set("notifications", "paused", "true" if self._notifications_paused else "false")
with open(config_path, "w", encoding="utf-8") as f:
f.write("# KX-Bridge Konfigurationsdatei\n\n")
cfg.write(f)
except Exception as e:
log.warning(f"Notif-Pause speichern fehlgeschlagen: {e}")
log.info(f"Benachrichtigungen {'pausiert' if self._notifications_paused else 'aktiv'}")
return self._json_cors({"status": "ok", "paused": self._notifications_paused})
async def handle_api_notifications_test(self, request):
try:
data = await request.json()
@@ -5343,6 +5379,7 @@ def build_app(bridge: KobraXBridge) -> web.Application:
r.add_get("/api/settings", bridge.handle_api_settings_get)
r.add_post("/api/settings", bridge.handle_api_settings_post)
r.add_post("/api/notifications/test", bridge.handle_api_notifications_test)
r.add_post("/api/notifications/pause", bridge.handle_api_notifications_pause)
r.add_get("/api/update/check", bridge.handle_api_update_check)
r.add_post("/api/update/apply", bridge.handle_api_update_apply)
r.add_post("/api/file_ready/clear", bridge.handle_api_file_ready_clear)

View File

@@ -530,6 +530,7 @@ function applyLang() {
var nhEl = document.getElementById("notif-hint");
if (nhEl && T.settings_notifications_hint) nhEl.innerHTML = T.settings_notifications_hint;
setText("lbl-notif-add", T.settings_notif_add);
notifUpdateToggleBtn();
setText("lbl-notif-interval", T.settings_notif_interval_lbl);
setText("lbl-notif-min-unit", T.settings_notif_min_unit);
setText("lbl-notif-layers-unit", T.settings_notif_layers_unit);
@@ -1525,7 +1526,39 @@ function drawChart(id, _, series) {
// ── Notifications ──
var _notifRows = [];
var _notifPaused = false;
var _NOTIF_EVENTS = ["started", "finished", "failed", "cancelled", "paused", "progress"];
function notifUpdateToggleBtn() {
var btn = document.getElementById("btn-notif-toggle");
var lbl = document.getElementById("lbl-notif-toggle");
if (!btn) return;
if (_notifPaused) {
if (lbl) lbl.textContent = T.settings_notif_paused || "Paused";
btn.style.background = "var(--warn, #c08a2d)";
btn.style.color = "#fff";
} else {
if (lbl) lbl.textContent = T.settings_notif_active || "Active";
btn.style.background = "var(--ok, #2e9e4f)";
btn.style.color = "#fff";
}
}
function notifTogglePaused() {
var target = !_notifPaused;
var btn = document.getElementById("btn-notif-toggle");
if (btn) btn.disabled = true;
post("/api/notifications/pause", { paused: target })
.then(function (r) {
return r.json();
})
.then(function (d) {
if (btn) btn.disabled = false;
_notifPaused = d && typeof d.paused === "boolean" ? d.paused : target;
notifUpdateToggleBtn();
})
.catch(function () {
if (btn) btn.disabled = false;
});
}
function notifRenderList(entries) {
_notifRows = entries.map(function (e) {
return {
@@ -1722,6 +1755,8 @@ function openSettings() {
var wuw = document.getElementById("s-web-upload-warning");
if (wuw) wuw.checked = d.web_upload_warning === undefined ? true : !!d.web_upload_warning;
notifRenderList(d.notifications || []);
_notifPaused = !!d.notifications_paused;
notifUpdateToggleBtn();
var enm = document.getElementById("s-notif-every-min");
if (enm) enm.value = d.notify_every_minutes || 0;
var enl = document.getElementById("s-notif-every-layers");
@@ -2589,6 +2624,7 @@ function saveSettings() {
Math.max(1, parseInt((document.getElementById("s-poll-interval") || {}).value, 10) || 3)
),
notifications: notifCollect(),
notifications_paused: _notifPaused,
notify_every_minutes:
parseInt((document.getElementById("s-notif-every-min") || {}).value || "0", 10) || 0,
notify_every_layers:

View File

@@ -1622,8 +1622,23 @@
<!-- Benachrichtigungen -->
<div class="set-group" id="setgrp-notifications">
<div class="card">
<div class="card-title">
<span>🔔</span> <span id="modal-sec-notifications">Benachrichtigungen</span>
<div
class="card-title"
style="display: flex; align-items: center; justify-content: space-between"
>
<span>
<span>🔔</span>
<span id="modal-sec-notifications">Benachrichtigungen</span>
</span>
<button
type="button"
class="btn btn-sm"
id="btn-notif-toggle"
onclick="notifTogglePaused()"
style="font-size: 11px; padding: 2px 10px"
>
<span id="lbl-notif-toggle">Active</span>
</button>
</div>
<div
style="font-size: 11px; color: var(--txt2); margin-bottom: 8px"

View File

@@ -237,6 +237,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "MQTT-Port",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "Aktiv",
"settings_notif_add": "Benachrichtigung hinzufügen",
"settings_notif_empty": "Keine Benachrichtigungen konfiguriert.",
"settings_notif_ev_cancelled": "Abgebrochen",
@@ -248,6 +249,7 @@
"settings_notif_interval_lbl": "Wiederholungsintervall",
"settings_notif_layers_unit": "Schichten",
"settings_notif_min_unit": "Min",
"settings_notif_paused": "Pausiert",
"settings_notif_send_image": "Bild",
"settings_notif_test": "Test",
"settings_notif_test_fail": "Fehler",

View File

@@ -241,6 +241,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "MQTT Port",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "Active",
"settings_notif_add": "Add notification",
"settings_notif_empty": "No notifications configured.",
"settings_notif_ev_cancelled": "Cancelled",
@@ -252,6 +253,7 @@
"settings_notif_interval_lbl": "Repeat interval",
"settings_notif_layers_unit": "layers",
"settings_notif_min_unit": "min",
"settings_notif_paused": "Paused",
"settings_notif_send_image": "Image",
"settings_notif_test": "Test",
"settings_notif_test_fail": "Failed",

View File

@@ -239,6 +239,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "MQTT Port",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "Activo",
"settings_notif_add": "Agregar notificación",
"settings_notif_empty": "Sin notificaciones configuradas.",
"settings_notif_ev_cancelled": "Cancelado",
@@ -250,6 +251,7 @@
"settings_notif_interval_lbl": "Intervalo de repetición",
"settings_notif_layers_unit": "capas",
"settings_notif_min_unit": "min",
"settings_notif_paused": "Pausado",
"settings_notif_send_image": "Imagen",
"settings_notif_test": "Prueba",
"settings_notif_test_fail": "Error",

View File

@@ -240,6 +240,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "Port MQTT",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "Actif",
"settings_notif_add": "Ajouter une notification",
"settings_notif_empty": "Aucune notification configurée.",
"settings_notif_ev_cancelled": "Annulé",
@@ -251,6 +252,7 @@
"settings_notif_interval_lbl": "Intervalle de répétition",
"settings_notif_layers_unit": "couches",
"settings_notif_min_unit": "min",
"settings_notif_paused": "En pause",
"settings_notif_send_image": "Image",
"settings_notif_test": "Test",
"settings_notif_test_fail": "Erreur",

View File

@@ -238,6 +238,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "Porta MQTT",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "Attivo",
"settings_notif_add": "Aggiungi notifica",
"settings_notif_empty": "Nessuna notifica configurata.",
"settings_notif_ev_cancelled": "Annullato",
@@ -249,6 +250,7 @@
"settings_notif_interval_lbl": "Intervallo di ripetizione",
"settings_notif_layers_unit": "strati",
"settings_notif_min_unit": "min",
"settings_notif_paused": "In pausa",
"settings_notif_send_image": "Immagine",
"settings_notif_test": "Test",
"settings_notif_test_fail": "Errore",

View File

@@ -237,6 +237,7 @@
"settings_mode_id_placeholder": "20030",
"settings_mqtt_port": "MQTT 端口",
"settings_mqtt_username_placeholder": "userXXXXXXXX",
"settings_notif_active": "已启用",
"settings_notif_add": "添加通知",
"settings_notif_empty": "未配置任何通知。",
"settings_notif_ev_cancelled": "已取消",
@@ -248,6 +249,7 @@
"settings_notif_interval_lbl": "重复间隔",
"settings_notif_layers_unit": "层",
"settings_notif_min_unit": "分钟",
"settings_notif_paused": "已暂停",
"settings_notif_send_image": "图像",
"settings_notif_test": "测试",
"settings_notif_test_fail": "失败",