Files
zap.stream/src/hooks/emoji.tsx
2023-07-15 14:37:38 +01:00

116 lines
2.6 KiB
TypeScript

import {
RequestBuilder,
EventKind,
ReplaceableNoteStore,
NoteCollection,
NostrEvent,
} from "@snort/system";
import { useRequestBuilder } from "@snort/system-react";
import { System } from "index";
import { useMemo } from "react";
import { findTag } from "utils";
import type { EmojiTag } from "../element/emoji";
import uniqBy from "lodash.uniqby";
export interface Emoji {
native?: string;
id?: string;
}
export interface EmojiPack {
address: string;
name: string;
author: string;
emojis: EmojiTag[];
}
function cleanShortcode(shortcode?: string) {
return shortcode?.replace(/\s+/, "_");
}
function toEmojiPack(ev: NostrEvent): EmojiPack {
const d = findTag(ev, "d") || "";
return {
address: `${ev.kind}:${ev.pubkey}:${d}`,
name: d,
author: ev.pubkey,
emojis: ev.tags
.filter((t) => t.at(0) === "emoji")
.map((t) => ["emoji", cleanShortcode(t.at(1)), t.at(2)]) as EmojiTag[],
};
}
export function packId(pack: EmojiPack): string {
return `${pack.author}:${pack.name}`;
}
export default function useEmoji(pubkey?: string) {
const sub = useMemo(() => {
if(!pubkey) return null;
const rb = new RequestBuilder(`emoji:${pubkey}`);
rb.withFilter()
.authors([pubkey])
.kinds([10030 as EventKind]);
return rb;
}, [pubkey]);
const { data: userEmoji } = useRequestBuilder<ReplaceableNoteStore>(
System,
ReplaceableNoteStore,
sub
);
const related = useMemo(() => {
if (userEmoji) {
return userEmoji.tags.filter(
(t) => t.at(0) === "a" && t.at(1)?.startsWith(`30030:`)
);
}
return [];
}, [userEmoji]);
const subRelated = useMemo(() => {
if(!pubkey) return null;
const splitted = related.map((t) => t.at(1)!.split(":"));
const authors = splitted
.map((s) => s.at(1))
.filter((s) => s)
.map((s) => s as string);
const identifiers = splitted
.map((s) => s.at(2))
.filter((s) => s)
.map((s) => s as string);
const rb = new RequestBuilder(`emoji-related:${pubkey}`);
rb.withFilter()
.kinds([30030 as EventKind])
.authors(authors)
.tag("d", identifiers);
rb.withFilter()
.kinds([30030 as EventKind])
.authors([pubkey]);
return rb;
}, [pubkey, related]);
const { data: relatedData } = useRequestBuilder<NoteCollection>(
System,
NoteCollection,
subRelated
);
const emojiPacks = useMemo(() => {
return relatedData ?? [];
}, [relatedData]);
const emojis = useMemo(() => {
return uniqBy(emojiPacks.map(toEmojiPack), packId);
}, [emojiPacks]);
return emojis;
}