diff --git a/root/static/scripts/common/components/CommonsImage.js b/root/static/scripts/common/components/CommonsImage.js index 289623eef71..8e258c61ccc 100644 --- a/root/static/scripts/common/components/CommonsImage.js +++ b/root/static/scripts/common/components/CommonsImage.js @@ -12,48 +12,57 @@ import * as React from 'react'; import {minimalEntity} from '../../../../utility/hydrate.js'; import entityHref from '../utility/entityHref.js'; -type Props = { - +cachedImage: ?CommonsImageT, - +entity: NonUrlRelatableEntityT, -}; - -type State = { - image: ?CommonsImageT, -}; - -class CommonsImage extends React.Component { - constructor(props: Props) { - super(props); - this.state = {image: props.cachedImage}; - } - - componentDidMount() { - if (!this.state.image) { - const $ = require('jquery'); - $.get(entityHref(this.props.entity, '/commons-image'), data => { - this.setState({image: data.image}); - }); +type CommonsImageRequestCallbackT = (CommonsImageT | null) => void; + +function loadCommonsImage( + entity: NonUrlRelatableEntityT, + callback: CommonsImageRequestCallbackT, +): void { + const url = entityHref(entity, '/commons-image'); + + fetch(url) + .then(resp => resp.json()) + .then((reqData) => { + callback(reqData.image); + }) + .catch((error) => { + console.error(error); + Sentry.captureException(error); + }); +} + +component CommonsImage( + cachedImage: ?CommonsImageT, + entity: NonUrlRelatableEntityT, +) { + const [commonsImage, setCommonsImage] = React.useState(cachedImage); + + const loadCallback: CommonsImageRequestCallbackT = + React.useCallback((data) => { + setCommonsImage(data); + }, [setCommonsImage]); + + React.useEffect(() => { + if (cachedImage == null) { + loadCommonsImage(entity, loadCallback); } - } - - render(): React.MixedElement | null { - const {image} = this.state; - return image ? ( -
- -
- - - {l('Image from Wikimedia Commons')} - - -
- ) : null; - } + }, [entity, loadCallback]); + + return commonsImage ? ( +
+ +
+ + + {l('Image from Wikimedia Commons')} + + +
+ ) : null; } -export default (hydrate( +export default (hydrate>( 'div.commons-image', CommonsImage, minimalEntity, -): React.AbstractComponent); +): component(...React.PropsOf)); diff --git a/root/static/scripts/common/components/WikipediaExtract.js b/root/static/scripts/common/components/WikipediaExtract.js index be741712377..2ec9a912925 100644 --- a/root/static/scripts/common/components/WikipediaExtract.js +++ b/root/static/scripts/common/components/WikipediaExtract.js @@ -31,59 +31,67 @@ type MinimalEntityWithWikipediaExtractT = { +gid: string, }; -type Props = { - +cachedWikipediaExtract: WikipediaExtractT | null, - +entity: - | EntityWithWikipediaExtractT - | MinimalEntityWithWikipediaExtractT, -}; +type WikipediaExtractRequestCallbackT = (WikipediaExtractT | null) => void; -type State = { - wikipediaExtract: WikipediaExtractT | null, -}; +function loadWikipediaExtract( + entity: EntityWithWikipediaExtractT | MinimalEntityWithWikipediaExtractT, + callback: WikipediaExtractRequestCallbackT, +): void { + const url = entityHref(entity, '/wikipedia-extract'); + + fetch(url) + .then(resp => resp.json()) + .then((reqData) => { + callback(reqData.wikipediaExtract); + }) + .catch((error) => { + console.error(error); + Sentry.captureException(error); + }); +} + +component WikipediaExtract( + cachedWikipediaExtract: WikipediaExtractT | null, + entity: EntityWithWikipediaExtractT | MinimalEntityWithWikipediaExtractT, +) { + const [wikipediaExtract, setWikipediaExtract] = + React.useState(cachedWikipediaExtract); -class WikipediaExtract extends React.Component { - constructor(props: Props) { - super(props); - this.state = {wikipediaExtract: props.cachedWikipediaExtract}; - } + const loadCallback: WikipediaExtractRequestCallbackT = + React.useCallback((data) => { + setWikipediaExtract(data); + }, [setWikipediaExtract]); - componentDidMount() { - if (!this.state.wikipediaExtract) { - const $ = require('jquery'); - $.get(entityHref(this.props.entity, '/wikipedia-extract'), data => { - this.setState(data); - }); + React.useEffect(() => { + if (cachedWikipediaExtract == null) { + loadWikipediaExtract(entity, loadCallback); } - } + }, [entity, loadCallback]); - render(): React.MixedElement | null { - const {wikipediaExtract} = this.state; - return wikipediaExtract ? ( - <> -

{l('Wikipedia')}

- - - {l('Continue reading at Wikipedia...')} - - {' '} - - {exp.l( - `Wikipedia content provided under the terms of the - {license_link|Creative Commons BY-SA license}`, - {license_link: 'https://creativecommons.org/licenses/by-sa/3.0/'}, - )} - - - ) : null; - } + return wikipediaExtract ? ( + <> +

{l('Wikipedia')}

+ + + {l('Continue reading at Wikipedia...')} + + {' '} + + {exp.l( + `Wikipedia content provided under the terms of the + {license_link|Creative Commons BY-SA license}`, + {license_link: 'https://creativecommons.org/licenses/by-sa/3.0/'}, + )} + + + ) : null; } -export default (hydrate( +export default (hydrate>( 'div.wikipedia-extract', WikipediaExtract, minimalEntity, -): React.AbstractComponent); +): component(...React.PropsOf));