Something went wrong. Try again.
leaflet fork for copy edit / bug fixes forked from leaflet.pub/leaflet
Something went wrong. Try again.
TypeScript
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174"use server";
import { AtpBaseClient, SiteStandardGraphRecommend } from "lexicons/api";import { getAuthIdentity } from "src/auth";import { restoreOAuthSession, OAuthSessionError } from "src/atproto-oauth";import { TID } from "@atproto/common";import { AtUri, Un$Typed } from "@atproto/api";import { supabaseServerClient } from "supabase/serverClient";import { Json } from "supabase/database.types";import { v7 } from "uuid";import { Notification, pingIdentityToUpdateNotification,} from "src/notifications";
type RecommendResult = | { success: true; uri: string } | { success: false; error: OAuthSessionError | { type: string; message: string }; };
export async function recommendAction(args: { document: string;}): Promise<RecommendResult> { let identity = await getAuthIdentity(); if (!identity || !identity.atp_did) { return { success: false, error: { type: "oauth_session_expired", message: "Not authenticated", did: "", }, }; }
const sessionResult = await restoreOAuthSession(identity.atp_did); if (!sessionResult.ok) { return { success: false, error: sessionResult.error }; } let credentialSession = sessionResult.value; let agent = new AtpBaseClient( credentialSession.fetchHandler.bind(credentialSession), );
// Recommends are unique per (recommender, document); reuse the existing one // so replays (e.g. the after-sign-in action when the user had already // recommended before logging out) don't violate that constraint. const { data: existingRecommend } = await supabaseServerClient .from("recommends_on_documents") .select("uri") .eq("document", args.document) .eq("recommender_did", credentialSession.did!) .maybeSingle(); if (existingRecommend) { return { success: true, uri: existingRecommend.uri }; }
let record: Un$Typed<SiteStandardGraphRecommend.Record> = { document: args.document, createdAt: new Date().toISOString(), };
let rkey = TID.nextStr(); let uri = AtUri.make( credentialSession.did!, "site.standard.graph.recommend", rkey, );
await agent.site.standard.graph.recommend.create( { rkey, repo: credentialSession.did! }, record, );
let res = await supabaseServerClient.from("recommends_on_documents").upsert({ uri: uri.toString(), document: args.document, recommender_did: credentialSession.did!, record: { $type: "site.standard.graph.recommend", ...record, } as unknown as Json, }); console.log(res);
// Notify the document owner let documentOwner = new AtUri(args.document).host; if (documentOwner !== credentialSession.did) { let notification: Notification = { id: v7(), recipient: documentOwner, data: { type: "recommend", document_uri: args.document, recommend_uri: uri.toString(), }, }; await supabaseServerClient.from("notifications").insert(notification); await pingIdentityToUpdateNotification(documentOwner); }
return { success: true, uri: uri.toString(), };}
export async function unrecommendAction(args: { document: string;}): Promise<RecommendResult> { let identity = await getAuthIdentity(); if (!identity || !identity.atp_did) { return { success: false, error: { type: "oauth_session_expired", message: "Not authenticated", did: "", }, }; }
const sessionResult = await restoreOAuthSession(identity.atp_did); if (!sessionResult.ok) { return { success: false, error: sessionResult.error }; } let credentialSession = sessionResult.value; let agent = new AtpBaseClient( credentialSession.fetchHandler.bind(credentialSession), );
// Find the existing recommend record const { data: existingRecommend } = await supabaseServerClient .from("recommends_on_documents") .select("uri") .eq("document", args.document) .eq("recommender_did", credentialSession.did!) .single();
if (!existingRecommend) { return { success: false, error: { type: "not_found", message: "Recommend not found", }, }; }
let uri = new AtUri(existingRecommend.uri);
// Delete from both collections (old and new schema) - one or both may exist await Promise.all([ agent.site.standard.graph.recommend .delete({ rkey: uri.rkey, repo: credentialSession.did! }) .catch(() => {}), agent.pub.leaflet.interactions.recommend .delete({ rkey: uri.rkey, repo: credentialSession.did! }) .catch(() => {}), ]);
await supabaseServerClient .from("recommends_on_documents") .delete() .eq("uri", existingRecommend.uri);
return { success: true, uri: existingRecommend.uri, };}