From 000f479b2f5103c2f32e25c69c1a2d05155f2d5c Mon Sep 17 00:00:00 2001 From: flop Date: Fri, 22 May 2026 17:48:48 +0200 Subject: [PATCH] fix: timestamps for timespan sections --- ts/src/browser.ts | 32 +++++++++++++++++++++++++------- ts/src/file.ts | 23 ++++++++++++----------- 2 files changed, 37 insertions(+), 18 deletions(-) diff --git a/ts/src/browser.ts b/ts/src/browser.ts index 1b22ce2..f4c650d 100644 --- a/ts/src/browser.ts +++ b/ts/src/browser.ts @@ -227,6 +227,14 @@ function setSectionType(si: number, sectionType: string) { (sec as any).elements = []; (sec as any).flags = {}; delete (sec as any).fontData; + if ((sec as any).sectionType === MonoDisplay.SectionType.ElementsTimespan) { + const now = BigInt(Math.floor(Date.now() / 1000)); + (sec as any).startTimestamp = now; + (sec as any).endTimestamp = now + 3600n; + } else { + delete (sec as any).startTimestamp; + delete (sec as any).endTimestamp; + } } markDirty(); triggerPreview(); } @@ -364,7 +372,8 @@ function loadBin(input: HTMLInputElement) { const reader = new FileReader(); reader.onload = e => { try { - file = new window.MonoDisplay.MonoDisplayParser().parse(e.target!.result as ArrayBuffer); + const parsed = new window.MonoDisplay.MonoDisplayParser().parse(e.target!.result as ArrayBuffer); + file = new MonoDisplayFile(parsed.sections); activeSecIndex = null; activeElIndex = null; triggerPreview(); @@ -512,15 +521,24 @@ const SectionCard: m.Component<{ si: number }> = { section.sectionType === MonoDisplay.SectionType.ElementsTimespan ? m(".el-list", ([ ["Start Time", "startTimestamp"], ["Stop Time", "endTimestamp"] ] as [string, string][]) - .map(([label, key]) => - m(".field", + .map(([label, key]) => { + let posix: bigint = (section as any)[key]; + if (!posix) { + posix = BigInt(Math.floor(Date.now() / 1000)); + setSectionField(si, key, posix); + } + const dtLocal = new Date(Number(posix) * 1000).toISOString().slice(0, 16); + return m(".field", m("label", label), m("input[type=datetime-local]", { - value: (section as any)[key], - onchange: (e: Event) => setSectionField(si, key, (e.target as HTMLInputElement).value), + value: dtLocal, + onchange: (e: Event) => { + const ms = new Date((e.target as HTMLInputElement).value).getTime(); + setSectionField(si, key, BigInt(Math.floor(ms / 1000))); + }, }), - ) - ) + ); + }) ) : null, m(".el-list", diff --git a/ts/src/file.ts b/ts/src/file.ts index 940997b..fddf599 100644 --- a/ts/src/file.ts +++ b/ts/src/file.ts @@ -108,25 +108,26 @@ export class MonoDisplayFile implements MonoFormatFile { (section.flags.clearBuffer ?? false ? 0x04 : 0); const encodedEls = section.elements.map(el => this.#encodeElement(el)); - const sectionDataSize = 4 + encodedEls.reduce((s, e) => s + e.byteLength, 0); + // sub-header: flags(2) + numElements(2) + startTimestamp(8) + endTimestamp(8) = 20 bytes + const sectionDataSize = 20 + encodedEls.reduce((s, e) => s + e.byteLength, 0); // sectionSize (in header) = 4 (header) + sectionDataSize const sectionSize = 4 + sectionDataSize; - const hdr = new Uint8Array(4 + 5*4); // section header (4) + section sub-header (4) + const hdr = new Uint8Array(4 + 20); // section header (4) + sub-header (20) const v = new DataView(hdr.buffer); v.setUint8(0, section.sectionType); v.setUint8(1, sectionSize & 0xFF); v.setUint8(2, (sectionSize >> 8) & 0xFF); v.setUint8(3, (sectionSize >> 16) & 0xFF); - v.setUint16(4, flagBits, true); // flags - v.setUint16(6, section.elements.length, true); // numElements - - // section.startTimestamp.valueOf() - const startTimestampLow = 0, startTimestampHigh = 0, endTimestampLow = 0, endTimestampHigh = 0; - v.setUint32(8, startTimestampLow, true); // flags - v.setUint32(12, startTimestampHigh, true); // numElements - v.setUint32(16, endTimestampLow, true); // numElements - v.setUint32(20, endTimestampHigh, true); // numElements + v.setUint16(4, flagBits, true); // flags + v.setUint16(6, section.elements.length, true); // numElements + + const start = section.startTimestamp ?? 0n; + const end = section.endTimestamp ?? 0n; + v.setUint32( 8, Number(start & 0xFFFFFFFFn), true); + v.setUint32(12, Number((start >> 32n) & 0xFFFFFFFFn), true); + v.setUint32(16, Number(end & 0xFFFFFFFFn), true); + v.setUint32(20, Number((end >> 32n) & 0xFFFFFFFFn), true); return this.#concat(hdr, ...encodedEls); }