From e13b8093894d8fb17f1a79a35ed890185d783e05 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Mon, 6 Mar 2023 22:13:50 +0800 Subject: [PATCH] Get highlights with library items, over fetching for now, can maybe trim stuff in future --- .../web/components/patterns/HighlightView.tsx | 117 +----- .../LibraryCards/HighlightItemCard.tsx | 96 +++-- .../patterns/LibraryCards/LibraryGridCard.tsx | 3 + .../patterns/LibraryCards/LibraryListCard.tsx | 3 + .../templates/homeFeed/HomeFeedContainer.tsx | 393 +++++++----------- .../queries/useGetLibraryItemsQuery.tsx | 6 + 6 files changed, 221 insertions(+), 397 deletions(-) diff --git a/packages/web/components/patterns/HighlightView.tsx b/packages/web/components/patterns/HighlightView.tsx index bd8650781..011362db2 100644 --- a/packages/web/components/patterns/HighlightView.tsx +++ b/packages/web/components/patterns/HighlightView.tsx @@ -12,21 +12,21 @@ type HighlightViewProps = { scrollToHighlight?: (arg: string) => void } +const StyledQuote = styled(Blockquote, { + margin: '0px 0px 0px 0px', + fontSize: '18px', + lineHeight: '27px', + color: '$grayText', + padding: '0px 16px', + borderLeft: '2px solid $omnivoreCtaYellow', +}) + export function HighlightView(props: HighlightViewProps): JSX.Element { const lines = useMemo( () => props.highlight.quote.split('\n'), [props.highlight.quote] ) - const StyledQuote = styled(Blockquote, { - margin: '0px 0px 0px 0px', - fontSize: '18px', - lineHeight: '27px', - color: '$grayText', - padding: '0px 16px', - borderLeft: '2px solid $omnivoreCtaYellow', - }) - return ( ) } - -export function PublicHighlightView(props: HighlightViewProps): JSX.Element { - const lines = useMemo( - () => props.highlight.quote.split('\n'), - [props.highlight.quote] - ) - - const StyledQuote = styled(Blockquote, { - margin: '16px 0px 0px 0px', - fontSize: '18px', - lineHeight: '1.5', - fontFamily: 'Inter', - color: '$readerFont', - }) - - return ( - - - {props.highlight.prefix} - - {lines.map((line: string, index: number) => ( - - {line} - {index !== lines.length - 1 && ( - <> -
-
- - )} -
- ))} -
- {props.highlight.suffix} -
-
- ) -} - -type HighlightFooterProps = { - site: string - author?: string - title?: string - fontSize?: string -} - -export function HighlightFooter(props: HighlightFooterProps): JSX.Element { - const fontSize = props.fontSize || '12px' - - return ( - - - From{' '} - - {props.title} - {props.author ? ` — ${props.author}` : null} - - - - {props.site} - - - ) -} diff --git a/packages/web/components/patterns/LibraryCards/HighlightItemCard.tsx b/packages/web/components/patterns/LibraryCards/HighlightItemCard.tsx index b290a68dd..d401509d3 100644 --- a/packages/web/components/patterns/LibraryCards/HighlightItemCard.tsx +++ b/packages/web/components/patterns/LibraryCards/HighlightItemCard.tsx @@ -1,7 +1,17 @@ import { styled } from '@stitches/react' -import { VStack, HStack } from '../../elements/LayoutPrimitives' +import { Fragment, useMemo } from 'react' +import { LabelChip } from '../../elements/LabelChip' +import { + VStack, + HStack, + Blockquote, + SpanBox, + Box, +} from '../../elements/LayoutPrimitives' import { StyledMark, StyledText } from '../../elements/StyledText' +import { HighlightView } from '../HighlightView' import { LinkedItemCardAction, LinkedItemCardProps } from './CardTypes' +import { TitleStyle } from './LibraryCardStyles' export interface HighlightItemCardProps extends Pick { @@ -13,18 +23,30 @@ export const PreviewImage = styled('img', { cursor: 'pointer', }) +const StyledQuote = styled(Blockquote, { + margin: '0px 0px 0px 0px', + fontSize: '16px', + lineHeight: '27px', + color: '$grayText', + paddingLeft: '20px', + // borderRadius: '8px', + borderLeft: '2px solid $omnivoreCtaYellow', +}) + export function HighlightItemCard(props: HighlightItemCardProps): JSX.Element { + const lines = useMemo(() => props.item.quote.split('\n'), [props.item.quote]) return ( - - - {props.item.quote} - - - - {props.item.image && ( - { - ;(e.target as HTMLElement).style.display = 'none' - }} - /> - )} - - {props.item.title} - - + {props.item.title} + + + + {lines.map((line: string, index: number) => ( + + {line} + {index !== lines.length - 1 && ( + <> +
+
+ + )} +
+ ))} +
+ + {props.item.labels?.map(({ name, color }, index) => ( + + ))} + +
) } diff --git a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx index dd7a5e961..1e795de66 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryGridCard.tsx @@ -138,6 +138,9 @@ export function LibraryGridCard(props: LinkedItemCardProps): JSX.Element { Math.round((props.item.wordsCount ?? 0) / 235) )} min read` : null} + {props.item.highlights?.length ?? 0 > 0 + ? ` • ${props.item.highlights?.length} highlights` + : null} ) : null} + {props.item.highlights?.length ?? 0 > 0 + ? ` • ${props.item.highlights?.length} highlights` + : null} Promise } +const DragnDropContainer = styled('div', { + width: '100%', + height: '80%', + position: 'absolute', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + zIndex: '1', + alignSelf: 'center', + left: 0, +}) + +const DragnDropStyle = styled('div', { + border: '3px dashed gray', + backgroundColor: 'aliceblue', + borderRadius: '5px', + width: '100%', + height: '100%', + opacity: '0.9', + display: 'flex', + justifyContent: 'center', + alignItems: 'center', + alignSelf: 'center', + left: 0, + margin: '16px', +}) + function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { const { viewerData } = useGetViewerQuery() const [layout, setLayout] = usePersistedState({ @@ -625,33 +652,6 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { const [, updateState] = useState({}) - const DragnDropContainer = styled('div', { - width: '100%', - height: '80%', - position: 'absolute', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - zIndex: '1', - alignSelf: 'center', - left: 0, - }) - - const DragnDropStyle = styled('div', { - border: '3px dashed gray', - backgroundColor: 'aliceblue', - borderRadius: '5px', - width: '100%', - height: '100%', - opacity: '0.9', - display: 'flex', - justifyContent: 'center', - alignItems: 'center', - alignSelf: 'center', - left: 0, - margin: '16px', - }) - const removeItem = () => { if (!props.linkToRemove) { return @@ -840,100 +840,24 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { }} /> ) : ( - - {props.items.map((linkedItem) => ( - div': { - bg: '$thBackground3', - }, - '&:focus': { - '> div': { - bg: '$thBackgroundActive', - }, - }, - '&:hover': { - '> div': { - bg: '$thBackgroundActive', - }, - '> a': { - bg: '$thBackgroundActive', - }, - }, - }} - > - {viewerData?.me && ( - { - if (action === 'delete') { - setShowRemoveLinkConfirmation(true) - props.setLinkToRemove(linkedItem) - } else if (action === 'editTitle') { - props.setShowEditTitleModal(true) - props.setLinkToEdit(linkedItem) - } else if (action == 'unsubscribe') { - setShowUnsubscribeConfirmation(true) - props.setLinkToUnsubscribe(linkedItem) - } else { - props.actionHandler(action, linkedItem) - } - }} - /> - )} - - ))} - + )} void - +type LibraryItemsProps = { + items: LibraryItem[] layout: LayoutType - updateLayout: (layout: LayoutType) => void + viewer: UserBasicData | undefined - setShowAddLinkModal: (show: boolean) => void + gridContainerRef: React.RefObject + + setShowEditTitleModal: (show: boolean) => void + setLinkToEdit: (set: LibraryItem | undefined) => void + setShowUnsubscribeConfirmation: (show: true) => void + setLinkToRemove: (set: LibraryItem | undefined) => void + setLinkToUnsubscribe: (set: LibraryItem | undefined) => void + setShowRemoveLinkConfirmation: (show: true) => void + + actionHandler: ( + action: LinkedItemCardAction, + item: LibraryItem | undefined + ) => Promise } -function LegacyMobileTopNav(props: LegacyMobileTopNavProps): JSX.Element { - const StyledToggleButton = styled('button', { - display: 'flex', - alignItems: 'center', - justifyContent: 'center', - p: '0px', - backgroundColor: 'transparent', - border: 'none', - cursor: 'pointer', - width: '32px', - height: '32px', - borderRadius: '4px', - '&:hover': { - opacity: 0.8, - }, - '&[data-state="on"]': { - bg: 'rgb(43, 43, 43)', - }, - }) - +function LibraryItems(props: LibraryItemsProps): JSX.Element { return ( - <> - - - Library - + + {props.items.map((linkedItem) => ( - { - props.updateLayout('GRID_LAYOUT') - }} - > - - - { - props.updateLayout('LIST_LAYOUT') - }} - > - - - - - - - - {props.viewer && ( - div': { + bg: '$thBackground3', + }, + '&:focus': { + '> div': { + bg: '$thBackgroundActive', + }, + }, + '&:hover': { + '> div': { + bg: '$thBackgroundActive', + }, + '> a': { + bg: '$thBackgroundActive', + }, }, }} > - {Object.keys(SAVED_SEARCHES).map((key) => { - const isInboxTerm = (term: string) => { - return !term || term === 'in:inbox' - } - - const searchQuery = SAVED_SEARCHES[key] - const style = - searchQuery === props.searchTerm || - (!props.searchTerm && isInboxTerm(searchQuery)) - ? 'ctaDarkYellow' - : 'ctaLightGray' - return ( - - ) - })} + {props.viewer && ( + { + if (action === 'delete') { + props.setShowRemoveLinkConfirmation(true) + props.setLinkToRemove(linkedItem) + } else if (action === 'editTitle') { + props.setShowEditTitleModal(true) + props.setLinkToEdit(linkedItem) + } else if (action == 'unsubscribe') { + props.setShowUnsubscribeConfirmation(true) + props.setLinkToUnsubscribe(linkedItem) + } else { + props.actionHandler(action, linkedItem) + } + }} + /> + )} - )} - + ))} + ) } diff --git a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx index 412b11000..0d4d7d686 100644 --- a/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx +++ b/packages/web/lib/networking/queries/useGetLibraryItemsQuery.tsx @@ -9,6 +9,7 @@ import { unsubscribeMutation } from '../mutations/unsubscribeMutation' import { articleReadingProgressMutation } from '../mutations/articleReadingProgressMutation' import { Label } from './../fragments/labelFragment' import { showErrorToast, showSuccessToast } from '../../toastHelpers' +import { Highlight, highlightFragment } from '../fragments/highlightFragment' export type LibraryItemsQueryInput = { limit: number @@ -85,6 +86,7 @@ export type LibraryItemNode = { savedAt?: string wordsCount?: number recommendations?: Recommendation[] + highlights?: Highlight[] } export type Recommendation = { @@ -182,6 +184,9 @@ export function useGetLibraryItemsQuery({ } recommendedAt } + highlights { + ...HighlightFields + } } } pageInfo { @@ -197,6 +202,7 @@ export function useGetLibraryItemsQuery({ } } } + ${highlightFragment} ` const variables = {