Changeset 50e80ac in Klonkt for src/assets/js/guardian.js
- Timestamp:
- 08/08/2026 02:19:06 AM (5 weeks ago)
- Branches:
- main
- Children:
- 3b43e4c
- Parents:
- 2bd31d6
- git-author:
- Robin <roboburr@…> (08/08/2026 02:18:27 AM)
- git-committer:
- roboburr <roboburr@…> (08/08/2026 02:19:06 AM)
- File:
-
- 1 edited
-
src/assets/js/guardian.js (modified) (3 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/assets/js/guardian.js
r2bd31d6 r50e80ac 536 536 * zouden dat verschil wegpoetsen. 537 537 */ 538 /** 539 * Een gate als cockpit-schakelaar (Barts richting, 8-8): een knop zoals de 540 * airco-toets in een dashboard -- lampje links, de naam erop, en een klein 541 * statusveld dat de stand toont. De KNOP is de toggle: aanraken stelt de 542 * andere stand voor, met de nf9-uitleg ervoor. Het lampje en het veld dragen 543 * dezelfde stand in twee vormen, want een lampje alleen is voor kleurenblind 544 * en onwennig volk geen antwoord. 545 * 546 * Drie standen, niet twee. "Uit" en "voor zover wij weten uit" zijn niet 547 * hetzelfde: dat tweede betekent dat niemand er ooit over besloot, en dat 548 * hoort niet te lezen als een genomen besluit. Wat er nog niet bestaat is 549 * een lege fitting, geen dichte deur. En een lopend voorstel knippert -- 550 * wachten is de enige stand die vanzelf verandert, dus de enige die om je 551 * blik mag vragen (en bij prefers-reduced-motion staat hij stil). 552 */ 538 553 function gateRow(w, g) { 539 // Drie standen, niet twee. "Uit" en "voor zover wij weten uit" zijn niet540 // hetzelfde: dat tweede betekent dat niemand er ooit over besloot, en dat541 // hoort niet te lezen als een genomen besluit.542 554 var stand = g.value === null || g.value === undefined 543 555 ? (T.gate_unknown || 'unknown') 544 556 : (g.value ? (T.prop_on || 'on') : (T.prop_off || 'off')); 545 557 if (!g.decided && g.value === false) stand = T.gate_default_off || stand; 546 var row = el('div', 'g-gate');547 var head = el('div', 'g-gate-head');548 head.appendChild(el('span', 'g-gate-name', gateLabel(g.feature)));549 row.appendChild(head);550 551 // De chip draagt de STAND en wisselt dus mee. Hij stond hier eerst op het552 // SOORT -- in het Nederlands "stand" -- vlak boven de werkelijke stand, dus553 // twee dingen die hetzelfde heetten waarvan er een nooit veranderde. Het554 // veranderlijke hoort bovenaan; het beschrijvende gaat naar de regel eronder.555 // Wat er nog niet is leest niet als een dichte poort maar als een lege plek.556 // 'Uit' zou onwaar zijn: plaatjes werken vandaag gewoon.557 558 if (!g.available) stand = T.gate_unavailable || 'not available yet'; 558 var soort = g.available === false ? 'planned' 559 560 var lamp = !g.available ? 'planned' 561 : (g.waiting || (g.proposal && g.proposal.status === 'open')) ? 'waiting' 559 562 : (g.value === true ? 'on' : (g.decided ? 'off' : 'undecided')); 560 head.appendChild(el('span', 'g-gate-chip g-gate-chip-' + soort, stand)); 561 562 var meta = el('div', 'g-gate-meta small'); 563 564 var wrap = el('div', 'g-sw-wrap'); 565 var btn = el('button', 'g-sw'); 566 btn.type = 'button'; 567 if (g.value === true || g.value === false) btn.setAttribute('aria-pressed', String(g.value)); 568 var head = el('span', 'g-sw-head'); 569 var lampEl = el('span', 'g-sw-lamp g-lamp-' + lamp); 570 lampEl.setAttribute('aria-hidden', 'true'); 571 head.appendChild(lampEl); 572 head.appendChild(el('span', 'g-sw-name', gateLabel(g.feature))); 573 btn.appendChild(head); 574 // Het statusveld: de stand als tekst, in een verzonken venstertje zoals de 575 // temperatuur op het aircopaneel. Bij een lopend voorstel telt het veld wat 576 // er wacht -- dat is op dat moment de waarheid over deze poort. 577 var veld = (g.waiting ? (T.gate_waiting || '{n} waiting').replace('{n}', g.waiting) : stand); 578 btn.appendChild(el('span', 'g-sw-state', veld)); 579 580 var meta = el('span', 'g-sw-meta small'); 563 581 meta.appendChild(el('span', 'g-gate-kind', T['gate_kind_' + g.kind] || g.kind)); 564 582 if (!g.available) meta.appendChild(el('span', 'g-dim', T.gate_planned_note || '')); … … 571 589 } 572 590 if (!g.reversible) meta.appendChild(el('span', 'g-gate-warn', T.gate_irreversible || '')); 573 if (g.waiting) { 574 meta.appendChild(el('span', 'g-gate-wait', (T.gate_waiting || '{n} waiting').replace('{n}', g.waiting))); 575 } 576 row.appendChild(meta); 591 btn.appendChild(meta); 592 wrap.appendChild(btn); 577 593 578 594 if (g.proposal) { 579 row.appendChild(el('p', 'small g-prop g-prop-' + g.proposal.status,595 wrap.appendChild(el('p', 'small g-prop g-prop-' + g.proposal.status, 580 596 (T.prop_line || 'Proposal {what} {value}: {status}') 581 597 .replace('{what}', gateLabel(g.feature)) … … 584 600 } 585 601 if (g.blockedBy) { 586 row.appendChild(el('p', 'small g-empty', (T.gate_blocked || 'needs {what} first')602 wrap.appendChild(el('p', 'small g-empty', (T.gate_blocked || 'needs {what} first') 587 603 .replace('{what}', gateLabel(g.blockedBy)))); 588 604 } 589 if (g.adjustable) { 590 // De knop zegt wat er GEBEURT, niet wat er staat -- de stand staat hierboven 591 // al. Staat de poort open, dan is het enige wat je kunt voorstellen hem 592 // dichtzetten, en dat hoort op de knop te staan voordat je klikt. 593 // 594 // De richting volgt de stand die we uit de besluiten kennen, dus ook voor 595 // een ward elders kun je nu DICHTZETTEN voorstellen. Dat was de veilige 596 // richting die eerder ontbrak toen de stand altijd onbekend was. 597 var openzetten = T.gate_propose_open || T.gate_propose || 'Propose'; 598 var dichtzetten = T.gate_propose_close || T.gate_propose || 'Propose'; 599 row.appendChild(gateButton(w, g.feature, g.value, openzetten, dichtzetten, openzetten, 600 g.reversible === false ? 'irreversible' : 'reversible')); 601 } 602 return row; 605 606 if (!g.adjustable) { 607 // Niet verstelbaar is niet hetzelfde als kapot: het lampje en het veld 608 // blijven de stand tonen, alleen de toets drukt niet in. 609 btn.disabled = true; 610 return wrap; 611 } 612 613 // De toets stelt de ANDERE stand voor; de richting volgt de stand die we 614 // uit de besluiten kennen, dus ook voor een ward elders kun je dichtzetten 615 // voorstellen. Bij openzetten eerst de nf9-uitleg (uitleg staat er, dan pas 616 // de knop); dichtzetten laat niets nieuws door en vraagt niet. 617 var allow = (g.value === true || g.value === false) ? !g.value : true; 618 var consequence = g.reversible === false ? 'irreversible' : 'reversible'; 619 btn.addEventListener('click', function () { 620 if (!allow) return doPropose(); 621 if (wrap.querySelector('.g-confirm')) return; // uitleg staat er al 622 var ask = el('div', 'g-confirm'); 623 ask.appendChild(el('p', 'small', warnText(consequence))); 624 var ja = el('button', 'small', T.warn_go || 'Yes, propose this'); 625 ja.addEventListener('click', function () { ask.remove(); doPropose(); }); 626 var nee = el('button', 'quiet small', T.warn_back || 'No, go back'); 627 nee.addEventListener('click', function () { ask.remove(); }); 628 ask.appendChild(ja); ask.appendChild(nee); 629 wrap.appendChild(ask); 630 }); 631 632 function doPropose() { 633 btn.disabled = true; 634 fetch('/guardian/wards/embeds', { 635 method: 'POST', headers: { 'Content-Type': 'application/json' }, 636 body: JSON.stringify({ uri: w.other_uri, feature: g.feature, allow: allow }), 637 }).then(function (r) { return r.json(); }) 638 .then(function (j) { 639 if (j && j.state === 'open') { 640 wrap.appendChild(el('p', 'small g-prop g-prop-open', 641 (T.prop_line || 'Proposal {what} {value}: {status}') 642 .replace('{what}', gateLabel(g.feature)) 643 .replace('{value}', allow ? (T.prop_on || 'on') : (T.prop_off || 'off')) 644 .replace('{status}', T.prop_st_open || 'open'))); 645 } 646 refresh(); 647 }) 648 .catch(function () { btn.disabled = false; }); 649 } 650 return wrap; 603 651 } 604 652
Note:
See TracChangeset
for help on using the changeset viewer.
![(please configure the [header_logo] section in trac.ini)](/chrome/site/your_project_logo.png)