Featured to top, centered, capped; banner ads capped 728px centered; slot CTA
- Featured card moved to the top of Overview, centered, max 760px; the rotating link is capped to 728px and centered (banner-sized, not a huge block). - Served banner creatives cap at min(100%,728px), centered — kills the oversized sample banner; ad slots center their creative + label. - Featured self-sell: shows "N of C slots open today" + "Feature your link →" that jumps to Campaigns with Featured preselected. - Campaign target/image/video URL fields get autocomplete=off and clear when the Campaigns pane opens, so no residual (e.g. massifly) URL carries over. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -117,8 +117,9 @@ window.IAP = (function () {
|
||||
const el = $(elId);
|
||||
if (!ad || !el) return;
|
||||
if (ad.imageUrl) {
|
||||
el.style.textAlign = 'center';
|
||||
el.innerHTML = '<a href="' + ad.targetUrl + '" target="_blank" rel="noopener nofollow">'
|
||||
+ '<img src="' + ad.imageUrl + '" alt="advertisement" style="max-width:100%;border-radius:8px"></a>'
|
||||
+ '<img src="' + ad.imageUrl + '" alt="advertisement" style="max-width:min(100%,728px);height:auto;display:block;margin:0 auto;border-radius:8px"></a>'
|
||||
+ '<div class="small muted">member ad' + reportTag(ad) + '</div>';
|
||||
} else {
|
||||
el.innerHTML = '<a href="' + ad.targetUrl + '" target="_blank" rel="noopener nofollow"><b>' + ad.title + '</b>'
|
||||
|
||||
@@ -46,6 +46,18 @@
|
||||
renderOneFeatured(); // show ONE at a time (true rotation), cycle if more than one
|
||||
clearInterval(featTimer);
|
||||
if (featItems.length > 1) featTimer = setInterval(() => { featIdx++; renderOneFeatured(); }, 6000);
|
||||
// self-sell: today's open slots + a CTA to feature your own link
|
||||
try {
|
||||
const st = await (await fetch('/api/featured/stats')).json();
|
||||
const today = (st.occupancy || []).find(d => d.offset === 0);
|
||||
const cta = $('featCta');
|
||||
if (cta) {
|
||||
cta.innerHTML = (today ? '<span class="muted">' + today.open + ' of ' + today.cap + ' featured slots open today. </span>' : '')
|
||||
+ '<a href="#campaigns" id="featBuy" style="color:var(--mint);font-weight:700;text-decoration:none">Feature your link →</a>';
|
||||
const fb = $('featBuy');
|
||||
if (fb) fb.addEventListener('click', e => { e.preventDefault(); setPane('campaigns'); const ct = $('cType'); if (ct) { ct.value = 'featured'; ct.dispatchEvent(new Event('change')); } });
|
||||
}
|
||||
} catch (e) {}
|
||||
} catch (e) {}
|
||||
}
|
||||
|
||||
@@ -376,6 +388,7 @@
|
||||
if (name === 'earn') setEarnSub(earnSub); // refresh whichever sub-tab is active
|
||||
if (name === 'profile') loadLineBanner();
|
||||
if (name === 'line') { loadLineage(); loadUplineMessages(); }
|
||||
if (name === 'campaigns') ['cTarget', 'cImage', 'cVideoUrl'].forEach(id => { if ($(id)) $(id).value = ''; }); // no residual URL between visits
|
||||
document.getElementById('memberArea').classList.remove('side-open'); // close mobile drawer
|
||||
if (location.hash !== '#' + name) history.replaceState(null, '', '#' + name);
|
||||
}
|
||||
|
||||
@@ -274,7 +274,9 @@ textarea{resize:vertical;font:inherit}
|
||||
.feat-day .fd-occ{font-family:var(--mono);font-size:11px;color:var(--muted)}
|
||||
.feat-day.open2 .fd-occ{color:var(--mint)}
|
||||
/* ── featured rotation strip ── */
|
||||
.feat-strip{display:flex;flex-direction:column;gap:8px;margin-top:10px}
|
||||
.feat-top{max-width:760px;margin:0 auto 16px}
|
||||
.feat-strip{display:flex;justify-content:center;margin-top:10px}
|
||||
.feat-strip a{max-width:728px;width:100%}
|
||||
.feat-strip a{display:flex;justify-content:space-between;gap:10px;padding:11px 14px;border-radius:10px;
|
||||
background:var(--panel);border:1px solid var(--line-strong);color:var(--ink);text-decoration:none;font-weight:600}
|
||||
.feat-strip a:hover{border-color:var(--mint)}
|
||||
|
||||
Reference in New Issue
Block a user