/* * Wire * Copyright (C) 2022 Wire Swiss GmbH * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see http://www.gnu.org/licenses/. * */ import {FC, useEffect, useState} from 'react'; import {amplify} from 'amplify'; import cx from 'classnames'; import {Button, ButtonVariant} from '@wireapp/react-ui-kit'; import {WebAppEvents} from '@wireapp/webapp-events'; import {GifImage} from 'Components/Giphy/GifImage'; import * as Icon from 'Components/Icon'; import {t} from 'Util/LocalizerUtil'; import {Gif, GiphyRepository} from '../../extension/GiphyRepository'; const GIPHY_CLOSE_TIMEOUT = 350; export enum GiphyState { DEFAULT = '', ERROR = 'GiphyViewModel.STATE.ERROR', LOADING = 'GiphyViewModel.STATE.LOADING', NO_SEARCH_RESULT = 'GiphyViewModel.STATE.NO_SEARCH_RESULT', RESULT = 'GiphyViewModel.STATE.RESULT', RESULTS = 'GiphyViewModel.STATE.RESULTS', } interface GiphyProps { readonly giphyRepository: GiphyRepository; inputValue: string; onClose: () => void; defaultGiphyState?: GiphyState; } const Giphy: FC = ({giphyRepository, defaultGiphyState = GiphyState.DEFAULT, inputValue, onClose}) => { const [playAnimation, setPlayAnimation] = useState(false); const [currentQuery, setCurrentQuery] = useState(inputValue); const [gifs, setGifs] = useState([]); const [selectedGif, setSelectedGif] = useState(null); const [currentGif, setCurrentGif] = useState(null); const [giphyState, setGiphyState] = useState(defaultGiphyState); const isErrorState = giphyState === GiphyState.ERROR; const isLoading = giphyState === GiphyState.LOADING; const isSingleGif = giphyState === GiphyState.RESULT; const isMultipleGifs = giphyState === GiphyState.RESULTS; const noSearchResults = giphyState === GiphyState.NO_SEARCH_RESULT; const hasGifs = gifs.length > 0; const loadingTxt = isLoading ? t('accessibility.giphyModal.loading') : ''; const clearGifs = (): void => { setGifs([]); setSelectedGif(null); setGiphyState(GiphyState.LOADING); }; const getGifs = async (query: string, displaySingleResult = false): Promise => { if (isErrorState) { return; } clearGifs(); try { const fetchedGifs = await giphyRepository.getGifs(query); if (fetchedGifs.length === 0) { setGiphyState(GiphyState.NO_SEARCH_RESULT); return; } if (fetchedGifs.length === 1 || displaySingleResult) { const gif = fetchedGifs[0]; setCurrentGif(gif); setGifs([gif]); setSelectedGif(gif); setGiphyState(GiphyState.RESULT); } else { setGifs(fetchedGifs); setGiphyState(GiphyState.RESULTS); } } catch (error) { console.warn(error); setGiphyState(GiphyState.ERROR); } }; const onGridClick = async () => getGifs(currentQuery); const onBackClick = () => { if (currentGif) { setGifs([currentGif]); setSelectedGif(currentGif); setGiphyState(GiphyState.RESULT); } }; const onCloseClick = () => { requestAnimationFrame(() => setPlayAnimation(false)); setTimeout(() => { onClose(); giphyRepository.resetOffset(); }, GIPHY_CLOSE_TIMEOUT); }; const showGiphy = async (query: string) => { setCurrentQuery(query); await getGifs(query, true); }; const getRandomGif = async () => { if (isErrorState) { return; } clearGifs(); try { const gif = await giphyRepository.getRandomGif({tag: currentQuery}); setCurrentGif(gif); setGifs([gif]); setSelectedGif(gif); setGiphyState(GiphyState.RESULT); } catch (error) { setGiphyState(GiphyState.ERROR); } }; const onSend = () => { if (selectedGif) { amplify.publish(WebAppEvents.EXTENSIONS.GIPHY.SEND, selectedGif.animated, currentQuery); setSelectedGif(null); onCloseClick(); } }; const onSelectGif = (clickedGif: Gif): void => { const hasMultipleGifs = gifs.length !== 1; if (hasMultipleGifs) { if (selectedGif === clickedGif) { setSelectedGif(null); } else { setSelectedGif(clickedGif); } } }; useEffect(() => { if (inputValue) { requestAnimationFrame(() => setPlayAnimation(true)); showGiphy(inputValue); } }, [inputValue]); return (
{isSingleGif && (
{isLoading && (
)} {isSingleGif && currentGif && (
)} {isMultipleGifs && (
{gifs.map(gif => ( ))}
)} {isErrorState && (
{t('extensionsGiphyNoGifs')}
)}
); }; export {Giphy};