From 4c5d7956abd804541817d33c03e9f7a0c6388290 Mon Sep 17 00:00:00 2001 From: Waters Church Date: Thu, 10 Sep 2026 16:20:46 -0400 Subject: [PATCH] pco-plan: display settings are per tile again (gear menu), admin keeps the connection Top bar (template, item-type tint, key color) and the whole show/hide checklist move from admin config to instanceSchema, grouped in the gear popover ("Top bar" open, "Show / hide" folded, three columns). They are browser-side choices stored with the layout, not server state. Admin now holds only credentials, service type, plan, poll interval and the ProPresenter follow switch. noteCategories moves to the tile too. Co-Authored-By: Claude Fable 5.1 --- README.md | 13 +++++++------ modules/pco-plan/client.js | 20 +++++++++----------- modules/pco-plan/module.json | 25 +++++++++++++++---------- 3 files changed, 31 insertions(+), 27 deletions(-) diff --git a/README.md b/README.md index 2e7cf07..da2bf4c 100644 --- a/README.md +++ b/README.md @@ -140,12 +140,13 @@ ignored from then on. description and item notes. When the ProPresenter module is running it follows that module's live item, highlights the matching plan item, dims what's done and shows the elapsed vs planned runtime and how far - ahead/behind the service is. Everything is configured in `/admin`: - Planning Center credentials (Personal Access Token app ID + secret, or an - OAuth token), the service type (a list grouped by your Planning Center - folders), an optional pinned plan, the top-bar text (placeholders such as - `{series} • {part} | {serviceType} • {date}`), colors, and a show/hide - checklist for every detail. Tiles only choose their text size. + ahead/behind the service is. Admin config is the connection: Planning + Center credentials (Personal Access Token app ID + secret, or an OAuth + token), the service type (a list grouped by your Planning Center folders) + and an optional pinned plan. Everything about the display is per tile + (gear menu): the top-bar text (placeholders such as + `{series} • {part} | {serviceType} • {date}`), colors, text size, and a + show/hide checklist for every detail. - **Clock** — a big booth clock; also the smallest possible module and the reference for module authors. diff --git a/modules/pco-plan/client.js b/modules/pco-plan/client.js index a883ed4..7efd441 100644 --- a/modules/pco-plan/client.js +++ b/modules/pco-plan/client.js @@ -2,9 +2,9 @@ The server part reads Planning Center and (optionally) follows the ProPresenter module's live item; this tile only renders the plan it is - streamed. What is shown is decided server-wide in /admin (moduleApi.config: - show/hide checklist, top-bar template, colors); the tile itself only owns - its text size and auto-scroll. */ + streamed. What is shown is this tile's own choice (gear menu → + moduleApi.instanceSettings: show/hide checklist, top-bar template, + colors, text size); /admin only holds the connection settings. */ const REFRESH_SVG = ''; @@ -43,10 +43,10 @@ export default function create({ root, moduleApi }) { const listEl = root.querySelector('.pp-list'); const footEl = root.querySelector('.pp-foot'); - /** Admin-wide display settings (the show/hide checklist lives there). */ - const cfg = () => moduleApi.config || {}; + /** This tile's display settings (gear menu) — read fresh on every render. */ + const cfg = () => moduleApi.instanceSettings || {}; const on = (key) => cfg()[key] !== false; // unset = shown - const tilePrefs = () => moduleApi.instanceSettings; + const tilePrefs = cfg; const serverNow = () => Date.now() + skew; /* ── title-bar controls ─────────────────────────────────────────── */ @@ -270,7 +270,7 @@ export default function create({ root, moduleApi }) { hint: `${state.serviceType?.name || 'This service type'} has no upcoming or recent plans in Planning Center.`, }; } - if (!visibleItems().length) return { title: 'Nothing to show', hint: 'Every item is hidden by the PCO Plan settings in Admin.' }; + if (!visibleItems().length) return { title: 'Nothing to show', hint: 'Every item is hidden by this tile’s settings (gear menu).' }; return null; } @@ -612,10 +612,8 @@ export default function create({ root, moduleApi }) { root.innerHTML = ''; }, onConfigChange() { - // Display settings changed in Admin: re-render from the new - // moduleApi.config. The server re-inits too and re-sends its state. - lastListKey = ''; - render(); + // Admin holds only connection settings; the server re-inits and its + // stream re-sends the state. Nothing cached here to refresh. }, }; } diff --git a/modules/pco-plan/module.json b/modules/pco-plan/module.json index 8e9c173..56dc60c 100644 --- a/modules/pco-plan/module.json +++ b/modules/pco-plan/module.json @@ -1,7 +1,7 @@ { "id": "pco-plan", "name": "PCO Plan", - "version": "1.1.0", + "version": "1.2.0", "description": "Order of service from Planning Center Services, following ProPresenter live", "client": "client.js", "server": "server.js", @@ -12,11 +12,6 @@ "Planning Center credentials": { "collapsed": "whenSet", "help": "Create a Personal Access Token at api.planningcenteronline.com (Application ID + Secret), or paste an OAuth 2.0 access token instead. Saved secrets never reach browsers." - }, - "Show / hide": { - "collapsed": true, - "columns": 3, - "help": "Untick anything the tiles should not show. Applies to every PCO Plan tile." } }, "configSchema": { @@ -63,7 +58,21 @@ "type": "switch", "label": "Follow the ProPresenter module's live item to highlight the current plan item and time it", "default": true + } + }, + "instanceGroups": { + "Top bar": { + "collapsed": false }, + "Show / hide": { + "collapsed": true, + "columns": 3, + "help": "Untick anything this tile should not show." + } + }, + "instanceSchema": { + "textSize": { "type": "number", "label": "Text size (px)", "default": 14 }, + "autoScroll": { "type": "boolean", "label": "Keep the current item in view", "default": true }, "noteCategories": { "type": "string", "label": "Item note categories to show (comma-separated, blank = all)", @@ -114,9 +123,5 @@ "showItemRuntime": { "type": "boolean", "label": "Item runtime (elapsed vs planned)", "default": true, "group": "Show / hide" }, "dimCompleted": { "type": "boolean", "label": "Dim completed items", "default": true, "group": "Show / hide" }, "showLiveFooter": { "type": "boolean", "label": "ProPresenter match line", "default": true, "group": "Show / hide" } - }, - "instanceSchema": { - "textSize": { "type": "number", "label": "Text size (px)", "default": 14 }, - "autoScroll": { "type": "boolean", "label": "Keep the current item in view", "default": true } } }