mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Get highlights with library items, over fetching for now, can maybe trim stuff in future
This commit is contained in:
parent
079b6e5c41
commit
e13b809389
6 changed files with 221 additions and 397 deletions
|
|
@ -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 (
|
||||
<VStack css={{ width: '100%', boxSizing: 'border-box' }}>
|
||||
<StyledQuote
|
||||
|
|
@ -58,102 +58,3 @@ export function HighlightView(props: HighlightViewProps): JSX.Element {
|
|||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
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 (
|
||||
<VStack css={{ width: '100%', bg: '$grayBackground', pt: '0px' }}>
|
||||
<StyledQuote>
|
||||
{props.highlight.prefix}
|
||||
<SpanBox
|
||||
css={{
|
||||
bg: '$omnivoreYellow',
|
||||
p: '1px',
|
||||
borderRadius: '2px',
|
||||
color: '#3d3d3d',
|
||||
}}
|
||||
>
|
||||
{lines.map((line: string, index: number) => (
|
||||
<Fragment key={index}>
|
||||
{line}
|
||||
{index !== lines.length - 1 && (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</SpanBox>
|
||||
{props.highlight.suffix}
|
||||
</StyledQuote>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
||||
type HighlightFooterProps = {
|
||||
site: string
|
||||
author?: string
|
||||
title?: string
|
||||
fontSize?: string
|
||||
}
|
||||
|
||||
export function HighlightFooter(props: HighlightFooterProps): JSX.Element {
|
||||
const fontSize = props.fontSize || '12px'
|
||||
|
||||
return (
|
||||
<VStack
|
||||
alignment="start"
|
||||
css={{ width: '100%', bg: '$grayBackground', pt: '0px', pb: '8px' }}
|
||||
>
|
||||
<StyledText
|
||||
css={{
|
||||
fontSize: fontSize,
|
||||
fontFamily: 'Inter',
|
||||
color: '$omnivoreGray',
|
||||
fontWeight: '400',
|
||||
mb: '0px',
|
||||
p: '0px',
|
||||
}}
|
||||
>
|
||||
From{' '}
|
||||
<SpanBox
|
||||
css={{
|
||||
fontSize: fontSize,
|
||||
color: '$omnivoreOrange',
|
||||
p: '0px',
|
||||
fontWeight: '400',
|
||||
mb: '0px',
|
||||
}}
|
||||
>
|
||||
{props.title}
|
||||
{props.author ? ` — ${props.author}` : null}
|
||||
</SpanBox>
|
||||
</StyledText>
|
||||
<StyledText
|
||||
css={{
|
||||
pt: '0px',
|
||||
mt: '0px',
|
||||
fontSize: '10px',
|
||||
fontFamily: 'Inter',
|
||||
color: '$omnivoreGray',
|
||||
fontWeight: '400',
|
||||
}}
|
||||
>
|
||||
{props.site}
|
||||
</StyledText>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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<LinkedItemCardProps, 'item'> {
|
||||
|
|
@ -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 (
|
||||
<VStack
|
||||
css={{
|
||||
p: '$2',
|
||||
p: '20px',
|
||||
gap: '20px',
|
||||
height: '100%',
|
||||
width: '100%',
|
||||
borderRadius: '0px',
|
||||
width: '320px',
|
||||
borderRadius: '8px',
|
||||
cursor: 'pointer',
|
||||
wordBreak: 'break-word',
|
||||
overflow: 'clip',
|
||||
border: '1px solid $grayBorder',
|
||||
border: '1px solid $thBorderColor',
|
||||
borderBottom: 'none',
|
||||
boxShadow: '0px 3px 11px rgba(32, 31, 29, 0.04)',
|
||||
bg: '$grayBg',
|
||||
|
|
@ -41,48 +63,34 @@ export function HighlightItemCard(props: HighlightItemCardProps): JSX.Element {
|
|||
props.handleAction('showDetail')
|
||||
}}
|
||||
>
|
||||
<StyledText
|
||||
<Box
|
||||
css={{
|
||||
lineHeight: '20px',
|
||||
...TitleStyle,
|
||||
height: '42px',
|
||||
}}
|
||||
>
|
||||
<StyledMark
|
||||
css={{
|
||||
background: 'rgb($highlightBackground)',
|
||||
color: '$highlightText',
|
||||
fontSize: '14px',
|
||||
}}
|
||||
>
|
||||
{props.item.quote}
|
||||
</StyledMark>
|
||||
</StyledText>
|
||||
<HStack
|
||||
css={{
|
||||
marginTop: 'auto',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'space-between',
|
||||
}}
|
||||
>
|
||||
{props.item.image && (
|
||||
<PreviewImage
|
||||
src={props.item.image}
|
||||
alt="Preview Image"
|
||||
width={16}
|
||||
height={16}
|
||||
css={{ borderRadius: '50%' }}
|
||||
onError={(e) => {
|
||||
;(e.target as HTMLElement).style.display = 'none'
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
<StyledText
|
||||
css={{
|
||||
fontWeight: '700',
|
||||
}}
|
||||
>
|
||||
{props.item.title}
|
||||
</StyledText>
|
||||
</HStack>
|
||||
{props.item.title}
|
||||
</Box>
|
||||
<StyledQuote>
|
||||
<SpanBox css={{ p: '1px', borderRadius: '2px' }}>
|
||||
{lines.map((line: string, index: number) => (
|
||||
<Fragment key={index}>
|
||||
{line}
|
||||
{index !== lines.length - 1 && (
|
||||
<>
|
||||
<br />
|
||||
<br />
|
||||
</>
|
||||
)}
|
||||
</Fragment>
|
||||
))}
|
||||
</SpanBox>
|
||||
<Box css={{ display: 'block', pt: '16px' }}>
|
||||
{props.item.labels?.map(({ name, color }, index) => (
|
||||
<LabelChip key={index} text={name || ''} color={color} />
|
||||
))}
|
||||
</Box>
|
||||
</StyledQuote>
|
||||
</VStack>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}
|
||||
</Box>
|
||||
<Box
|
||||
css={{
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ export function LibraryListCard(props: LinkedItemCardProps): JSX.Element {
|
|||
</SpanBox>
|
||||
</>
|
||||
) : null}
|
||||
{props.item.highlights?.length ?? 0 > 0
|
||||
? ` • ${props.item.highlights?.length} highlights`
|
||||
: null}
|
||||
</Box>
|
||||
<Box
|
||||
css={{
|
||||
|
|
|
|||
|
|
@ -604,6 +604,33 @@ type HomeFeedContentProps = {
|
|||
) => Promise<void>
|
||||
}
|
||||
|
||||
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<LayoutType>({
|
||||
|
|
@ -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 {
|
|||
}}
|
||||
/>
|
||||
) : (
|
||||
<Box
|
||||
ref={props.gridContainerRef}
|
||||
css={{
|
||||
py: '$3',
|
||||
display: 'grid',
|
||||
width: '100%',
|
||||
gridAutoRows: 'auto',
|
||||
borderRadius: '8px',
|
||||
gridGap: layout == 'LIST_LAYOUT' ? '0' : '20px',
|
||||
marginTop: layout == 'LIST_LAYOUT' ? '21px' : '0',
|
||||
marginBottom: '0px',
|
||||
paddingTop: layout == 'LIST_LAYOUT' ? '0' : '21px',
|
||||
paddingBottom: layout == 'LIST_LAYOUT' ? '0px' : '21px',
|
||||
overflow: 'hidden',
|
||||
'@xlgDown': {
|
||||
border: 'unset',
|
||||
borderRadius: layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
},
|
||||
'@smDown': {
|
||||
border: 'unset',
|
||||
width: layout == 'LIST_LAYOUT' ? '100vw' : undefined,
|
||||
margin:
|
||||
layout == 'LIST_LAYOUT' ? '16px -16px' : undefined,
|
||||
borderRadius: layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
},
|
||||
'@md': {
|
||||
gridTemplateColumns:
|
||||
layout == 'LIST_LAYOUT' ? 'none' : '1fr 1fr',
|
||||
},
|
||||
'@lg': {
|
||||
gridTemplateColumns:
|
||||
layout == 'LIST_LAYOUT' ? 'none' : 'repeat(2, 1fr)',
|
||||
},
|
||||
'@xl': {
|
||||
gridTemplateColumns:
|
||||
layout == 'LIST_LAYOUT' ? 'none' : 'repeat(3, 1fr)',
|
||||
},
|
||||
'@xxl': {
|
||||
gridTemplateColumns:
|
||||
layout == 'LIST_LAYOUT' ? 'none' : 'repeat(4, 1fr)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{props.items.map((linkedItem) => (
|
||||
<Box
|
||||
className="linkedItemCard"
|
||||
data-testid="linkedItemCard"
|
||||
id={linkedItem.node.id}
|
||||
tabIndex={0}
|
||||
key={linkedItem.node.id}
|
||||
css={{
|
||||
width: '100%',
|
||||
'&> div': {
|
||||
bg: '$thBackground3',
|
||||
},
|
||||
'&:focus': {
|
||||
'> div': {
|
||||
bg: '$thBackgroundActive',
|
||||
},
|
||||
},
|
||||
'&:hover': {
|
||||
'> div': {
|
||||
bg: '$thBackgroundActive',
|
||||
},
|
||||
'> a': {
|
||||
bg: '$thBackgroundActive',
|
||||
},
|
||||
},
|
||||
}}
|
||||
>
|
||||
{viewerData?.me && (
|
||||
<LinkedItemCard
|
||||
layout={layout}
|
||||
item={linkedItem.node}
|
||||
viewer={viewerData.me}
|
||||
handleAction={(action: LinkedItemCardAction) => {
|
||||
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)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
))}
|
||||
</Box>
|
||||
<LibraryItems
|
||||
items={props.items}
|
||||
layout={layout}
|
||||
viewer={viewerData?.me}
|
||||
gridContainerRef={props.gridContainerRef}
|
||||
showEditTitleModal={props.showEditTitleModal}
|
||||
setShowEditTitleModal={props.setShowEditTitleModal}
|
||||
setLinkToEdit={props.setLinkToEdit}
|
||||
setShowUnsubscribeConfirmation={
|
||||
setShowUnsubscribeConfirmation
|
||||
}
|
||||
setLinkToRemove={props.setLinkToRemove}
|
||||
setLinkToUnsubscribe={props.setLinkToUnsubscribe}
|
||||
setShowRemoveLinkConfirmation={
|
||||
setShowRemoveLinkConfirmation
|
||||
}
|
||||
actionHandler={props.actionHandler}
|
||||
/>
|
||||
)}
|
||||
<HStack
|
||||
distribution="center"
|
||||
|
|
@ -1042,141 +966,120 @@ function HomeFeedGrid(props: HomeFeedContentProps): JSX.Element {
|
|||
)
|
||||
}
|
||||
|
||||
type LegacyMobileTopNavProps = {
|
||||
viewer?: UserBasicData
|
||||
searchTerm?: string
|
||||
applySearchQuery: (searchQuery: string) => void
|
||||
|
||||
type LibraryItemsProps = {
|
||||
items: LibraryItem[]
|
||||
layout: LayoutType
|
||||
updateLayout: (layout: LayoutType) => void
|
||||
viewer: UserBasicData | undefined
|
||||
|
||||
setShowAddLinkModal: (show: boolean) => void
|
||||
gridContainerRef: React.RefObject<HTMLDivElement>
|
||||
|
||||
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<void>
|
||||
}
|
||||
|
||||
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 (
|
||||
<>
|
||||
<HStack
|
||||
alignment="center"
|
||||
distribution="start"
|
||||
css={{ width: '100%', '@md': { display: 'none' } }}
|
||||
>
|
||||
<StyledText
|
||||
style="subHeadline"
|
||||
css={{
|
||||
mr: '32px',
|
||||
'@smDown': {
|
||||
mr: '16px',
|
||||
},
|
||||
}}
|
||||
>
|
||||
Library
|
||||
</StyledText>
|
||||
<Box
|
||||
ref={props.gridContainerRef}
|
||||
css={{
|
||||
py: '$3',
|
||||
display: 'grid',
|
||||
width: '100%',
|
||||
gridAutoRows: 'auto',
|
||||
borderRadius: '8px',
|
||||
gridGap: props.layout == 'LIST_LAYOUT' ? '0' : '20px',
|
||||
marginTop: props.layout == 'LIST_LAYOUT' ? '21px' : '0',
|
||||
marginBottom: '0px',
|
||||
paddingTop: props.layout == 'LIST_LAYOUT' ? '0' : '21px',
|
||||
paddingBottom: props.layout == 'LIST_LAYOUT' ? '0px' : '21px',
|
||||
overflow: 'hidden',
|
||||
'@xlgDown': {
|
||||
border: 'unset',
|
||||
borderRadius: props.layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
},
|
||||
'@smDown': {
|
||||
border: 'unset',
|
||||
width: props.layout == 'LIST_LAYOUT' ? '100vw' : undefined,
|
||||
margin: props.layout == 'LIST_LAYOUT' ? '16px -16px' : undefined,
|
||||
borderRadius: props.layout == 'LIST_LAYOUT' ? 0 : undefined,
|
||||
},
|
||||
'@md': {
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT' ? 'none' : '1fr 1fr',
|
||||
},
|
||||
'@lg': {
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(2, 1fr)',
|
||||
},
|
||||
'@xl': {
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(3, 1fr)',
|
||||
},
|
||||
'@xxl': {
|
||||
gridTemplateColumns:
|
||||
props.layout == 'LIST_LAYOUT' ? 'none' : 'repeat(4, 1fr)',
|
||||
},
|
||||
}}
|
||||
>
|
||||
{props.items.map((linkedItem) => (
|
||||
<Box
|
||||
className="linkedItemCard"
|
||||
data-testid="linkedItemCard"
|
||||
id={linkedItem.node.id}
|
||||
tabIndex={0}
|
||||
key={linkedItem.node.id}
|
||||
css={{
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
>
|
||||
<StyledToggleButton
|
||||
data-state={props.layout === 'GRID_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
props.updateLayout('GRID_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<GridLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
<StyledToggleButton
|
||||
data-state={props.layout === 'LIST_LAYOUT' ? 'on' : 'off'}
|
||||
onClick={() => {
|
||||
props.updateLayout('LIST_LAYOUT')
|
||||
}}
|
||||
>
|
||||
<ListLayoutIcon color={'rgb(211, 211, 213)'} />
|
||||
</StyledToggleButton>
|
||||
</Box>
|
||||
<Button
|
||||
style="ctaDarkYellow"
|
||||
css={{ marginLeft: 'auto' }}
|
||||
onClick={() => {
|
||||
props.setShowAddLinkModal(true)
|
||||
}}
|
||||
>
|
||||
Add Link
|
||||
</Button>
|
||||
</HStack>
|
||||
<LibrarySearchBar
|
||||
searchTerm={props.searchTerm}
|
||||
applySearchQuery={props.applySearchQuery}
|
||||
/>
|
||||
|
||||
{props.viewer && (
|
||||
<Box
|
||||
css={{
|
||||
display: 'flex',
|
||||
width: '100%',
|
||||
height: '44px',
|
||||
marginTop: '16px',
|
||||
gap: '8px',
|
||||
flexDirection: 'row',
|
||||
overflowY: 'scroll',
|
||||
scrollbarWidth: 'none',
|
||||
'&::-webkit-scrollbar': {
|
||||
display: 'none',
|
||||
'&> 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 (
|
||||
<Button
|
||||
key={key}
|
||||
style={style}
|
||||
onClick={() => {
|
||||
props.applySearchQuery(searchQuery)
|
||||
}}
|
||||
css={{
|
||||
p: '10px 12px',
|
||||
height: '37.5px',
|
||||
borderRadius: '6px',
|
||||
whiteSpace: 'nowrap',
|
||||
}}
|
||||
>
|
||||
{key}
|
||||
</Button>
|
||||
)
|
||||
})}
|
||||
{props.viewer && (
|
||||
<LinkedItemCard
|
||||
layout={props.layout}
|
||||
item={linkedItem.node}
|
||||
viewer={props.viewer}
|
||||
handleAction={(action: LinkedItemCardAction) => {
|
||||
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)
|
||||
}
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
)}
|
||||
</>
|
||||
))}
|
||||
</Box>
|
||||
)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue