1ee0b5626e
- Welcome tour (3 levels x 10s) unlocks welcome credits; line banner in Profile; public /wall/<username> - 'Your next move' redesigned as a milestone stepper - Solo composer: BV-style rich editor (H2/H3, inline image+video, undo/redo, raw text) - Solo read reward now requires clicking through to the advertiser, not just dwelling - Sanitizer: inline media whitelist + script/style stripped whole Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
34 lines
1.6 KiB
JavaScript
34 lines
1.6 KiB
JavaScript
// Public banner wall: a member's line banner plus their upline ladder, with
|
||
// their join link. The viral surface: members send traffic here, every visit
|
||
// puts eyes on the whole line.
|
||
(async function () {
|
||
await IAP.renderNav('');
|
||
const name = location.pathname.split('/').pop();
|
||
let w = null;
|
||
try { w = await (await fetch('/api/wall/' + encodeURIComponent(name))).json(); } catch (e) {}
|
||
const title = IAP.$('wallTitle');
|
||
if (!w || w.error) {
|
||
title.textContent = 'No wall under that name.';
|
||
IAP.$('wallJoin').href = '/my';
|
||
return;
|
||
}
|
||
title.innerHTML = 'The <em>' + String(w.name).replace(/[&<>]/g, '') + '</em> line';
|
||
IAP.$('wallCtaHead').textContent = 'Join ' + w.name + '’s line';
|
||
IAP.$('wallJoin').href = w.joinUrl;
|
||
const grid = IAP.$('wallGrid');
|
||
grid.innerHTML = '';
|
||
w.ladder.forEach((m, i) => {
|
||
const d = document.createElement('div');
|
||
d.className = 'wall-card';
|
||
const safe = String(m.name || 'member').replace(/[&<>]/g, '');
|
||
d.innerHTML = '<div class="wall-pos">Position ' + (i + 1) + (i === 0 ? ' · this wall' : '') + '</div>'
|
||
+ (m.bannerUrl
|
||
? '<a href="' + m.targetUrl + '" target="_blank" rel="noopener nofollow"><img src="' + m.bannerUrl + '" alt="' + safe + ' banner"></a>'
|
||
: m.targetUrl
|
||
? '<a href="' + m.targetUrl + '" target="_blank" rel="noopener nofollow"><b>' + safe + '</b><br><span class="muted small">visit their site</span></a>'
|
||
: '<b>' + safe + '</b><br><span class="muted small">banner slot open</span>')
|
||
+ '<div class="small muted" style="margin-top:8px">' + safe + '</div>';
|
||
grid.appendChild(d);
|
||
});
|
||
})();
|