Something went wrong. Try again.
This repository has no description
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282// Per-livestream content metadata (content warnings, distribution// policy, content rights). Ported from// js/app/store/slices/contentMetadataSlice.ts. The slice reads PDS// agents and the active session from the bluesky slice via get().// `resolveDIDDocument` / `getPDSServiceEndpoint` are imported from// the web's lib/did helper (a copy of @streamplace/components/utils/did// because that package is React-Native-coupled).import { StateCreator } from "zustand";import { getPDSServiceEndpoint, resolveDIDDocument } from "../../did";import { AppStore } from "../index";
export interface ContentMetadataSlice { creating: boolean; updating: boolean; error: string | null; lastCreatedRecord: any | null; // actions createContentMetadata: (params: { contentWarnings?: string[]; distributionPolicy?: { deleteAfter?: number; allowedBroadcasters?: string[]; }; contentRights?: { creator?: string; copyrightNotice?: string; copyrightYear?: number; license?: string; creditLine?: string; }; }) => Promise<void>; updateContentMetadata: (params: { rkey?: string; livestreamRef?: { uri: string; cid: string }; contentWarnings?: string[]; distributionPolicy?: { deleteAfter?: number; allowedBroadcasters?: string[]; }; contentRights?: { creator?: string; copyrightNotice?: string; copyrightYear?: number; license?: string; creditLine?: string; }; }) => Promise<void>; getContentMetadata: (params?: { userDid?: string; rkey?: string; }) => Promise<void>; clearError: () => void;}
export const createContentMetadataSlice: StateCreator< AppStore, [], [], ContentMetadataSlice> = (set, get) => ({ creating: false, updating: false, error: null, lastCreatedRecord: null,
createContentMetadata: async ({ contentWarnings = [], distributionPolicy = { deleteAfter: undefined }, contentRights = {}, }) => { set({ creating: true, error: null }); try { const { pdsAgent, oauthSession } = get(); if (!pdsAgent) { throw new Error("No agent"); }
const did = oauthSession?.did; if (!did) { throw new Error("No DID"); }
const metadataRecord = { $type: "place.stream.metadata.configuration", createdAt: new Date().toISOString(), ...(contentWarnings.length > 0 && { contentWarnings: { warnings: contentWarnings }, }), ...((distributionPolicy.deleteAfter !== undefined || (distributionPolicy.allowedBroadcasters && distributionPolicy.allowedBroadcasters.length > 0)) && { distributionPolicy: { ...(distributionPolicy.deleteAfter !== undefined && { deleteAfter: distributionPolicy.deleteAfter, }), ...(distributionPolicy.allowedBroadcasters && { allowedBroadcasters: distributionPolicy.allowedBroadcasters, }), }, }), ...(contentRights && Object.keys(contentRights).length > 0 && { contentRights, }), };
const result = await pdsAgent.com.atproto.repo.createRecord({ repo: did, collection: "place.stream.metadata.configuration", rkey: "self", record: metadataRecord, });
const rkey = result.data.uri.split("/").pop();
set({ creating: false, error: null, lastCreatedRecord: { record: metadataRecord, uri: result.data.uri, cid: result.data.cid, rkey, }, }); } catch (error: any) { set({ creating: false, error: error?.message ?? "Failed to create content metadata", }); throw error; } },
updateContentMetadata: async ({ rkey, livestreamRef, contentWarnings = [], distributionPolicy = { deleteAfter: undefined }, contentRights = {}, }) => { set({ updating: true, error: null }); try { const { pdsAgent, oauthSession } = get(); if (!pdsAgent) { throw new Error("No agent"); }
const did = oauthSession?.did; if (!did) { throw new Error("No DID"); }
const metadataRecord = { $type: "place.stream.metadata.configuration", ...(livestreamRef && { livestreamRef }), createdAt: new Date().toISOString(), ...(contentWarnings.length > 0 && { contentWarnings: { warnings: contentWarnings }, }), ...((distributionPolicy.deleteAfter !== undefined || (distributionPolicy.allowedBroadcasters && distributionPolicy.allowedBroadcasters.length > 0)) && { distributionPolicy: { ...(distributionPolicy.deleteAfter !== undefined && { deleteAfter: distributionPolicy.deleteAfter, }), ...(distributionPolicy.allowedBroadcasters && { allowedBroadcasters: distributionPolicy.allowedBroadcasters, }), }, }), ...(contentRights && Object.keys(contentRights).length > 0 && { contentRights, }), };
const result = await pdsAgent.com.atproto.repo.putRecord({ repo: did, collection: "place.stream.metadata.configuration", rkey: rkey || "self", record: metadataRecord, });
set({ updating: false, error: null, lastCreatedRecord: { record: metadataRecord, uri: `at://${did}/place.stream.metadata.configuration/${ rkey || "self" }`, cid: result.data.cid, }, }); } catch (error: any) { set({ updating: false, error: error?.message ?? "Failed to update content metadata", }); throw error; } },
getContentMetadata: async ({ userDid, rkey = "self" } = {}) => { set({ error: null }); try { const { pdsAgent, oauthSession } = get(); if (!pdsAgent) { throw new Error("No agent"); }
const targetDid = userDid || oauthSession?.did; if (!targetDid) { throw new Error("No DID provided or user not authenticated"); }
try { let targetPDS: string | null = null; try { const didDoc = await resolveDIDDocument(targetDid); targetPDS = getPDSServiceEndpoint(didDoc); } catch { // best-effort: fall through to default agent }
let agent = pdsAgent; if (targetPDS && targetPDS !== (pdsAgent as any)?.host) { const { StreamplaceAgent } = await import("streamplace"); agent = new StreamplaceAgent(targetPDS) as any; }
const result = await agent.com.atproto.repo.getRecord({ repo: targetDid, collection: "place.stream.metadata.configuration", rkey, });
if (!result.success) { throw new Error("Failed to get content metadata record"); }
set({ error: null, lastCreatedRecord: { userDid: targetDid, record: result.data.value, uri: result.data.uri, cid: result.data.cid, }, }); } catch (error: any) { if ( error.message?.includes("not found") || error.message?.includes("RecordNotFound") ) { set({ error: null, lastCreatedRecord: { userDid: targetDid, record: null, uri: null, cid: null, }, }); return; } throw error; } } catch (error: any) { set({ error: error?.message ?? "Failed to get content metadata", }); } },
clearError: () => { set({ error: null }); },});