mirror of
https://github.com/Kpa-clawbot/meshcore-analyzer.git
synced 2026-06-04 09:21:18 +00:00
4cd51a41e7
## Summary Strips the Share Channel modal (shipped in #1090) down to its essentials. Removes redundant affordances that the QR already provides. ## What changed **Removed from the Share modal:** - The URL text printed inside the QR box (the QR encodes the URL) - The inline Copy Key button inside the QR box (overlapped the image) - The `meshcore://` URL input field below the QR - The Copy URL button next to the URL field **Result — the modal now contains exactly:** - Title `Share: <Channel Name>` - QR code (just the QR `<img>`, nothing else in that box) - Hex Key field with a single Copy button BELOW the QR - Privacy warning - ✕ close button (top right) ## Implementation - `public/channels.js` — drop the `meshcore://` URL field-group from share modal markup; `openShareModal()` no longer looks up `#chShareUrl` or builds a URL into a field; pass `{ qrOnly: true }` when calling `ChannelQR.generate` so the QR box renders ONLY the QR image. - `public/channel-qr.js` — `generate(name, secret, target, opts)` now accepts `opts.qrOnly` which short-circuits before appending the inline URL line + Copy Key button. Default behaviour (no opts) unchanged, so the Add-Channel "Generate & Show QR" flow is untouched. ## Tests (TDD: red → green) - New: `test-channel-issue-1101.js` (static grep) — asserts the URL field is gone from markup, `openShareModal` no longer references it, and `ChannelQR.generate` honours `qrOnly`. - Updated: `test-channel-issue-1087.js` and `test-channel-issue-1087-e2e.js` — those previously asserted the URL field's presence (which is exactly what #1101 removes); they now assert ONLY the hex key field exists, AND that `#chShareQr` contains exactly one `<img>` and no `.channel-qr-url` / `.channel-qr-copy` children. - Wired into `.github/workflows/deploy.yml` `node-test` job. Commit history shows red (test commit `c0c254a`) → green (fix commit `6315a19`) per AGENTS.md TDD requirement. E2E assertion added: test-channel-issue-1087-e2e.js:184 ## Acceptance criteria - [x] Share modal contains only: QR, "Copy Key" button, privacy warning - [x] No "Copy URL" affordance anywhere in the modal - [x] No duplicated hex key field below - [x] E2E test asserts the absence of the removed elements Fixes #1101 --------- Co-authored-by: meshcore-bot <bot@meshcore.local> Co-authored-by: clawbot <clawbot@users.noreply.github.com>
95 lines
4.1 KiB
JavaScript
95 lines
4.1 KiB
JavaScript
/**
|
|
* #1101 — Strip Share modal: remove redundant URL copy + duplicated key field.
|
|
*
|
|
* Acceptance criteria:
|
|
* - Share modal contains only: QR (just the QR image, nothing else
|
|
* in that box), Hex Key field with single Copy button BELOW the QR,
|
|
* privacy warning, Close ✕ button.
|
|
* - No "Copy URL" affordance ANYWHERE in the modal.
|
|
* - No duplicated meshcore:// URL field below the QR.
|
|
* - The QR box (#chShareQr) must contain ONLY the QR image — no URL
|
|
* text, no Copy Key button overlapping it.
|
|
*/
|
|
'use strict';
|
|
|
|
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
let passed = 0, failed = 0;
|
|
function assert(cond, msg) {
|
|
if (cond) { passed++; console.log(' ✓ ' + msg); }
|
|
else { failed++; console.error(' ✗ ' + msg); }
|
|
}
|
|
|
|
const channelsSrc = fs.readFileSync(path.join(__dirname, 'public', 'channels.js'), 'utf8');
|
|
const qrSrc = fs.readFileSync(path.join(__dirname, 'public', 'channel-qr.js'), 'utf8');
|
|
|
|
console.log('\n=== #1101: Share modal markup ===');
|
|
|
|
// Locate the share modal markup block.
|
|
const shareModalIdx = channelsSrc.indexOf('id="chShareModal"');
|
|
assert(shareModalIdx > 0, 'share modal markup located');
|
|
// Tighten block isolation: scan forward for the share modal's own
|
|
// closing tag (the outer overlay div is indented 6 spaces, so its
|
|
// matching close is the first "\n </div>" we hit after the
|
|
// opener). Falls back to the old ch-main heuristic if that pattern
|
|
// disappears for any reason.
|
|
let shareEnd = channelsSrc.indexOf('\n </div>', shareModalIdx);
|
|
if (shareEnd < 0) {
|
|
shareEnd = channelsSrc.indexOf('<div class="ch-main"', shareModalIdx);
|
|
}
|
|
const shareModalBlock = channelsSrc.substring(shareModalIdx, shareEnd);
|
|
assert(shareModalBlock.length > 0 && shareModalBlock.length < 4000,
|
|
'share modal block isolated');
|
|
|
|
// Hex key field MUST still be present (single source of truth).
|
|
assert(/id="chShareKey"/.test(shareModalBlock),
|
|
'share modal still exposes the hex key field with a Copy button');
|
|
|
|
// meshcore:// URL field MUST be removed.
|
|
assert(!/id="chShareUrl"/.test(shareModalBlock),
|
|
'share modal does NOT render a #chShareUrl input field');
|
|
assert(!/data-share-field="url"/.test(shareModalBlock),
|
|
'share modal does NOT render any [data-share-field="url"] element');
|
|
assert(!/data-share-copy="url"/.test(shareModalBlock),
|
|
'share modal does NOT render any [data-share-copy="url"] button');
|
|
assert(!/meshcore:\/\/ URL/.test(shareModalBlock),
|
|
'share modal does NOT show a "meshcore:// URL" label');
|
|
|
|
// Privacy warning + close button still required.
|
|
assert(/ch-modal-warn/.test(shareModalBlock),
|
|
'share modal still includes the privacy warning');
|
|
assert(/id="chShareModalClose"/.test(shareModalBlock),
|
|
'share modal still has the ✕ close button');
|
|
|
|
console.log('\n=== #1101: openShareModal() body ===');
|
|
|
|
// openShareModal must no longer reference chShareUrl or build URL into a field.
|
|
const openIdx = channelsSrc.indexOf('function openShareModal(');
|
|
assert(openIdx > 0, 'openShareModal located');
|
|
const openEnd = channelsSrc.indexOf('function ', openIdx + 30);
|
|
const openBlock = channelsSrc.substring(openIdx, openEnd);
|
|
assert(!/getElementById\('chShareUrl'\)/.test(openBlock),
|
|
'openShareModal does NOT look up #chShareUrl');
|
|
assert(!/urlField\.value\s*=/.test(openBlock),
|
|
'openShareModal does NOT assign to urlField.value');
|
|
|
|
console.log('\n=== #1101: ChannelQR.generate() supports qrOnly ===');
|
|
|
|
// ChannelQR.generate must accept an opts.qrOnly flag so the Share
|
|
// modal's QR box can render JUST the QR image — no URL line, no
|
|
// inline Copy Key button. (The Share modal has its own dedicated
|
|
// hex key field + Copy button BELOW the QR.)
|
|
assert(/function generate\([^)]*opts[^)]*\)/.test(qrSrc),
|
|
'ChannelQR.generate accepts an opts argument');
|
|
assert(/qrOnly/.test(qrSrc),
|
|
'ChannelQR.generate honours opts.qrOnly');
|
|
|
|
// Share modal call site must pass qrOnly:true.
|
|
assert(/ChannelQR\.generate\([^)]*qrOnly[^)]*\)/.test(channelsSrc) ||
|
|
/ChannelQR\.generate\([\s\S]{0,200}qrOnly\s*:\s*true/.test(channelsSrc),
|
|
'openShareModal passes { qrOnly: true } to ChannelQR.generate');
|
|
|
|
console.log('\n=== Results: ' + passed + ' passed, ' + failed + ' failed ===');
|
|
process.exit(failed > 0 ? 1 : 0);
|