Timers: admin "Timer font" option with a monospace choice
A new Display-group select (Default / Monospace) sets the font for the timer and LTC digits. Monospace keeps the numbers from shifting sideways as they change — easier to read on a fast-moving countdown or timecode. Flows through server state → client applies a `tm-mono` class and re-fits the digit sizing; both timer and LTC values (.tm-time) honor it. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
1d46657e06
commit
5fe39539fc
@@ -176,9 +176,10 @@ below. Nothing is installed without someone clicking.
|
|||||||
discovered timer (and the LTC card) as its own tile, or add "All timers"
|
discovered timer (and the LTC card) as its own tile, or add "All timers"
|
||||||
and pick a selection via the tile's "Timers ▾" menu; overruns are
|
and pick a selection via the tile's "Timers ▾" menu; overruns are
|
||||||
unmistakably red. Read-only — no start/stop controls. Admin config is in
|
unmistakably red. Read-only — no start/stop controls. Admin config is in
|
||||||
two groups: **ProPresenter** (endpoint host : port, API password) and
|
three groups: **ProPresenter** (endpoint host : port, API password),
|
||||||
**LTC Timecode** (the listener switch, and — when it's on — the audio
|
**LTC Timecode** (the listener switch, and — when it's on — the audio
|
||||||
device and channel).
|
device and channel), and **Display** (Timer font — Default or Monospace,
|
||||||
|
which keeps the digits from shifting as the numbers change).
|
||||||
|
|
||||||
ProPresenter exposes no timecode over any API, so LTC is decoded from the
|
ProPresenter exposes no timecode over any API, so LTC is decoded from the
|
||||||
audio signal, behind the admin **LTC listener** switch (off ⇒ no LTC tile
|
audio signal, behind the admin **LTC listener** switch (off ⇒ no LTC tile
|
||||||
|
|||||||
@@ -393,6 +393,14 @@ export default function create({ root, moduleApi }) {
|
|||||||
rebuildMenu();
|
rebuildMenu();
|
||||||
updateLtcAnchor();
|
updateLtcAnchor();
|
||||||
|
|
||||||
|
// Admin-chosen digit font. A font swap changes glyph metrics, so re-fit
|
||||||
|
// the digit sizing when it actually changes.
|
||||||
|
const mono = state?.timerFont === 'monospace';
|
||||||
|
if (mono !== wrap.classList.contains('tm-mono')) {
|
||||||
|
wrap.classList.toggle('tm-mono', mono);
|
||||||
|
fit();
|
||||||
|
}
|
||||||
|
|
||||||
let hint = '';
|
let hint = '';
|
||||||
if (state && !state.enabled && !state.ltc?.supported) {
|
if (state && !state.enabled && !state.ltc?.supported) {
|
||||||
hint = 'No ProPresenter connection — set the host and port in Admin.';
|
hint = 'No ProPresenter connection — set the host and port in Admin.';
|
||||||
|
|||||||
@@ -42,6 +42,16 @@
|
|||||||
"group": "LTC Timecode",
|
"group": "LTC Timecode",
|
||||||
"showWhen": "ltcEnabled",
|
"showWhen": "ltcEnabled",
|
||||||
"default": 1
|
"default": 1
|
||||||
|
},
|
||||||
|
"timerFont": {
|
||||||
|
"type": "select",
|
||||||
|
"label": "Timer font",
|
||||||
|
"group": "Display",
|
||||||
|
"default": "default",
|
||||||
|
"options": [
|
||||||
|
{ "value": "default", "label": "Default (system)" },
|
||||||
|
{ "value": "monospace", "label": "Monospace — steadier changing digits" }
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,10 +57,11 @@ const { createLtcListener } = require('./ltc-listener');
|
|||||||
/** Set by init(), read by the routes — both are rebuilt together on remount. */
|
/** Set by init(), read by the routes — both are rebuilt together on remount. */
|
||||||
let current = null;
|
let current = null;
|
||||||
|
|
||||||
function clearedState(enabled, ltcEnabled = false) {
|
function clearedState(enabled, ltcEnabled = false, timerFont = 'default') {
|
||||||
return {
|
return {
|
||||||
enabled,
|
enabled,
|
||||||
ltcEnabled,
|
ltcEnabled,
|
||||||
|
timerFont,
|
||||||
reachable: false,
|
reachable: false,
|
||||||
lastError: '',
|
lastError: '',
|
||||||
timers: [],
|
timers: [],
|
||||||
@@ -86,8 +87,9 @@ module.exports = {
|
|||||||
const ltcEnabled = Boolean(config.ltcEnabled);
|
const ltcEnabled = Boolean(config.ltcEnabled);
|
||||||
const ltcDevice = String(config.ltcDevice || '');
|
const ltcDevice = String(config.ltcDevice || '');
|
||||||
const ltcChannel = Math.max(1, Math.trunc(Number(config.ltcChannel)) || 1);
|
const ltcChannel = Math.max(1, Math.trunc(Number(config.ltcChannel)) || 1);
|
||||||
|
const timerFont = config.timerFont === 'monospace' ? 'monospace' : 'default';
|
||||||
|
|
||||||
let latest = clearedState(enabled, ltcEnabled);
|
let latest = clearedState(enabled, ltcEnabled, timerFont);
|
||||||
let lastFrame = '';
|
let lastFrame = '';
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
let pollTimer = null;
|
let pollTimer = null;
|
||||||
@@ -207,6 +209,7 @@ module.exports = {
|
|||||||
latest = {
|
latest = {
|
||||||
enabled,
|
enabled,
|
||||||
ltcEnabled,
|
ltcEnabled,
|
||||||
|
timerFont,
|
||||||
reachable: latest.reachable,
|
reachable: latest.reachable,
|
||||||
lastError: latest.lastError,
|
lastError: latest.lastError,
|
||||||
timers: latest.timers,
|
timers: latest.timers,
|
||||||
|
|||||||
@@ -113,6 +113,13 @@
|
|||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Admin "Timer font: Monospace" — steadier digits as the numbers change.
|
||||||
|
Applies to timer and LTC values alike (both are .tm-time). */
|
||||||
|
[data-module="propresenter-timers"] .tm-mono .tm-time {
|
||||||
|
font-family: ui-monospace, "SF Mono", "Menlo", "Cascadia Mono", "Consolas", monospace;
|
||||||
|
letter-spacing: 0;
|
||||||
|
}
|
||||||
|
|
||||||
[data-module="propresenter-timers"] .tm-state {
|
[data-module="propresenter-timers"] .tm-state {
|
||||||
flex: none;
|
flex: none;
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user