openvibers/openvibe.live Commits
Donate modal: zero balance no longer hides the direct PowerChat route
Changes
@@@ -5051,7 +5051,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig</div></div>--<script src="/js/vibes.js?v=9" defer></script>++<script src="/js/vibes.js?v=10" defer></script><script src="/js/opencoins.js?v=6" defer></script><script src="/js/cosmetics-ui.js?v=2" defer></script><!-- Broadcast modules — load order matters: state → devices → vods → workspace → core -->@@@ -230,31 +230,31 @@ function openvibeBucksDonateModal() {</div>`;}--// Donate modal boot: balance-first. No Vibes → send the viewer straight to Buy Vibes--// (works on every channel; includes the PowerChat purchase rail); with a balance,--// show it. Separately, streamers with their OWN PowerChat get the direct-tip option.++// Donate modal boot: balance-first, but NEVER at the cost of the direct route.++// - Balance ≥ 1: normal Vibes donate form (+ the direct-PowerChat option when the++// streamer has their own PowerChat).++// - Balance 0 + streamer HAS PowerChat: stay here and offer BOTH — tip them++// directly (no Vibes needed) or go buy Vibes first.++// - Balance 0 + no direct route: straight to Buy Vibes (any channel, all rails).async function _initDonateModal() {-- try {-- const data = await api('/funds/balance');-- const bal = Math.round(data.balance || 0);-- const line = document.getElementById('donate-balance-line');-- if (line) line.innerHTML = `Your balance: <strong>${bal.toLocaleString()}</strong> Vibes`;-- if (bal < 1) {-- toast('You don’t have any Vibes yet — grab some first, then come back to donate! 🛒', 'info');-- showModal('buy-funds');-- return;-- }-- } catch { /* not logged in / balance unavailable — leave the form as-is */ }-- _initDonatePowerchat();--}--async function _initDonatePowerchat() {-- const box = document.getElementById('donate-powerchat-direct');const streamerId = _donateStreamerId();-- if (!box || !streamerId) return;-- try {-- const d = await api(`/powerchat/donate-link?streamer_id=${streamerId}`);-- if (d && d.mode === 'direct') box.style.display = '';-- } catch { /* streamer has no PowerChat — keep hidden */ }++ const [bal, directAvailable] = await Promise.all([++ api('/funds/balance').then(d => Math.round(d.balance || 0)).catch(() => null),++ streamerId++ ? api(`/powerchat/donate-link?streamer_id=${streamerId}`).then(d => !!(d && d.mode === 'direct')).catch(() => false)++ : Promise.resolve(false),++ ]);++ const box = document.getElementById('donate-powerchat-direct');++ if (box && directAvailable) box.style.display = '';++ const line = document.getElementById('donate-balance-line');++ if (bal === null) return; // not logged in / balance unavailable — leave the form as-is++ if (line) line.innerHTML = `Your balance: <strong>${bal.toLocaleString()}</strong> Vibes${bal < 1 ? ' — <a href="#" onclick="showModal(\'buy-funds\');return false">buy some</a> to donate Vibes' : ''}`;++ if (bal < 1 && !directAvailable) {++ toast('You don’t have any Vibes yet — grab some first, then come back to donate! 🛒', 'info');++ showModal('buy-funds');++ } else if (bal < 1 && directAvailable) {++ toast('No Vibes yet — tip this channel directly via PowerChat below, or buy Vibes first. ⚡', 'info');++ }}// DIRECT real-money tip — only offered when the streamer has their own PowerChat.@@@ -230,7 +230,7 @@<script src="/js/emotes.js?v=8"></script><script src="/js/gif-picker.js?v=1"></script><script src="/js/channel-uploads.js?v=12"></script>-- <script src="/js/vibes.js?v=9"></script>++ <script src="/js/vibes.js?v=10"></script><script src="/js/opencoins.js?v=6"></script><script src="/js/cosmetics-ui.js?v=2"></script><script src="/js/chat.js?v=75"></script>
@@ -5051,7 +5051,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
@@ -5051,7 +5051,7 @@ curl -s https://openvibe.media/live/@Goosely/chat-insight.json | jq ".chat_insig
</div>
</div>
</div>
</div>
-<script src="/js/vibes.js?v=9" defer></script>
+<script src="/js/vibes.js?v=10" defer></script>
<script src="/js/opencoins.js?v=6" defer></script>
<script src="/js/opencoins.js?v=6" defer></script>
<script src="/js/cosmetics-ui.js?v=2" defer></script>
<script src="/js/cosmetics-ui.js?v=2" defer></script>
<!-- Broadcast modules — load order matters: state → devices → vods → workspace → core -->
<!-- Broadcast modules — load order matters: state → devices → vods → workspace → core -->
@@ -230,31 +230,31 @@ function openvibeBucksDonateModal() {
@@ -230,31 +230,31 @@ function openvibeBucksDonateModal() {
</div>`;
</div>`;
}
}
-// Donate modal boot: balance-first. No Vibes → send the viewer straight to Buy Vibes
-// (works on every channel; includes the PowerChat purchase rail); with a balance,
-// show it. Separately, streamers with their OWN PowerChat get the direct-tip option.
+// Donate modal boot: balance-first, but NEVER at the cost of the direct route.
+// - Balance ≥ 1: normal Vibes donate form (+ the direct-PowerChat option when the
+// streamer has their own PowerChat).
+// - Balance 0 + streamer HAS PowerChat: stay here and offer BOTH — tip them
+// directly (no Vibes needed) or go buy Vibes first.
+// - Balance 0 + no direct route: straight to Buy Vibes (any channel, all rails).
async function _initDonateModal() {
async function _initDonateModal() {
- try {
- const data = await api('/funds/balance');
- const bal = Math.round(data.balance || 0);
- const line = document.getElementById('donate-balance-line');
- if (line) line.innerHTML = `Your balance: <strong>${bal.toLocaleString()}</strong> Vibes`;
- if (bal < 1) {
- toast('You don’t have any Vibes yet — grab some first, then come back to donate! 🛒', 'info');
- showModal('buy-funds');
- return;
- }
- } catch { /* not logged in / balance unavailable — leave the form as-is */ }
- _initDonatePowerchat();
-}
-async function _initDonatePowerchat() {
- const box = document.getElementById('donate-powerchat-direct');
const streamerId = _donateStreamerId();
const streamerId = _donateStreamerId();
- if (!box || !streamerId) return;
- try {
- const d = await api(`/powerchat/donate-link?streamer_id=${streamerId}`);
- if (d && d.mode === 'direct') box.style.display = '';
- } catch { /* streamer has no PowerChat — keep hidden */ }
+ const [bal, directAvailable] = await Promise.all([
+ api('/funds/balance').then(d => Math.round(d.balance || 0)).catch(() => null),
+ streamerId
+ ? api(`/powerchat/donate-link?streamer_id=${streamerId}`).then(d => !!(d && d.mode === 'direct')).catch(() => false)
+ : Promise.resolve(false),
+ ]);
+ const box = document.getElementById('donate-powerchat-direct');
+ if (box && directAvailable) box.style.display = '';
+ const line = document.getElementById('donate-balance-line');
+ if (bal === null) return; // not logged in / balance unavailable — leave the form as-is
+ if (line) line.innerHTML = `Your balance: <strong>${bal.toLocaleString()}</strong> Vibes${bal < 1 ? ' — <a href="#" onclick="showModal(\'buy-funds\');return false">buy some</a> to donate Vibes' : ''}`;
+ if (bal < 1 && !directAvailable) {
+ toast('You don’t have any Vibes yet — grab some first, then come back to donate! 🛒', 'info');
+ showModal('buy-funds');
+ } else if (bal < 1 && directAvailable) {
+ toast('No Vibes yet — tip this channel directly via PowerChat below, or buy Vibes first. ⚡', 'info');
+ }
}
}
// DIRECT real-money tip — only offered when the streamer has their own PowerChat.
// DIRECT real-money tip — only offered when the streamer has their own PowerChat.
@@ -230,7 +230,7 @@
@@ -230,7 +230,7 @@
<script src="/js/emotes.js?v=8"></script>
<script src="/js/emotes.js?v=8"></script>
<script src="/js/gif-picker.js?v=1"></script>
<script src="/js/gif-picker.js?v=1"></script>
<script src="/js/channel-uploads.js?v=12"></script>
<script src="/js/channel-uploads.js?v=12"></script>
- <script src="/js/vibes.js?v=9"></script>
+ <script src="/js/vibes.js?v=10"></script>
<script src="/js/opencoins.js?v=6"></script>
<script src="/js/opencoins.js?v=6"></script>
<script src="/js/cosmetics-ui.js?v=2"></script>
<script src="/js/cosmetics-ui.js?v=2"></script>
<script src="/js/chat.js?v=75"></script>
<script src="/js/chat.js?v=75"></script>