openvibers/openvibe.live Commits
Setup progress: refresh every surface when a task is completed
Changes
@@@ -5215,8 +5215,8 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig<script src="/js/footer-live.js?v=1" defer></script><script src="/js/home-fx.js?v=9" defer></script><script src="/js/home-tour.js?v=6" defer></script>--<script src="/js/ov-guide.js?v=1" defer></script>--<script src="/js/guides-live.js?v=5" defer></script>++<script src="/js/ov-guide.js?v=2" defer></script>++<script src="/js/guides-live.js?v=6" defer></script><!-- ── OpenVibe shared libs (notifications, account sync, themes) ── --><script src="/shared/theme-loader.js?v=1" defer></script>@@@ -243,13 +243,32 @@// ── Journey: the setup hub (checklist) ────────────────────let PROG = null;async function loadProgress() { try { PROG = await api('/streams/setup-progress'); } catch { PROG = null; } return PROG; }++++ /**++ * Re-read progress and repaint anything that shows it.++ *++ * Finishing a task inside a journey changes the answer, but nothing told the rest of the page.++ * A streamer would set up a donation goal, get the confetti, and still see 7/12 on the home++ * page banner until they reloaded — reported by Maticus. The setup endpoint is cheap and++ * cached server-side, so re-reading it after anything that could have moved the needle costs++ * nothing and keeps every surface honest.++ */++ async function refreshSetupProgress() {++ await loadProgress();++ try {++ const slot = document.getElementById('tour-next-up');++ if (slot && typeof window.setupNextUp === 'function') await window.setupNextUp(slot);++ } catch { /* */ }++ }++ window.refreshSetupProgress = refreshSetupProgress;G.register('setup-hub', {title: 'Streamer setup', kicker: 'Streamer setup', noStepBar: true, onOpen: loadProgress,steps: [{id: 'hub', title: 'Streamer setup', icon: 'fa-list-check',heading: 'Your streaming setup',render: async (ctx) => {-- const p = PROG || await loadProgress();++ // Always fresh: the hub is usually reopened straight after finishing something.++ const p = await loadProgress();if (!p) return ui.lead('Could not load your setup right now.');const pct = Math.round((p.done / p.total) * 100);const groups = {}; p.tasks.forEach(t => { (groups[t.group] = groups[t.group] || []).push(t); });@@@ -277,6 +296,10 @@onClose: (ctx, finished) => { if (finished && me()) G.open('setup-hub'); },});++ // Any journey finishing may have completed a setup task, so repaint the surfaces that++ // display progress. Cheap, cached, and it keeps the home banner in step with the hub.++ document.addEventListener('ovguide:closed', () => { if (me()) refreshSetupProgress(); });++// ── Entry points ───────────────────────────────────────────window.openGoLiveWizard = (o = {}) => { const step = o.step || 'stream'; if (onBroadcast()) return G.open('golive', { step }); G.cfg.navigate(`/broadcast?guide=golive:${step}`); };window.startGoLiveWizard = () => openGoLiveWizard({ step: 'stream' });@@@ -141,7 +141,11 @@S.open = false; root.classList.remove('is-open'); document.body.classList.remove('ovg-lock');const j = S.journey;if (j) { store(j.id, { ...(store(j.id) || {}), seen: true, finished: !!finished || !!(store(j.id) || {}).finished, dismissed: !finished, when: Date.now() }); try { if (typeof j.onClose === 'function') j.onClose(S.ctx, !!finished); } catch { /* */ } }++ const closedId = j ? j.id : null;S.journey = null; S.step = null;++ // Anything that watches setup state (the home page banner, the setup hub's own counter)++ // needs to know a journey just ended — a task may have been completed inside it.++ try { document.dispatchEvent(new CustomEvent('ovguide:closed', { detail: { journey: closedId, finished: !!finished } })); } catch { /* */ }}// ── Spotlight: point at something real on the page ─────────
@@ -5215,8 +5215,8 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
@@ -5215,8 +5215,8 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
<script src="/js/footer-live.js?v=1" defer></script>
<script src="/js/footer-live.js?v=1" defer></script>
<script src="/js/home-fx.js?v=9" defer></script>
<script src="/js/home-fx.js?v=9" defer></script>
<script src="/js/home-tour.js?v=6" defer></script>
<script src="/js/home-tour.js?v=6" defer></script>
-<script src="/js/ov-guide.js?v=1" defer></script>
-<script src="/js/guides-live.js?v=5" defer></script>
+<script src="/js/ov-guide.js?v=2" defer></script>
+<script src="/js/guides-live.js?v=6" defer></script>
<!-- ── OpenVibe shared libs (notifications, account sync, themes) ── -->
<!-- ── OpenVibe shared libs (notifications, account sync, themes) ── -->
<script src="/shared/theme-loader.js?v=1" defer></script>
<script src="/shared/theme-loader.js?v=1" defer></script>
@@ -243,13 +243,32 @@
@@ -243,13 +243,32 @@
// ── Journey: the setup hub (checklist) ────────────────────
// ── Journey: the setup hub (checklist) ────────────────────
let PROG = null;
let PROG = null;
async function loadProgress() { try { PROG = await api('/streams/setup-progress'); } catch { PROG = null; } return PROG; }
async function loadProgress() { try { PROG = await api('/streams/setup-progress'); } catch { PROG = null; } return PROG; }
+
+ /**
+ * Re-read progress and repaint anything that shows it.
+ *
+ * Finishing a task inside a journey changes the answer, but nothing told the rest of the page.
+ * A streamer would set up a donation goal, get the confetti, and still see 7/12 on the home
+ * page banner until they reloaded — reported by Maticus. The setup endpoint is cheap and
+ * cached server-side, so re-reading it after anything that could have moved the needle costs
+ * nothing and keeps every surface honest.
+ */
+ async function refreshSetupProgress() {
+ await loadProgress();
+ try {
+ const slot = document.getElementById('tour-next-up');
+ if (slot && typeof window.setupNextUp === 'function') await window.setupNextUp(slot);
+ } catch { /* */ }
+ }
+ window.refreshSetupProgress = refreshSetupProgress;
G.register('setup-hub', {
G.register('setup-hub', {
title: 'Streamer setup', kicker: 'Streamer setup', noStepBar: true, onOpen: loadProgress,
title: 'Streamer setup', kicker: 'Streamer setup', noStepBar: true, onOpen: loadProgress,
steps: [{
steps: [{
id: 'hub', title: 'Streamer setup', icon: 'fa-list-check',
id: 'hub', title: 'Streamer setup', icon: 'fa-list-check',
heading: 'Your streaming setup',
heading: 'Your streaming setup',
render: async (ctx) => {
render: async (ctx) => {
- const p = PROG || await loadProgress();
+ // Always fresh: the hub is usually reopened straight after finishing something.
+ const p = await loadProgress();
if (!p) return ui.lead('Could not load your setup right now.');
if (!p) return ui.lead('Could not load your setup right now.');
const pct = Math.round((p.done / p.total) * 100);
const pct = Math.round((p.done / p.total) * 100);
const groups = {}; p.tasks.forEach(t => { (groups[t.group] = groups[t.group] || []).push(t); });
const groups = {}; p.tasks.forEach(t => { (groups[t.group] = groups[t.group] || []).push(t); });
@@ -277,6 +296,10 @@
@@ -277,6 +296,10 @@
onClose: (ctx, finished) => { if (finished && me()) G.open('setup-hub'); },
onClose: (ctx, finished) => { if (finished && me()) G.open('setup-hub'); },
});
});
+ // Any journey finishing may have completed a setup task, so repaint the surfaces that
+ // display progress. Cheap, cached, and it keeps the home banner in step with the hub.
+ document.addEventListener('ovguide:closed', () => { if (me()) refreshSetupProgress(); });
+
// ── Entry points ───────────────────────────────────────────
// ── Entry points ───────────────────────────────────────────
window.openGoLiveWizard = (o = {}) => { const step = o.step || 'stream'; if (onBroadcast()) return G.open('golive', { step }); G.cfg.navigate(`/broadcast?guide=golive:${step}`); };
window.openGoLiveWizard = (o = {}) => { const step = o.step || 'stream'; if (onBroadcast()) return G.open('golive', { step }); G.cfg.navigate(`/broadcast?guide=golive:${step}`); };
window.startGoLiveWizard = () => openGoLiveWizard({ step: 'stream' });
window.startGoLiveWizard = () => openGoLiveWizard({ step: 'stream' });
@@ -141,7 +141,11 @@
@@ -141,7 +141,11 @@
S.open = false; root.classList.remove('is-open'); document.body.classList.remove('ovg-lock');
S.open = false; root.classList.remove('is-open'); document.body.classList.remove('ovg-lock');
const j = S.journey;
const j = S.journey;
if (j) { store(j.id, { ...(store(j.id) || {}), seen: true, finished: !!finished || !!(store(j.id) || {}).finished, dismissed: !finished, when: Date.now() }); try { if (typeof j.onClose === 'function') j.onClose(S.ctx, !!finished); } catch { /* */ } }
if (j) { store(j.id, { ...(store(j.id) || {}), seen: true, finished: !!finished || !!(store(j.id) || {}).finished, dismissed: !finished, when: Date.now() }); try { if (typeof j.onClose === 'function') j.onClose(S.ctx, !!finished); } catch { /* */ } }
+ const closedId = j ? j.id : null;
S.journey = null; S.step = null;
S.journey = null; S.step = null;
+ // Anything that watches setup state (the home page banner, the setup hub's own counter)
+ // needs to know a journey just ended — a task may have been completed inside it.
+ try { document.dispatchEvent(new CustomEvent('ovguide:closed', { detail: { journey: closedId, finished: !!finished } })); } catch { /* */ }
}
}
// ── Spotlight: point at something real on the page ─────────
// ── Spotlight: point at something real on the page ─────────