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
···
parseSocialAppPostUrl,
displayNameCache,
deleteFronter,
+
getPkFronters,
} from "@/lib/utils";
import {
parseCanonicalResourceUri,
···
) => {
if (!authToken) return;
const frontersArray = await storage.getItem<string[]>("sync:fronters");
-
let members: Parameters<typeof putFronter>["1"] = frontersArray ?? [];
+
let members: Parameters<typeof putFronter>["1"] =
+
frontersArray?.map((n) => ({ name: n, uri: undefined })) ?? [];
+
if (members.length === 0) {
+
members = await getPkFronters();
+
}
if (members.length === 0) {
-
const pkFronters = await storage.getItem<string[]>("sync:pk-fronter");
-
if (pkFronters) {
-
members = pkFronters.map((id) => ({ type: "pk", memberId: id }));
-
} else {
-
members = await getSpFronters();
-
}
+
members = await getSpFronters();
}
// dont write if no names is specified or no sp/pk fronters are fetched
if (members.length === 0) return;
+26 -16
src/entrypoints/popup/App.svelte
···
let queryError = $state("");
let isQuerying = $state(false);
let fronters = $state<string[]>([]);
-
let pkFronters = $state<string[]>([]);
+
let pkSystemId = $state<string>("");
let spToken = $state("");
let isFromCurrentTab = $state(false);
···
storage.setItem("sync:fronters", newFronters);
};
-
const updatePkFronters = (newPkFronters: string[]) => {
-
pkFronters = newPkFronters;
-
storage.setItem("sync:pk-fronter", newPkFronters);
+
const updatePkSystem = (event: any) => {
+
pkSystemId = (event.target as HTMLInputElement).value;
+
storage.setItem("sync:pk-system", pkSystemId);
};
const updateSpToken = (event: any) => {
···
fronters = frontersArray;
}
-
const pkFrontersArray =
-
await storage.getItem<string[]>("sync:pk-fronter");
-
if (pkFrontersArray && Array.isArray(pkFrontersArray)) {
-
pkFronters = pkFrontersArray;
+
const pkSystem = await storage.getItem<string>("sync:pk-system");
+
if (pkSystem) {
+
pkSystemId = pkSystem;
}
const token = await storage.getItem<string>("sync:sp_token");
···
</span>
</div>
</div>
-
<FronterList
-
bind:fronters={pkFronters}
-
onUpdate={updatePkFronters}
-
label="PK FRONTERS"
-
placeholder="enter_member_ids"
-
note="PluralKit member IDs, overrides SP fronters"
-
fetchNames={true}
-
/>
+
<div class="config-card">
+
<div class="config-row">
+
<span class="config-label">PK SYSTEM</span>
+
<input
+
type="password"
+
placeholder="enter_pk_system_id"
+
oninput={updatePkSystem}
+
bind:value={pkSystemId}
+
class="config-input"
+
class:has-value={pkSystemId}
+
/>
+
</div>
+
<div class="config-note">
+
<span class="note-text">
+
when set, pulls fronters from PluralKit (fronter
+
history must be public)
+
</span>
+
</div>
+
</div>
<FronterList
bind:fronters
onUpdate={updateFronters}
+39 -12
src/lib/utils.ts
···
export type MemberUri =
| { type: "at"; recordUri: ResourceUri }
-
| { type: "pk"; memberId: string }
+
| { type: "pk"; systemId: string; memberId: string }
| { type: "sp"; systemId: string; memberId: string };
export const parseMemberId = (memberId: GenericUri): MemberUri => {
···
switch (uri.protocol) {
case "pk:": {
const split = uri.pathname.split("/").slice(1);
-
return { type: "pk", memberId: split[0] };
+
return { type: "pk", systemId: split[0], memberId: split[1] };
}
case "sp:": {
const split = uri.pathname.split("/").slice(1);
···
}
};
-
export const getFronterNames = async (members: (string | MemberUri)[]) => {
+
export const getFronterNames = async (
+
members: { name?: string; uri?: MemberUri }[],
+
) => {
const promises = await Promise.allSettled(
members.map(async (m): Promise<Fronter["members"][0] | null> => {
-
if (typeof m === "string")
-
return Promise.resolve({ uri: undefined, name: m });
-
const name = await fetchMember(m);
-
return name ? { uri: m, name } : null;
+
if (!m.uri) return Promise.resolve({ uri: undefined, name: m.name! });
+
if (m.name) return Promise.resolve({ uri: m.uri, name: m.name });
+
const name = await fetchMember(m.uri);
+
return name ? { uri: m.uri, name } : null;
}),
);
return promises
···
export const putFronter = async (
subject: FronterSchema["subject"],
-
members: (string | MemberUri)[],
+
members: { name?: string; uri?: MemberUri }[],
authToken: string,
): Promise<Result<Fronter, string>> => {
const parsedRecordUri = parseResourceUri(subject);
···
return ok(true);
};
-
export const getSpFronters = async (): Promise<MemberUri[]> => {
+
export const getSpFronters = async (): Promise<
+
Parameters<typeof putFronter>["1"]
+
> => {
const spToken = await storage.getItem<string>("sync:sp_token");
if (!spToken) return [];
const resp = await fetch(`https://api.apparyllis.com/v1/fronters`, {
···
if (!resp.ok) return [];
const spFronters = (await resp.json()) as any[];
return spFronters.map((fronter) => ({
-
type: "sp",
-
memberId: fronter.content.member,
-
systemId: fronter.content.uid,
+
name: undefined,
+
uri: {
+
type: "sp",
+
memberId: fronter.content.member,
+
systemId: fronter.content.uid,
+
},
+
}));
+
};
+
+
export const getPkFronters = async (): Promise<
+
Parameters<typeof putFronter>["1"]
+
> => {
+
const pkSystemId = await storage.getItem<string>("sync:pk-system");
+
if (!pkSystemId) return [];
+
const resp = await fetch(
+
`https://api.pluralkit.me/v2/systems/${pkSystemId}/fronters`,
+
);
+
if (!resp.ok) return [];
+
const pkFronters = await resp.json();
+
return (pkFronters.members as any[]).map((member) => ({
+
name: member.display_name ?? member.name,
+
uri: {
+
type: "pk",
+
memberId: member.id,
+
systemId: member.system,
+
},
}));
};