This commit is contained in:
root
2026-10-01 22:16:48 +02:00
parent b6d1909d7f
commit 9dfdf79fa7
39 changed files with 4560 additions and 181 deletions
+39 -5
View File
@@ -11,15 +11,46 @@ export function downlinkView(ctx) {
const dl = h('button', { class: 'btn', type: 'button', disabled: true }, 'DOWNLOAD .BIN');
const refresh = h('button', { class: 'btn', type: 'button', disabled: !ship }, 'REFRESH');
// Earlier downlinks: pick a day, or step with the arrows. `days` is oldest first.
const older = h('button', { class: 'btn', type: 'button', disabled: true, 'aria-label': 'Previous downlink' }, '<');
const newer = h('button', { class: 'btn', type: 'button', disabled: true, 'aria-label': 'Next downlink' }, '>');
const pick = h('select', { class: 'daypick', 'aria-label': 'Downlink day', disabled: true });
let days = [];
let shown = null; // the day on screen; null = the latest
function syncPicker() {
clear(pick).append(...days.slice().reverse().map((d, i) =>
h('option', { value: String(d) }, `DAY ${d}${i === 0 ? ' (LATEST)' : ''}`)));
const at = shown == null ? days.length - 1 : days.indexOf(shown);
if (at >= 0) pick.value = String(days[at]);
pick.disabled = days.length < 2;
older.disabled = at <= 0;
newer.disabled = at < 0 || at >= days.length - 1;
}
function go(step) {
const at = shown == null ? days.length - 1 : days.indexOf(shown);
const to = days[at + step];
if (to !== undefined) fetchIt(to);
}
older.addEventListener('click', () => go(-1));
newer.addEventListener('click', () => go(1));
pick.addEventListener('change', () => fetchIt(Number(pick.value)));
let current = null;
async function fetchIt() {
async function fetchIt(day) {
if (!ship) return;
refresh.disabled = true;
try {
const { bytes, day } = await api.downlink(ship.id);
current = { bytes, day };
days = await api.downlinkDays(ship.id);
// Refreshing (no day given) jumps to the latest; a stale choice falls back to it too.
shown = day != null && days.includes(day) ? day : null;
const got = await api.downlink(ship.id, shown);
const bytes = got.bytes;
shown = got.day === days[days.length - 1] ? null : got.day;
syncPicker();
current = { bytes, day: got.day };
const allZero = bytes.every((b) => b === 0);
meta.textContent = `SHIP #${ship.id} // FROM THE RUN OF DAY ${day} // ${bytes.length} BYTES`;
meta.textContent = `SHIP #${ship.id} // FROM THE RUN OF DAY ${got.day} // ${bytes.length} BYTES`;
dl.disabled = false;
clear(body).append(
...(allZero ? [h('p', { class: 'warn' }, 'BUFFER IS ALL ZEROS: THE SHIP HAS NOT WRITTEN ANYTHING TO ITS DOWNLINK BUFFER.')] : []),
@@ -28,6 +59,9 @@ export function downlinkView(ctx) {
);
} catch (e) {
current = null;
days = [];
shown = null;
syncPicker();
dl.disabled = true;
meta.textContent = '';
clear(body).append(
@@ -53,7 +87,7 @@ export function downlinkView(ctx) {
return h('section', { class: 'panel' },
h('div', { class: 'panel-title' }, 'DOWNLINK RECEIVER', h('span', { class: 'spacer' }), meta),
h('div', { class: 'toolbar pad' }, refresh, h('span', { class: 'spacer' }), dl),
h('div', { class: 'toolbar pad' }, refresh, older, pick, newer, h('span', { class: 'spacer' }), dl),
body,
);
}