fix(rmeets): default room view to clean full-screen Jitsi without shell

Swap default /:room route to serve minimal full-screen Jitsi (previously
required ?minimal=1). Shell mode now opt-in via ?shell=1 or director mode.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Jeff Emmett 2026-04-06 14:11:05 -04:00
parent 391d3a0cb6
commit 13410dd3e7
1 changed files with 46 additions and 26 deletions

View File

@ -454,6 +454,19 @@ routes.get("/:room", (c) => {
const director = c.req.query("director") === "1"; const director = c.req.query("director") === "1";
const sessionId = c.req.query("session") || ""; const sessionId = c.req.query("session") || "";
// Full rSpace shell mode — only when explicitly requested via ?shell=1 or director mode
if (c.req.query("shell") === "1" || director) {
return c.html(renderShell({
title: `${room} — rMeets | rSpace`,
moduleId: "rmeets",
spaceSlug: space,
modules: getModuleInfoList(),
theme: "dark",
body: `<folk-jitsi-room room="${escapeHtml(room)}" jitsi-url="${escapeHtml(JITSI_URL)}" space="${escapeHtml(space)}"${director ? ` director="1" session="${escapeHtml(sessionId)}"` : ""}></folk-jitsi-room>`,
scripts: `<script type="module" src="/modules/rmeets/components/folk-jitsi-room.js?v=3"></script>`,
}));
}
if (c.req.query("iframe") === "1") { if (c.req.query("iframe") === "1") {
return c.html(renderExternalAppShell({ return c.html(renderExternalAppShell({
title: `${room} — rMeets | rSpace`, title: `${room} — rMeets | rSpace`,
@ -466,21 +479,27 @@ routes.get("/:room", (c) => {
})); }));
} }
// Minimal mode — full-screen Jitsi without rSpace shell (for scheduled meeting links) // Default: clean full-screen Jitsi — no rSpace shell, mobile-friendly
if (c.req.query("minimal") === "1" || c.req.query("join") === "1") {
const jitsiRoom = encodeURIComponent(room); const jitsiRoom = encodeURIComponent(room);
return c.html(`<!DOCTYPE html> return c.html(`<!DOCTYPE html>
<html lang="en"> <html lang="en">
<head> <head>
<meta charset="UTF-8"> <meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1"> <meta name="viewport" content="width=device-width,initial-scale=1,maximum-scale=1,user-scalable=no,viewport-fit=cover">
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent">
<meta name="theme-color" content="#111111">
<title>${escapeHtml(room)} Meeting</title> <title>${escapeHtml(room)} Meeting</title>
<style> <style>
*{margin:0;padding:0;box-sizing:border-box} *{margin:0;padding:0;box-sizing:border-box}
html,body{height:100%;overflow:hidden;background:#111;font-family:system-ui,sans-serif} html,body{height:100%;overflow:hidden;background:#111;font-family:system-ui,-apple-system,sans-serif;touch-action:manipulation}
#jitsi-container{width:100%;height:100%} #jitsi-container{width:100%;height:100%;height:100dvh;padding:env(safe-area-inset-top) env(safe-area-inset-right) env(safe-area-inset-bottom) env(safe-area-inset-left)}
.loading{display:flex;align-items:center;justify-content:center;height:100%;color:#94a3b8;flex-direction:column;gap:12px} #jitsi-container iframe{width:100%!important;height:100%!important;border:none!important}
.loading{display:flex;align-items:center;justify-content:center;height:100%;color:#94a3b8;flex-direction:column;gap:12px;font-size:0.95rem}
.loading .spinner{width:32px;height:32px;border:3px solid #334155;border-top-color:#6366f1;border-radius:50%;animation:spin 0.8s linear infinite} .loading .spinner{width:32px;height:32px;border:3px solid #334155;border-top-color:#6366f1;border-radius:50%;animation:spin 0.8s linear infinite}
.ended{display:flex;align-items:center;justify-content:center;height:100%;color:#e2e8f0;flex-direction:column;gap:16px;font-size:1.1rem}
.ended a{color:#6366f1;text-decoration:none;padding:10px 24px;border:1px solid #6366f1;border-radius:8px;font-size:0.95rem;transition:background 0.15s}
.ended a:hover,.ended a:active{background:#6366f122}
@keyframes spin{to{transform:rotate(360deg)}} @keyframes spin{to{transform:rotate(360deg)}}
</style> </style>
</head> </head>
@ -500,34 +519,35 @@ routes.get("/:room", (c) => {
startWithVideoMuted: false, startWithVideoMuted: false,
prejoinPageEnabled: true, prejoinPageEnabled: true,
disableDeepLinking: true, disableDeepLinking: true,
disableThirdPartyRequests: true,
enableClosePage: false,
disableInviteFunctions: false,
toolbarButtons: [
"microphone","camera","desktop","hangup",
"raisehand","tileview","toggle-camera",
"fullscreen","chat","settings",
"participants-pane","select-background",
],
}, },
interfaceConfigOverrides: { interfaceConfigOverrides: {
SHOW_JITSI_WATERMARK: false, SHOW_JITSI_WATERMARK: false,
SHOW_BRAND_WATERMARK: false, SHOW_BRAND_WATERMARK: false,
SHOW_POWERED_BY: false, SHOW_POWERED_BY: false,
TOOLBAR_BUTTONS: [ MOBILE_APP_PROMO: false,
"microphone","camera","closedcaptions","desktop","fullscreen", HIDE_DEEP_LINKING_LOGO: true,
"fodeviceselection","hangup","chat","recording","livestreaming", DISABLE_JOIN_LEAVE_NOTIFICATIONS: false,
"etherpad","settings","raisehand","videoquality","filmstrip",
"feedback","shortcuts","tileview","participants-pane",
],
}, },
}); });
api.addEventListener("readyToClose", () => { window.close(); }); api.addEventListener("readyToClose", function() {
try { window.close(); } catch(e) {}
// window.close() fails if the tab wasn't opened by JS (common on mobile)
document.getElementById("jitsi-container").innerHTML =
'<div class="ended"><span>Meeting ended</span>'
+ '<a href="${escapeHtml(`/${space}/rmeets`)}">Back to rMeets</a></div>';
});
</script> </script>
</body> </body>
</html>`); </html>`);
}
return c.html(renderShell({
title: `${room} — rMeets | rSpace`,
moduleId: "rmeets",
spaceSlug: space,
modules: getModuleInfoList(),
theme: "dark",
body: `<folk-jitsi-room room="${escapeHtml(room)}" jitsi-url="${escapeHtml(JITSI_URL)}" space="${escapeHtml(space)}"${director ? ` director="1" session="${escapeHtml(sessionId)}"` : ""}></folk-jitsi-room>`,
scripts: `<script type="module" src="/modules/rmeets/components/folk-jitsi-room.js?v=3"></script>`,
}));
}); });
// ── Helpers ── // ── Helpers ──