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
+1 -1
View File
@@ -186,7 +186,7 @@ function LandingPage() {
function Skeleton() {
return (
<Container>
<div className="flex-1 flex-col flex gap-2 pb-8">
<div className="flex-1 flex-col flex gap-2 p-5 pb-8">
<div className="flex gap-2.5 items-center">
<div className="w-10 h-10 overflow-hidden rounded-full bg-neutral-100 dark:bg-slate-700 shrink-0 animate-pulse" />
<div className="flex-1">
+1 -1
View File
@@ -2,7 +2,7 @@
<html>
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, viewport-fit=cover">
<meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover">
<meta name="referrer" content="origin-when-cross-origin">
<!--
Preconnect to essential domains
+3 -9
View File
@@ -109,7 +109,7 @@ function EmbedDialogInner({
<Trans>Embed post</Trans>
</Text>
<Text
style={[a.text_md, t.atoms.text_contrast_medium, a.leading_normal]}>
style={[a.text_md, t.atoms.text_contrast_medium, a.leading_snug]}>
<Trans>
Embed this post in your website. Simply copy the following snippet
and paste it into the HTML code of your website.
@@ -117,12 +117,7 @@ function EmbedDialogInner({
</Text>
</View>
<View
style={[
a.border,
t.atoms.border_contrast_low,
a.rounded_sm,
a.overflow_hidden,
]}>
style={[a.border, t.atoms.border_contrast_low, {borderRadius: 18}]}>
<Button
label={
showCustomisation
@@ -190,10 +185,9 @@ function EmbedDialogInner({
<Button
label={_(msg`Copy code`)}
color="primary"
variant="solid"
size="large"
onPress={() => {
navigator.clipboard.writeText(snippet)
void navigator.clipboard.writeText(snippet)
setCopied(true)
}}>
{copied ? (
+15 -15
View File
@@ -2399,12 +2399,12 @@ msgstr ""
msgid "Collapses list of users for a given notification"
msgstr ""
#: src/components/dialogs/Embed.tsx:155
#: src/components/dialogs/Embed.tsx:150
#: src/screens/Settings/AppearanceSettings.tsx:81
msgid "Color mode"
msgstr ""
#: src/components/dialogs/Embed.tsx:152
#: src/components/dialogs/Embed.tsx:147
msgid "Color theme"
msgstr ""
@@ -2646,7 +2646,7 @@ msgstr ""
msgid "Copied to clipboard"
msgstr ""
#: src/components/dialogs/Embed.tsx:203
#: src/components/dialogs/Embed.tsx:197
#: src/screens/Settings/components/CopyButton.tsx:66
msgid "Copied!"
msgstr ""
@@ -2673,8 +2673,8 @@ msgstr ""
msgid "Copy author DID"
msgstr ""
#: src/components/dialogs/Embed.tsx:191
#: src/components/dialogs/Embed.tsx:208
#: src/components/dialogs/Embed.tsx:186
#: src/components/dialogs/Embed.tsx:202
msgid "Copy code"
msgstr ""
@@ -2948,7 +2948,7 @@ msgstr ""
msgid "Custom"
msgstr ""
#: src/components/dialogs/Embed.tsx:145
#: src/components/dialogs/Embed.tsx:140
msgid "Customization options"
msgstr ""
@@ -2964,8 +2964,8 @@ msgstr ""
msgid "Dangerous substances or drug abuse"
msgstr ""
#: src/components/dialogs/Embed.tsx:169
#: src/components/dialogs/Embed.tsx:171
#: src/components/dialogs/Embed.tsx:164
#: src/components/dialogs/Embed.tsx:166
#: src/screens/Settings/AppearanceSettings.tsx:93
#: src/screens/Settings/AppearanceSettings.tsx:114
msgid "Dark"
@@ -3613,7 +3613,7 @@ msgstr ""
msgid "Email Verified"
msgstr ""
#: src/components/dialogs/Embed.tsx:183
#: src/components/dialogs/Embed.tsx:178
msgid "Embed HTML code"
msgstr ""
@@ -5004,7 +5004,7 @@ msgstr ""
msgid "Hide all events"
msgstr ""
#: src/components/dialogs/Embed.tsx:129
#: src/components/dialogs/Embed.tsx:124
msgid "Hide customization options"
msgstr ""
@@ -5701,8 +5701,8 @@ msgstr ""
msgid "Let's go!"
msgstr ""
#: src/components/dialogs/Embed.tsx:164
#: src/components/dialogs/Embed.tsx:166
#: src/components/dialogs/Embed.tsx:159
#: src/components/dialogs/Embed.tsx:161
#: src/screens/Settings/AppearanceSettings.tsx:89
msgid "Light"
msgstr ""
@@ -9359,7 +9359,7 @@ msgstr ""
msgid "Show badge and filter from feeds"
msgstr ""
#: src/components/dialogs/Embed.tsx:130
#: src/components/dialogs/Embed.tsx:125
msgid "Show customization options"
msgstr ""
@@ -9910,8 +9910,8 @@ msgstr ""
msgid "Switch to {0}"
msgstr ""
#: src/components/dialogs/Embed.tsx:159
#: src/components/dialogs/Embed.tsx:161
#: src/components/dialogs/Embed.tsx:154
#: src/components/dialogs/Embed.tsx:156
#: src/screens/Settings/AppearanceSettings.tsx:85
#: src/screens/Settings/AppearanceSettings.tsx:135
msgid "System"
+1 -1
View File
@@ -277,7 +277,7 @@ export async function compressImage(
async function moveIfNecessary(from: string) {
const cacheDir = IS_NATIVE && getImageCacheDirectory()
if (cacheDir && from.startsWith(cacheDir)) {
if (cacheDir && !from.startsWith(cacheDir)) {
const to = joinPath(cacheDir, nanoid(36))
await makeDirectoryAsync(cacheDir, {intermediates: true})
+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 {
+1 -1
View File
@@ -9,7 +9,7 @@
-->
<meta
name="viewport"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1.00001, viewport-fit=cover"
content="width=device-width, initial-scale=1, minimum-scale=1, maximum-scale=1, viewport-fit=cover"
/>
<!--
Preconnect to essential domains