fix(rgov): render canvas directly instead of redirecting to /rspace
The rgov module page was showing a static description with a link to /rspace. Now it renders the actual canvas (same as rspace module) with moduleId="rgov" so GovMod shapes display inline at /rgov. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
parent
8f8ec25788
commit
996f9ec465
|
|
@ -8,6 +8,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import { Hono } from "hono";
|
import { Hono } from "hono";
|
||||||
|
import { resolve } from "path";
|
||||||
import { renderShell } from "../../server/shell";
|
import { renderShell } from "../../server/shell";
|
||||||
import { getModuleInfoList } from "../../shared/module";
|
import { getModuleInfoList } from "../../shared/module";
|
||||||
import type { RSpaceModule } from "../../shared/module";
|
import type { RSpaceModule } from "../../shared/module";
|
||||||
|
|
@ -16,10 +17,53 @@ import { addShapes, getDocumentData } from "../../server/community-store";
|
||||||
|
|
||||||
const routes = new Hono();
|
const routes = new Hono();
|
||||||
|
|
||||||
// ── Module page (within a space) ──
|
// ── Canvas content loader (same approach as rspace module) ──
|
||||||
|
|
||||||
routes.get("/", (c) => {
|
const DIST_DIR = resolve(import.meta.dir, "../../dist");
|
||||||
|
let canvasCache: { body: string; styles: string; scripts: string } | null = null;
|
||||||
|
|
||||||
|
function extractCanvasContent(html: string) {
|
||||||
|
const bodyMatch = html.match(/<body[^>]*>([\s\S]*?)<\/body>/i);
|
||||||
|
const styleMatches = [...html.matchAll(/<style[^>]*>([\s\S]*?)<\/style>/gi)];
|
||||||
|
const scriptMatches = [...html.matchAll(/<script[^>]*>[\s\S]*?<\/script>/gi)];
|
||||||
|
return {
|
||||||
|
body: bodyMatch?.[1] || "",
|
||||||
|
styles: styleMatches.map(m => m[0]).join("\n"),
|
||||||
|
scripts: scriptMatches.map(m => m[0]).join("\n"),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
async function getCanvasContent() {
|
||||||
|
if (canvasCache) return canvasCache;
|
||||||
|
|
||||||
|
const moduleFile = Bun.file(resolve(DIST_DIR, "canvas-module.html"));
|
||||||
|
if (await moduleFile.exists()) {
|
||||||
|
canvasCache = {
|
||||||
|
body: await moduleFile.text(),
|
||||||
|
styles: "",
|
||||||
|
scripts: `<script type="module" src="/canvas-module.js"></script>`,
|
||||||
|
};
|
||||||
|
return canvasCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
const fullFile = Bun.file(resolve(DIST_DIR, "canvas.html"));
|
||||||
|
if (await fullFile.exists()) {
|
||||||
|
canvasCache = extractCanvasContent(await fullFile.text());
|
||||||
|
return canvasCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
body: `<div style="padding:2rem;text-align:center;color:#64748b;">Canvas loading...</div>`,
|
||||||
|
styles: "",
|
||||||
|
scripts: "",
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
// ── Module page (within a space) — renders canvas directly ──
|
||||||
|
|
||||||
|
routes.get("/", async (c) => {
|
||||||
const space = c.req.param("space") || "demo";
|
const space = c.req.param("space") || "demo";
|
||||||
|
const canvas = await getCanvasContent();
|
||||||
|
|
||||||
return c.html(renderShell({
|
return c.html(renderShell({
|
||||||
title: `${space} — rGov | rSpace`,
|
title: `${space} — rGov | rSpace`,
|
||||||
|
|
@ -27,29 +71,9 @@ routes.get("/", (c) => {
|
||||||
spaceSlug: space,
|
spaceSlug: space,
|
||||||
modules: getModuleInfoList(),
|
modules: getModuleInfoList(),
|
||||||
theme: "dark",
|
theme: "dark",
|
||||||
body: `
|
body: canvas.body,
|
||||||
<div style="max-width:640px;margin:60px auto;padding:0 24px;color:#e2e8f0;font-family:system-ui,sans-serif;">
|
styles: canvas.styles,
|
||||||
<h1 style="font-size:28px;margin-bottom:8px;">⚖️ rGov — GovMods</h1>
|
scripts: canvas.scripts,
|
||||||
<p style="color:#94a3b8;margin-bottom:24px;">Do-ocratic circuit components for multiplayer collaboration</p>
|
|
||||||
<p style="color:#cbd5e1;line-height:1.6;margin-bottom:16px;">
|
|
||||||
Build governance decision circuits by wiring GovMods together on the canvas:
|
|
||||||
</p>
|
|
||||||
<ul style="color:#cbd5e1;line-height:1.8;margin-bottom:24px;padding-left:20px;">
|
|
||||||
<li><strong>Signoff Gates</strong> — Yes/No approval checkpoints</li>
|
|
||||||
<li><strong>Thresholds</strong> — Numeric targets (hours, dollars, signatures)</li>
|
|
||||||
<li><strong>Knobs</strong> — Tunable parameters with temporal viscosity</li>
|
|
||||||
<li><strong>Projects</strong> — Circuit aggregators showing "X of Y gates satisfied"</li>
|
|
||||||
<li><strong>Amendments</strong> — Propose in-place circuit modifications</li>
|
|
||||||
<li><strong>Quadratic Transform</strong> — Weight dampening (sqrt/log) for fair voting</li>
|
|
||||||
<li><strong>Conviction Accumulator</strong> — Time-weighted conviction scoring</li>
|
|
||||||
<li><strong>Multisig Gate</strong> — M-of-N approval multiplexor</li>
|
|
||||||
<li><strong>Sankey Visualizer</strong> — Auto-discovered governance flow diagram</li>
|
|
||||||
</ul>
|
|
||||||
<a href="/rspace" style="display:inline-block;background:linear-gradient(to right,#7c3aed,#1d4ed8);color:white;padding:10px 20px;border-radius:8px;text-decoration:none;font-weight:600;">
|
|
||||||
Open Canvas →
|
|
||||||
</a>
|
|
||||||
</div>
|
|
||||||
`,
|
|
||||||
}));
|
}));
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue