diff --git a/.eslintrc.json b/.eslintrc.json
index 32283e620..81c196021 100644
--- a/.eslintrc.json
+++ b/.eslintrc.json
@@ -116,7 +116,8 @@
"idbDel": "readonly",
"idbAdd": "readonly",
"initChangelog": "readonly",
- "sendNotification": "readonly"
+ "sendNotification": "readonly",
+ "monitorConnection": "readonly"
},
"ignorePatterns": [
"node_modules",
diff --git a/extensions-builtin/sdnext-modernui b/extensions-builtin/sdnext-modernui
index a445b6b09..b189fac67 160000
--- a/extensions-builtin/sdnext-modernui
+++ b/extensions-builtin/sdnext-modernui
@@ -1 +1 @@
-Subproject commit a445b6b09f3974f95d410f19575200109e1a8b83
+Subproject commit b189fac67d24bf21c9b65cf45add5b8c29f7456f
diff --git a/html/locale_en.json b/html/locale_en.json
index 8113a811b..056637d2b 100644
--- a/html/locale_en.json
+++ b/html/locale_en.json
@@ -32,7 +32,6 @@
{"id":"","label":"","localized":"","reload":"","hint":"Sort by time, descending"}
],
"main": [
- {"id":"","label":"SD.Next","localized":"","reload":"","hint":"SD.Next
All-in-one WebUI for AI generative image and video creation"},
{"id":"","label":"Prompt","localized":"","reload":"","hint":"Describe image you want to generate"},
{"id":"","label":"Start","localized":"","reload":"","hint":"Start"},
{"id":"","label":"End","localized":"","reload":"","hint":"End"},
diff --git a/javascript/monitor.js b/javascript/monitor.js
new file mode 100644
index 000000000..1c194af08
--- /dev/null
+++ b/javascript/monitor.js
@@ -0,0 +1,33 @@
+async function updateIndicator(online, data, msg) {
+ const el = document.getElementById('logo_nav');
+ if (!el || !data) return;
+ const status = online ? 'online' : 'offline';
+ const template = `
+ Version: ${data.updated}
+ Commit: ${data.hash}
+ Branch: ${data.branch}
+ Status: ${status}
+ `;
+ if (online) {
+ el.dataset.hint = template;
+ el.style.backgroundColor = 'var(--sd-main-accent-color)';
+ log('monitorConnection: online', data);
+ } else {
+ el.dataset.hint = template;
+ el.style.backgroundColor = 'var(--color-error)';
+ log('monitorConnection: offline', msg);
+ }
+}
+
+async function monitorConnection() {
+ try {
+ const res = await fetch(`${window.api}/version`);
+ const data = await res.json();
+ const url = res.url.split('/sdapi')[0].replace('http', 'ws'); // update global url as ws need fqdn
+ const ws = new WebSocket(`${url}/queue/join`);
+ ws.onopen = () => updateIndicator(true, data, '');
+ ws.onclose = () => updateIndicator(false, data, '');
+ ws.onerror = (e) => updateIndicator(false, data, e.message);
+ ws.onmessage = (evt) => log('monitorConnection: message', evt.data);
+ } catch { /**/ }
+}
diff --git a/javascript/ui.js b/javascript/ui.js
index a61297a54..8c5cd6630 100644
--- a/javascript/ui.js
+++ b/javascript/ui.js
@@ -601,4 +601,5 @@ async function reconnectUI() {
const sd_model_observer = new MutationObserver(sd_model_callback);
sd_model_observer.observe(sd_model, { attributes: true, childList: true, subtree: true });
log('reconnectUI');
+ monitorConnection();
}