diff --git a/modules/rmeets/mod.ts b/modules/rmeets/mod.ts new file mode 100644 index 0000000..4484928 --- /dev/null +++ b/modules/rmeets/mod.ts @@ -0,0 +1,116 @@ +/** + * rMeets module — video meetings powered by Jitsi. + * + * Hub page with Quick Meet + room name input, + * room pages embed Jitsi via renderExternalAppShell. + */ + +import { Hono } from "hono"; +import { renderShell, renderExternalAppShell, escapeHtml } from "../../server/shell"; +import { getModuleInfoList } from "../../shared/module"; +import type { RSpaceModule } from "../../shared/module"; + +const JITSI_URL = process.env.JITSI_URL || "https://jeffsi.localvibe.live"; +const routes = new Hono(); + +// ── Room embed ── + +routes.get("/room/:room", (c) => { + const space = c.req.param("space") || "demo"; + const room = c.req.param("room"); + return c.html(renderExternalAppShell({ + title: `${room} — rMeets | rSpace`, + moduleId: "rmeets", + spaceSlug: space, + modules: getModuleInfoList(), + appUrl: `${JITSI_URL}/${encodeURIComponent(room)}`, + appName: "Jitsi Meet", + theme: "dark", + })); +}); + +// ── Direct Jitsi lobby ── + +routes.get("/meet", (c) => { + const space = c.req.param("space") || "demo"; + return c.html(renderExternalAppShell({ + title: `Jitsi Meet — rMeets | rSpace`, + moduleId: "rmeets", + spaceSlug: space, + modules: getModuleInfoList(), + appUrl: JITSI_URL, + appName: "Jitsi Meet", + theme: "dark", + })); +}); + +// ── Hub page ── + +routes.get("/", (c) => { + const space = c.req.param("space") || "demo"; + const base = `/${escapeHtml(space)}/rmeets`; + const randomId = Math.random().toString(36).slice(2, 10); + return c.html(renderShell({ + title: `rMeets — ${space} | rSpace`, + moduleId: "rmeets", + spaceSlug: space, + modules: getModuleInfoList(), + theme: "dark", + styles: ``, + body: `
+

rMeets

+

Video meetings powered by Jitsi — no account required

+ +
`, + })); +}); + +// ── Module export ── + +export const meetsModule: RSpaceModule = { + id: "rmeets", + name: "rMeets", + icon: "📹", + description: "Video meetings powered by Jitsi", + scoping: { defaultScope: "space", userConfigurable: false }, + routes, + externalApp: { url: JITSI_URL, name: "Jitsi Meet" }, +}; diff --git a/server/index.ts b/server/index.ts index e12673f..92382cd 100644 --- a/server/index.ts +++ b/server/index.ts @@ -66,6 +66,7 @@ import { dataModule } from "../modules/rdata/mod"; import { splatModule } from "../modules/rsplat/mod"; import { photosModule } from "../modules/rphotos/mod"; import { socialsModule } from "../modules/rsocials/mod"; +import { meetsModule } from "../modules/rmeets/mod"; // import { docsModule } from "../modules/rdocs/mod"; // import { designModule } from "../modules/rdesign/mod"; import { scheduleModule } from "../modules/rschedule/mod"; @@ -111,6 +112,7 @@ registerModule(socialsModule); // registerModule(docsModule); // placeholder — not yet an rApp // registerModule(designModule); // placeholder — not yet an rApp registerModule(scheduleModule); +registerModule(meetsModule); // ── Config ── const PORT = Number(process.env.PORT) || 3000;