From bc59f728fb524a5d4413df81a26742a0831ec73e Mon Sep 17 00:00:00 2001 From: Jay Harris Date: Fri, 21 Oct 2022 12:11:31 +1300 Subject: [PATCH 1/4] Move hook to its own file --- .../default/braveToday/cards/CardImage.tsx | 57 +----------------- .../default/braveToday/customize/FeedCard.tsx | 4 +- .../braveToday/customize/SourcesListEntry.tsx | 4 +- .../default/braveToday/useUnpaddedImageUrl.ts | 58 +++++++++++++++++++ 4 files changed, 65 insertions(+), 58 deletions(-) create mode 100644 components/brave_new_tab_ui/components/default/braveToday/useUnpaddedImageUrl.ts diff --git a/components/brave_new_tab_ui/components/default/braveToday/cards/CardImage.tsx b/components/brave_new_tab_ui/components/default/braveToday/cards/CardImage.tsx index 5686a3bf4cd6..9685c0c0e693 100644 --- a/components/brave_new_tab_ui/components/default/braveToday/cards/CardImage.tsx +++ b/components/brave_new_tab_ui/components/default/braveToday/cards/CardImage.tsx @@ -5,7 +5,8 @@ import * as React from 'react' import * as Card from '../cardSizes' -import getBraveNewsController, * as BraveNews from '../../../../api/brave_news' +import * as BraveNews from '../../../../api/brave_news' +import { useUnpaddedImageUrl } from '../useUnpaddedImageUrl' type Props = { imageUrl?: string @@ -14,60 +15,8 @@ type Props = { onLoaded?: () => any } -const cache: { [url: string]: string } = {} - -export function useGetUnpaddedImage (paddedUrl: string | undefined, onLoaded?: () => any, useCache?: boolean) { - const [unpaddedUrl, setUnpaddedUrl] = React.useState('') - - React.useEffect(() => { - const onReceiveUnpaddedUrl = (result: string) => { - if (useCache) cache[paddedUrl!] = result - setUnpaddedUrl(result) - - if (onLoaded) window.requestAnimationFrame(() => onLoaded()) - } - - // Storybook method - // @ts-expect-error - if (window.braveStorybookUnpadUrl) { - // @ts-expect-error - window.braveStorybookUnpadUrl(paddedUrl) - .then(onReceiveUnpaddedUrl) - return - } - - if (!paddedUrl) return - - if (cache[paddedUrl]) { - onReceiveUnpaddedUrl(cache[paddedUrl]) - return - } - - let blobUrl: string - getBraveNewsController().getImageData({ url: paddedUrl }) - .then(async (result) => { - if (!result.imageData) { - return - } - - const blob = new Blob([new Uint8Array(result.imageData)], { type: 'image/*' }) - blobUrl = URL.createObjectURL(blob) - onReceiveUnpaddedUrl(blobUrl) - }) - .catch(err => { - console.error(`Error getting image for ${paddedUrl}.`, err) - }) - - // Only revoke the URL if we aren't using the cache. - return () => { - if (!useCache) URL.revokeObjectURL(blobUrl) - } - }, [paddedUrl]) - return unpaddedUrl -} - export default function CardImage (props: Props) { - const unpaddedUrl = useGetUnpaddedImage(props.imageUrl, props.onLoaded) + const unpaddedUrl = useUnpaddedImageUrl(props.imageUrl, props.onLoaded) const [isImageLoaded, setIsImageLoaded] = React.useState(false) React.useEffect(() => { if (unpaddedUrl) { diff --git a/components/brave_new_tab_ui/components/default/braveToday/customize/FeedCard.tsx b/components/brave_new_tab_ui/components/default/braveToday/customize/FeedCard.tsx index d4916e6f9f96..d1e1ebfad334 100644 --- a/components/brave_new_tab_ui/components/default/braveToday/customize/FeedCard.tsx +++ b/components/brave_new_tab_ui/components/default/braveToday/customize/FeedCard.tsx @@ -8,10 +8,10 @@ import * as React from 'react' import styled from 'styled-components' import { api } from '../../../../api/brave_news/news' import Flex from '../../../Flex' -import { useGetUnpaddedImage } from '../cards/CardImage' import FollowButton from './FollowButton' import { getCardColor } from './colors' import { usePublisher, usePublisherFollowed } from './Context' +import { useUnpaddedImageUrl } from '../useUnpaddedImageUrl' interface CardProps { backgroundColor?: string @@ -63,7 +63,7 @@ export default function FeedCard (props: { const { followed, setFollowed } = usePublisherFollowed(props.publisherId) const backgroundColor = publisher.backgroundColor || getCardColor(publisher.feedSource?.url || publisher.publisherId) - const coverUrl = useGetUnpaddedImage(publisher.coverUrl?.url, undefined, /* useCache= */true) + const coverUrl = useUnpaddedImageUrl(publisher.coverUrl?.url, undefined, /* useCache= */true) return {coverUrl && } diff --git a/components/brave_new_tab_ui/components/default/braveToday/customize/SourcesListEntry.tsx b/components/brave_new_tab_ui/components/default/braveToday/customize/SourcesListEntry.tsx index 480b18d56bab..eeb708a07a66 100644 --- a/components/brave_new_tab_ui/components/default/braveToday/customize/SourcesListEntry.tsx +++ b/components/brave_new_tab_ui/components/default/braveToday/customize/SourcesListEntry.tsx @@ -7,8 +7,8 @@ import * as React from 'react' import styled from 'styled-components' import { getLocale } from '$web-common/locale' import Flex from '../../../Flex' -import { useGetUnpaddedImage } from '../cards/CardImage' import { useChannelSubscribed, usePublisher, usePublisherFollowed } from './Context' +import { useUnpaddedImageUrl } from '../useUnpaddedImageUrl' interface Props { publisherId: string @@ -60,7 +60,7 @@ const ChannelNameText = styled.span` ` function FavIcon (props: { src?: string }) { - const url = useGetUnpaddedImage(props.src, undefined, /* useCache= */true) + const url = useUnpaddedImageUrl(props.src, undefined, /* useCache= */true) const [error, setError] = React.useState(false) return {url && !error && setError(true)} />} diff --git a/components/brave_new_tab_ui/components/default/braveToday/useUnpaddedImageUrl.ts b/components/brave_new_tab_ui/components/default/braveToday/useUnpaddedImageUrl.ts new file mode 100644 index 000000000000..1a42dd2614d1 --- /dev/null +++ b/components/brave_new_tab_ui/components/default/braveToday/useUnpaddedImageUrl.ts @@ -0,0 +1,58 @@ +// Copyright (c) 2022 The Brave Authors. All rights reserved. +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this file, +// you can obtain one at http://mozilla.org/MPL/2.0/. + +import * as React from 'react' +import getBraveNewsController from '../../../api/brave_news' + +const cache: { [url: string]: string } = {} +export function useUnpaddedImageUrl (paddedUrl: string | undefined, onLoaded?: () => any, useCache?: boolean) { + const [unpaddedUrl, setUnpaddedUrl] = React.useState('') + + React.useEffect(() => { + const onReceiveUnpaddedUrl = (result: string) => { + if (useCache) cache[paddedUrl!] = result + setUnpaddedUrl(result) + + if (onLoaded) window.requestAnimationFrame(() => onLoaded()) + } + + // Storybook method + // @ts-expect-error + if (window.braveStorybookUnpadUrl) { + // @ts-expect-error + window.braveStorybookUnpadUrl(paddedUrl) + .then(onReceiveUnpaddedUrl) + return + } + + if (!paddedUrl) return + + if (cache[paddedUrl]) { + onReceiveUnpaddedUrl(cache[paddedUrl]) + return + } + + let blobUrl: string + getBraveNewsController().getImageData({ url: paddedUrl }) + .then(async (result) => { + if (!result.imageData) { + return + } + + const blob = new Blob([new Uint8Array(result.imageData)], { type: 'image/*' }) + blobUrl = URL.createObjectURL(blob) + onReceiveUnpaddedUrl(blobUrl) + }) + .catch(err => { + console.error(`Error getting image for ${paddedUrl}.`, err) + }) + + // Only revoke the URL if we aren't using the cache. + return () => { + if (!useCache) URL.revokeObjectURL(blobUrl) + } + }, [paddedUrl]) + return unpaddedUrl +} From 1736b4b7ab27186c6cf3d3c2056b0db6161cb975 Mon Sep 17 00:00:00 2001 From: Jay Harris Date: Fri, 21 Oct 2022 14:03:29 +1300 Subject: [PATCH 2/4] Make it possible to lazy load unpadded urls --- .../braveToday/customize/Configure.tsx | 2 +- .../default/braveToday/customize/FeedCard.tsx | 11 ++++-- .../default/braveToday/useUnpaddedImageUrl.ts | 39 +++++++++++++++++++ 3 files changed, 48 insertions(+), 4 deletions(-) diff --git a/components/brave_new_tab_ui/components/default/braveToday/customize/Configure.tsx b/components/brave_new_tab_ui/components/default/braveToday/customize/Configure.tsx index 3bb4a27dd616..08cb38664701 100644 --- a/components/brave_new_tab_ui/components/default/braveToday/customize/Configure.tsx +++ b/components/brave_new_tab_ui/components/default/braveToday/customize/Configure.tsx @@ -114,7 +114,7 @@ export default function Configure () { } return ( - +