CI / test (push) Successful in 1m5s
Rooms made on the website (hosted_room, migration 0005), the REST routes in docs/hosted-rooms.md, and the realtime room.* protocol: joining with the capacity, adult and linked-account rules, seats, numbered messages with forged senders dropped and a rate limit, closing. The Rooms page lists them, with a form to make one and the owner's edit and close. Co-Authored-By: Claude Opus 5.5 <[email protected]>
57 lines
1.8 KiB
TypeScript
57 lines
1.8 KiB
TypeScript
"use server";
|
|
import { revalidatePath } from "next/cache";
|
|
import { redirect } from "next/navigation";
|
|
import { api, unwrap } from "@/lib/api";
|
|
import { attempt, field, type ActionState } from "@/lib/actions";
|
|
|
|
const rating = (form: FormData) => (field(form, "rating") === "adult" ? ("adult" as const) : ("general" as const));
|
|
|
|
/** Makes a hosted room, then goes back to the list. */
|
|
export async function createRoom(_: ActionState, form: FormData): Promise<ActionState> {
|
|
const state = await attempt(async () => {
|
|
unwrap(
|
|
await api["hosted-rooms"].post({
|
|
name: field(form, "name"),
|
|
description: field(form, "description"),
|
|
roomPid: Number(field(form, "roomPid")),
|
|
rating: rating(form),
|
|
maxUsers: Number(field(form, "maxUsers")),
|
|
imvuId: Number(field(form, "imvuId")),
|
|
}),
|
|
);
|
|
revalidatePath("/rooms");
|
|
});
|
|
if (state?.error) return state;
|
|
redirect("/rooms");
|
|
}
|
|
|
|
/** The owner's changes to a room. */
|
|
export async function saveRoom(_: ActionState, form: FormData): Promise<ActionState> {
|
|
const n = field(form, "n");
|
|
const state = await attempt(async () => {
|
|
unwrap(
|
|
await api["hosted-rooms"]({ n }).patch({
|
|
name: field(form, "name"),
|
|
description: field(form, "description"),
|
|
roomPid: Number(field(form, "roomPid")),
|
|
rating: rating(form),
|
|
maxUsers: Number(field(form, "maxUsers")),
|
|
}),
|
|
);
|
|
revalidatePath("/rooms");
|
|
});
|
|
if (state?.error) return state;
|
|
redirect("/rooms");
|
|
}
|
|
|
|
/** Closes a room: everyone in it is sent out. */
|
|
export async function closeRoom(_: ActionState, form: FormData): Promise<ActionState> {
|
|
const n = field(form, "n");
|
|
const state = await attempt(async () => {
|
|
unwrap(await api["hosted-rooms"]({ n }).delete());
|
|
revalidatePath("/rooms");
|
|
});
|
|
if (state?.error) return state;
|
|
redirect("/rooms");
|
|
}
|