Remove recordings feature, replay sessions directly, bump to 0.6.0
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:
@@ -0,0 +1,94 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import {
|
||||
Dialog,
|
||||
DialogContent,
|
||||
DialogDescription,
|
||||
DialogFooter,
|
||||
DialogHeader,
|
||||
DialogTitle,
|
||||
} from "@/components/ui/dialog";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "@/components/ui/select";
|
||||
import { autoMapDeviceSlots } from "@/lib/buttplug/device-remap";
|
||||
import type { ReplayDeviceSlot, ConnectedDeviceInfo } from "@/lib/buttplug/types";
|
||||
|
||||
interface DeviceRemapDialogProps {
|
||||
open: boolean;
|
||||
deviceSlots: ReplayDeviceSlot[];
|
||||
connectedDevices: ConnectedDeviceInfo[];
|
||||
onCancel: () => void;
|
||||
onConfirm: (mapping: Map<number, number>) => void;
|
||||
}
|
||||
|
||||
export function DeviceRemapDialog({
|
||||
open,
|
||||
deviceSlots,
|
||||
connectedDevices,
|
||||
onCancel,
|
||||
onConfirm,
|
||||
}: DeviceRemapDialogProps) {
|
||||
const autoMapped = autoMapDeviceSlots(deviceSlots, connectedDevices);
|
||||
const [assignments, setAssignments] = useState<Record<number, number | null>>(
|
||||
Object.fromEntries(deviceSlots.map((slot, i) => [slot.sourceSessionDeviceId, autoMapped[i]?.matchedDeviceIndex ?? null])),
|
||||
);
|
||||
|
||||
const allAssigned = deviceSlots.every((s) => assignments[s.sourceSessionDeviceId] !== null);
|
||||
|
||||
function handleConfirm() {
|
||||
const mapping = new Map<number, number>();
|
||||
for (const slot of deviceSlots) {
|
||||
const deviceIndex = assignments[slot.sourceSessionDeviceId];
|
||||
if (deviceIndex !== null && deviceIndex !== undefined) mapping.set(slot.sourceSessionDeviceId, deviceIndex);
|
||||
}
|
||||
onConfirm(mapping);
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog open={open} onOpenChange={(o) => !o && onCancel()}>
|
||||
<DialogContent>
|
||||
<DialogHeader>
|
||||
<DialogTitle>Match devices for replay</DialogTitle>
|
||||
<DialogDescription>
|
||||
Web Bluetooth doesn't expose a stable device id across sessions, so match each recorded
|
||||
device to a currently-connected one. Two identically-named devices can't be told apart
|
||||
automatically.
|
||||
</DialogDescription>
|
||||
</DialogHeader>
|
||||
<div className="flex flex-col gap-3">
|
||||
{deviceSlots.map((slot) => (
|
||||
<div key={slot.sourceSessionDeviceId} className="flex items-center justify-between gap-3">
|
||||
<span className="text-sm font-medium">{slot.slotLabel}</span>
|
||||
<Select
|
||||
value={assignments[slot.sourceSessionDeviceId]?.toString() ?? undefined}
|
||||
onValueChange={(v) =>
|
||||
setAssignments((prev) => ({ ...prev, [slot.sourceSessionDeviceId]: Number(v) }))
|
||||
}
|
||||
>
|
||||
<SelectTrigger size="sm" className="w-48">
|
||||
<SelectValue placeholder="Unmatched" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
{connectedDevices.map((d) => (
|
||||
<SelectItem key={d.index} value={d.index.toString()}>
|
||||
{d.displayName ?? d.name}
|
||||
</SelectItem>
|
||||
))}
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<DialogFooter>
|
||||
<Button variant="ghost" onClick={onCancel}>
|
||||
Cancel
|
||||
</Button>
|
||||
<Button onClick={handleConfirm} disabled={!allAssigned}>
|
||||
Start replay
|
||||
</Button>
|
||||
</DialogFooter>
|
||||
</DialogContent>
|
||||
</Dialog>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user