diff --git a/Cargo.lock b/Cargo.lock index 0ed6c53..d8c9f0f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -108,11 +108,11 @@ dependencies = [ [[package]] name = "autoblink-core-dbserver" -version = "1.22.1" +version = "1.22.2" [[package]] name = "autoblink-core-midi" -version = "1.22.1" +version = "1.22.2" dependencies = [ "serde", "serde_json", @@ -120,11 +120,11 @@ dependencies = [ [[package]] name = "autoblink-core-prolink" -version = "1.22.1" +version = "1.22.2" [[package]] name = "autoblink-esp32-emulator" -version = "1.22.1" +version = "1.22.2" dependencies = [ "anyhow", "autoblink-core-prolink", @@ -138,7 +138,7 @@ dependencies = [ [[package]] name = "autoblink-host" -version = "1.22.1" +version = "1.22.2" dependencies = [ "anyhow", "autoblink-core-prolink", diff --git a/Cargo.toml b/Cargo.toml index aafa611..30d8f8b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,7 +13,7 @@ members = [ exclude = ["esp32"] [workspace.package] -version = "1.22.1" +version = "1.22.2" edition = "2021" license = "Proprietary" authors = ["AUTOBLINK team"] diff --git a/esp32/Cargo.lock b/esp32/Cargo.lock index 4f8673f..000790c 100644 --- a/esp32/Cargo.lock +++ b/esp32/Cargo.lock @@ -58,22 +58,22 @@ checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" [[package]] name = "autoblink-core-dbserver" -version = "1.22.1" +version = "1.22.2" [[package]] name = "autoblink-core-midi" -version = "1.22.1" +version = "1.22.2" dependencies = [ "serde", ] [[package]] name = "autoblink-core-prolink" -version = "1.22.1" +version = "1.22.2" [[package]] name = "autoblink-esp32" -version = "1.22.1" +version = "1.22.2" dependencies = [ "anyhow", "autoblink-core-dbserver", diff --git a/esp32/Cargo.toml b/esp32/Cargo.toml index 1888fe9..737974d 100644 --- a/esp32/Cargo.toml +++ b/esp32/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "autoblink-esp32" # The firmware is not in the workspace. Keep this version the same as the workspace version. -version = "1.22.1" +version = "1.22.2" edition = "2021" license = "Proprietary" authors = ["AUTOBLINK team"] diff --git a/webui/index.html b/webui/index.html index 73ea7e6..8c7d35e 100644 --- a/webui/index.html +++ b/webui/index.html @@ -85,6 +85,9 @@ .deck canvas.wave{display:block;width:100%;height:56px;margin-top:6px;border-radius:3px;background:#08080d} .deck canvas.wave.lane{height:74px} .empty{color:var(--dim);padding:8px 0} +#nomaster{padding:24px 0;text-align:center;font-size:14px} +.spin{display:inline-block;width:12px;height:12px;border:2px solid var(--dim);border-top-color:var(--accent);border-radius:50%;animation:spin .8s linear infinite;vertical-align:middle} +@keyframes spin{to{transform:rotate(360deg)}} /* mixer: one channel strip next to its deck, with knobs */ .ch{display:flex;flex-direction:column;align-items:center;gap:2px;background:#0d0d16;border:1px solid var(--border);border-radius:8px;padding:6px 4px;width:62px} .ch .chn{font-weight:600;font-size:11px;margin-bottom:2px} @@ -158,7 +161,8 @@

Another screen is connected

Master deck —

-
+ +
---.-
@@ -223,7 +227,7 @@

System

Firmware
installed —
-
+
@@ -279,6 +283,8 @@

System

set('mode', s.mode || '—'); set('iface', s.iface || '—'); set('state', m.playing ? '▶ PLAY' : '■ STOP'); + $('nomaster').hidden = !s.no_devices; + $('mgrid').hidden = !!s.no_devices; $('state').className = m.playing ? 'play' : 'stop'; set('bpm', m.bpm > 0 ? m.bpm.toFixed(2) : '---.-'); @@ -315,8 +321,11 @@

System

/** Shows the state of the firmware update. */ function renderOta(o) { const busy = o.state === 'checking' || o.state === 'downloading' || o.state === 'restarting'; - set('fwstate', (OTA_TEXT[o.state] || o.state) + (o.latest && o.state !== 'up-to-date' ? ' · v' + o.latest : '')); - $('fwcheck').disabled = busy; + // The box sends no status during the check. A status that comes 1.5 s after the click shows the result. + if (!busy && Date.now() - otaClick > 1500) otaClick = 0; + set('fwstate', otaClick ? OTA_TEXT.checking : (OTA_TEXT[o.state] || o.state) + (o.latest && o.state !== 'up-to-date' ? ' · v' + o.latest : '')); + $('fwcheck').disabled = busy || otaClick > 0; + $('fwspin').hidden = !(o.state === 'checking' || otaClick); $('fwinstall').hidden = o.state !== 'available'; set('fwinstall', 'Install v' + (o.latest || '?')); $('fwbar').hidden = o.state !== 'downloading'; @@ -324,7 +333,21 @@

System

set('fwerr', o.error || ''); } -$('fwcheck').onclick = () => send({ type: 'ota_check' }); +let otaClick = 0; +$('fwcheck').onclick = () => { + otaClick = Date.now(); + set('fwstate', OTA_TEXT.checking); + $('fwcheck').disabled = true; + $('fwspin').hidden = false; + send({ type: 'ota_check' }); +}; +/** Stops the spinner of the update check. */ +function otaDone() { + otaClick = 0; + set('fwstate', ''); + $('fwcheck').disabled = false; + $('fwspin').hidden = true; +} $('reboot').onclick = () => { const playing = status && (status.decks || []).some((d) => d.playing); const warn = playing ? 'A deck plays. The MIDI clock stops until the box is back, about 15 s.\n\n' : ''; @@ -781,7 +804,7 @@

System

set('conn', 'waiting'); } -const handlers = { hello: onHello, status: onStatus, settings: onSettings, ports: onPorts, log: onLog, beat: onBeat, busy: onBusy, error: (m) => toast(m.text) }; +const handlers = { hello: onHello, status: onStatus, settings: onSettings, ports: onPorts, log: onLog, beat: onBeat, busy: onBusy, error: (m) => { otaDone(); toast(m.text); } }; function connect() { const proto = location.protocol === 'https:' ? 'wss://' : 'ws://';