From a5d03e01dbc140ab5173122eca87db483715f8b1 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 24 Oct 2023 17:03:36 +0800 Subject: [PATCH 1/3] Label flair for the web --- .../LibraryCards/LibraryCardStyles.tsx | 41 +++++++++++++++++-- .../patterns/LibraryCards/LibraryGridCard.tsx | 12 ++++-- .../patterns/LibraryCards/LibraryListCard.tsx | 12 ++++-- 3 files changed, 56 insertions(+), 9 deletions(-) diff --git a/packages/web/components/patterns/LibraryCards/LibraryCardStyles.tsx b/packages/web/components/patterns/LibraryCards/LibraryCardStyles.tsx index 52e4ddd43..e7fd81c5a 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryCardStyles.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryCardStyles.tsx @@ -2,7 +2,13 @@ import dayjs from 'dayjs' import relativeTime from 'dayjs/plugin/relativeTime' import { ChangeEvent, useMemo } from 'react' import { LibraryItemNode } from '../../../lib/networking/queries/useGetLibraryItemsQuery' -import { Box, SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { Box, HStack, SpanBox, VStack } from '../../elements/LayoutPrimitives' +import { RecommendedFlairIcon } from '../../elements/icons/RecommendedFlairIcon' +import { PinnedFlairIcon } from '../../elements/icons/PinnedFlairIcon' +import { FavoriteFlairIcon } from '../../elements/icons/FavoriteFlairIcon' +import { NewsletterFlairIcon } from '../../elements/icons/NewsletterFlairIcon' +import { FeedFlairIcon } from '../../elements/icons/FeedFlairIcon' +import { Label } from '../../../lib/networking/fragments/labelFragment' dayjs.extend(relativeTime) @@ -83,6 +89,32 @@ const shouldHideUrl = (url: string): boolean => { return false } +export const FLAIR_ICON_NAMES = [ + 'favorite', + 'pinned', + 'recommended', + 'newsletter', + 'feed', + 'rss', +] + +const flairIconForLabel = (label: Label): JSX.Element | undefined => { + switch (label.name.toLocaleLowerCase()) { + case 'favorite': + return + case 'pinned': + return + case 'recommended': + return + case 'newsletter': + return + case 'rss': + case 'feed': + return + } + return undefined +} + export const siteName = ( originalArticleUrl: string, itemUrl: string @@ -114,7 +146,10 @@ export function LibraryItemMetadata( }, [props.item.highlights]) return ( - + + {props.item.labels?.map((label) => { + return flairIconForLabel(label) + })} {timeAgo(props.item.savedAt)} {` `} {props.item.wordsCount ?? 0 > 0 @@ -126,7 +161,7 @@ export function LibraryItemMetadata( {highlightCount > 0 ? ` • ${highlightCount} highlight${highlightCount > 1 ? 's' : ''}` : null} - + ) } diff --git a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx index 0ba2db164..0d139fbd3 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx @@ -13,6 +13,7 @@ import { siteName, TitleStyle, MenuStyle, + FLAIR_ICON_NAMES, } from './LibraryCardStyles' import { sortedLabels } from '../../../lib/labelsSort' import { LibraryHoverActions } from './LibraryHoverActions' @@ -285,9 +286,14 @@ const LibraryGridCardContent = (props: LinkedItemCardProps): JSX.Element => { marginLeft: '-4px', // offset because the chips have margin }} > - {sortedLabels(props.item.labels).map(({ name, color }, index) => ( - - ))} + {sortedLabels(props.item.labels) + .filter( + ({ name }) => + FLAIR_ICON_NAMES.indexOf(name.toLocaleLowerCase()) == -1 + ) + .map(({ name, color }, index) => ( + + ))} diff --git a/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx index 95b8c4002..666a0b04c 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryListCard.tsx @@ -11,6 +11,7 @@ import { siteName, TitleStyle, MenuStyle, + FLAIR_ICON_NAMES, } from './LibraryCardStyles' import { sortedLabels } from '../../../lib/labelsSort' import { LIBRARY_LEFT_MENU_WIDTH } from '../../templates/homeFeed/LibraryFilterMenu' @@ -354,9 +355,14 @@ export function LibraryListCardContent( display: 'block', }} > - {sortedLabels(props.item.labels).map(({ name, color }, index) => ( - - ))} + {sortedLabels(props.item.labels) + .filter( + ({ name }) => + FLAIR_ICON_NAMES.indexOf(name.toLocaleLowerCase()) == -1 + ) + .map(({ name, color }, index) => ( + + ))} From a95a5ac2a5c8452d6e806e94956ab2b203249a84 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 24 Oct 2023 17:08:24 +0800 Subject: [PATCH 2/3] Add flair icon --- .../elements/icons/FavoriteFlairIcon.tsx | 29 ++++++++++++ .../elements/icons/FeedFlairIcon.tsx | 44 +++++++++++++++++++ .../elements/icons/NewsletterFlairIcon.tsx | 33 ++++++++++++++ .../elements/icons/PinnedFlairIcon.tsx | 29 ++++++++++++ .../elements/icons/RecommendedFlairIcon.tsx | 33 ++++++++++++++ 5 files changed, 168 insertions(+) create mode 100644 packages/web/components/elements/icons/FavoriteFlairIcon.tsx create mode 100644 packages/web/components/elements/icons/FeedFlairIcon.tsx create mode 100644 packages/web/components/elements/icons/NewsletterFlairIcon.tsx create mode 100644 packages/web/components/elements/icons/PinnedFlairIcon.tsx create mode 100644 packages/web/components/elements/icons/RecommendedFlairIcon.tsx diff --git a/packages/web/components/elements/icons/FavoriteFlairIcon.tsx b/packages/web/components/elements/icons/FavoriteFlairIcon.tsx new file mode 100644 index 000000000..ab7ab8386 --- /dev/null +++ b/packages/web/components/elements/icons/FavoriteFlairIcon.tsx @@ -0,0 +1,29 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { IconProps } from './IconProps' + +import React from 'react' + +export class FavoriteFlairIcon extends React.Component { + render() { + const size = (this.props.size || 26).toString() + const color = (this.props.color || '#2A2A2A').toString() + + return ( + + + + + + ) + } +} diff --git a/packages/web/components/elements/icons/FeedFlairIcon.tsx b/packages/web/components/elements/icons/FeedFlairIcon.tsx new file mode 100644 index 000000000..d9001ebbd --- /dev/null +++ b/packages/web/components/elements/icons/FeedFlairIcon.tsx @@ -0,0 +1,44 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { IconProps } from './IconProps' + +import React from 'react' + +export class FeedFlairIcon extends React.Component { + render() { + const size = (this.props.size || 26).toString() + const color = (this.props.color || '#2A2A2A').toString() + + return ( + + + + + + + + ) + } +} diff --git a/packages/web/components/elements/icons/NewsletterFlairIcon.tsx b/packages/web/components/elements/icons/NewsletterFlairIcon.tsx new file mode 100644 index 000000000..47cef57f8 --- /dev/null +++ b/packages/web/components/elements/icons/NewsletterFlairIcon.tsx @@ -0,0 +1,33 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { IconProps } from './IconProps' + +import React from 'react' + +export class NewsletterFlairIcon extends React.Component { + render() { + const size = (this.props.size || 26).toString() + const color = (this.props.color || '#2A2A2A').toString() + + return ( + + + + + + + ) + } +} diff --git a/packages/web/components/elements/icons/PinnedFlairIcon.tsx b/packages/web/components/elements/icons/PinnedFlairIcon.tsx new file mode 100644 index 000000000..f563a93bb --- /dev/null +++ b/packages/web/components/elements/icons/PinnedFlairIcon.tsx @@ -0,0 +1,29 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { IconProps } from './IconProps' + +import React from 'react' + +export class PinnedFlairIcon extends React.Component { + render() { + const size = (this.props.size || 26).toString() + const color = (this.props.color || '#2A2A2A').toString() + + return ( + + + + + + ) + } +} diff --git a/packages/web/components/elements/icons/RecommendedFlairIcon.tsx b/packages/web/components/elements/icons/RecommendedFlairIcon.tsx new file mode 100644 index 000000000..aec665505 --- /dev/null +++ b/packages/web/components/elements/icons/RecommendedFlairIcon.tsx @@ -0,0 +1,33 @@ +/* eslint-disable functional/no-class */ +/* eslint-disable functional/no-this-expression */ +import { IconProps } from './IconProps' + +import React from 'react' + +export class RecommendedFlairIcon extends React.Component { + render() { + const size = (this.props.size || 26).toString() + const color = (this.props.color || '#2A2A2A').toString() + + return ( + + + + + + + ) + } +} From 769f3b6b03fbf1c0814b9fd2b4fe9a50e905f127 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Tue, 24 Oct 2023 17:25:44 +0800 Subject: [PATCH 3/3] Fix svgs --- .../web/components/elements/icons/FeedFlairIcon.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/packages/web/components/elements/icons/FeedFlairIcon.tsx b/packages/web/components/elements/icons/FeedFlairIcon.tsx index d9001ebbd..1b1c4b78f 100644 --- a/packages/web/components/elements/icons/FeedFlairIcon.tsx +++ b/packages/web/components/elements/icons/FeedFlairIcon.tsx @@ -22,20 +22,20 @@ export class FeedFlairIcon extends React.Component { d="M8.73861 3.23242L3.40527 5.89909L8.73861 8.56576L14.0719 5.89909L8.73861 3.23242Z" fill="#FF7B03" stroke="#FF7B03" - stroke-linecap="round" - stroke-linejoin="round" + strokeLinecap="round" + strokeLinejoin="round" />