Merge branch 'app-2066' into app-2067
# Conflicts: # src/components/dialogs/GifSelect.tsx
This commit is contained in:
@@ -8,7 +8,7 @@ import {
|
|||||||
parseStarterPackUri,
|
parseStarterPackUri,
|
||||||
} from '#/lib/strings/starter-pack'
|
} from '#/lib/strings/starter-pack'
|
||||||
import {messages} from '#/locale/locales/en/messages'
|
import {messages} from '#/locale/locales/en/messages'
|
||||||
import {klipyStaticUrl} from '#/state/queries/klipy'
|
import {klipyUrlToBskyGifUrl} from '#/state/queries/klipy'
|
||||||
import {tenorUrlToBskyGifUrl} from '#/state/queries/tenor'
|
import {tenorUrlToBskyGifUrl} from '#/state/queries/tenor'
|
||||||
import {cleanError} from '../../src/lib/strings/errors'
|
import {cleanError} from '../../src/lib/strings/errors'
|
||||||
import {createFullHandle, makeValidHandle} from '../../src/lib/strings/handles'
|
import {createFullHandle, makeValidHandle} from '../../src/lib/strings/handles'
|
||||||
@@ -858,7 +858,7 @@ describe('parseEmbedPlayerFromUrl', () => {
|
|||||||
source: 'klipy',
|
source: 'klipy',
|
||||||
isGif: true,
|
isGif: true,
|
||||||
hideDetails: true,
|
hideDetails: true,
|
||||||
playerUri: 'https://static.klipy.com/ii/abc123/73/ac/someFile.gif',
|
playerUri: 'https://k.gifs.bsky.app/ii/abc123/73/ac/someFile.gif',
|
||||||
dimensions: {
|
dimensions: {
|
||||||
width: 300,
|
width: 300,
|
||||||
height: 200,
|
height: 200,
|
||||||
@@ -1073,13 +1073,30 @@ describe('tenorUrlToBskyGifUrl', () => {
|
|||||||
)
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
describe('klipyStaticUrl', () => {
|
describe('klipyUrlToBskyGifUrl', () => {
|
||||||
it('returns the URL as-is for valid KLIPY static URLs', () => {
|
const inputs = [
|
||||||
const input = 'https://static.klipy.com/ii/abc123/73/ac/someFile.gif'
|
'https://static.klipy.com/ii/abc123/73/ac/someFile.gif',
|
||||||
expect(klipyStaticUrl(input)).toEqual(input)
|
'https://static.klipy.com/ii/abc123/73/ac/someFile.gif?hh=200&ww=300',
|
||||||
|
]
|
||||||
|
|
||||||
|
it.each(inputs)(
|
||||||
|
'returns url with k.gifs.bsky.app as hostname for input url',
|
||||||
|
input => {
|
||||||
|
const out = klipyUrlToBskyGifUrl(input)
|
||||||
|
expect(out.startsWith('https://k.gifs.bsky.app/')).toEqual(true)
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
|
it('preserves the path and query params when rewriting', () => {
|
||||||
|
const out = klipyUrlToBskyGifUrl(
|
||||||
|
'https://static.klipy.com/ii/abc123/73/ac/someFile.gif?hh=200&ww=300',
|
||||||
|
)
|
||||||
|
expect(out).toEqual(
|
||||||
|
'https://k.gifs.bsky.app/ii/abc123/73/ac/someFile.gif?hh=200&ww=300',
|
||||||
|
)
|
||||||
})
|
})
|
||||||
|
|
||||||
it('returns empty string for invalid URLs', () => {
|
it('returns empty string for invalid URLs', () => {
|
||||||
expect(klipyStaticUrl('not-a-url')).toEqual('')
|
expect(klipyUrlToBskyGifUrl('not-a-url')).toEqual('')
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -59,7 +59,10 @@ export const ExternalEmbed = ({
|
|||||||
}
|
}
|
||||||
}, [link.uri, playHaptic])
|
}, [link.uri, playHaptic])
|
||||||
|
|
||||||
if (embedPlayerParams?.source === 'tenor') {
|
if (
|
||||||
|
embedPlayerParams?.source === 'tenor' ||
|
||||||
|
embedPlayerParams?.source === 'klipy'
|
||||||
|
) {
|
||||||
const parsedAlt = parseAltFromGIFDescription(link.description)
|
const parsedAlt = parseAltFromGIFDescription(link.description)
|
||||||
return (
|
return (
|
||||||
<View style={style}>
|
<View style={style}>
|
||||||
|
|||||||
@@ -683,8 +683,12 @@ export function parseKlipyGif(urlp: URL):
|
|||||||
return {success: false}
|
return {success: false}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Use the base URL without dimension params as the player URI
|
// Use the base URL without dimension params as the player URI,
|
||||||
|
// routed through the bsky KLIPY proxy (k.gifs.bsky.app). Mirrors
|
||||||
|
// Tenor's t.gifs.bsky.app rewrite, but on a separate hostname so
|
||||||
|
// the two upstreams can be routed independently.
|
||||||
const playerUrl = new URL(urlp.href)
|
const playerUrl = new URL(urlp.href)
|
||||||
|
playerUrl.hostname = 'k.gifs.bsky.app'
|
||||||
playerUrl.searchParams.delete('hh')
|
playerUrl.searchParams.delete('hh')
|
||||||
playerUrl.searchParams.delete('ww')
|
playerUrl.searchParams.delete('ww')
|
||||||
|
|
||||||
|
|||||||
@@ -140,7 +140,7 @@ function createKlipyApi<Input extends object>(
|
|||||||
},
|
},
|
||||||
})
|
})
|
||||||
if (!res.ok) {
|
if (!res.ok) {
|
||||||
throw new Error('Failed to fetch KLIPY API')
|
throw new Error(`Failed to fetch KLIPY API (status ${res.status})`)
|
||||||
}
|
}
|
||||||
const body: {next: string; results: Gif[]} = await res.json()
|
const body: {next: string; results: Gif[]} = await res.json()
|
||||||
return {
|
return {
|
||||||
@@ -151,18 +151,21 @@ function createKlipyApi<Input extends object>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the static URL for a KLIPY GIF preview image.
|
* Rewrites a KLIPY static CDN URL through the bsky proxy
|
||||||
* KLIPY images are served directly from their CDN (static.klipy.com),
|
* (k.gifs.bsky.app). Mirrors `tenorUrlToBskyGifUrl`, but uses a
|
||||||
* unlike Tenor which routes through t.gifs.bsky.app.
|
* separate hostname from Tenor's t.gifs.bsky.app so the two
|
||||||
|
* upstreams can be routed independently.
|
||||||
*/
|
*/
|
||||||
export function klipyStaticUrl(gifUrl: string) {
|
export function klipyUrlToBskyGifUrl(klipyUrl: string) {
|
||||||
|
let url
|
||||||
try {
|
try {
|
||||||
new URL(gifUrl)
|
url = new URL(klipyUrl)
|
||||||
return gifUrl
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
logger.debug('invalid url passed to klipyStaticUrl()')
|
logger.debug('invalid url passed to klipyUrlToBskyGifUrl()')
|
||||||
return ''
|
return ''
|
||||||
}
|
}
|
||||||
|
url.hostname = 'k.gifs.bsky.app'
|
||||||
|
return url.href
|
||||||
}
|
}
|
||||||
|
|
||||||
type KlipyAutocompleteResponse = {
|
type KlipyAutocompleteResponse = {
|
||||||
|
|||||||
@@ -105,14 +105,19 @@ export function tenorUrlToBskyGifUrl(tenorUrl: string) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the appropriate URL for a GIF preview image.
|
* Returns the appropriate URL for a GIF preview image.
|
||||||
* Rewrites Tenor URLs through the bsky proxy (t.gifs.bsky.app);
|
* Tenor URLs (media.tenor.com) are routed through t.gifs.bsky.app;
|
||||||
* KLIPY URLs pass through directly to their CDN.
|
* KLIPY URLs (static.klipy.com) are routed through k.gifs.bsky.app.
|
||||||
*/
|
*/
|
||||||
export function gifPreviewUrl(gifUrl: string) {
|
export function gifPreviewUrl(gifUrl: string) {
|
||||||
try {
|
try {
|
||||||
const url = new URL(gifUrl)
|
const url = new URL(gifUrl)
|
||||||
if (url.hostname === 'media.tenor.com') {
|
if (url.hostname === 'media.tenor.com') {
|
||||||
return tenorUrlToBskyGifUrl(gifUrl)
|
url.hostname = 't.gifs.bsky.app'
|
||||||
|
return url.href
|
||||||
|
}
|
||||||
|
if (url.hostname === 'static.klipy.com') {
|
||||||
|
url.hostname = 'k.gifs.bsky.app'
|
||||||
|
return url.href
|
||||||
}
|
}
|
||||||
return gifUrl
|
return gifUrl
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
|||||||
Reference in New Issue
Block a user