CI / test (push) Successful in 1m10s
Moderators (up to 20 IMVU accounts, set by ID or name) and the owner account boot and ban over realtime (room.boot); bans are listed and lifted over REST. Private rooms are unlisted and joined by the owner, moderators and holders of an accepted invite (room.invite / room.invited / room.invite_reply / room.invite_answer). Room images (PNG/JPEG by magic bytes, up to 512 KB) are stored in the database and served with cache headers. Per-person favorites, ratings and recent rooms. room.watch pushes room.occupancy; participants carry their IMVU name, and GET .../participants lists them. Contract in docs/hosted-rooms.md, "Phase 2". Co-Authored-By: Claude Opus 5.5 <[email protected]>
29 lines
1.2 KiB
TypeScript
29 lines
1.2 KiB
TypeScript
"use client";
|
|
// A hosted room card's favorite star and rating buttons.
|
|
import { Star } from "lucide-react";
|
|
import { ActionForm, SubmitButton } from "@/components/forms";
|
|
import { cn } from "@/lib/utils";
|
|
import { rateRoom, setFavorite } from "./actions";
|
|
|
|
export function RoomActions({ n, favorite, canRate }: { n: number; favorite: boolean; canRate: boolean }) {
|
|
return (
|
|
<div className="flex flex-wrap items-center gap-3">
|
|
<ActionForm action={setFavorite} fields={{ n, favorite: favorite ? "0" : "1" }} className="space-y-0">
|
|
<SubmitButton variant="ghost" size="icon" aria-label={favorite ? "Unstar" : "Star"} title={favorite ? "Unstar" : "Star"}>
|
|
<Star className={cn("size-4", favorite && "fill-current text-amber-500")} />
|
|
</SubmitButton>
|
|
</ActionForm>
|
|
{canRate && (
|
|
<ActionForm action={rateRoom} fields={{ n }} className="flex items-center gap-0.5 space-y-0">
|
|
<span className="mr-1 text-xs text-muted-foreground">Rate</span>
|
|
{[1, 2, 3, 4, 5].map((k) => (
|
|
<SubmitButton key={k} name="score" value={String(k)} variant="ghost" size="xs" aria-label={`${k} of 5`}>
|
|
{k}
|
|
</SubmitButton>
|
|
))}
|
|
</ActionForm>
|
|
)}
|
|
</div>
|
|
);
|
|
}
|