125x125 sidebar banner (sized ad serving) + shorts report link

- New 125x125 "square button" banner size; ad serve now filters by width/height,
  and the sidebar slot serves a 125x125 banner (empty until such inventory exists).
- Shorts reel gets a "report this short" link (posts to /api/report-ad).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-07 08:47:17 -05:00
parent 31a6560e9e
commit ae580b966c
14 changed files with 33 additions and 21 deletions
+3 -2
View File
@@ -111,9 +111,10 @@ window.IAP = (function () {
const rl = el.querySelector('.ad-report');
if (rl) rl.addEventListener('click', e => { e.preventDefault(); reportAd(Number(rl.dataset.cid)); });
}
async function adSlot(type, elId) {
async function adSlot(type, elId, opts) {
try {
const { ad } = await (await fetch('/api/ads/slot?type=' + type)).json();
const q = '/api/ads/slot?type=' + type + (opts && opts.width ? '&w=' + opts.width + '&h=' + opts.height : '');
const { ad } = await (await fetch(q)).json();
const el = $(elId);
if (!ad || !el) return;
if (ad.imageUrl) {
+1 -1
View File
@@ -1714,7 +1714,7 @@
// banner + text placements inside the back office (they ARE the audience)
IAP.adSlot('banner', 'adSlotLogin');
IAP.adSlot('banner', 'adSlotOverview');
IAP.adSlot('text', 'adSlotSide');
IAP.adSlot('banner', 'adSlotSide', { width: 125, height: 125 }); // square button ad in the sidebar
render();
})();
+8 -1
View File
@@ -21,7 +21,7 @@
$('shMsg').textContent = r.status.left <= 0 ? 'That\'s today\'s shorts. Come back tomorrow.' : 'No shorts in rotation right now. Check back soon.';
return;
}
st.token = r.token; st.secs = r.ad.watchSecs;
st.token = r.token; st.secs = r.ad.watchSecs; st.adId = r.ad.id;
const v = $('shVideo');
$('shMsg').hidden = true; v.hidden = false;
v.src = r.ad.videoUrl; v.currentTime = 0;
@@ -53,6 +53,13 @@
$('shNext').hidden = false;
}
$('shNext').addEventListener('click', load);
$('shReport').addEventListener('click', e => {
e.preventDefault(); if (!st.adId) return;
const reason = (prompt('Report this short: broken, inappropriate, spam, scam, or other', 'inappropriate') || '').trim().toLowerCase();
if (!reason) return;
fetch('/api/report-ad', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ campaignId: st.adId, reason }) })
.then(() => { $('shReport').textContent = '✓ reported — thanks'; }).catch(() => {});
});
// presence enforcement: pause when the tab/window loses focus, resume on return
document.addEventListener('visibilitychange', () => {
const v = $('shVideo'); if (!v || !v.src) return;
+3
View File
@@ -574,3 +574,6 @@ img{max-width:100%}
.lt-node.deep{color:var(--muted)}
.lt-node.qualified{border-color:#ffb238;color:#ffd15c;box-shadow:0 0 0 1px rgba(255,177,56,.35)}
.lt-node.open{border-style:dashed;color:var(--muted);background:transparent}
.sh-report{display:block;text-align:center;margin-top:10px;color:rgba(255,255,255,.45);font-size:12px}
.sh-report:hover{color:rgba(255,255,255,.8)}