view who was fronting when a record was made

feat: pull fronters from pk system

ptr.pet 5f2414d1 02c8be6f

verified
Changed files
+72 -35
src
entrypoints
lib
+7 -7
src/entrypoints/background.ts
··· 12 12 parseSocialAppPostUrl, 13 13 displayNameCache, 14 14 deleteFronter, 15 + getPkFronters, 15 16 } from "@/lib/utils"; 16 17 import { 17 18 parseCanonicalResourceUri, ··· 81 82 ) => { 82 83 if (!authToken) return; 83 84 const frontersArray = await storage.getItem<string[]>("sync:fronters"); 84 - let members: Parameters<typeof putFronter>["1"] = frontersArray ?? []; 85 + let members: Parameters<typeof putFronter>["1"] = 86 + frontersArray?.map((n) => ({ name: n, uri: undefined })) ?? []; 87 + if (members.length === 0) { 88 + members = await getPkFronters(); 89 + } 85 90 if (members.length === 0) { 86 - const pkFronters = await storage.getItem<string[]>("sync:pk-fronter"); 87 - if (pkFronters) { 88 - members = pkFronters.map((id) => ({ type: "pk", memberId: id })); 89 - } else { 90 - members = await getSpFronters(); 91 - } 91 + members = await getSpFronters(); 92 92 } 93 93 // dont write if no names is specified or no sp/pk fronters are fetched 94 94 if (members.length === 0) return;
+26 -16
src/entrypoints/popup/App.svelte
··· 13 13 let queryError = $state(""); 14 14 let isQuerying = $state(false); 15 15 let fronters = $state<string[]>([]); 16 - let pkFronters = $state<string[]>([]); 16 + let pkSystemId = $state<string>(""); 17 17 let spToken = $state(""); 18 18 let isFromCurrentTab = $state(false); 19 19 ··· 51 51 storage.setItem("sync:fronters", newFronters); 52 52 }; 53 53 54 - const updatePkFronters = (newPkFronters: string[]) => { 55 - pkFronters = newPkFronters; 56 - storage.setItem("sync:pk-fronter", newPkFronters); 54 + const updatePkSystem = (event: any) => { 55 + pkSystemId = (event.target as HTMLInputElement).value; 56 + storage.setItem("sync:pk-system", pkSystemId); 57 57 }; 58 58 59 59 const updateSpToken = (event: any) => { ··· 80 80 fronters = frontersArray; 81 81 } 82 82 83 - const pkFrontersArray = 84 - await storage.getItem<string[]>("sync:pk-fronter"); 85 - if (pkFrontersArray && Array.isArray(pkFrontersArray)) { 86 - pkFronters = pkFrontersArray; 83 + const pkSystem = await storage.getItem<string>("sync:pk-system"); 84 + if (pkSystem) { 85 + pkSystemId = pkSystem; 87 86 } 88 87 89 88 const token = await storage.getItem<string>("sync:sp_token"); ··· 232 231 </span> 233 232 </div> 234 233 </div> 235 - <FronterList 236 - bind:fronters={pkFronters} 237 - onUpdate={updatePkFronters} 238 - label="PK FRONTERS" 239 - placeholder="enter_member_ids" 240 - note="PluralKit member IDs, overrides SP fronters" 241 - fetchNames={true} 242 - /> 234 + <div class="config-card"> 235 + <div class="config-row"> 236 + <span class="config-label">PK SYSTEM</span> 237 + <input 238 + type="password" 239 + placeholder="enter_pk_system_id" 240 + oninput={updatePkSystem} 241 + bind:value={pkSystemId} 242 + class="config-input" 243 + class:has-value={pkSystemId} 244 + /> 245 + </div> 246 + <div class="config-note"> 247 + <span class="note-text"> 248 + when set, pulls fronters from PluralKit (fronter 249 + history must be public) 250 + </span> 251 + </div> 252 + </div> 243 253 <FronterList 244 254 bind:fronters 245 255 onUpdate={updateFronters}
+39 -12
src/lib/utils.ts
··· 54 54 55 55 export type MemberUri = 56 56 | { type: "at"; recordUri: ResourceUri } 57 - | { type: "pk"; memberId: string } 57 + | { type: "pk"; systemId: string; memberId: string } 58 58 | { type: "sp"; systemId: string; memberId: string }; 59 59 60 60 export const parseMemberId = (memberId: GenericUri): MemberUri => { ··· 62 62 switch (uri.protocol) { 63 63 case "pk:": { 64 64 const split = uri.pathname.split("/").slice(1); 65 - return { type: "pk", memberId: split[0] }; 65 + return { type: "pk", systemId: split[0], memberId: split[1] }; 66 66 } 67 67 case "sp:": { 68 68 const split = uri.pathname.split("/").slice(1); ··· 142 142 } 143 143 }; 144 144 145 - export const getFronterNames = async (members: (string | MemberUri)[]) => { 145 + export const getFronterNames = async ( 146 + members: { name?: string; uri?: MemberUri }[], 147 + ) => { 146 148 const promises = await Promise.allSettled( 147 149 members.map(async (m): Promise<Fronter["members"][0] | null> => { 148 - if (typeof m === "string") 149 - return Promise.resolve({ uri: undefined, name: m }); 150 - const name = await fetchMember(m); 151 - return name ? { uri: m, name } : null; 150 + if (!m.uri) return Promise.resolve({ uri: undefined, name: m.name! }); 151 + if (m.name) return Promise.resolve({ uri: m.uri, name: m.name }); 152 + const name = await fetchMember(m.uri); 153 + return name ? { uri: m.uri, name } : null; 152 154 }), 153 155 ); 154 156 return promises ··· 244 246 245 247 export const putFronter = async ( 246 248 subject: FronterSchema["subject"], 247 - members: (string | MemberUri)[], 249 + members: { name?: string; uri?: MemberUri }[], 248 250 authToken: string, 249 251 ): Promise<Result<Fronter, string>> => { 250 252 const parsedRecordUri = parseResourceUri(subject); ··· 315 317 return ok(true); 316 318 }; 317 319 318 - export const getSpFronters = async (): Promise<MemberUri[]> => { 320 + export const getSpFronters = async (): Promise< 321 + Parameters<typeof putFronter>["1"] 322 + > => { 319 323 const spToken = await storage.getItem<string>("sync:sp_token"); 320 324 if (!spToken) return []; 321 325 const resp = await fetch(`https://api.apparyllis.com/v1/fronters`, { ··· 326 330 if (!resp.ok) return []; 327 331 const spFronters = (await resp.json()) as any[]; 328 332 return spFronters.map((fronter) => ({ 329 - type: "sp", 330 - memberId: fronter.content.member, 331 - systemId: fronter.content.uid, 333 + name: undefined, 334 + uri: { 335 + type: "sp", 336 + memberId: fronter.content.member, 337 + systemId: fronter.content.uid, 338 + }, 339 + })); 340 + }; 341 + 342 + export const getPkFronters = async (): Promise< 343 + Parameters<typeof putFronter>["1"] 344 + > => { 345 + const pkSystemId = await storage.getItem<string>("sync:pk-system"); 346 + if (!pkSystemId) return []; 347 + const resp = await fetch( 348 + `https://api.pluralkit.me/v2/systems/${pkSystemId}/fronters`, 349 + ); 350 + if (!resp.ok) return []; 351 + const pkFronters = await resp.json(); 352 + return (pkFronters.members as any[]).map((member) => ({ 353 + name: member.display_name ?? member.name, 354 + uri: { 355 + type: "pk", 356 + memberId: member.id, 357 + systemId: member.system, 358 + }, 332 359 })); 333 360 }; 334 361