import { IGif } from "@giphy/js-types" ; import React , { FunctionComponent , useCallback , useEffect } from "react" ; import { useField } from "react-final-form" ; import { isMediaLink , MediaLink } from "coral-common/helpers/findMediaLinks" ; import { Icon } from "coral-ui/components/v2" ; import { CallOut } from "coral-ui/components/v3" ; import { MediaConfirmPrompt , MediaPreview , } from "../../Comment/MediaConfirmation" ; import ExternalImageInput from "../../ExternalImageInput" ; import GiphyInput , { GifPreview } from "../../GiphyInput" ; import { getMediaValidators } from "../../helpers" ; export type Widget = "giphy" | "external" | null ; interface GiphyConfig { key : string | null ; enabled : boolean ; maxRating : string | null ; } interface Props { widget : Widget ; setWidget : ( widget : Widget ) => void ; siteID : string ; pastedMedia : MediaLink | null ; setPastedMedia : ( media : MediaLink | null ) => void ; giphyConfig : GiphyConfig ; } interface Media { id ? : string ; type : "giphy" | "twitter" | "youtube" | "external" ; url : string ; width ? : string ; height ? : string ; } const MediaField = ( { widget , setWidget , siteID , pastedMedia , setPastedMedia , giphyConfig , } ) => { const { input : { value , onChange } , meta : { valid , dirty , error } , } = useField < Media | undefined > ( "media" , { validate : getMediaValidators ( ) , } ) ; const onGiphySelect = useCallback ( ( gif ) => onChange ( { type : "giphy" , id : gif . id , url : gif . images . original . url , } ) , [ onChange ] ) ; const onExternalImageSelect = useCallback ( ( url ) => onChange ( { type : "external" , url , } ) , [ onChange ] ) ; const onRemove = useCallback ( ( ) => { onChange ( undefined ) ; setPastedMedia ( null ) ; } , [ onChange , setPastedMedia ] ) ; const onConfirmPastedMedia = useCallback ( ( ) => { onChange ( pastedMedia ! ) ; setPastedMedia ( null ) ; } , [ onChange , pastedMedia , setPastedMedia ] ) ; useEffect ( ( ) => { if ( ! widget && dirty && ! valid ) { onChange ( undefined ) ; } if ( ! widget ) { return ; } if ( value ) { if ( widget === value . type ) { if ( dirty && valid ) { setWidget ( null ) ; } } else { onChange ( undefined ) ; } } if ( pastedMedia ) { setWidget ( null ) ; } } , [ dirty , valid , value , onChange , pastedMedia , setPastedMedia , setWidget , widget , ] ) ; return ( < > { } { pastedMedia ? ( < MediaConfirmPrompt media = { pastedMedia } onConfirm = { onConfirmPastedMedia } onRemove = { onRemove } / > ) : widget === "giphy" ? ( giphyConfig . key && giphyConfig . maxRating && ( < GiphyInput onSelect = { onGiphySelect } apiKey = { giphyConfig . key } maxRating = { giphyConfig . maxRating } / > ) ) : widget === "external" ? ( < ExternalImageInput onSelect = { onExternalImageSelect } / > ) : null } { } { ! widget && value ?. url && valid ? ( isMediaLink ( value ) ? ( < MediaPreview media = { value } siteID = { siteID } onRemove = { onRemove } / > ) : ( < GifPreview url = { value . url } onRemove = { onRemove } / > ) ) : null } { } { error && ( < CallOut color = "error" title = { error } titleWeight = "semiBold" icon = { < Icon > error < /Icon>} role="alert"/ > ) } < />); } ; export default MediaField ;