diff --git a/web/messages/de.json b/web/messages/de.json index b320022..cfcde5a 100644 --- a/web/messages/de.json +++ b/web/messages/de.json @@ -48,6 +48,17 @@ "pairing_submit": "PIN bestätigen", "pairing_success": "Erfolgreich gekoppelt.", "pairing_failed": "Kopplung fehlgeschlagen — PIN prüfen und erneut versuchen.", + "pairing_native_title": "Gerät koppeln", + "pairing_native_desc": "Zeige hier eine Einmal-PIN an und gib sie in deiner punktfunk-App ein, um dieses Gerät zu koppeln.", + "pairing_native_disabled": "Der native Host läuft nicht. Starte ihn mit `serve --native`, um punktfunk-Geräte zu koppeln.", + "pairing_native_arm": "Gerät koppeln", + "pairing_native_enter": "Gib diese PIN auf deinem Gerät ein:", + "pairing_native_expires": "Läuft ab in", + "pairing_native_cancel": "Abbrechen", + "pairing_native_devices": "Gekoppelte Geräte", + "pairing_native_empty": "Noch keine Geräte gekoppelt.", + "pairing_native_unpair_confirm": "Dieses Gerät entkoppeln? Es muss sich erneut koppeln, um zu verbinden.", + "pairing_moonlight_title": "Moonlight-Kopplung (GameStream)", "settings_title": "Einstellungen", "settings_token_label": "API-Token", "settings_token_help": "Bearer-Token für die Verwaltungs-API. Bei einem Loopback-Host ohne Token leer lassen.", diff --git a/web/messages/en.json b/web/messages/en.json index 7981445..f81046f 100644 --- a/web/messages/en.json +++ b/web/messages/en.json @@ -48,6 +48,17 @@ "pairing_submit": "Submit PIN", "pairing_success": "Paired successfully.", "pairing_failed": "Pairing failed — check the PIN and try again.", + "pairing_native_title": "Pair a device", + "pairing_native_desc": "Show a one-time PIN here, then enter it in your punktfunk app to pair this device.", + "pairing_native_disabled": "The native host isn't running. Start it with `serve --native` to pair punktfunk devices.", + "pairing_native_arm": "Pair a device", + "pairing_native_enter": "Enter this PIN on your device:", + "pairing_native_expires": "Expires in", + "pairing_native_cancel": "Cancel", + "pairing_native_devices": "Paired devices", + "pairing_native_empty": "No devices paired yet.", + "pairing_native_unpair_confirm": "Unpair this device? It will need to pair again to connect.", + "pairing_moonlight_title": "Moonlight (GameStream) pairing", "settings_title": "Settings", "settings_token_label": "API token", "settings_token_help": "Bearer token for the management API. Leave empty for a loopback host with no token.", diff --git a/web/src/routes/pairing.tsx b/web/src/routes/pairing.tsx index dbbb81c..f8bc694 100644 --- a/web/src/routes/pairing.tsx +++ b/web/src/routes/pairing.tsx @@ -1,12 +1,29 @@ import { useState } from 'react' import { createFileRoute } from '@tanstack/react-router' import { useQueryClient } from '@tanstack/react-query' -import { KeyRound, CheckCircle2 } from 'lucide-react' +import { KeyRound, CheckCircle2, Smartphone, Timer, Trash2 } from 'lucide-react' +import { + useGetNativePairing, + useArmNativePairing, + useDisarmNativePairing, + useListNativeClients, + useUnpairNativeClient, + getGetNativePairingQueryKey, + getListNativeClientsQueryKey, +} from '@/api/gen/native/native' import { useGetPairingStatus, useSubmitPairingPin, getGetPairingStatusQueryKey, } from '@/api/gen/pairing/pairing' +import { + Table, + TableBody, + TableCell, + TableHead, + TableHeader, + TableRow, +} from '@/components/ui/table' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' import { Button } from '@/components/ui/button' import { Input } from '@/components/ui/input' @@ -17,11 +34,157 @@ import { useLocale } from '@/lib/i18n' export const Route = createFileRoute('/pairing')({ component: PairingPage }) +/** Seconds → `m:ss`. */ +function fmtTime(secs: number): string { + const s = Math.max(0, Math.floor(secs)) + return `${Math.floor(s / 60)}:${(s % 60).toString().padStart(2, '0')}` +} + function PairingPage() { useLocale() + return ( +
{m.pairing_native_disabled()}
+ ) : d.armed && d.pin ? ( +{m.pairing_native_enter()}
+
+
{m.pairing_native_desc()}
+ + > + )} +{m.pairing_idle()}
- ) : ( - - )} -{m.pairing_idle()}
+ ) : ( + + )} +