Skip to content

Commit

Permalink
[Brave News]: FeedV2 Tweaks (#21295)
Browse files Browse the repository at this point in the history
  • Loading branch information
fallaciousreasoning committed Dec 13, 2023
1 parent 665cfe1 commit 8fa5317
Show file tree
Hide file tree
Showing 18 changed files with 188 additions and 120 deletions.
4 changes: 3 additions & 1 deletion browser/ui/webui/brave_webui_source.cc
Original file line number Diff line number Diff line change
Expand Up @@ -242,12 +242,14 @@ void CustomizeWebUIHTMLSource(content::WebUI* web_ui,
{ "braveNewsAdvertBadge", IDS_BRAVE_NEWS_ADVERT_BADGE},
{ "braveNewsHideContentFrom", IDS_BRAVE_NEWS_HIDE_CONTENT_FROM},
{ "braveNewsSourcesRecommendation", IDS_BRAVE_NEWS_SOURCES_RECOMMENDATION},
{ "braveNewsNoArticles", IDS_BRAVE_NEWS_NO_ARTICLES},
{ "braveNewsNoArticlesTitle", IDS_BRAVE_NEWS_NO_ARTICLES_TITLE},
{ "braveNewsNoArticlesMessage", IDS_BRAVE_NEWS_NO_ARTICLES_MESSAGE},
{ "braveNewsCustomizeFeed", IDS_BRAVE_NEWS_CUSTOMIZE_FEED},
{ "braveNewsRefreshFeed", IDS_BRAVE_NEWS_REFRESH_FEED},
{ "braveNewsOpenArticlesIn", IDS_BRAVE_NEWS_OPEN_ARTICLES_IN},
{ "braveNewsOpenArticlesInNewTab", IDS_BRAVE_NEWS_OPEN_ARTICLES_IN_NEW_TAB},
{ "braveNewsOpenArticlesInCurrentTab", IDS_BRAVE_NEWS_OPEN_ARTICLES_IN_CURRENT_TAB},
{ "braveNewsCaughtUp", IDS_BRAVE_NEWS_CAUGHT_UP},

// Brave News Channels
{ "braveNewsChannel-Brave", IDS_BRAVE_NEWS_CHANNEL_BRAVE},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import * as React from 'react'
import styled, { css } from 'styled-components'
import Flex from '$web-common/Flex'
import FeedCard from './FeedCard'
import PublisherCard from '../../../../../brave_news/browser/resources/shared/PublisherCard'
import { ArrowRight } from '../../../../../brave_news/browser/resources/shared/Icons'

const CARD_SIZE = 208
Expand Down Expand Up @@ -84,7 +84,7 @@ const ItemsContainer = styled(Flex)`
}
`

const FeedCardContainer = styled.div`
const PublisherCardContainer = styled.div`
min-width: calc((100cqi - ${CARD_GAP} * 2) / 3);
max-width: ${CARD_SIZE_PX};
scroll-snap-align: start;
Expand Down Expand Up @@ -138,9 +138,9 @@ export default function Carousel(props: Props) {
</Subtitle>}
<CarouselContainer>
<ItemsContainer direction='row' gap={CARD_GAP} ref={scrollContainerRef as any} onScroll={updateAvailableDirections}>
{props.publisherIds.map(p => <FeedCardContainer key={p}>
<FeedCard publisherId={p} />
</FeedCardContainer>)}
{props.publisherIds.map(p => <PublisherCardContainer key={p}>
<PublisherCard publisherId={p} />
</PublisherCardContainer>)}
</ItemsContainer>
<ScrollButtonLeft onClick={() => scroll('left')} hidden={availableDirections === 'right' || availableDirections === 'none'}>
{ArrowRight}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import styled from 'styled-components'
import { useBraveNews, useChannels } from '../../../../../brave_news/browser/resources/shared/Context'
import ChannelCard from './ChannelCard'
import DiscoverSection from './DiscoverSection'
import FeedCard, { DirectFeedCard } from './FeedCard'
import PublisherCard, { DirectPublisherCard } from '../../../../../brave_news/browser/resources/shared/PublisherCard'
import { PopularCarousel } from './Popular'
import { SuggestionsCarousel } from './Suggestions'
import useSearch from './useSearch'
Expand Down Expand Up @@ -89,7 +89,7 @@ function SearchResults (props: SearchResultsProps) {
}
<DiscoverSection name={getLocale('braveNewsAllSourcesHeader')}>
{search.filteredSources.publisherIds.map(publisherId =>
<FeedCard key={publisherId} publisherId={publisherId} />
<PublisherCard key={publisherId} publisherId={publisherId} />
)}
{showFetchPermissionButton &&
<div>
Expand All @@ -99,7 +99,7 @@ function SearchResults (props: SearchResultsProps) {
</div>
}
{search.filteredSources.direct.map(r =>
<DirectFeedCard key={r.feedUrl.url} feedUrl={r.feedUrl.url} title={r.feedTitle} />)}
<DirectPublisherCard key={r.feedUrl.url} feedUrl={r.feedUrl.url} title={r.feedTitle} />)}
{!search.canQueryFilterSources &&
getLocale('braveNewsSearchQueryTooShort')
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Carousel from './Carousel'
import CustomizeLink from './CustomizeLink'
import CustomizePage from './CustomizePage'
import DiscoverSection from './DiscoverSection'
import FeedCard from './FeedCard'
import PublisherCard from '../../../../../brave_news/browser/resources/shared/PublisherCard'

const usePopularPublisherIds = () => {
const { filteredPublisherIds, publishers, locale } = useBraveNews()
Expand Down Expand Up @@ -49,7 +49,7 @@ export function PopularPage () {
const popularPublisherIds = usePopularPublisherIds()
return <CustomizePage title={getLocale('braveNewsPopularTitle')}>
<DiscoverSection>
{popularPublisherIds.map(p => <FeedCard key={p} publisherId={p} />)}
{popularPublisherIds.map(p => <PublisherCard key={p} publisherId={p} />)}
</DiscoverSection>
</CustomizePage>
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import Carousel from './Carousel'
import CustomizeLink from './CustomizeLink'
import CustomizePage from './CustomizePage'
import DiscoverSection from './DiscoverSection'
import FeedCard from './FeedCard'
import PublisherCard from '../../../../../brave_news/browser/resources/shared/PublisherCard'

export function SuggestionsCarousel () {
const { suggestedPublisherIds, setCustomizePage } = useBraveNews()
Expand All @@ -31,7 +31,7 @@ export function SuggestionsPage () {
const { suggestedPublisherIds } = useBraveNews()
return <CustomizePage title={getLocale('braveNewsSuggestionsTitle')}>
<DiscoverSection>
{suggestedPublisherIds.map(p => <FeedCard key={p} publisherId={p} />)}
{suggestedPublisherIds.map(p => <PublisherCard key={p} publisherId={p} />)}
</DiscoverSection>
</CustomizePage>
}
23 changes: 12 additions & 11 deletions components/brave_new_tab_ui/components/default/page/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,19 +88,20 @@ const StyledPage = styled('div') <PageProps>`
NTP items remain in the same place, and still allows NTP
Page to scroll to the bottom before that starts happening. */
z-index: 3;
/* Blur out the content when Brave News is interacted
with. We need the opacity to fade out our background image.
We need the background image to overcome the bug
where a backdrop-filter element's ancestor which has
a filter must also have a background. When this bug is
fixed then this element won't need the background.
*/
opacity: calc(1 - var(--ntp-extra-content-effect-multiplier));
filter: blur(var(--blur-amount));
background: var(--default-bg-color);
${getPageBackground}
}
/* Blur out the content when Brave News is interacted
with. We need the opacity to fade out our background image.
We need the background image to overcome the bug
where a backdrop-filter element's ancestor which has
a filter must also have a background. When this bug is
fixed then this element won't need the background.
*/
opacity: calc(1 - var(--ntp-extra-content-effect-multiplier));
filter: blur(var(--blur-amount));
background: var(--default-bg-color);
${getPageBackground}
@media screen and (max-width: ${breakpointEveryBlock}) {
display: flex;
flex-direction: column;
Expand Down
1 change: 0 additions & 1 deletion components/brave_new_tab_ui/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,4 @@
"**/*.tsx",
"**/*.d.ts",
"../definitions/*.d.ts"
]
}
19 changes: 15 additions & 4 deletions components/brave_news/browser/resources/Feed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ import HeroArticle from "./feed/Hero";
import { getHistoryValue, setHistoryState } from "./shared/history";
import NoArticles from "./feed/NoArticles";
import LoadingCard from "./feed/LoadingCard";
import { spacing } from "@brave/leo/tokens/css";
import CaughtUp from "./feed/CaughtUp";

// Restoring scroll position is complicated - we have two available strategies:
// 1. Scroll to the same position - as long as the window hasn't been resized,
Expand All @@ -27,11 +29,17 @@ interface NewsScrollData {
scrollPos: number,
}

const CARD_CLASS = 'feed-card'
const FeedContainer = styled.div`
width: 540px;
display: flex;
flex-direction: column;
gap: 12px;
gap: ${spacing.xl};
/* Hide Ad elements, if we weren't able to fill them */
& .${CARD_CLASS}:empty {
display: none;
}
`

interface Props {
Expand All @@ -52,7 +60,6 @@ export const NEWS_FEED_CLASS = "news-feed"
// The number of cards to load at a time. Making this too high will result in
// jank as all the cards are rendered at once.
const PAGE_SIZE = 25;
const CARD_CLASS = 'feed-card'
const HISTORY_SCROLL_DATA = 'bn-scroll-data'
const HISTORY_CARD_COUNT = 'bn-card-count'

Expand All @@ -73,7 +80,7 @@ export default function Component({ feed }: Props) {
// Store the number of cards we've loaded in history - otherwise when we
// navigate back we might not be able to scroll down far enough.
React.useEffect(() => {
setHistoryState({ HISTORY_CARD_COUNT: cardCount })
setHistoryState({ [HISTORY_CARD_COUNT]: cardCount })
}, [cardCount])

// Track the feed scroll position - if we mount this component somewhere with
Expand Down Expand Up @@ -138,7 +145,11 @@ export default function Component({ feed }: Props) {

return <FeedContainer className={NEWS_FEED_CLASS}>
{feed
? !feed.items.length ? <NoArticles /> : cards
? !feed.items.length ? <NoArticles />
: <>
{cards}
<CaughtUp />
</>
: <LoadingCard />}
</FeedContainer>
}
2 changes: 1 addition & 1 deletion components/brave_news/browser/resources/feed/Ad.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,6 @@ export default function Advert(props: Props) {
{advert.title}
</SecureLink>
</Title>
<CtaButton kind='outline'>{advert.ctaText}</CtaButton>
<CtaButton kind='plain-faint'>{advert.ctaText}</CtaButton>
</Container>
}
3 changes: 2 additions & 1 deletion components/brave_news/browser/resources/feed/Article.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ interface Props {
const Container = styled(Card)`
display: flex;
flex-direction: column;
padding-top: ${spacing.l};
`

export default function Article({ info, hideChannel }: Props) {
Expand All @@ -27,7 +28,7 @@ export default function Article({ info, hideChannel }: Props) {

return <Container ref={setElementRef} onClick={braveNewsCardClickHandler(url)}>
<ArticleMetaRow article={info.data} hideChannel={hideChannel} />
<Flex direction='row' gap={spacing.m} justify='space-between'>
<Flex direction='row' gap={spacing.m} justify='space-between' align='start'>
<Title>
<BraveNewsLink href={url}>{info.data.title}</BraveNewsLink>
</Title>
Expand Down
19 changes: 13 additions & 6 deletions components/brave_news/browser/resources/feed/ArticleMetaRow.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ import { getLocale } from '$web-common/locale';
import { getTranslatedChannelName } from "../shared/channel";

const MenuButton = styled(Button)`
--leo-button-padding: ${spacing.s};
--leo-button-padding: 0;
flex-grow: 0;
`
Expand All @@ -34,6 +34,12 @@ export const MetaInfoContainer = styled.h4`
gap: ${spacing.s};
`

const publisherDescription = (article: FeedItemMetadata) => {
if (article.publisherName) return article.publisherName
const url = new URL(article.url.url)
return url.origin
}

export function MetaInfo(props: { article: FeedItemMetadata, hideChannel?: boolean }) {
const maybeChannel = !props.hideChannel && <>
{channelIcons[props.article.categoryName] ?? channelIcons.default} {getTranslatedChannelName(props.article.categoryName)}
Expand All @@ -43,7 +49,7 @@ export function MetaInfo(props: { article: FeedItemMetadata, hideChannel?: boole
{props.article.relativeTimeDescription}
</>
return <MetaInfoContainer>
{props.article.publisherName} {maybeChannel} {maybeTime}
{publisherDescription(props.article)} {maybeChannel} {maybeTime}
</MetaInfoContainer>
}

Expand All @@ -52,15 +58,16 @@ export default function ArticleMetaRow(props: { article: FeedItemMetadata, hideC
<MetaInfo {...props} />

<ButtonMenu>
<MenuButton slot='anchor-content' kind='plain-faint'>
<MenuButton slot='anchor-content' kind='plain-faint' size="tiny">
<Icon name='more-horizontal' />
</MenuButton>
<leo-menu-item onClick={e => {
getBraveNewsController().setPublisherPref(props.article.publisherId, UserEnabled.DISABLED)
e.stopPropagation()
}}>{getLocale('braveNewsHideContentFrom', {
'$1': props.article.publisherName
})}</leo-menu-item>
}}>
{getLocale('braveNewsHideContentFrom')
.replace('$1', publisherDescription(props.article))}
</leo-menu-item>
</ButtonMenu>
</Flex>
}
25 changes: 20 additions & 5 deletions components/brave_news/browser/resources/feed/Card.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@
// License, v. 2.0. If a copy of the MPL was not distributed with this file,
// You can obtain one at https://mozilla.org/MPL/2.0/.

import * as React from 'react';
import { color, effect, font, radius, spacing } from '@brave/leo/tokens/css';
import styled from "styled-components";
import SecureLink, { SecureLinkProps, validateScheme } from '$web-common/SecureLink';
import * as React from 'react';
import { configurationCache, useBraveNews } from '../shared/Context';

export const Header = styled.h2`
Expand All @@ -27,14 +27,29 @@ export const Title = styled.h3`
margin: 0;
text-align: start;
font: ${font.primary.default.regular};
font: ${font.primary.default.semibold};
color: var(--bn-glass-100);
&> a { all: unset; }
`

export const SmallImage = styled.img`
const HidableImage = ({ onError, ...rest }: React.DetailedHTMLProps<React.ImgHTMLAttributes<HTMLImageElement>, HTMLImageElement>) => {
const ref = React.useRef<HTMLImageElement>()

React.useEffect(() => {
ref.current!.style.opacity = ''
}, [rest.src])

const handleError = React.useCallback((e) => {
ref.current!.style.opacity = '0'
onError?.(e)
}, [onError])

return <img {...rest} ref={ref as any} onError={handleError} />
}

export const SmallImage = styled(HidableImage)`
&:not([src]) { opacity: 0; }
min-width: 96px;
Expand All @@ -48,7 +63,7 @@ export const SmallImage = styled.img`
border-radius: 6px;
`

export const LargeImage = styled.img`
export const LargeImage = styled(HidableImage)`
&:not([src]) { opacity: 0; }
width: 100%;
Expand All @@ -65,7 +80,7 @@ export default styled.div`
background: var(--bn-glass-container);
border-radius: ${radius.xl};
color: var(--bn-glass-100);
padding: ${spacing["2Xl"]};
padding: ${spacing.xl};
&:has(${Title} a:focus-visible) {
box-shadow: ${effect.focusState};
Expand Down
31 changes: 31 additions & 0 deletions components/brave_news/browser/resources/feed/CaughtUp.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright (c) 2023 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 https://mozilla.org/MPL/2.0/.

import * as React from 'react';
import styled from 'styled-components';
import Flex from '$web-common/Flex';
import { getLocale } from '../../../../common/locale';
import Icon from '@brave/leo/react/icon';
import { spacing } from '@brave/leo/tokens/css';

const Container = styled(Flex)`
color: var(--bn-glass-50);
gap: ${spacing.xl};
& > hr {
flex: 1;
border-color: var(--bn-glass-10);
}
`

export default function CaughtUp() {
return <Container align='center' justify='stretch'>
<hr />
<Flex align='center' gap={6}>
<Icon name='check-circle-outline' /> <span>{getLocale('braveNewsCaughtUp')}</span>
</Flex>
<hr />
</Container>
}
3 changes: 2 additions & 1 deletion components/brave_news/browser/resources/feed/Cluster.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,8 @@ interface Props {
const Container = styled(Card)`
display: flex;
flex-direction: column;
gap: ${spacing.m};
gap: ${spacing['2Xl']};
padding-top: ${spacing['2Xl']};
`

export default function Cluster({ info }: Props) {
Expand Down
Loading

0 comments on commit 8fa5317

Please sign in to comment.