diff options
author | Samuel Newman <mozzius@protonmail.com> | 2024-04-19 03:42:26 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-19 03:42:26 +0100 |
commit | ba1c4834ab23726c065aff31ef09e3578210ff01 (patch) | |
tree | 7c3335e22daf3b21e2e315d170b0936e0e26b5e6 /src/state/queries | |
parent | 20907381858b61fec61249c6ef836b9696e1ab05 (diff) | |
download | voidsky-ba1c4834ab23726c065aff31ef09e3578210ff01.tar.zst |
Add GIF select to composer (#3600)
* create dialog with flatlist in it * use alf for composer photos/camera/gif buttons * add gif icons * focus textinput on gif dialog close * add giphy API + gif grid * web support * add consent confirmation * track gif select * desktop web consent styles * use InlineLinkText instead of Link * add error/loading state * hide sideborders on web * disable composer buttons where necessary * skip cardyb and set thumbnail directly * switch legacy analytics to statsig * remove autoplay prop * disable photo/gif buttons if external media is present * memoize listmaybeplaceholder * fix pagination * don't set `value` of TextInput, clear via ref * remove console.log * close modal if press escape * pass alt text in the description * Fix typo * Rm dialog --------- Co-authored-by: Dan Abramov <dan.abramov@gmail.com>
Diffstat (limited to 'src/state/queries')
-rw-r--r-- | src/state/queries/giphy.ts | 280 |
1 files changed, 280 insertions, 0 deletions
diff --git a/src/state/queries/giphy.ts b/src/state/queries/giphy.ts new file mode 100644 index 000000000..ca5ff65f5 --- /dev/null +++ b/src/state/queries/giphy.ts @@ -0,0 +1,280 @@ +import {keepPreviousData, useInfiniteQuery} from '@tanstack/react-query' + +import {GIPHY_API_KEY, GIPHY_API_URL} from '#/lib/constants' + +export const RQKEY_ROOT = 'giphy' +export const RQKEY_TRENDING = [RQKEY_ROOT, 'trending'] +export const RQKEY_SEARCH = (query: string) => [RQKEY_ROOT, 'search', query] + +const getTrendingGifs = createGiphyApi< + { + limit?: number + offset?: number + rating?: string + random_id?: string + bundle?: string + }, + {data: Gif[]; pagination: Pagination} +>('/v1/gifs/trending') + +const searchGifs = createGiphyApi< + { + q: string + limit?: number + offset?: number + rating?: string + lang?: string + random_id?: string + bundle?: string + }, + {data: Gif[]; pagination: Pagination} +>('/v1/gifs/search') + +export function useGiphyTrending() { + return useInfiniteQuery({ + queryKey: RQKEY_TRENDING, + queryFn: ({pageParam}) => getTrendingGifs({offset: pageParam}), + initialPageParam: 0, + getNextPageParam: lastPage => + lastPage.pagination.offset + lastPage.pagination.count, + }) +} + +export function useGifphySearch(query: string) { + return useInfiniteQuery({ + queryKey: RQKEY_SEARCH(query), + queryFn: ({pageParam}) => searchGifs({q: query, offset: pageParam}), + initialPageParam: 0, + getNextPageParam: lastPage => + lastPage.pagination.offset + lastPage.pagination.count, + enabled: !!query, + placeholderData: keepPreviousData, + }) +} + +function createGiphyApi<Input extends object, Ouput>( + path: string, +): (input: Input) => Promise< + Ouput & { + meta: Meta + } +> { + return async input => { + const url = new URL(path, GIPHY_API_URL) + url.searchParams.set('api_key', GIPHY_API_KEY) + + for (const [key, value] of Object.entries(input)) { + url.searchParams.set(key, String(value)) + } + + const res = await fetch(url.toString(), { + method: 'GET', + headers: { + 'Content-Type': 'application/json', + }, + }) + if (!res.ok) { + throw new Error('Failed to fetch Giphy API') + } + return res.json() + } +} + +export type Gif = { + type: string + id: string + slug: string + url: string + bitly_url: string + embed_url: string + username: string + source: string + rating: string + content_url: string + user: User + source_tld: string + source_post_url: string + update_datetime: string + create_datetime: string + import_datetime: string + trending_datetime: string + images: Images + title: string + alt_text: string +} + +type Images = { + fixed_height: { + url: string + width: string + height: string + size: string + mp4: string + mp4_size: string + webp: string + webp_size: string + } + + fixed_height_still: { + url: string + width: string + height: string + } + + fixed_height_downsampled: { + url: string + width: string + height: string + size: string + webp: string + webp_size: string + } + + fixed_width: { + url: string + width: string + height: string + size: string + mp4: string + mp4_size: string + webp: string + webp_size: string + } + + fixed_width_still: { + url: string + width: string + height: string + } + + fixed_width_downsampled: { + url: string + width: string + height: string + size: string + webp: string + webp_size: string + } + + fixed_height_small: { + url: string + width: string + height: string + size: string + mp4: string + mp4_size: string + webp: string + webp_size: string + } + + fixed_height_small_still: { + url: string + width: string + height: string + } + + fixed_width_small: { + url: string + width: string + height: string + size: string + mp4: string + mp4_size: string + webp: string + webp_size: string + } + + fixed_width_small_still: { + url: string + width: string + height: string + } + + downsized: { + url: string + width: string + height: string + size: string + } + + downsized_still: { + url: string + width: string + height: string + } + + downsized_large: { + url: string + width: string + height: string + size: string + } + + downsized_medium: { + url: string + width: string + height: string + size: string + } + + downsized_small: { + mp4: string + width: string + height: string + mp4_size: string + } + + original: { + width: string + height: string + size: string + frames: string + mp4: string + mp4_size: string + webp: string + webp_size: string + } + + original_still: { + url: string + width: string + height: string + } + + looping: { + mp4: string + } + + preview: { + mp4: string + mp4_size: string + width: string + height: string + } + + preview_gif: { + url: string + width: string + height: string + } +} + +type User = { + avatar_url: string + banner_url: string + profile_url: string + username: string + display_name: string +} + +type Meta = { + msg: string + status: number + response_id: string +} + +type Pagination = { + offset: number + total_count: number + count: number +} |