Companion Buttons 1.1.0: pages in the + picker, buttons chosen on the tile
The picker row (page list, Clear, Done) is gone. Each Companion page is now its own + entry, titled with the page's name, showing the whole page minus page up/down. The grid icon switches the tile to choosing: click buttons to take them out or put them back, click the icon again when done. The gear holds one switch, Page layout (Companion's rows and columns, or packed). - Tiles follow their page by Companion's page id and buttons by row/column, so inserted pages and re-imported pages keep showing. - A tile remounted after a settings change asks GET /state for the snapshot the already-open stream sent, instead of waiting blank. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
+28
-5
@@ -8,9 +8,10 @@
|
||||
*
|
||||
* then point Companion Buttons at host 127.0.0.1, port 18000 in /admin.
|
||||
*
|
||||
* It serves the two subscriptions the module uses — pages.watch and
|
||||
* preview.graphics.controlId — over a hand-rolled websocket (no deps), with
|
||||
* three pages. Page 1's first button flips between green and red every two
|
||||
* It serves the three subscriptions the module uses — pages.watch,
|
||||
* preview.graphics.controlId and controls.watchControl — over a hand-rolled
|
||||
* websocket (no deps), with three pages: a status page with a page-up
|
||||
* button, a camera page, and an unnamed page holding only navigation. Page 1's first button flips between green and red every two
|
||||
* seconds, like a status button; page 1's second button redraws the same
|
||||
* picture every 300 ms, like a button fed a variable that has not changed.
|
||||
* Every 30 s it sends PING and drops a client that does not answer PONG,
|
||||
@@ -123,9 +124,22 @@ function readFrames(state, data, onText, onClose) {
|
||||
|
||||
function startMock(port = 0, { renameAfter = 0, moveAfter = 0, log = () => {} } = {}) {
|
||||
const pages = {
|
||||
p1: { id: 'p1', name: '1\\nStatus', controls: { 0: { 0: 'bank:flip', 1: 'bank:steady', 2: 'bank:blue' } } },
|
||||
p1: { id: 'p1', name: '1\\nStatus', controls: { 0: { 0: 'bank:flip', 1: 'bank:steady', 2: 'bank:blue' }, 1: { 0: 'bank:up1' } } },
|
||||
p2: { id: 'p2', name: 'Cameras', controls: { 0: { 0: 'bank:cam1' }, 1: { 3: 'bank:cam2' } } },
|
||||
p3: { id: 'p3', name: 'PAGE', controls: {} },
|
||||
p3: { id: 'p3', name: 'PAGE', controls: { 0: { 0: 'bank:up3' } } },
|
||||
};
|
||||
const layered = (value, isExpression = false) => ({
|
||||
type: 'button-layered',
|
||||
style: { layers: [{ id: 'canvas', type: 'canvas' }, { id: 'text0', type: 'text', text: { value, isExpression } }] },
|
||||
});
|
||||
const configs = {
|
||||
'bank:flip': layered('FLIP'),
|
||||
'bank:steady': layered('Steady'),
|
||||
'bank:blue': layered('Blue'),
|
||||
'bank:cam1': { type: 'button', style: { text: 'CAM 1' } },
|
||||
'bank:cam2': layered('CAM 2'),
|
||||
'bank:up1': { type: 'pageup', style: {} },
|
||||
'bank:up3': { type: 'pageup', style: {} },
|
||||
};
|
||||
const order = ['p1', 'p2', 'p3'];
|
||||
const looks = {
|
||||
@@ -184,6 +198,14 @@ function startMock(port = 0, { renameAfter = 0, moveAfter = 0, log = () => {} }
|
||||
}
|
||||
if (msg.method !== 'subscription') return send(client, { id: msg.id, error: { message: 'mock: only subscriptions' } });
|
||||
const { path, input } = msg.params || {};
|
||||
if (path === 'controls.watchControl') {
|
||||
const cfg = configs[input && input.controlId];
|
||||
if (!cfg) return send(client, { id: msg.id, error: { message: `Control ${input && input.controlId} not found` } });
|
||||
stats.subscriptions += 1;
|
||||
client.subs.set(msg.id, { path, input });
|
||||
send(client, { id: msg.id, result: { type: 'started' } });
|
||||
return send(client, { id: msg.id, result: { type: 'data', data: { type: 'init', config: cfg, runtime: {} } } });
|
||||
}
|
||||
if (path !== 'pages.watch' && path !== 'preview.graphics.controlId') {
|
||||
return send(client, { id: msg.id, error: { message: `No procedure found on path "${path}"` } });
|
||||
}
|
||||
@@ -276,6 +298,7 @@ function startMock(port = 0, { renameAfter = 0, moveAfter = 0, log = () => {} }
|
||||
redraw,
|
||||
looks,
|
||||
pages,
|
||||
configs,
|
||||
/** Drop every client without a close frame, as a crash or a cable pull would. */
|
||||
dropAll() {
|
||||
for (const c of clients) c.socket.destroy();
|
||||
|
||||
Reference in New Issue
Block a user