openvibers/openvibe.live Commits

The mini player follows you to other OpenVibe sites (#699)

OP OpenVibers committed 5 days ago · b6a1fac0cf · 2 files, +29 −2

* The mini player follows you to other OpenVibe sites (Shared 4.152.0 overlay.js)

While the picture is in the mini player, Live declares it as a portable card: a link to another OpenVibe site carries
it, and that site frames Live's own /embed/<name> with the channel's chat beside it. Coming back to a channel closes
the card. Pointer capture can no longer throw a drag away.

* A card carried back to a channel page is not reopened (window.OVOverlayHere)

* Merge branch 'main' into mini-crosssite

Changes

ddiff --git a/public/js/app.js b/public/js/app.js
iindex ca5f0ad1..204f3a2a 100644
---- a/public/js/app.js
++++ b/public/js/app.js
@@@ -1031,6 +1031,12 @@ function _ovNavStart() {
}
function _ovNavEnd() { if (!_ovNavOn) return; _ovNavOn = 0; _ovNavWaiting = false; try { window.OVMark && window.OVMark.navEnd('app'); } catch { /* */ } }
++// A floating card carried here from another OpenVibe site (Shared overlay.js) that frames Live's own channel embed is
++// not reopened on a channel page: the page plays the channel itself, and one stream never plays twice.
++window.OVOverlayHere = (card) => {
++ try { return new URL(card.src).origin === location.origin && /^\/embed\//.test(new URL(card.src).pathname) && /^\/(?:@|stream)/.test(location.pathname); } catch { return false; }
++};
++
function navigate(urlPath, replace = false) {
if (isOffSite(urlPath)) { if (replace) location.replace(urlPath); else location.href = urlPath; return; }
urlPath = sameSitePath(urlPath);
ddiff --git a/public/js/ov-mini-player.js b/public/js/ov-mini-player.js
iindex 36c1deba..2e071fe6 100644
---- a/public/js/ov-mini-player.js
++++ b/public/js/ov-mini-player.js
@@@ -170,12 +170,13 @@
function wireGestures(box) {
const pts = new Map();
let drag = null, pinch = null, lastTap = 0, grip = null;
++ const capture = (id) => { try { box.setPointerCapture(id); } catch { /* a pointer the browser no longer tracks */ } };
const vel = [];
box.addEventListener('pointerdown', (e) => {
if (e.target.closest('.ov-mp-b')) return;
-- if (e.target.closest('.ov-mp-grip')) { grip = { x: e.clientX, w: st.w, corner: st.corner }; box.setPointerCapture(e.pointerId); e.preventDefault(); return; }
++ if (e.target.closest('.ov-mp-grip')) { grip = { x: e.clientX, w: st.w, corner: st.corner }; capture(e.pointerId); e.preventDefault(); return; }
pts.set(e.pointerId, { x: e.clientX, y: e.clientY });
-- box.setPointerCapture(e.pointerId);
++ capture(e.pointerId);
if (pts.size === 2) {
const [a, b] = [...pts.values()];
pinch = { d: Math.hypot(a.x - b.x, a.y - b.y) || 1, w: st.w };
@@@ -368,6 +369,7 @@
const onPlayerPage = nextPath && (isChannelPath(nextPath) || String(nextPath).startsWith('/broadcast'));
if (onPlayerPage) {
if (st.box) release();
++ try { if (window.OVOverlay) window.OVOverlay.close('live'); } catch { /* */ }
return false;
}
if (st.box) return true; // already a mini player
@@@ -399,9 +401,27 @@
}
requestAnimationFrame(() => settle(s.corner, w));
if (!fine()) showUi();
++ declare(true);
return true;
}
++ // Across OpenVibe sites (Shared 4.152.0 overlay.js): while the picture is in this mini player, a link to another
++ // OpenVibe site carries it as a floating card that frames Live's own /embed/<name> (a new session there; this one
++ // ends with the page), with the channel's chat beside it. Coming back to the channel closes that card.
++ function declare(on) {
++ const nav = window.OpenVibeNavbar;
++ if (!nav || typeof nav.overlays !== 'function') return;
++ nav.overlays().then((O) => {
++ if (!O) return;
++ if (!on || !st.user) { O.declare('live', null); return; }
++ const u = encodeURIComponent(st.user);
++ O.declare('live', {
++ src: `${location.origin}/embed/${u}`, title: st.title, live: true, href: `${location.origin}/@${u}`,
++ side: { src: `${location.origin}/popout/${u}`, title: `${st.title} \u00b7 chat` },
++ });
++ }).catch(() => { /* the overlay host could not load: the mini player still works here */ });
++ }
++
/** The viewer closed it: the player goes away for good. */
function closeForGood() {
if (typeof destroyPlayer === 'function') { try { destroyPlayer(); } catch { /* */ } }
@@@ -413,6 +433,7 @@
if (!st.box) return;
const box = st.box;
toggleChat(false);
++ declare(false);
st.box = null;
clearTimeout(st.idle);
if (st.onResize) { removeEventListener('resize', st.onResize); st.onResize = null; }