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.
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 334801de44cb0fe911d5a88b
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.
src/Event.tsx
// Opening an event: /e/<id> for the audience, /e/<id>/admin and /e/<id>/present for its owners,
// and /<code> for someone who typed the 6-digit code into the address bar.
import { useEffect, useState } from "react";
import { get, set } from "@bounded-sh/client";
import { me, explain } from "./lib/bounded";
import { useEventAccess } from "./lib/event";
import { Audience } from "./Audience";
import { Admin } from "./Admin";
import { Present } from "./Present";
export type View = "audience" | "admin" | "present";
export function Loading({ text }: { text: string }) {
return <div className="wrap page-pad"><div className="loading"><span className="spinner" /> {text}</div></div>;
}
function Stop({ title, text, action }: { title: string; text: string; action?: [string, string] }) {
return (
<div className="wrap page-pad narrow">
<h1 className="h1">{title}</h1>
<p className="lede" style={{ marginTop: 14 }}>{text}</p>
<a className="btn" style={{ marginTop: 24 }} href={action?.[1] ?? "/"} data-nav>{action?.[0] ?? "Go to Polls"}</a>
</div>
);
}
export function EventPage({ eventId, view }: { eventId: string; view: View }) {
const access = useEventAccess(eventId);
if (access.state === "opening") return <Loading text="Opening the event..." />;
if (access.state === "missing") return <Stop title="This event does not exist." text="Check the link or the code. Event links are long and every character counts." />;
if (access.state === "error") return <div className="wrap page-pad narrow"><p className="notice notice-error">{access.error}</p></div>;
if (access.state === "badkey") return <Stop title="That admin link is not right." text="The key at the end of the link does not match this event. Copy the whole admin link again." action={["Open the event", `/e/${eventId}`]} />;
if (view !== "audience" && !access.owner) {
return <Stop title="Only the event's host can open this." text="To run this event on this device, open the admin link you got when the event was made." action={["Join as audience", `/e/${eventId}`]} />;
}
if (view === "admin") return <Admin eventId={eventId} />;
if (view === "present") return <Present eventId={eventId} />;
return <Audience eventId={eventId} uid={access.uid} owner={access.owner} />;
}
/** Looks up a join code. Each try is recorded first, because tries are what keep codes from being scanned. */
export async function findEvent(code: string): Promise<string> {
const uid = await me();
if (!(await get(`codetries/${uid}/t/${code}`))) {
try {
await set(`codetries/${uid}/t/${code}`, { n: 1 });
} catch (err) {
const e = err as { decline?: { invariant?: string }; message?: string };
if (e?.decline?.invariant || /exceed|cap|409/i.test(String(e?.message))) throw new Error("Too many codes tried on this device. Wait 10 minutes, or ask for the event link.");
throw new Error(explain(err));
}
}
const found = (await get(`codes/${code}`)) as { event: string } | null;
if (!found?.event) throw new Error("No event has that code. Check the numbers and try again.");
return found.event;
}
export function CodeJoin({ code }: { code: string }) {
const [error, setError] = useState("");
useEffect(() => {
let cancelled = false;
findEvent(code).then(
(eventId) => {
if (cancelled) return;
// Replace the code in history, so Back does not look the code up again.
history.replaceState(null, "", `/e/${eventId}`);
window.dispatchEvent(new PopStateEvent("popstate"));
},
(err) => { if (!cancelled) setError(err instanceof Error ? err.message : explain(err)); },
);
return () => { cancelled = true; };
}, [code]);
if (!error) return <Loading text="Finding the event..." />;
return <Stop title="We could not find that event." text={error} action={["Try another code", "/#join"]} />;
}
Change history
Point OpenApps links to openapps.free
Bind agent address in policy constants
Use OpenApps service URLs and add contribution strip
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync
Bounded source sync