Skip to content

Commit

Permalink
Move to Tenor for GIFs (#3654)
Browse files Browse the repository at this point in the history
* update some urls

* right order for dimensions

* add GIF coder for ios

* remove giphy check

* rewrite tenor urls

* remove all the unnecessary stuff for consent

* rm print

* rm log

* check if id and filename are strings
  • Loading branch information
haileyok authored Apr 22, 2024
1 parent 4f40ff3 commit 8878821
Show file tree
Hide file tree
Showing 5 changed files with 50 additions and 90 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,7 @@ public class ExpoBlueskyGifViewModule: Module {
Name("ExpoBlueskyGifView")

OnCreate {
// See expo-image. SDImageAWebPCoder is preferred (and uses Apple's own WebP coder)
// but only is available on 14.0+. We probably don't have many users on iOS 13 but
// for now let's keep it there until RN targets change.
if #available(iOS 14.0, tvOS 14.0, *) {
SDImageCodersManager.shared.addCoder(SDImageAWebPCoder.shared)
} else {
SDImageCodersManager.shared.addCoder(SDImageWebPCoder.shared)
}
SDImageCodersManager.shared.addCoder(SDImageGIFCoder.shared)
}

AsyncFunction("prefetchAsync") { (sources: [URL]) in
Expand Down
46 changes: 23 additions & 23 deletions src/lib/strings/embed-player.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import {Dimensions} from 'react-native'
import {Dimensions, Platform} from 'react-native'

import {isWeb} from 'platform/detection'
const {height: SCREEN_HEIGHT} = Dimensions.get('window')
Expand Down Expand Up @@ -255,16 +255,6 @@ export function parseEmbedPlayerFromUrl(
if (urlp.hostname === 'giphy.com' || urlp.hostname === 'www.giphy.com') {
const [_, gifs, nameAndId] = urlp.pathname.split('/')

const h = urlp.searchParams.get('hh')
const w = urlp.searchParams.get('ww')
let dimensions
if (h && w) {
dimensions = {
height: Number(h),
width: Number(w),
}
}

/*
* nameAndId is a string that consists of the name (dash separated) and the id of the gif (the last part of the name)
* We want to get the id of the gif, then direct to media.giphy.com/media/{id}/giphy.webp so we can
Expand All @@ -281,10 +271,7 @@ export function parseEmbedPlayerFromUrl(
isGif: true,
hideDetails: true,
metaUri: `https://giphy.com/gifs/${gifId}`,
playerUri: `https://i.giphy.com/media/${gifId}/${
dimensions && isWeb ? 'giphy.mp4' : '200.webp'
}`,
dimensions,
playerUri: `https://i.giphy.com/media/${gifId}/giphy.webp`,
}
}
}
Expand Down Expand Up @@ -350,21 +337,34 @@ export function parseEmbedPlayerFromUrl(
}
}

if (urlp.hostname === 'tenor.com' || urlp.hostname === 'www.tenor.com') {
const [_, pathOrIntl, pathOrFilename, intlFilename] =
urlp.pathname.split('/')
const isIntl = pathOrFilename === 'view'
const filename = isIntl ? intlFilename : pathOrFilename
if (urlp.hostname === 'media.tenor.com') {
let [_, id, filename] = urlp.pathname.split('/')

if ((pathOrIntl === 'view' || pathOrFilename === 'view') && filename) {
const includesExt = filename.split('.').pop() === 'gif'
const h = urlp.searchParams.get('hh')
const w = urlp.searchParams.get('ww')
let dimensions
if (h && w) {
dimensions = {
height: Number(h),
width: Number(w),
}
}

if (id && filename && dimensions && id.includes('AAAAC')) {
if (Platform.OS === 'web') {
id = id.replace('AAAAC', 'AAAP3')
filename = filename.replace('.gif', '.webm')
} else {
id = id.replace('AAAAC', 'AAAAM')
}

return {
type: 'tenor_gif',
source: 'tenor',
isGif: true,
hideDetails: true,
playerUri: `${url}${!includesExt ? '.gif' : ''}`,
playerUri: `https://t.gifs.bsky.app/${id}/${filename}`,
dimensions,
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/view/com/composer/Composer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,7 +318,7 @@ export const ComposePost = observer(function ComposePost({
const onSelectGif = useCallback(
(gif: Gif) => {
setExtLink({
uri: `${gif.media_formats.gif.url}?hh=${gif.media_formats.gif.dims[0]}&ww=${gif.media_formats.gif.dims[1]}`,
uri: `${gif.media_formats.gif.url}?hh=${gif.media_formats.gif.dims[1]}&ww=${gif.media_formats.gif.dims[0]}`,
isLoading: true,
meta: {
url: gif.media_formats.gif.url,
Expand Down
18 changes: 7 additions & 11 deletions src/view/com/util/post-embeds/ExternalLinkEmbed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,8 @@ export const ExternalLinkEmbed = ({
return params
}
}, [link.uri, externalEmbedPrefs])
const isCompatibleGiphy =
embedPlayerParams?.source === 'giphy' && embedPlayerParams.dimensions

if (isCompatibleGiphy) {
if (embedPlayerParams?.source === 'tenor') {
return <GifEmbed params={embedPlayerParams} thumb={link.thumb} />
}

Expand Down Expand Up @@ -69,14 +67,12 @@ export const ExternalLinkEmbed = ({
paddingHorizontal: isMobile ? 10 : 14,
},
]}>
{!isCompatibleGiphy && (
<Text
type="sm"
numberOfLines={1}
style={[pal.textLight, {marginVertical: 2}]}>
{toNiceDomain(link.uri)}
</Text>
)}
<Text
type="sm"
numberOfLines={1}
style={[pal.textLight, {marginVertical: 2}]}>
{toNiceDomain(link.uri)}
</Text>

{!embedPlayerParams?.isGif && !embedPlayerParams?.dimensions && (
<Text type="lg-bold" numberOfLines={3} style={[pal.text]}>
Expand Down
65 changes: 18 additions & 47 deletions src/view/com/util/post-embeds/GifEmbed.tsx
Original file line number Diff line number Diff line change
@@ -1,14 +1,10 @@
import React from 'react'
import {Pressable, View} from 'react-native'
import {Image} from 'expo-image'
import {FontAwesomeIcon} from '@fortawesome/react-native-fontawesome'

import {EmbedPlayerParams} from 'lib/strings/embed-player'
import {useAutoplayDisabled, useExternalEmbedsPrefs} from 'state/preferences'
import {useAutoplayDisabled} from 'state/preferences'
import {atoms as a, useTheme} from '#/alf'
import {useDialogControl} from '#/components/Dialog'
import * as Dialog from '#/components/Dialog'
import {GiphyConsentPrompt} from '#/components/dialogs/GifSelect'
import {Loader} from '#/components/Loader'
import {GifView} from '../../../../../modules/expo-bluesky-gif-view'
import {GifViewStateChangeEvent} from '../../../../../modules/expo-bluesky-gif-view/src/GifView.types'
Expand All @@ -17,12 +13,10 @@ function PlaybackControls({
onPress,
isPlaying,
isLoaded,
needsPermissions,
}: {
onPress: () => void
isPlaying: boolean
isLoaded: boolean
needsPermissions: boolean
}) {
const t = useTheme()

Expand All @@ -41,16 +35,15 @@ function PlaybackControls({
top: 0,
bottom: 0,
zIndex: 2,
backgroundColor:
!needsPermissions && !isLoaded
? t.atoms.bg_contrast_25.backgroundColor
: !isPlaying
? 'rgba(0, 0, 0, 0.3)'
: undefined,
backgroundColor: !isLoaded
? t.atoms.bg_contrast_25.backgroundColor
: !isPlaying
? 'rgba(0, 0, 0, 0.3)'
: undefined,
},
]}
onPress={onPress}>
{!needsPermissions && !isLoaded ? (
{!isLoaded ? (
<View>
<View style={[a.align_center, a.justify_center]}>
<Loader size="xl" />
Expand Down Expand Up @@ -87,18 +80,15 @@ export function GifEmbed({
params: EmbedPlayerParams
thumb?: string
}) {
const consentControl = useDialogControl()
const autoplayDisabled = useAutoplayDisabled()
const externalEmbedsPrefs = useExternalEmbedsPrefs()
const needsPermissions = externalEmbedsPrefs?.giphy === undefined

const playerRef = React.useRef<GifView>(null)

const [playerState, setPlayerState] = React.useState<{
isPlaying: boolean
isLoaded: boolean
}>({
isPlaying: !autoplayDisabled && !needsPermissions,
isPlaying: !autoplayDisabled,
isLoaded: false,
})

Expand All @@ -110,12 +100,8 @@ export function GifEmbed({
)

const onPress = React.useCallback(() => {
if (needsPermissions) {
consentControl.open()
} else {
playerRef.current?.toggleAsync()
}
}, [consentControl, needsPermissions])
playerRef.current?.toggleAsync()
}, [])

return (
<View style={[a.rounded_sm, a.overflow_hidden, a.mt_sm]}>
Expand All @@ -131,30 +117,15 @@ export function GifEmbed({
onPress={onPress}
isPlaying={playerState.isPlaying}
isLoaded={playerState.isLoaded}
needsPermissions={needsPermissions}
/>
{needsPermissions ? (
<>
<Image
style={[a.flex_1, a.rounded_sm]}
source={{uri: thumb}}
accessibilityIgnoresInvertColors
/>
<Dialog.Outer control={consentControl}>
<Dialog.Handle />
<GiphyConsentPrompt />
</Dialog.Outer>
</>
) : (
<GifView
source={params.playerUri}
placeholderSource={thumb}
style={[a.flex_1, a.rounded_sm]}
autoplay={!autoplayDisabled}
onPlayerStateChange={onPlayerStateChange}
ref={playerRef}
/>
)}
<GifView
source={params.playerUri}
placeholderSource={thumb}
style={[a.flex_1, a.rounded_sm]}
autoplay={!autoplayDisabled}
onPlayerStateChange={onPlayerStateChange}
ref={playerRef}
/>
</View>
</View>
)
Expand Down

0 comments on commit 8878821

Please sign in to comment.