feat: add QR share button to each pub row in invites view
- Import details, summary from hyperaxe - renderPubTable converted to async, generates QR SVG per pub key - Each row: details/summary collapsible QR panel below the key link (same pattern as profile and tribe invite QR, no JS required) - All three renderPubTable calls updated with await - QR falls back silently if key is missing or generation fails Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
parent
16f9189e61
commit
12acd6fd20
1 changed files with 29 additions and 14 deletions
|
|
@ -1,4 +1,4 @@
|
|||
const { form, button, div, h2, h3, p, section, ul, li, a, br, hr, input, span, table, tr, td } = require("../server/node_modules/hyperaxe");
|
||||
const { form, button, div, h2, h3, p, section, ul, li, a, br, hr, input, span, table, tr, td, details, summary } = require("../server/node_modules/hyperaxe");
|
||||
const QRCode = require('../server/node_modules/qrcode');
|
||||
const path = require("path");
|
||||
const fs = require('fs');
|
||||
|
|
@ -75,16 +75,31 @@ const invitesView = async ({ invitesEnabled }) => {
|
|||
const activePubs = filteredPubs.filter(pubItem => !hasError(pubItem));
|
||||
const unreachablePubs = pubs.filter(hasError);
|
||||
|
||||
const renderPubTable = (items, actionFn) => table({ class: 'block-info-table' },
|
||||
pubTableHeader(),
|
||||
items.map(pubItem => tr(
|
||||
td(pubItem.host || '—'),
|
||||
td(String(pubItem.port || 8008)),
|
||||
td(String(pubItem.announcers || 0)),
|
||||
td(a({ href: encodePubLink(pubItem.key), class: 'user-link' }, pubItem.key)),
|
||||
td(actionFn(pubItem))
|
||||
))
|
||||
);
|
||||
const renderPubTable = async (items, actionFn) => {
|
||||
const rows = await Promise.all(items.map(async pubItem => {
|
||||
let qrSvg = '';
|
||||
try {
|
||||
if (pubItem.key) qrSvg = await QRCode.toString(pubItem.key, { type: 'svg' });
|
||||
} catch {}
|
||||
return tr(
|
||||
td(pubItem.host || '—'),
|
||||
td(String(pubItem.port || 8008)),
|
||||
td(String(pubItem.announcers || 0)),
|
||||
td(
|
||||
a({ href: encodePubLink(pubItem.key), class: 'user-link' }, pubItem.key),
|
||||
qrSvg ? details({ class: 'qr-share-details' },
|
||||
summary({ class: 'qr-share-btn' }, '⬡ QR'),
|
||||
div({ class: 'qr-share-panel' },
|
||||
div({ class: 'qr-code', innerHTML: qrSvg }),
|
||||
p({ class: 'qr-share-id' }, pubItem.key)
|
||||
)
|
||||
) : null
|
||||
),
|
||||
td(actionFn(pubItem))
|
||||
);
|
||||
}));
|
||||
return table({ class: 'block-info-table' }, pubTableHeader(), ...rows);
|
||||
};
|
||||
|
||||
const title = i18n.invites;
|
||||
const description = i18n.invitesDescription;
|
||||
|
|
@ -130,7 +145,7 @@ const invitesView = async ({ invitesEnabled }) => {
|
|||
hr(),
|
||||
h2(`${i18n.invitesAcceptedInvites} (${activePubs.length})`),
|
||||
activePubs.length
|
||||
? renderPubTable(activePubs, pubItem =>
|
||||
? await renderPubTable(activePubs, pubItem =>
|
||||
form({ action: '/settings/invite/unfollow', method: 'post' },
|
||||
input({ type: 'hidden', name: 'key', value: pubItem.key }),
|
||||
button({ type: 'submit' }, i18n.invitesUnfollow)
|
||||
|
|
@ -140,7 +155,7 @@ const invitesView = async ({ invitesEnabled }) => {
|
|||
hr(),
|
||||
h2(`${i18n.invitesUnfollowedInvites} (${unfollowed.length})`),
|
||||
unfollowed.length
|
||||
? renderPubTable(unfollowed, pubItem =>
|
||||
? await renderPubTable(unfollowed, pubItem =>
|
||||
form({ action: '/settings/invite/follow', method: 'post' },
|
||||
input({ type: 'hidden', name: 'key', value: pubItem.key }),
|
||||
input({ type: 'hidden', name: 'host', value: pubItem.host || '' }),
|
||||
|
|
@ -152,7 +167,7 @@ const invitesView = async ({ invitesEnabled }) => {
|
|||
hr(),
|
||||
h2(`${i18n.invitesUnreachablePubs} (${unreachablePubs.length})`),
|
||||
unreachablePubs.length
|
||||
? renderPubTable(unreachablePubs, pubItem =>
|
||||
? await renderPubTable(unreachablePubs, pubItem =>
|
||||
div({ class: 'error-box' },
|
||||
p({ class: 'error-title' }, i18n.errorDetails),
|
||||
p({ class: 'error-pre' }, String(pubItem.error || i18n.genericError))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue