Merge branch 'app-2066' into app-2067

# Conflicts:
#	src/state/queries/klipy.ts
This commit is contained in:
vineyardbovines
2026-04-14 15:03:11 -04:00
8 changed files with 28 additions and 107 deletions
+4 -76
View File
@@ -141,18 +141,18 @@ function createKlipyApi<Input extends object>(
if (!res.ok) {
throw new Error('Failed to fetch KLIPY API')
}
const body: KlipyResponse = await res.json()
const body: {next: string; results: Gif[]} = await res.json()
return {
next: body.next,
results: body.data.map(normalizeKlipyGif),
results: body.results,
}
}
}
/**
* Returns the static URL for a KLIPY GIF preview image.
* Currently a pass-through; will route through the bsky proxy once the
* backend proxy PR (tango) is deployed.
* KLIPY images are served directly from their CDN (static.klipy.com),
* unlike Tenor which routes through t.gifs.bsky.app.
*/
export function klipyStaticUrl(gifUrl: string) {
try {
@@ -164,78 +164,6 @@ export function klipyStaticUrl(gifUrl: string) {
}
}
/**
* Maps a native KLIPY gif object onto the Tenor-shaped `Gif` type so
* downstream consumers (resolveGif, composer drafts, ExternalEmbed, etc.)
* continue to work unchanged.
*
* NOTE: the exact KLIPY response shape needs to be verified against the
* backend proxy once the tango PR is deployed — some fields here are
* best-effort based on what's documented today.
*/
function normalizeKlipyGif(k: KlipyGif): Gif {
const toMediaObject = (v: KlipyFileVariant) => ({
url: v.url,
dims: [v.width, v.height] as [number, number],
duration: 0,
size: 0,
})
return {
id: k.slug,
title: k.title ?? '',
content_description: k.content_description ?? k.title ?? '',
tags: k.tags ?? [],
media_formats: {
gif: toMediaObject(k.file.hd.gif),
tinygif: toMediaObject(k.file.sm.gif),
preview: toMediaObject(k.file.sm.gif),
},
// Tenor-only fields; stub sensibly for KLIPY.
created: 0,
hasaudio: false,
hascaption: false,
flags: '',
itemurl: k.url ?? '',
url: k.url ?? '',
}
}
type KlipyFileVariant = {
url: string
width: number
height: number
}
type KlipyFileFormats = {
gif: KlipyFileVariant
webp?: KlipyFileVariant
mp4?: KlipyFileVariant
}
type KlipyFile = {
/** Small/thumbnail size, used in the picker grid */
sm: KlipyFileFormats
/** Medium size */
md: KlipyFileFormats
/** Full/large size, used when posting */
hd: KlipyFileFormats
}
type KlipyGif = {
slug: string
title?: string
content_description?: string
tags?: string[]
url?: string
file: KlipyFile
}
type KlipyResponse = {
next: string
data: KlipyGif[]
}
type KlipyAutocompleteResponse = {
locale: string
results: string[]
+2 -3
View File
@@ -105,9 +105,8 @@ export function tenorUrlToBskyGifUrl(tenorUrl: string) {
/**
* Returns the appropriate URL for a GIF preview image.
* Rewrites Tenor URLs through the bsky proxy; KLIPY URLs pass through
* directly (will route through the bsky proxy once the tango backend-proxy
* PR is deployed).
* Rewrites Tenor URLs through the bsky proxy (t.gifs.bsky.app);
* KLIPY URLs pass through directly to their CDN.
*/
export function gifPreviewUrl(gifUrl: string) {
try {