canvas-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 93fdaafeda16
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 788ba0fa01083b300ad50913
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
src/main.tsx
// Canvas's entry. "/" keeps the static landing and mounts the board starter and "Your boards" into it.
// "/b/<id>" is a board (view only, or editable with "#edit=<key>"), "/b/<id>/admin#k=<key>" the admin
// link, and "/new" or "/new/<template>" make a board and open it.
import { lazy, Suspense } from "react";
import { createRoot } from "react-dom/client";
import { usePath } from "./lib/router";
import { Toaster } from "./ui";
import { StartBoard, YourBoards, NewBoard } from "./Home";

// The board page brings the data client and, after it, the editor; the landing page loads neither.
const BoardPage = lazy(() => import("./BoardPage").then((m) => ({ default: m.BoardPage })));
import "./styles.css";

// The editor's fonts are served from this site, not a CDN.
(window as unknown as { EXCALIDRAW_ASSET_PATH: string }).EXCALIDRAW_ASSET_PATH = "/";

const LANDING_TITLE = document.title;

function App() {
  const path = usePath();
  const board = path.match(/^\/b\/([A-Za-z0-9]{16,32})(\/admin)?\/?$/);
  const make = path.match(/^\/new(?:\/([a-z-]+))?\/?$/);
  document.body.classList.toggle("app-mode", Boolean(board || make));
  if (!board && !make) document.title = LANDING_TITLE;
  return (
    <>
      {board ? (
        <Suspense fallback={<div className="board-loading"><span className="spinner" /> Opening the board...</div>}>
          <BoardPage key={board[1]} boardId={board[1]} admin={Boolean(board[2])} />
        </Suspense>
      ) : make ? <NewBoard key={path} template={make[1] ?? null} /> : null}
      <Toaster />
    </>
  );
}

createRoot(document.getElementById("app")!).render(<App />);
const startSlot = document.getElementById("start");
if (startSlot) createRoot(startSlot).render(<StartBoard />);
const yoursSlot = document.getElementById("your-boards");
if (yoursSlot) createRoot(yoursSlot).render(<YourBoards />);

const head = document.querySelector(".site-head");
const onScroll = () => head?.classList.toggle("scrolled", window.scrollY > 4);
window.addEventListener("scroll", onScroll, { passive: true });
onScroll();

Change history

Point OpenApps links to openapps.free
93fdaafeda · 18 hours ago
Bind AGENT_ADDRESS in policy constants
bf8f43b096 · 20 hours ago
Use functions.openapps.xyz alias, add OpenApp contribution strip
56f1a381b2 · 20 hours ago
Bounded source sync
9ec707aeb8 · 1 day ago
Bounded source sync
5645481c23 · 1 day ago
Bounded source sync
c38fe71874 · 1 day ago
Bounded source sync
28c0350b40 · 1 day ago