Skip to content

Commit

Permalink
Merge branch 'main' into hailey/gif-view
Browse files Browse the repository at this point in the history
# Conflicts:
#	src/components/dialogs/GifSelect.tsx
  • Loading branch information
haileyok committed Apr 22, 2024
2 parents 5338f1d + 49b5d42 commit 4f40ff3
Show file tree
Hide file tree
Showing 7 changed files with 237 additions and 430 deletions.
147 changes: 29 additions & 118 deletions src/components/dialogs/GifSelect.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,14 @@ import {BottomSheetFlatListMethods} from '@discord/bottom-sheet'
import {msg, Trans} from '@lingui/macro'
import {useLingui} from '@lingui/react'

import {GIPHY_PRIVACY_POLICY} from '#/lib/constants'
import {logEvent} from '#/lib/statsig/statsig'
import {cleanError} from '#/lib/strings/errors'
import {isWeb} from '#/platform/detection'
import {
useExternalEmbedsPrefs,
useSetExternalEmbedPref,
} from '#/state/preferences'
import {Gif, useGifphySearch, useGiphyTrending} from '#/state/queries/giphy'
Gif,
useFeaturedGifsQuery,
useGifSearchQuery,
} from '#/state/queries/tenor'
import {ErrorScreen} from '#/view/com/util/error/ErrorScreen'
import {ErrorBoundary} from '#/view/com/util/ErrorBoundary'
import {atoms as a, useBreakpoints, useTheme} from '#/alf'
Expand All @@ -22,10 +21,8 @@ import * as TextField from '#/components/forms/TextField'
import {useThrottledValue} from '#/components/hooks/useThrottledValue'
import {ArrowLeft_Stroke2_Corner0_Rounded as Arrow} from '#/components/icons/Arrow'
import {MagnifyingGlass2_Stroke2_Corner0_Rounded as Search} from '#/components/icons/MagnifyingGlass2'
import {InlineLinkText} from '#/components/Link'
import {Button, ButtonIcon, ButtonText} from '../Button'
import {ListFooter, ListMaybePlaceholder} from '../Lists'
import {Text} from '../Typography'

export function GifSelectDialog({
control,
Expand All @@ -36,27 +33,13 @@ export function GifSelectDialog({
onClose: () => void
onSelectGif: (gif: Gif) => void
}) {
const externalEmbedsPrefs = useExternalEmbedsPrefs()
const onSelectGif = useCallback(
(gif: Gif) => {
control.close(() => onSelectGifProp(gif))
},
[control, onSelectGifProp],
)

let content = null
let snapPoints
switch (externalEmbedsPrefs?.giphy) {
case 'show':
content = <GifList onSelectGif={onSelectGif} />
snapPoints = ['100%']
break
case 'hide':
default:
content = <GiphyConsentPrompt />
break
}

const renderErrorBoundary = useCallback(
(error: any) => <DialogError details={String(error)} />,
[],
Expand All @@ -65,28 +48,35 @@ export function GifSelectDialog({
return (
<Dialog.Outer
control={control}
nativeOptions={{sheet: {snapPoints}}}
nativeOptions={{sheet: {snapPoints: ['100%']}}}
onClose={onClose}>
<Dialog.Handle />
<ErrorBoundary renderError={renderErrorBoundary}>{content}</ErrorBoundary>
<ErrorBoundary renderError={renderErrorBoundary}>
<GifList control={control} onSelectGif={onSelectGif} />
</ErrorBoundary>
</Dialog.Outer>
)
}

function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
function GifList({
control,
onSelectGif,
}: {
control: Dialog.DialogControlProps
onSelectGif: (gif: Gif) => void
}) {
const {_} = useLingui()
const t = useTheme()
const {gtMobile} = useBreakpoints()
const textInputRef = useRef<TextInput>(null)
const listRef = useRef<BottomSheetFlatListMethods>(null)
const [undeferredSearch, setSearch] = useState('')
const search = useThrottledValue(undeferredSearch, 500)
const {close} = Dialog.useDialogContext()

const isSearching = search.length > 0

const trendingQuery = useGiphyTrending()
const searchQuery = useGifphySearch(search)
const trendingQuery = useFeaturedGifsQuery()
const searchQuery = useGifSearchQuery(search)

const {
data,
Expand All @@ -100,17 +90,7 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
} = isSearching ? searchQuery : trendingQuery

const flattenedData = useMemo(() => {
const uniquenessSet = new Set<string>()

function filter(gif: Gif) {
if (!gif) return false
if (uniquenessSet.has(gif.id)) {
return false
}
uniquenessSet.add(gif.id)
return true
}
return data?.pages.flatMap(page => page.data.filter(filter)) || []
return data?.pages.flatMap(page => page.results) || []
}, [data])

const renderItem = useCallback(
Expand All @@ -133,9 +113,9 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
textInputRef.current?.clear()
setSearch('')
} else {
close()
control.close()
}
}, [close, isSearching])
}, [control, isSearching])

const listHeader = useMemo(() => {
return (
Expand Down Expand Up @@ -166,7 +146,7 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
variant="ghost"
color="secondary"
shape="round"
onPress={() => close()}
onPress={() => control.close()}
label={_(msg`Close GIF dialog`)}>
<ButtonIcon icon={Arrow} size="md" />
</Button>
Expand All @@ -176,7 +156,7 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
<TextField.Icon icon={Search} />
<TextField.Input
label={_(msg`Search GIFs`)}
placeholder={_(msg`Powered by GIPHY`)}
placeholder={_(msg`Search Tenor`)}
onChangeText={text => {
setSearch(text)
listRef.current?.scrollToOffset({offset: 0, animated: false})
Expand All @@ -187,14 +167,14 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
maxLength={50}
onKeyPress={({nativeEvent}) => {
if (nativeEvent.key === 'Escape') {
close()
control.close()
}
}}
/>
</TextField.Root>
</View>
)
}, [gtMobile, t.atoms.bg, _, close])
}, [gtMobile, t.atoms.bg, _, control])

return (
<>
Expand All @@ -218,12 +198,12 @@ function GifList({onSelectGif}: {onSelectGif: (gif: Gif) => void}) {
emptyType="results"
sideBorders={false}
errorTitle={_(msg`Failed to load GIFs`)}
errorMessage={_(msg`There was an issue connecting to GIPHY.`)}
errorMessage={_(msg`There was an issue connecting to Tenor.`)}
emptyMessage={
isSearching
? _(msg`No search results found for "${search}".`)
: _(
msg`No trending GIFs found. There may be an issue with GIPHY.`,
msg`No featured GIFs found. There may be an issue with Tenor.`,
)
}
/>
Expand Down Expand Up @@ -282,7 +262,9 @@ function GifPreview({
{aspectRatio: 1, opacity: pressed ? 0.8 : 1},
t.atoms.bg_contrast_25,
]}
source={{uri: gif.images.preview_gif.url}}
source={{
uri: gif.media_formats.tinygif.url,
}}
contentFit="cover"
accessibilityLabel={gif.title}
accessibilityHint=""
Expand All @@ -294,77 +276,6 @@ function GifPreview({
)
}

export function GiphyConsentPrompt() {
const {_} = useLingui()
const t = useTheme()
const {gtMobile} = useBreakpoints()
const setExternalEmbedPref = useSetExternalEmbedPref()
const {close} = Dialog.useDialogContext()

const onShowPress = useCallback(() => {
close(() => setExternalEmbedPref('giphy', 'show'))
}, [close, setExternalEmbedPref])

const onHidePress = useCallback(() => {
close(() => {
setExternalEmbedPref('giphy', 'hide')
})
}, [close, setExternalEmbedPref])

const gtMobileWeb = gtMobile && isWeb

return (
<Dialog.ScrollableInner label={_(msg`Permission to use GIPHY`)}>
<View style={a.gap_sm}>
<Text style={[a.text_2xl, a.font_bold]}>
<Trans>Permission to use GIPHY</Trans>
</Text>

<View style={[a.mt_sm, a.mb_2xl, a.gap_lg]}>
<Text>
<Trans>Bluesky uses GIPHY for GIF features within the app.</Trans>
</Text>

<Text style={t.atoms.text_contrast_medium}>
<Trans>
GIPHY may collect information about you and your device. You can
find out more in their{' '}
<InlineLinkText to={GIPHY_PRIVACY_POLICY} onPress={() => close()}>
privacy policy
</InlineLinkText>
.
</Trans>
</Text>
</View>
</View>
<View style={[a.gap_md, gtMobileWeb && a.flex_row_reverse]}>
<Button
label={_(msg`Enable GIPHY`)}
onPress={onShowPress}
onAccessibilityEscape={close}
color="primary"
size={gtMobileWeb ? 'small' : 'medium'}
variant="solid">
<ButtonText>
<Trans>Enable GIPHY</Trans>
</ButtonText>
</Button>
<Button
label={_(msg`No thanks`)}
onAccessibilityEscape={close}
onPress={onHidePress}
color="secondary"
size={gtMobileWeb ? 'small' : 'medium'}
variant="ghost">
<ButtonText>
<Trans>No thanks</Trans>
</ButtonText>
</Button>
</View>
</Dialog.ScrollableInner>
)
}

function DialogError({details}: {details?: string}) {
const {_} = useLingui()
const control = Dialog.useDialogContext()
Expand Down
14 changes: 6 additions & 8 deletions src/lib/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,11 +90,9 @@ export const BSKY_FEED_OWNER_DIDS = [
'did:plc:q6gjnaw2blty4crticxkmujt',
]

export const GIPHY_API_URL = 'https://api.giphy.com'
export const GIPHY_API_KEY = Platform.select({
ios: 'ydVxhrQkwlcUjkVKx15mF6vyaNJbMeez',
android: 'Vwj3Ib7857dj3EcIg24Hiz1LbRVdGeYF',
default: 'vyL3hQQ8AipwcmIB8kFvg0NDs9faWg7G',
})
export const GIPHY_PRIVACY_POLICY =
'https://support.giphy.com/hc/en-us/articles/360032872931-GIPHY-Privacy-Policy'
export const GIF_SERVICE = 'https://gifs.bsky.app'

export const GIF_SEARCH = (params: string) =>
`${GIF_SERVICE}/tenor/v2/search?${params}`
export const GIF_FEATURED = (params: string) =>
`${GIF_SERVICE}/tenor/v2/featured?${params}`
Loading

0 comments on commit 4f40ff3

Please sign in to comment.