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/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.
+
+
+ )
+}
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..9d445f05d 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,99 +36,152 @@ 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
+ )
+ }
+ 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()
+ }
+ }
+
+ 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 (
<>
-
-
- {/*
-
- */}
-
- {props.items.map((linkedItem) => (
- {
- setCurrentItem(linkedItem)
- event.preventDefault()
- }}
- >
- {props.viewer && (
-
- )}
-
- ))}
-
+ alignment="center"
+ distribution="start"
+ >
+
+
+
+
{currentItem && (
<>
-
+
+
+
>
)}
@@ -139,10 +213,56 @@ export function HighlightItemsLayout(
)
}
+type LibraryItemsListProps = {
+ items: LibraryItem[]
+ viewer: UserBasicData | undefined
+
+ currentItem: LibraryItem | undefined
+ setCurrentItem: (item: LibraryItem | undefined) => void
+
+ deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => 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
selected: boolean
+ deleteHighlight: (item: LibraryItemNode, highlight: Highlight) => void
}
function LibraryItemCard(props: HighlightTitleCardProps): JSX.Element {
@@ -152,6 +272,7 @@ function LibraryItemCard(props: HighlightTitleCardProps): JSX.Element {
@@ -238,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 {
@@ -266,7 +389,6 @@ function HighlightList(props: HighlightListProps): JSX.Element {
HIGHLIGHTS
@@ -302,15 +423,17 @@ function HighlightList(props: HighlightListProps): JSX.Element {
/>
-
+
{(props.item.node.highlights ?? []).map((highlight) => (
))}
+
diff --git a/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx b/packages/web/components/templates/homeFeed/HomeFeedContainer.tsx
index a5e1c827c..10fa7bed3 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' && (