sign-off-axi 0.5.7 → 0.5.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +1 -1
- package/web/index.html +24 -12
package/package.json
CHANGED
package/web/index.html
CHANGED
|
@@ -1292,12 +1292,13 @@
|
|
|
1292
1292
|
.split-bar .later { display: inline-flex; align-items: center; gap: 0.5rem; margin-left: auto; min-height: var(--ctl); padding: 0 0.75rem; border-radius: var(--r-ctl); background: none; color: var(--text); font-weight: 400; }
|
|
1293
1293
|
.split-bar .later:hover, .dl-hover button:hover { background: var(--sunk); }
|
|
1294
1294
|
.split-bar .later .glyph { width: 1.25rem; height: 1.25rem; stroke-width: 1.75; color: var(--muted); }
|
|
1295
|
-
/* The ask fills the pane, so its answer bar stays at the pane's foot even under a short ask. */
|
|
1295
|
+
/* The ask fills the pane, so its answer bar stays at the pane's foot even under a short ask; under a tall one it comes after the last option, so it never covers one. */
|
|
1296
1296
|
.split-detail > .decide { display: flex; flex: 1; flex-direction: column; width: 100%; max-width: 46rem; margin: 0 auto; padding: 0.5rem 2.5rem 0; }
|
|
1297
1297
|
.split-detail > .decide .dhero, .split-detail > .decide .decide-preview { margin-top: 1.5rem; }
|
|
1298
1298
|
.split-detail .decide > * { flex: none; } .split-detail .decide > :not(.decide-bar):nth-last-child(2) { margin-bottom: 1.5rem; }
|
|
1299
|
-
.split-detail .decide-bar {
|
|
1299
|
+
.split-detail .decide-bar { margin: auto -2.5rem 0; padding: 1rem 2.5rem 1.25rem; border-top: 1px solid var(--line); background: var(--bg); }
|
|
1300
1300
|
.split-detail .decide-bar .answer { min-width: 13rem; padding: 0 1.5rem; }
|
|
1301
|
+
.split-detail .decide-bar .open-link { display: inline-flex; align-items: center; justify-content: center; min-width: 13rem; min-height: 3.25rem; padding: 0 1.5rem; border-radius: 1rem; font-size: var(--t-m); }
|
|
1301
1302
|
.split-detail [data-kbd]::after { content: attr(data-kbd); display: inline-grid; place-items: center; min-width: 1.375rem; height: 1.375rem; margin-left: 0.625rem; padding: 0 0.3125rem; border-radius: 0.375rem;
|
|
1302
1303
|
background: rgb(255 255 255 / 0.22); color: inherit; font-size: 0.75rem; font-weight: 600; line-height: 1; vertical-align: 0.0625rem; }
|
|
1303
1304
|
.split-bar [data-kbd]::after { background: var(--sunk); color: var(--muted); }
|
|
@@ -1651,20 +1652,25 @@
|
|
|
1651
1652
|
};
|
|
1652
1653
|
/** A sign-in: the service, what it unlocks, who waits, the time left and one Open for its link. Its poster closes it with signin done. */
|
|
1653
1654
|
function signin(d, lead, saved, err) {
|
|
1654
|
-
|
|
1655
|
+
const { open, line } = signinOpen(d, saved, err);
|
|
1656
|
+
return el('article', { class: 'row signin', id: `item-${d.key}` }, el('div', {}, lead,
|
|
1657
|
+
el('p', { class: 'line', dir: 'auto' }, `Unlocks: ${d.unlocks}`), el('p', { class: 'line', dir: 'auto' }, `Waits: ${d.waits}`), line), open, err);
|
|
1658
|
+
}
|
|
1659
|
+
/** A sign-in's one Open and the line under it, for its card and its desk page alike. */
|
|
1660
|
+
function signinOpen(d, saved, err) {
|
|
1661
|
+
if (d.start) return started(d, saved, err);
|
|
1655
1662
|
const gone = !!d.expires && Date.parse(d.expires) <= Date.now();
|
|
1656
1663
|
const open = saved ? '' : gone ? el('button', { class: 'open-link', disabled: '' }, 'Open')
|
|
1657
1664
|
: el('a', { class: 'open-link', href: d.link, target: '_blank', rel: 'noopener noreferrer', 'aria-label': `Open the ${d.title} sign-in` }, 'Open');
|
|
1658
1665
|
// The time left counts down on the page (data-expires); an expired link is drawn once more, with Open off.
|
|
1659
|
-
const
|
|
1666
|
+
const line = saved ? el('p', { class: 'meta' }, `Signed in at ${when(saved.at)}.`) : d.expires
|
|
1660
1667
|
? el('p', { class: gone ? 'expiry gone' : 'expiry', ...(!gone && { 'data-expires': d.expires }) }, expiry(d.expires)) : '';
|
|
1661
|
-
return
|
|
1662
|
-
el('p', { class: 'line', dir: 'auto' }, `Unlocks: ${d.unlocks}`), el('p', { class: 'line', dir: 'auto' }, `Waits: ${d.waits}`), left), open, err);
|
|
1668
|
+
return { open, line };
|
|
1663
1669
|
}
|
|
1664
1670
|
/** What a tap-time sign-in did last, in plain words. */
|
|
1665
1671
|
const RUNS = { none: 'Each tap gets a new link.', starting: 'Getting a new link…', live: 'The sign-in page is open. Finish it there.' };
|
|
1666
1672
|
/** A sign-in whose link this host makes at each tap: Open starts it and sends a new tab to the new link, so its link never expires on the card. */
|
|
1667
|
-
function started(d,
|
|
1673
|
+
function started(d, saved, err) {
|
|
1668
1674
|
const failed = d.run?.startsWith('failed: ') && d.run.slice(8);
|
|
1669
1675
|
const open = saved ? '' : FROZEN || state.readonly ? el('button', { class: 'open-link', disabled: '' }, 'Open')
|
|
1670
1676
|
: el('button', { class: 'open-link', 'aria-label': `Open the ${d.title} sign-in` }, 'Open');
|
|
@@ -1690,9 +1696,7 @@
|
|
|
1690
1696
|
}
|
|
1691
1697
|
};
|
|
1692
1698
|
const line = saved ? `Signed in at ${when(saved.at)}.` : failed ? `The last try failed: ${failed} Tap Open to try again.` : RUNS[d.run] ?? RUNS.none;
|
|
1693
|
-
return el('
|
|
1694
|
-
el('p', { class: 'line', dir: 'auto' }, `Unlocks: ${d.unlocks}`), el('p', { class: 'line', dir: 'auto' }, `Waits: ${d.waits}`),
|
|
1695
|
-
el('p', { class: failed ? 'expiry gone' : saved ? 'meta' : 'expiry' }, line)), open, err);
|
|
1699
|
+
return { open, line: el('p', { class: failed ? 'expiry gone' : saved ? 'meta' : 'expiry' }, line) };
|
|
1696
1700
|
}
|
|
1697
1701
|
setInterval(() => {
|
|
1698
1702
|
// While a sign-in runs on this host, the page checks often, so the card closes soon after the sign-in is done.
|
|
@@ -3443,7 +3447,7 @@
|
|
|
3443
3447
|
let skipTo = '';
|
|
3444
3448
|
/** Asks the person chose to answer in their own words, kept across redraws. */
|
|
3445
3449
|
const own = new Set();
|
|
3446
|
-
function decidePage(d, next) {
|
|
3450
|
+
function decidePage(d, next, desk = false) {
|
|
3447
3451
|
if (!d) return el('p', { class: 'empty' }, EMPTY.waiting);
|
|
3448
3452
|
const to = next ? `#decide/${next.key}` : '#waiting';
|
|
3449
3453
|
skipTo = next && !state.readonly ? to : '';
|
|
@@ -3462,6 +3466,14 @@
|
|
|
3462
3466
|
const gone = xBtn(d, 'Dismiss');
|
|
3463
3467
|
if (gone) { gone.setAttribute('role', 'menuitem'); gone.addEventListener('click', () => (location.hash = to)); }
|
|
3464
3468
|
const more = (...items) => (state.readonly ? '' : moreSheet('More', [['Ask me later', () => { location.hash = '#waiting'; toLater([d.key], true); }, 'later', 'clock'], ...items, gone]));
|
|
3469
|
+
if (d.type === 'signin' && desk) {
|
|
3470
|
+
// On a desk a sign-in reads like any ask: who waits, the headline, what it unlocks, and Open as the bar's one button. Its row beside it counts the link's time down, so only a line that is not that countdown shows here.
|
|
3471
|
+
const err = el('div', { class: 'err', role: 'alert', id: `err-${d.key}` }), { open, line } = signinOpen(d, undefined, err);
|
|
3472
|
+
if (open) open.textContent = 'Open sign-in', open.dataset.kbd = '↵';
|
|
3473
|
+
const kicker = el('p', { class: 'kicker' }, el('span', { class: 'k' }, TYPE_NAMES.signin), ` · ${d.waits}${d.filed ? ` · ${when(d.filed)}` : ''}`);
|
|
3474
|
+
return el('section', { class: 'decide signin-ask' }, el('div', { class: 'lead' }, kicker, el('h2', { dir: 'auto' }, `Sign in to ${d.title}`)),
|
|
3475
|
+
el('p', { class: 'why', dir: 'auto' }, `Unlocks: ${d.unlocks}`), line?.dataset?.expires ? '' : line, err, el('div', { class: 'decide-bar' }, open, more()));
|
|
3476
|
+
}
|
|
3465
3477
|
if (d.type === 'signin') {
|
|
3466
3478
|
const signinPage = el('div', { class: 'decide' }, row(d, { x: false }), el('div', { class: 'decide-bar' }, more()));
|
|
3467
3479
|
if (!state.readonly) swipe(signinPage);
|
|
@@ -3543,7 +3555,7 @@
|
|
|
3543
3555
|
if (!d) return split([top, list], [items.length ? el('p', { class: 'empty' }, 'Open a review from the list.') : allClear()], [[['?'], 'All keys']]);
|
|
3544
3556
|
const g = groupOf(d), later = el('button', { class: 'later', 'data-kbd': 'L', 'aria-keyshortcuts': 'L' }, glyph('clock'), g === 'later' ? 'Back from Later' : 'Later');
|
|
3545
3557
|
later.onclick = () => { toLater([d.key], g !== 'later'); if (g !== 'later' && next) location.hash = `#decide/${next.key}`; };
|
|
3546
|
-
return split([top, list], [el('div', { class: 'split-bar' }, queue.length > 1 ? pager(queue, i) : '', state.readonly ? '' : later), decidePage(d, next)],
|
|
3558
|
+
return split([top, list], [el('div', { class: 'split-bar' }, queue.length > 1 ? pager(queue, i) : '', state.readonly ? '' : later), decidePage(d, next, true)],
|
|
3547
3559
|
[[['J', 'K'], 'Move'], [['↵'], 'Answer'], [['?'], 'All keys']]);
|
|
3548
3560
|
}
|
|
3549
3561
|
/** Evidence on a desk: the list of updates beside the one selected. */
|