forked from Kieran/snort
feat: PLEBHY search
This commit is contained in:
parent
403ed97ad3
commit
081a07e384
@ -11,7 +11,8 @@
|
||||
}
|
||||
|
||||
.user-item,
|
||||
.emoji-item {
|
||||
.emoji-item,
|
||||
.gif-item {
|
||||
color: var(--font-color);
|
||||
background: var(--note-bg);
|
||||
display: flex;
|
||||
@ -22,7 +23,8 @@
|
||||
}
|
||||
|
||||
.user-item:hover,
|
||||
.emoji-item:hover {
|
||||
.emoji-item:hover,
|
||||
.gif-item:hover {
|
||||
background: var(--gray-tertiary);
|
||||
}
|
||||
|
||||
|
@ -9,9 +9,11 @@ import { NostrPrefix } from "@snort/nostr";
|
||||
|
||||
import Avatar from "Element/Avatar";
|
||||
import Nip05 from "Element/Nip05";
|
||||
import { ProxyImg } from "Element/ProxyImg";
|
||||
import { hexToBech32 } from "Util";
|
||||
import { MetadataCache } from "Cache";
|
||||
import { UserCache } from "Cache/UserCache";
|
||||
import PLEBHY, { PLEBHYItem } from "Plebhy";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -44,6 +46,17 @@ const UserItem = (metadata: MetadataCache) => {
|
||||
);
|
||||
};
|
||||
|
||||
const PlebhyItem = (item: PLEBHYItem) => {
|
||||
return (
|
||||
<div key={item.etag} className="gif-item">
|
||||
<div className="gif">
|
||||
<ProxyImg src={decodeURIComponent(item.images.original.url)} width={100} />
|
||||
</div>
|
||||
<div className="gif-name">{item.name}</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
interface TextareaProps {
|
||||
autoFocus: boolean;
|
||||
className: string;
|
||||
@ -53,6 +66,7 @@ interface TextareaProps {
|
||||
}
|
||||
|
||||
const Textarea = (props: TextareaProps) => {
|
||||
const plebHy = new PLEBHY();
|
||||
const { formatMessage } = useIntl();
|
||||
|
||||
const userDataProvider = async (token: string) => {
|
||||
@ -65,6 +79,10 @@ const Textarea = (props: TextareaProps) => {
|
||||
.map(({ name, char }) => ({ name, char }));
|
||||
};
|
||||
|
||||
const plebhyDataProvider = (token: string) => {
|
||||
return plebHy.search(token);
|
||||
};
|
||||
|
||||
return (
|
||||
// @ts-expect-error If anybody can figure out how to type this, please do
|
||||
<ReactTextareaAutocomplete
|
||||
@ -85,6 +103,11 @@ const Textarea = (props: TextareaProps) => {
|
||||
component: (props: { entity: MetadataCache }) => <UserItem {...props.entity} />,
|
||||
output: (item: { pubkey: string }) => `@${hexToBech32(NostrPrefix.PublicKey, item.pubkey)}`,
|
||||
},
|
||||
"~": {
|
||||
dataProvider: plebhyDataProvider,
|
||||
component: (props: { entity: PLEBHYItem }) => <PlebhyItem {...props.entity} />,
|
||||
output: (item: PLEBHYItem) => decodeURIComponent(item.images.original.url),
|
||||
},
|
||||
}}
|
||||
/>
|
||||
);
|
||||
|
59
packages/app/src/Plebhy.ts
Normal file
59
packages/app/src/Plebhy.ts
Normal file
@ -0,0 +1,59 @@
|
||||
export interface PLEBHYItem {
|
||||
type: "gif" | "sticker";
|
||||
sid: string;
|
||||
ptag: string;
|
||||
etag: string;
|
||||
name: string;
|
||||
title: string;
|
||||
images: {
|
||||
original: PLEBHYImage;
|
||||
downsized: PLEBHYImage;
|
||||
};
|
||||
}
|
||||
|
||||
export interface PLEBHYImage {
|
||||
url: string;
|
||||
size: number;
|
||||
width: number;
|
||||
height: number;
|
||||
}
|
||||
|
||||
export default class PLEBHY {
|
||||
#url: string;
|
||||
#key: string;
|
||||
|
||||
constructor(url?: string, key?: string) {
|
||||
this.#url = url ?? "https://getcurrent.io";
|
||||
this.#key = key ?? "8B4362ACDA28567FB47C9D7BCA952";
|
||||
}
|
||||
|
||||
async search(term: string, limit?: number) {
|
||||
const { data } = await this.#getJson<{ data: Array<PLEBHYItem> }>(
|
||||
`/plebhy?apikey=${this.#key}&search=${encodeURIComponent(term)}&limit=${limit ?? 10}`
|
||||
);
|
||||
return data;
|
||||
}
|
||||
|
||||
async #getJson<T>(
|
||||
path: string,
|
||||
method?: "GET" | string,
|
||||
body?: { [key: string]: string },
|
||||
headers?: { [key: string]: string }
|
||||
): Promise<T> {
|
||||
const rsp = await fetch(`${this.#url}${path}`, {
|
||||
method: method,
|
||||
body: body ? JSON.stringify(body) : undefined,
|
||||
headers: {
|
||||
accept: "application/json",
|
||||
...(body ? { "content-type": "application/json" } : {}),
|
||||
...headers,
|
||||
},
|
||||
});
|
||||
|
||||
const obj = await rsp.json();
|
||||
if ("error" in obj) {
|
||||
throw new Error(obj.error);
|
||||
}
|
||||
return obj as T;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user