a tool for shared writing and social publishing
at debug/datetime 235 lines 6.4 kB view raw
1"use server"; 2import { TID } from "@atproto/common"; 3import { 4 AtpBaseClient, 5 PubLeafletPublication, 6 PubLeafletThemeColor, 7} from "lexicons/api"; 8import { createOauthClient } from "src/atproto-oauth"; 9import { getIdentityData } from "actions/getIdentityData"; 10import { supabaseServerClient } from "supabase/serverClient"; 11import { Json } from "supabase/database.types"; 12import { AtUri } from "@atproto/syntax"; 13import { $Typed } from "@atproto/api"; 14 15export async function updatePublication({ 16 uri, 17 name, 18 description, 19 iconFile, 20 preferences, 21}: { 22 uri: string; 23 name: string; 24 description: string; 25 iconFile: File | null; 26 preferences?: Omit<PubLeafletPublication.Preferences, "$type">; 27}) { 28 const oauthClient = await createOauthClient(); 29 let identity = await getIdentityData(); 30 if (!identity || !identity.atp_did) return; 31 32 let credentialSession = await oauthClient.restore(identity.atp_did); 33 let agent = new AtpBaseClient( 34 credentialSession.fetchHandler.bind(credentialSession), 35 ); 36 let { data: existingPub } = await supabaseServerClient 37 .from("publications") 38 .select("*") 39 .eq("uri", uri) 40 .single(); 41 if (!existingPub || existingPub.identity_did !== identity.atp_did) return; 42 let aturi = new AtUri(existingPub.uri); 43 44 let record: PubLeafletPublication.Record = { 45 $type: "pub.leaflet.publication", 46 ...(existingPub.record as object), 47 name, 48 }; 49 if (preferences) { 50 record.preferences = preferences; 51 } 52 53 if (description !== undefined) { 54 record.description = description; 55 } 56 57 // Upload the icon if provided How do I tell if there isn't a new one? 58 if (iconFile && iconFile.size > 0) { 59 const buffer = await iconFile.arrayBuffer(); 60 const uploadResult = await agent.com.atproto.repo.uploadBlob( 61 new Uint8Array(buffer), 62 { encoding: iconFile.type }, 63 ); 64 65 if (uploadResult.data.blob) { 66 record.icon = uploadResult.data.blob; 67 } 68 } 69 70 let result = await agent.com.atproto.repo.putRecord({ 71 repo: credentialSession.did!, 72 rkey: aturi.rkey, 73 record, 74 collection: record.$type, 75 validate: false, 76 }); 77 78 //optimistically write to our db! 79 let { data: publication, error } = await supabaseServerClient 80 .from("publications") 81 .update({ 82 name: record.name, 83 record: record as Json, 84 }) 85 .eq("uri", uri) 86 .select() 87 .single(); 88 return { success: true, publication }; 89} 90 91export async function updatePublicationBasePath({ 92 uri, 93 base_path, 94}: { 95 uri: string; 96 base_path: string; 97}) { 98 const oauthClient = await createOauthClient(); 99 let identity = await getIdentityData(); 100 if (!identity || !identity.atp_did) return; 101 102 let credentialSession = await oauthClient.restore(identity.atp_did); 103 let agent = new AtpBaseClient( 104 credentialSession.fetchHandler.bind(credentialSession), 105 ); 106 let { data: existingPub } = await supabaseServerClient 107 .from("publications") 108 .select("*") 109 .eq("uri", uri) 110 .single(); 111 if (!existingPub || existingPub.identity_did !== identity.atp_did) return; 112 let aturi = new AtUri(existingPub.uri); 113 114 let record: PubLeafletPublication.Record = { 115 ...(existingPub.record as PubLeafletPublication.Record), 116 base_path, 117 }; 118 119 let result = await agent.com.atproto.repo.putRecord({ 120 repo: credentialSession.did!, 121 rkey: aturi.rkey, 122 record, 123 collection: record.$type, 124 validate: false, 125 }); 126 127 //optimistically write to our db! 128 let { data: publication, error } = await supabaseServerClient 129 .from("publications") 130 .update({ 131 name: record.name, 132 record: record as Json, 133 }) 134 .eq("uri", uri) 135 .select() 136 .single(); 137 return { success: true, publication }; 138} 139 140type Color = 141 | $Typed<PubLeafletThemeColor.Rgb, "pub.leaflet.theme.color#rgb"> 142 | $Typed<PubLeafletThemeColor.Rgba, "pub.leaflet.theme.color#rgba">; 143export async function updatePublicationTheme({ 144 uri, 145 theme, 146}: { 147 uri: string; 148 theme: { 149 backgroundImage?: File | null; 150 backgroundRepeat?: number | null; 151 backgroundColor: Color; 152 primary: Color; 153 pageBackground: Color; 154 showPageBackground: boolean; 155 accentBackground: Color; 156 accentText: Color; 157 }; 158}) { 159 const oauthClient = await createOauthClient(); 160 let identity = await getIdentityData(); 161 if (!identity || !identity.atp_did) return; 162 163 let credentialSession = await oauthClient.restore(identity.atp_did); 164 let agent = new AtpBaseClient( 165 credentialSession.fetchHandler.bind(credentialSession), 166 ); 167 let { data: existingPub } = await supabaseServerClient 168 .from("publications") 169 .select("*") 170 .eq("uri", uri) 171 .single(); 172 if (!existingPub || existingPub.identity_did !== identity.atp_did) return; 173 let aturi = new AtUri(existingPub.uri); 174 175 let oldRecord = existingPub.record as PubLeafletPublication.Record; 176 let record: PubLeafletPublication.Record = { 177 ...oldRecord, 178 $type: "pub.leaflet.publication", 179 theme: { 180 backgroundImage: theme.backgroundImage 181 ? { 182 $type: "pub.leaflet.theme.backgroundImage", 183 image: ( 184 await agent.com.atproto.repo.uploadBlob( 185 new Uint8Array(await theme.backgroundImage.arrayBuffer()), 186 { encoding: theme.backgroundImage.type }, 187 ) 188 )?.data.blob, 189 width: theme.backgroundRepeat || undefined, 190 repeat: !!theme.backgroundRepeat, 191 } 192 : theme.backgroundImage === null 193 ? undefined 194 : oldRecord.theme?.backgroundImage, 195 backgroundColor: theme.backgroundColor 196 ? { 197 ...theme.backgroundColor, 198 } 199 : undefined, 200 primary: { 201 ...theme.primary, 202 }, 203 pageBackground: { 204 ...theme.pageBackground, 205 }, 206 showPageBackground: theme.showPageBackground, 207 accentBackground: { 208 ...theme.accentBackground, 209 }, 210 accentText: { 211 ...theme.accentText, 212 }, 213 }, 214 }; 215 216 let result = await agent.com.atproto.repo.putRecord({ 217 repo: credentialSession.did!, 218 rkey: aturi.rkey, 219 record, 220 collection: record.$type, 221 validate: false, 222 }); 223 224 //optimistically write to our db! 225 let { data: publication, error } = await supabaseServerClient 226 .from("publications") 227 .update({ 228 name: record.name, 229 record: record as Json, 230 }) 231 .eq("uri", uri) 232 .select() 233 .single(); 234 return { success: true, publication }; 235}