Shorts = portrait-only reel; Watch videos = landscape; badge name in gold

- Videos now carry client-detected pixel dimensions (videoW/videoH) captured at
  campaign create (upload or direct link). serveVideo takes an orientation filter:
  Shorts reel (/shorts) serves portrait (height>width); the Watch videos tab
  serves landscape, including legacy/unknown-dimension videos so nothing is orphaned.
- shorts.js requests the portrait feed and has a client guard that skips any
  landscape video that slips through. Create form shows the detected orientation.
- Achievement badge share image: member name now renders in gold with a dark
  outline (was low-contrast dark ink) and sits centered on the ribbon.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
martbost
2026-09-07 05:41:17 -05:00
parent 5e3f2540f4
commit a634f83a8e
7 changed files with 63 additions and 15 deletions
+2 -1
View File
@@ -867,7 +867,8 @@ const server = http.createServer(async (req, res) => {
if (!s || !s.email) return json(res, 401, { error: 'Sign in first.' });
const status = await ads.videoStatus(s.email);
if (status.left <= 0) return json(res, 200, { ad: null, status });
const ad = await ads.serveVideo({ excludeEmail: s.email }); // never your own video
const orientation = String(u.searchParams.get('orientation') || ''); // 'portrait' = Shorts reel, 'landscape' = Watch videos tab
const ad = await ads.serveVideo({ excludeEmail: s.email, orientation }); // never your own video
if (!ad) return json(res, 200, { ad: null, status });
const token = crypto.randomBytes(16).toString('hex');
videoTokens.set(s.email, { token, ts: Date.now(), id: ad.id, secs: ad.watchSecs });