From f61efd2d3eaf552a7a226babadf5b5341cde0407 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 17 Mar 2023 14:11:03 +0800 Subject: [PATCH 1/6] Better handlding of deleting highlights from the library highlights view --- .../templates/homeFeed/EmptyLibrary.tsx | 1 + .../templates/homeFeed/HighlightItem.tsx | 24 +-- .../templates/homeFeed/HighlightsLayout.tsx | 204 +++++++++++++----- .../templates/homeFeed/HomeFeedContainer.tsx | 2 +- 4 files changed, 157 insertions(+), 74 deletions(-) diff --git a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx index eadc62608..f7965adc2 100644 --- a/packages/web/components/templates/homeFeed/EmptyLibrary.tsx +++ b/packages/web/components/templates/homeFeed/EmptyLibrary.tsx @@ -18,6 +18,7 @@ export function EmptyLibrary(props: EmptyLibraryProps): JSX.Element { color: '$grayTextContrast', textAlign: 'center', paddingTop: '88px', + flex: '1', }} > diff --git a/packages/web/components/templates/homeFeed/HighlightItem.tsx b/packages/web/components/templates/homeFeed/HighlightItem.tsx index 7955f11dd..43fdc60ed 100644 --- a/packages/web/components/templates/homeFeed/HighlightItem.tsx +++ b/packages/web/components/templates/homeFeed/HighlightItem.tsx @@ -21,12 +21,15 @@ import { } from '../../elements/LayoutPrimitives' import { StyledText } from '../../elements/StyledText' import { ConfirmationModal } from '../../patterns/ConfirmationModal' +import { theme } from '../../tokens/stitches.config' import { SetLabelsModal } from '../article/SetLabelsModal' type HighlightItemProps = { highlight: Highlight viewer: UserBasicData | undefined item: LibraryItemNode + + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } const StyledQuote = styled(Blockquote, { @@ -140,10 +143,6 @@ export function HighlightItem(props: HighlightItemProps): JSX.Element { css={{ marginLeft: 'auto', width: '20px', - visibility: hover ? 'unset' : 'hidden', - '@media (hover: none)': { - visibility: 'unset', - }, }} > { - ;(async () => { - const markdown = highlightAsMarkdown(props.highlight) - await navigator.clipboard.writeText(markdown) - showSuccessToast('Highlight copied') - })() - }, [props.highlight]) - return ( - + } > @@ -249,7 +245,7 @@ export function HighlightsMenu(props: HighlightsMenuProps): JSX.Element { /> { - exportHighlight() + props.setShowConfirmDeleteHighlightId(props.highlight.id) }} title="Delete" /> diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx index 129d0f8f7..425be9134 100644 --- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx +++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx @@ -1,7 +1,11 @@ import { HighlighterCircle } from 'phosphor-react' -import { useCallback, useEffect, useState } from 'react' +import { useCallback, useEffect, useReducer, useState } from 'react' import { Toaster } from 'react-hot-toast' -import { LibraryItem } from '../../../lib/networking/queries/useGetLibraryItemsQuery' +import { Highlight } from '../../../lib/networking/fragments/highlightFragment' +import { + LibraryItem, + LibraryItemNode, +} from '../../../lib/networking/queries/useGetLibraryItemsQuery' import { UserBasicData } from '../../../lib/networking/queries/useGetViewerQuery' import { showErrorToast, showSuccessToast } from '../../../lib/toastHelpers' import { Dropdown, DropdownOption } from '../../elements/DropdownElements' @@ -14,6 +18,8 @@ import { timeAgo, } from '../../patterns/LibraryCards/LibraryCardStyles' import { LibraryHighlightGridCard } from '../../patterns/LibraryCards/LibraryHighlightGridCard' +import { EmptyHighlights } from './EmptyHighlights' +import { HEADER_HEIGHT, MOBILE_HEADER_HEIGHT } from './HeaderSpacer' import { HighlightItem, highlightsAsMarkdown } from './HighlightItem' type HighlightItemsLayoutProps = { @@ -30,14 +36,74 @@ export function HighlightItemsLayout( undefined ) + const listReducer = ( + state: LibraryItem[], + action: { + type: string + itemId?: string + highlightId?: string + items?: LibraryItem[] + } + ) => { + switch (action.type) { + case 'RESET': + return action.items ?? [] + case 'REMOVE_HIGHLIGHT': + const item = state.find((li) => li.node.id === action.itemId) + if (item && item.node.highlights) { + item.node.highlights = item.node.highlights.filter( + (h) => h.id !== action.highlightId + ) + } + return state.filter( + (item) => item.node.highlights && item.node.highlights.length > 0 + ) + default: + throw new Error() + } + } + + const [items, dispatchList] = useReducer(listReducer, []) + + function handleDelete(item: LibraryItemNode, highlight: Highlight) { + dispatchList({ + type: 'REMOVE_HIGHLIGHT', + itemId: item.id, + highlightId: highlight.id, + }) + } + + useEffect(() => { + dispatchList({ + type: 'RESET', + items: props.items, + }) + }, [props.items]) + useEffect(() => { // Only set the current item on larger screens if (window.innerWidth >= 992 /* lgDown */) { - if (!currentItem && props.items.length > 0) { - setCurrentItem(props.items[0]) + if (!currentItem && items.length > 0) { + setCurrentItem(items[0]) } } - }, [currentItem, setCurrentItem, props.items]) + }, [currentItem, setCurrentItem, items]) + + if (items.length < 1) { + return ( + + + + ) + } return ( <> @@ -45,6 +111,7 @@ export function HighlightItemsLayout( css={{ width: '100%', height: '100%', + position: 'relative', bg: '$thBackground2', }} distribution="start" @@ -63,59 +130,30 @@ export function HighlightItemsLayout( distribution="start" alignment="start" > - - {/* - - */} - - {props.items.map((linkedItem) => ( - { - setCurrentItem(linkedItem) - event.preventDefault() - }} - > - {props.viewer && ( - - )} + {items.length > 0 ? ( + <> + + + + ) : ( + + No highlights found - ))} + )} {currentItem && ( <> @@ -130,7 +168,11 @@ export function HighlightItemsLayout( }, }} > - + )} @@ -139,6 +181,47 @@ export function HighlightItemsLayout( ) } +type LibraryItemsListProps = { + items: LibraryItem[] + viewer: UserBasicData | undefined + + currentItem: LibraryItem | undefined + setCurrentItem: (item: LibraryItem | undefined) => void +} + +function LibraryItemsList(props: LibraryItemsListProps): JSX.Element { + return ( + <> + {props.items.map((linkedItem) => ( + { + props.setCurrentItem(linkedItem) + event.preventDefault() + }} + > + {props.viewer && ( + + )} + + ))} + + ) +} + type HighlightTitleCardProps = { item: LibraryItem viewer: UserBasicData @@ -238,6 +321,8 @@ function HighlightTitleCard(props: HighlightTitleCardProps): JSX.Element { type HighlightListProps = { item: LibraryItem viewer: UserBasicData | undefined + + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } function HighlightList(props: HighlightListProps): JSX.Element { @@ -288,7 +373,7 @@ function HighlightList(props: HighlightListProps): JSX.Element { fontSize: '15px', fontFamily: '$display', width: '100%', - color: '$thTextContrast2', + color: 'thTextContrast2', }} > HIGHLIGHTS @@ -309,6 +394,7 @@ function HighlightList(props: HighlightListProps): JSX.Element { viewer={props.viewer} item={props.item.node} highlight={highlight} + deleteHighlight={props.deleteHighlight} /> ))} diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx index 5385d4417..c4b0134f6 100644 --- a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx +++ b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx @@ -686,7 +686,7 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element { setShowFilterMenu={setShowFilterMenu} /> - {props.mode == 'highlights' && ( + {!props.isValidating && props.mode == 'highlights' && ( Date: Fri, 17 Mar 2023 14:59:37 +0800 Subject: [PATCH 2/6] Positioning fixes for the highlights mode in the library --- .../templates/homeFeed/HighlightsLayout.tsx | 106 +++++++++++------- 1 file changed, 65 insertions(+), 41 deletions(-) diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx index 425be9134..ec74ead75 100644 --- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx +++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx @@ -110,57 +110,70 @@ export function HighlightItemsLayout( - - {items.length > 0 ? ( - <> - - - - ) : ( - - No highlights found - - )} - + + + + + + {currentItem && ( <> - + + + )} @@ -203,6 +227,7 @@ function LibraryItemsList(props: LibraryItemsListProps): JSX.Element { width: '100%', height: '100%', px: '15px', + cursor: 'pointer', }} onClick={(event) => { props.setCurrentItem(linkedItem) @@ -351,7 +376,6 @@ function HighlightList(props: HighlightListProps): JSX.Element { - + {(props.item.node.highlights ?? []).map((highlight) => ( ))} + From 6043d08046ca782848f86d700372592ec82e337b Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 17 Mar 2023 15:01:34 +0800 Subject: [PATCH 3/6] Remove unneeded prop --- packages/web/components/templates/homeFeed/HighlightsLayout.tsx | 2 -- 1 file changed, 2 deletions(-) diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx index ec74ead75..feee69d4b 100644 --- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx +++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx @@ -346,8 +346,6 @@ function HighlightTitleCard(props: HighlightTitleCardProps): JSX.Element { type HighlightListProps = { item: LibraryItem viewer: UserBasicData | undefined - - deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } function HighlightList(props: HighlightListProps): JSX.Element { From e2bf22f3aedbe5e75a30939caf52791a5812dab7 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 17 Mar 2023 15:08:13 +0800 Subject: [PATCH 4/6] Update current item when deleting items if current item is deleted --- .../components/templates/homeFeed/HighlightsLayout.tsx | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx index feee69d4b..637942125 100644 --- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx +++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx @@ -55,9 +55,17 @@ export function HighlightItemsLayout( (h) => h.id !== action.highlightId ) } - return state.filter( + const result = state.filter( (item) => item.node.highlights && item.node.highlights.length > 0 ) + if ( + item && + item == currentItem && + (item.node.highlights?.length ?? 0) < 1 + ) { + setCurrentItem(result.length > 0 ? result[0] : undefined) + } + return result default: throw new Error() } From baad0030ca7a51c7282420560c0a1f97eea350c3 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 17 Mar 2023 15:24:22 +0800 Subject: [PATCH 5/6] Handle highlight delete in the mobile library view --- .../LibraryCards/LibraryHighlightGridCard.tsx | 5 ++++- .../templates/homeFeed/HighlightsLayout.tsx | 17 ++++++++++++----- 2 files changed, 16 insertions(+), 6 deletions(-) diff --git a/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx index c7eaa004d..fb5b4cd1b 100644 --- a/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx +++ b/packages/web/components/patterns/LibraryCards/LibraryHighlightGridCard.tsx @@ -1,5 +1,5 @@ import { Box, VStack, HStack } from '../../elements/LayoutPrimitives' -import { useMemo, useState } from 'react' +import { useCallback, useMemo, useState } from 'react' import { CaretDown, CaretUp } from 'phosphor-react' import { MetaStyle, timeAgo, TitleStyle } from './LibraryCardStyles' import { styled } from '@stitches/react' @@ -20,6 +20,8 @@ export const GridSeparator = styled(Box, { type LibraryHighlightGridCardProps = { viewer: UserBasicData item: LibraryItemNode + + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } export function LibraryHighlightGridCard( @@ -128,6 +130,7 @@ export function LibraryHighlightGridCard( viewer={props.viewer} item={props.item} highlight={highlight} + deleteHighlight={props.deleteHighlight} /> ))} diff --git a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx index 637942125..9d445f05d 100644 --- a/packages/web/components/templates/homeFeed/HighlightsLayout.tsx +++ b/packages/web/components/templates/homeFeed/HighlightsLayout.tsx @@ -136,22 +136,21 @@ export function HighlightItemsLayout( minWidth: '430px', overflowY: 'scroll', height: '100%', + '@lgDown': { + width: '100%', + minWidth: 'unset', + }, }} distribution="start" alignment="start" > @@ -219,6 +219,8 @@ type LibraryItemsListProps = { currentItem: LibraryItem | undefined setCurrentItem: (item: LibraryItem | undefined) => void + + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } function LibraryItemsList(props: LibraryItemsListProps): JSX.Element { @@ -247,6 +249,7 @@ function LibraryItemsList(props: LibraryItemsListProps): JSX.Element { item={linkedItem} viewer={props.viewer} selected={props.currentItem?.node.id == linkedItem.node.id} + deleteHighlight={props.deleteHighlight} /> )} @@ -259,6 +262,7 @@ type HighlightTitleCardProps = { item: LibraryItem viewer: UserBasicData selected: boolean + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } function LibraryItemCard(props: HighlightTitleCardProps): JSX.Element { @@ -268,6 +272,7 @@ function LibraryItemCard(props: HighlightTitleCardProps): JSX.Element { @@ -354,6 +359,8 @@ function HighlightTitleCard(props: HighlightTitleCardProps): JSX.Element { type HighlightListProps = { item: LibraryItem viewer: UserBasicData | undefined + + deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void } function HighlightList(props: HighlightListProps): JSX.Element { From 8f6a8cc036c6ab3f3a96a4c4a716ef1bdd443053 Mon Sep 17 00:00:00 2001 From: Jackson Harper Date: Fri, 17 Mar 2023 15:53:55 +0800 Subject: [PATCH 6/6] Empty highlights component --- .../templates/homeFeed/EmptyHighlights.tsx | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 packages/web/components/templates/homeFeed/EmptyHighlights.tsx diff --git a/packages/web/components/templates/homeFeed/EmptyHighlights.tsx b/packages/web/components/templates/homeFeed/EmptyHighlights.tsx new file mode 100644 index 000000000..204904acc --- /dev/null +++ b/packages/web/components/templates/homeFeed/EmptyHighlights.tsx @@ -0,0 +1,23 @@ +import { Book } from 'phosphor-react' +import { VStack } from '../../elements/LayoutPrimitives' +import { StyledText } from '../../elements/StyledText' +import { theme } from '../../tokens/stitches.config' + +export function EmptyHighlights(): JSX.Element { + return ( + + + + No results found. + + + ) +}