Remove recordings feature, replay sessions directly, bump to 0.6.0
CI / Build and push image (push) Successful in 1m41s
CI / Static checks (push) Successful in 2m12s

Recordings were just a thin named pointer over an already-captured
session's events, so the whole separate feature (recordings table, API
routes, pages, UI) is gone: any completed session can now be named and
replayed directly. Replaying no longer creates a session or duplicates
events of its own - it just bumps the source session's playCount/lastPlayedAt.

Also renames play_sessions/playSession(s) to sessions/session(s) throughout
the schema, queries, API routes, and UI for consistency, and updates the
README to match the new flow.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
2026-08-27 21:38:51 +02:00
co-authored by Claude Sonnet 5
parent 2a3c4ff1f2
commit 401b9b5033
46 changed files with 1710 additions and 1018 deletions
+7 -8
View File
@@ -20,10 +20,10 @@ import type { ConnectedDeviceInfo } from "@/lib/buttplug/types";
import { DeviceScanPanel } from "./DeviceScanPanel";
import { DeviceCard } from "./DeviceCard";
import { RecordControls } from "./RecordControls";
import { SaveRecordingDialog } from "@/components/recordings/SaveRecordingDialog";
import { NameSessionDialog } from "./NameSessionDialog";
import { Card, CardContent } from "@/components/ui/card";
interface ActivePlaySession {
interface ActiveSession {
id: number;
startedAt: number;
sessionDeviceIdByDeviceIndex: Map<number, number>;
@@ -49,7 +49,7 @@ export function ButtplugConsole() {
const setRecording = useButtplugStore((s) => s.setRecording);
const storeError = useButtplugStore((s) => s.error);
const [activeSession, setActiveSession] = useState<ActivePlaySession | null>(null);
const [activeSession, setActiveSession] = useState<ActiveSession | null>(null);
const [elapsedMs, setElapsedMs] = useState(0);
const [sessionBusy, setSessionBusy] = useState(false);
const [savePromptSessionId, setSavePromptSessionId] = useState<number | null>(null);
@@ -105,14 +105,13 @@ export function ButtplugConsole() {
try {
const deviceList = Object.values(devices);
const body = {
kind: "live" as const,
devices: deviceList.map((d) => ({
slotLabel: d.displayName ?? d.name,
bleName: d.name,
capabilities: { outputs: [...new Set(d.actuators.map((a) => a.outputType))], featureCount: d.actuators.length },
})),
};
const res = await fetch("/api/play-sessions", {
const res = await fetch("/api/sessions", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
@@ -151,7 +150,7 @@ export function ButtplugConsole() {
setSessionBusy(true);
eventBuffer.stop();
setRecording(false);
await fetch(`/api/play-sessions/${activeSession.id}`, {
await fetch(`/api/sessions/${activeSession.id}`, {
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ status: "completed" }),
@@ -270,8 +269,8 @@ export function ButtplugConsole() {
</div>
)}
<SaveRecordingDialog
playSessionId={savePromptSessionId}
<NameSessionDialog
sessionId={savePromptSessionId}
onClose={() => setSavePromptSessionId(null)}
onSaved={() => setSavePromptSessionId(null)}
/>