diff --git a/js/web/src/lib/store/slices/blueskySlice.ts b/js/web/src/lib/store/slices/blueskySlice.ts index 2acdf5e9..95dcb09d 100644 --- a/js/web/src/lib/store/slices/blueskySlice.ts +++ b/js/web/src/lib/store/slices/blueskySlice.ts @@ -113,7 +113,10 @@ export interface BlueskySlice { createStreamKeyRecord: (store: boolean) => Promise; clearStreamKeyRecord: () => void; getStreamKeyRecords: () => Promise; - deleteStreamKeyRecord: (rkey: string, batchRkeys?: string[]) => Promise; + deleteStreamKeyRecord: ( + rkey?: string, + batchRkeys?: string[], + ) => Promise; setPDS: (pds: string) => Promise; createLivestreamRecord: ( title: string, @@ -576,7 +579,12 @@ export const createBlueskySlice: StateCreator< }); } }, - deleteStreamKeyRecord: async (rkey: string, batchRkeys?: string[]) => { + deleteStreamKeyRecord: async (rkey?: string, batchRkeys?: string[]) => { + // If batchRkeys is provided, it takes precedence over rkey and deletes all keys in the array. + // If not, it deletes the single rkey. If neither is provided, it throws an error. + if (!rkey && !batchRkeys) { + throw new Error("No rkey(s) provided for deletion"); + } set({ isDeletingKey: true }); const state = get() as BlueskySlice; if (!state.pdsAgent) { @@ -596,17 +604,18 @@ export const createBlueskySlice: StateCreator< await state.pdsAgent.com.atproto.repo.deleteRecord({ repo: did, collection: "place.stream.key", - rkey: keysToDelete[0], + rkey: keysToDelete[0] as string, }); } else { // Batch delete via applyWrites await state.pdsAgent.com.atproto.repo.applyWrites({ repo: did, + // TODO: type this properly writes: keysToDelete.map((k) => ({ $type: "com.atproto.repo.applyWrites#delete" as const, collection: "place.stream.key", rkey: k, - })), + })) as any, }); } diff --git a/js/web/src/routes/dashboard/stream/index.tsx b/js/web/src/routes/dashboard/stream/index.tsx index 79983dab..82c6b5fd 100644 --- a/js/web/src/routes/dashboard/stream/index.tsx +++ b/js/web/src/routes/dashboard/stream/index.tsx @@ -11,23 +11,24 @@ import { DialogTitle, } from "@/components/ui/dialog"; import { Input } from "@/components/ui/input"; +import { Tabs, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; import { CUSTOM_LICENSE, LICENSE_OPTIONS } from "@/lib/content-licenses"; import { CONTENT_WARNINGS } from "@/lib/content-warnings"; import { useSession } from "@/lib/session"; import { useStore } from "@/lib/store"; +import { useKeyRecords } from "@/lib/store/hooks"; import { cn } from "@/lib/utils"; -import { createFileRoute, Link } from "@tanstack/react-router"; +import { createFileRoute } from "@tanstack/react-router"; import { - ChevronRight, Clipboard, ExternalLink, - Eye, - EyeClosed, Key, Loader2, Shield, Tags, + Trash2, + X, } from "lucide-react"; import { useCallback, useEffect, useMemo, useState } from "react"; import { useTranslation } from "react-i18next"; @@ -94,7 +95,7 @@ export function StreamSettingsPage() { {/* Desktop: sidebar */} -
+
{/* Desktop: sidebar */} -
+