import {uniqBy, uniq, now, choice} from "@welshman/lib" import { GROUPS, GROUP_JOIN, asDecryptedEvent, getGroupTags, getRelayTagValues, readList, editList, makeList, createList, createEvent, displayProfile, } from "@welshman/util" import {pk, signer, repository, INDEXER_RELAYS} from "@app/base" import { getWriteRelayUrls, loadGroup, loadGroupMembership, loadProfile, loadFollows, loadMutes, getRelaySelectionsByPubkey, loadRelaySelections, makeThunk, publishThunk, ensurePlaintext, getProfilesByPubkey, } from "@app/state" // Utils export const getPubkeyHints = (pubkey: string) => { const selections = getRelaySelectionsByPubkey().get(pubkey) const relays = selections ? getWriteRelayUrls(selections) : [] const hints = relays.length ? relays : INDEXER_RELAYS return hints } export const getPubkeyPetname = (pubkey: string) => { const profile = getProfilesByPubkey().get(pubkey) const display = displayProfile(profile) return display } export const makeMention = (pubkey: string, hints?: string[]) => ["p", pubkey, choice(hints || getPubkeyHints(pubkey)), getPubkeyPetname(pubkey)] export const makeIMeta = (url: string, data: Record) => ["imeta", `url ${url}`, ...Object.entries(data).map(([k, v]) => [k, v].join(' '))] // Loaders export const loadUserData = async (pubkey: string, hints: string[] = []) => { const relaySelections = await loadRelaySelections(pubkey, INDEXER_RELAYS) const relays = uniq([ ...getRelayTagValues(relaySelections?.tags || []), ...INDEXER_RELAYS, ...hints, ]) const membership = await loadGroupMembership(pubkey, relays) const promises = [ loadProfile(pubkey, relays), loadFollows(pubkey, relays), loadMutes(pubkey, relays), ] for (const [_, nom, url] of getGroupTags(membership?.event.tags || [])) { promises.push(loadGroup(nom, [url])) } await Promise.all(promises) } // Updates export type ModifyTags = (tags: string[][]) => string[][] export const updateList = async (kind: number, modifyTags: ModifyTags) => { const $pk = pk.get()! const $signer = signer.get()! const [prev] = repository.query([{kinds: [kind], authors: [$pk]}]) const relays = getWriteRelayUrls(getRelaySelectionsByPubkey().get($pk)) // Preserve content if we have it const event = prev ? {...prev, tags: modifyTags(prev.tags)} : createEvent(kind, {tags: modifyTags([])}) publishThunk(makeThunk({event, relays})) } export const addGroupMemberships = (newTags: string[][]) => updateList(GROUPS, (tags: string[][]) => uniqBy(t => t.join(""), [...tags, ...newTags])) export const removeGroupMemberships = (noms: string[]) => updateList(GROUPS, (tags: string[][]) => tags.filter(t => !noms.includes(t[1]))) export const sendJoinRequest = async (nom: string, url: string) => { const event = createEvent(GROUP_JOIN, {tags: [["h", nom]]}) const result = await publishThunk(makeThunk({event, relays: [url]})) return result[url] }