Something went wrong. Try again.
Monorepo for Tangled tangled.org
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970import type { Did } from "@atcute/lexicons/syntax";import type { OAuthUserAgent } from "@atcute/oauth-browser-client";import { getOrCreateDelegatedSession } from "#lib/api/actAs.ts";import type { BobbinContext } from "#lib/api/client.ts";import { PROFILE_COLLECTION } from "#lib/api/profile.ts";import { loadProfile, writeProfile } from "#lib/api/profileSettings.ts";import type { ProfileRecord } from "#lib/api/records.ts";
export const PINNED_LIMIT = 6;
export type PinnedKey = NonNullable<ProfileRecord["pinnedRepositories"]>[number];
// legacy repos are pinned by at-uri, which the lexicon still types as a didexport const asPinnedKey = (key: string) => key as PinnedKey;
export const pinKeyOf = (repo: { repoDid: string; uri?: string }): PinnedKey => asPinnedKey( repo.uri && !repo.uri.includes("/org.tangled.repo.manifest/") ? repo.uri : repo.repoDid );
export const addPinned = <K extends string>(keys: readonly K[], key: K): K[] => { const existing = keys.filter((entry) => entry !== key); if (existing.length >= PINNED_LIMIT) { throw new Error( `Unpin a repository first. Profiles show up to ${PINNED_LIMIT} pinned repositories.` ); } return [...existing, key];};
export const removePinned = <K extends string>(keys: readonly K[], key: K): K[] => keys.filter((entry) => entry !== key);
export const movePinned = <K extends string>(keys: readonly K[], from: number, to: number): K[] => { if (from === to || from < 0 || from >= keys.length) return [...keys]; const next = [...keys]; const [moved] = next.splice(from, 1); next.splice(Math.min(Math.max(to, 0), next.length), 0, moved); return next;};
export const pinnedWith = ( current: ProfileRecord | null, key: string, pinned: boolean): ProfileRecord => { const keys = current?.pinnedRepositories ?? []; const pin = asPinnedKey(key); const next = pinned ? addPinned(keys, pin) : removePinned(keys, pin); const { pinnedRepositories: _pinnedRepositories, ...rest } = current ?? {}; return { ...rest, $type: PROFILE_COLLECTION, ...(next.length > 0 ? { pinnedRepositories: next } : {}) };};
export const setRepositoryPinned = async ( ctx: BobbinContext, agent: OAuthUserAgent, ownerDid: Did, key: string, pinned: boolean): Promise<ProfileRecord> => { const ownerAgent = agent.sub === ownerDid ? agent : await getOrCreateDelegatedSession(agent, ownerDid); const current = await loadProfile(ctx, ownerDid); return writeProfile(ctx, ownerAgent, pinnedWith(current, key, pinned));};