diff --git a/js/script.js b/js/script.js
index c1a9d9c..e703fe4 100644
--- a/js/script.js
+++ b/js/script.js
@@ -52,7 +52,7 @@ const btnRestart = document.querySelector('.btn-restart');
const btnHalt = document.querySelector('.btn-halt');
const btnPlotter = document.querySelector('.btn-plotter');
const btnClear = document.querySelector('.btn-clear');
-const btnConnect = document.querySelectorAll('.btn-connect');
+let btnConnect = document.querySelectorAll('.btn-connect');
const btnNew = document.querySelectorAll('.btn-new');
const btnOpen = document.querySelectorAll('.btn-open');
const btnFormat = document.querySelectorAll('.btn-format');
@@ -77,6 +77,21 @@ const MAX_EDITOR_FONT_SIZE = 48;
// disconnect, we prefer the last backend over re-prompting for one.
const LAST_BACKEND_KEY = "webeditor.lastBackend";
+const CONNECTION_DETAILS = {
+ [CONNTYPE.Web]: {
+ label: "WiFi",
+ iconClass: "fa-solid fa-wifi",
+ },
+ [CONNTYPE.Ble]: {
+ label: "Bluetooth",
+ iconClass: "fa-brands fa-bluetooth-b",
+ },
+ [CONNTYPE.Usb]: {
+ label: "USB",
+ iconClass: "fa-brands fa-usb",
+ },
+};
+
function getLastBackend() {
try {
const name = window.localStorage.getItem(LAST_BACKEND_KEY);
@@ -100,6 +115,43 @@ function rememberLastBackend(workflowType) {
}
}
+function getConnectionIndicatorType() {
+ if (workflow && workflow.type !== CONNTYPE.None) {
+ return workflow.type;
+ }
+ return getLastBackend();
+}
+
+function getConnectButtonContents(isConnected) {
+ const action = isConnected ? "Disconnect" : "Connect";
+ const connectionType = getConnectionIndicatorType();
+ const details = CONNECTION_DETAILS[connectionType];
+
+ if (!details) {
+ return {
+ html: action,
+ label: action,
+ title: action,
+ };
+ }
+
+ const status = isConnected ? "Connected via" : "Last connection";
+ const actionLabel = isConnected
+ ? `Disconnect ${details.label}`
+ : `Connect using ${details.label}`;
+
+ return {
+ html: `${details.label} ${action}`,
+ label: actionLabel,
+ title: `${status}: ${details.label}`,
+ };
+}
+
+function getConnectButtons() {
+ btnConnect = document.querySelectorAll('.btn-connect');
+ return btnConnect;
+}
+
const editorTheme = EditorView.theme({}, {dark: getCssVar('editor-theme-dark').trim() === '1'});
const editorFontSizeCompartment = new Compartment();
@@ -629,6 +681,7 @@ async function loadWorkflow(workflowType = null) {
}
workflow = workflows[workflowType];
rememberLastBackend(workflowType);
+ updateUIConnected(false);
// Initialize the workflow
await workflow.init({
terminal: state.terminal,
@@ -657,6 +710,7 @@ async function loadWorkflow(workflowType = null) {
}
// Unload workflow
workflow = null;
+ updateUIConnected(false);
}
}
@@ -723,10 +777,13 @@ async function debugLog(msg) {
}
function updateUIConnected(isConnected) {
+ const buttonState = getConnectButtonContents(isConnected);
if (isConnected) {
// Set to Connected State
- btnConnect.forEach((element) => {
- element.innerHTML = "Disconnect";
+ getConnectButtons().forEach((element) => {
+ element.innerHTML = buttonState.html;
+ element.setAttribute("aria-label", buttonState.label);
+ element.title = buttonState.title;
element.disabled = false;
});
if (workflow.showInfo !== undefined) {
@@ -734,8 +791,10 @@ function updateUIConnected(isConnected) {
}
} else {
// Set to Disconnected State
- btnConnect.forEach((element) => {
- element.innerHTML = "Connect";
+ getConnectButtons().forEach((element) => {
+ element.innerHTML = buttonState.html;
+ element.setAttribute("aria-label", buttonState.label);
+ element.title = buttonState.title;
element.disabled = false;
});
btnInfo.disabled = true;
@@ -1046,7 +1105,8 @@ function applySettings() {
document.addEventListener('DOMContentLoaded', async (event) => {
await setupXterm();
applySettings();
- btnConnect.forEach((element) => {
+ updateUIConnected(false);
+ getConnectButtons().forEach((element) => {
element.addEventListener('click', async function(e) {
e.preventDefault();
e.stopPropagation();
diff --git a/sass/layout/_header.scss b/sass/layout/_header.scss
index 30d1fea..144dea8 100644
--- a/sass/layout/_header.scss
+++ b/sass/layout/_header.scss
@@ -107,10 +107,35 @@
& {
background-color: transparent;
margin: 0;
+ align-items: center;
+ display: inline-flex;
+ gap: 8px;
+ justify-content: center;
+ min-width: 118px;
}
}
}
+.connection-indicator {
+ align-items: center;
+ display: inline-flex;
+ gap: 5px;
+ white-space: nowrap;
+
+ i {
+ font-size: 16px;
+ line-height: 1;
+ }
+}
+
+.connection-label {
+ font-size: 13px;
+}
+
+.connect-action {
+ white-space: nowrap;
+}
+
.site-navigation {
padding: 0 0 10px 0;
font-size: 18px;
diff --git a/sass/layout/_header_mobile.scss b/sass/layout/_header_mobile.scss
index b3ed46a..be151e1 100644
--- a/sass/layout/_header_mobile.scss
+++ b/sass/layout/_header_mobile.scss
@@ -108,4 +108,15 @@
#mobile-editor-bar {
display: block !important;
}
+
+ #mobile-header {
+ .get-started button {
+ gap: 6px;
+ min-width: 94px;
+ }
+
+ .connection-label {
+ display: none;
+ }
+ }
}