44816571b6
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
100 lines
3.8 KiB
JavaScript
100 lines
3.8 KiB
JavaScript
// Video Maker client. Renders take ~15-40s server-side, so the button holds a
|
||
// spinner and the copy warns before the wait rather than after it.
|
||
(function () {
|
||
'use strict';
|
||
var ANGLES = [
|
||
{ k: 'two', label: 'You only need two' },
|
||
{ k: 'pocket', label: 'Pocket change' },
|
||
{ k: 'phone', label: 'Runs from your phone' },
|
||
{ k: 'graveyard', label: 'Side-hustle graveyard' },
|
||
{ k: 'overview', label: 'General overview' }
|
||
];
|
||
var $ = function (id) { return document.getElementById(id); };
|
||
var angle = 'two', busy = false;
|
||
|
||
function renderAngles() {
|
||
var host = $('vdAngles');
|
||
host.innerHTML = '';
|
||
ANGLES.forEach(function (x) {
|
||
var b = document.createElement('button');
|
||
b.type = 'button';
|
||
b.className = 'vd-angle' + (x.k === angle ? ' on' : '');
|
||
b.textContent = x.label;
|
||
b.addEventListener('click', function () { angle = x.k; renderAngles(); });
|
||
host.appendChild(b);
|
||
});
|
||
}
|
||
|
||
function showMeter(m) {
|
||
if (!m || !m.limit) { $('vdMeter').textContent = ''; return; }
|
||
$('vdMeter').innerHTML = '<b>' + m.remaining + '</b> of ' + m.limit + ' videos left this month';
|
||
}
|
||
|
||
function gate(msg) {
|
||
var g = $('vdGate');
|
||
g.style.display = 'block';
|
||
g.innerHTML = msg;
|
||
$('vdCard').style.opacity = '.55';
|
||
$('vdGo').disabled = true;
|
||
$('vdName').disabled = true;
|
||
}
|
||
|
||
async function boot() {
|
||
renderAngles();
|
||
try {
|
||
var r = await fetch('/api/public/suite-meters');
|
||
if (r.status === 401) { gate('You’re not signed in yet. <a href="/suite" style="color:var(--gold);font-weight:700">Open the Suite</a> and connect the wallet that holds your position, then come back.'); return; }
|
||
if (r.status === 403) { gate('The Video Maker isn’t open for this position yet. <a href="/suite" style="color:var(--gold);font-weight:700">See your Suite</a>.'); return; }
|
||
if (!r.ok) return;
|
||
var d = await r.json();
|
||
var m = d.meters && d.meters.video;
|
||
if (m && m.reason === 'locked') {
|
||
gate('The Video Maker unlocks at <b>Fabrica (level 3)</b>. You’re at level ' + d.level + ' — keep climbing and it opens, along with the Email Engine. <a href="/how-pay-works#exact-costs" style="color:var(--gold);font-weight:700">See what upgrades cost →</a>');
|
||
return;
|
||
}
|
||
showMeter(m);
|
||
} catch (e) {}
|
||
}
|
||
|
||
async function run() {
|
||
if (busy) return;
|
||
busy = true;
|
||
$('vdErr').style.display = 'none';
|
||
$('vdOut').style.display = 'none';
|
||
$('vdGo').disabled = true;
|
||
$('vdGo').innerHTML = '<span class="spin"></span>Rendering your video… (about a minute)';
|
||
try {
|
||
var r = await fetch('/api/public/suite-video', {
|
||
method: 'POST', headers: { 'Content-Type': 'application/json' },
|
||
body: JSON.stringify({ angle: angle, name: $('vdName').value.trim() })
|
||
});
|
||
var d = await r.json();
|
||
if (!r.ok) {
|
||
$('vdErr').textContent = d.error || 'That didn’t go through — try again.';
|
||
$('vdErr').style.display = 'block';
|
||
if (d.meter) showMeter(d.meter);
|
||
} else {
|
||
$('vdDl').href = d.url;
|
||
$('vdSize').textContent = 'MP4 · about ' + d.mb + ' MB · ready to post anywhere.';
|
||
$('vdOut').style.display = 'block';
|
||
showMeter(d.meter);
|
||
$('vdOut').scrollIntoView({ behavior: 'smooth', block: 'nearest' });
|
||
}
|
||
} catch (e) {
|
||
$('vdErr').textContent = 'Connection hiccup — try again.';
|
||
$('vdErr').style.display = 'block';
|
||
}
|
||
busy = false;
|
||
$('vdGo').disabled = false;
|
||
$('vdGo').textContent = '🎬 Make my video';
|
||
}
|
||
|
||
document.addEventListener('DOMContentLoaded', function () {
|
||
boot();
|
||
$('vdGo').addEventListener('click', run);
|
||
$('vdName').addEventListener('input', function () {
|
||
$('vdPrev').textContent = $('vdName').value.trim() || 'Your name';
|
||
});
|
||
});
|
||
})();
|