claim controller ui
This commit is contained in:
parent
a7a7eeac0c
commit
ea1f1a3358
3 changed files with 95 additions and 10 deletions
|
|
@ -276,13 +276,29 @@ export const deviceSocketApp = new Elysia().group("/dev-socket", (app) =>
|
|||
export const deviceClaimApp = new Elysia()
|
||||
.use(betterAuthElysia)
|
||||
.group("/devices", (app) =>
|
||||
app.post(
|
||||
"/:deviceId/connect",
|
||||
async ({ user, params }) => {
|
||||
await claimDeviceForUser(params.deviceId, user.id);
|
||||
sendDeviceEvent(params.deviceId, { type: "device_connected" });
|
||||
return { ok: true, deviceId: params.deviceId, userId: user.id };
|
||||
},
|
||||
{ auth: true },
|
||||
),
|
||||
app
|
||||
.get(
|
||||
"/mine",
|
||||
async ({ user }) => {
|
||||
const devices = await db
|
||||
.select({
|
||||
id: deviceConnection.id,
|
||||
lastSeen: deviceConnection.lastSeen,
|
||||
})
|
||||
.from(deviceConnection)
|
||||
.where(eq(deviceConnection.userId, user.id));
|
||||
|
||||
return { devices };
|
||||
},
|
||||
{ auth: true },
|
||||
)
|
||||
.post(
|
||||
"/:deviceId/connect",
|
||||
async ({ user, params }) => {
|
||||
await claimDeviceForUser(params.deviceId, user.id);
|
||||
sendDeviceEvent(params.deviceId, { type: "device_connected" });
|
||||
return { ok: true, deviceId: params.deviceId, userId: user.id };
|
||||
},
|
||||
{ auth: true },
|
||||
),
|
||||
);
|
||||
|
|
|
|||
67
web/src/components/device-choice.tsx
Normal file
67
web/src/components/device-choice.tsx
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
import { useQuery } from "@tanstack/react-query";
|
||||
import { useState } from "react";
|
||||
import { Button } from "#/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardContent,
|
||||
CardDescription,
|
||||
CardHeader,
|
||||
CardTitle,
|
||||
} from "#/components/ui/card";
|
||||
import { useParty } from "#/hooks/use-party";
|
||||
import { useUser } from "#/hooks/user";
|
||||
import { client } from "#/lib/eden";
|
||||
|
||||
const CONTROLLER_DEVICE_ID = "esp32-1";
|
||||
|
||||
export function DeviceChoice() {
|
||||
const { user } = useUser();
|
||||
const { party } = useParty();
|
||||
const [dismissed, setDismissed] = useState(false);
|
||||
const [isClaiming, setIsClaiming] = useState(false);
|
||||
|
||||
const { data, isLoading } = useQuery({
|
||||
queryKey: ["devices", "mine"],
|
||||
queryFn: () => client.api.devices.mine.get(),
|
||||
enabled: Boolean(user && !party && !dismissed),
|
||||
});
|
||||
|
||||
if (!user || party || dismissed || isLoading) return null;
|
||||
|
||||
const devices = data?.data?.devices ?? [];
|
||||
if (devices.length > 0) return null;
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<CardHeader>
|
||||
<CardTitle>Play with the controller?</CardTitle>
|
||||
<CardDescription>
|
||||
Claim {CONTROLLER_DEVICE_ID} for this session, or continue on this
|
||||
device only.
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
<CardContent className="grid gap-3 sm:grid-cols-2">
|
||||
<Button
|
||||
size="lg"
|
||||
disabled={isClaiming}
|
||||
onClick={async () => {
|
||||
setIsClaiming(true);
|
||||
try {
|
||||
await client.api
|
||||
.devices({ deviceId: CONTROLLER_DEVICE_ID })
|
||||
.connect.post();
|
||||
setDismissed(true);
|
||||
} finally {
|
||||
setIsClaiming(false);
|
||||
}
|
||||
}}
|
||||
>
|
||||
Play on controller
|
||||
</Button>
|
||||
<Button size="lg" variant="outline" onClick={() => setDismissed(true)}>
|
||||
Play without controller
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
);
|
||||
}
|
||||
|
|
@ -1,4 +1,5 @@
|
|||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import { DeviceChoice } from "#/components/device-choice";
|
||||
import { PartyView } from "#/components/party/party-view";
|
||||
import { PartyQr } from "#/components/party-qr";
|
||||
import { StartParty } from "#/components/start-party";
|
||||
|
|
@ -16,8 +17,9 @@ function App() {
|
|||
return (
|
||||
<MainContent>
|
||||
<UserInfo />
|
||||
<DeviceChoice />
|
||||
{!user?.lastSyncAt && <SyncButton />}
|
||||
{user && party?.data?.status != "running" && <PartyQr />}
|
||||
{user && party?.data?.status !== "running" && <PartyQr />}
|
||||
{party && !party.data && members.length > 1 && <StartParty />}
|
||||
{party?.data && <PartyView />}
|
||||
</MainContent>
|
||||
|
|
|
|||
Loading…
Reference in a new issue