omnivore/packages/web/components/patterns/HighlightView.tsx

170 lines
4.5 KiB
TypeScript
Raw Normal View History

2023-03-31 07:57:17 +00:00
/* eslint-disable react/no-children-prop */
import { useState } from 'react'
2022-02-11 17:24:33 +00:00
import type { Highlight } from '../../lib/networking/fragments/highlightFragment'
import { LabelChip } from '../elements/LabelChip'
import {
Box,
VStack,
Blockquote,
SpanBox,
HStack,
} from '../elements/LayoutPrimitives'
2024-02-16 04:25:45 +00:00
import { styled } from '../tokens/stitches.config'
import { HighlightViewNote } from './HighlightNotes'
2023-03-31 04:26:03 +00:00
import ReactMarkdown from 'react-markdown'
import remarkGfm from 'remark-gfm'
2024-02-16 04:25:45 +00:00
import { highlightColorVar } from '../../lib/themeUpdater'
2023-06-23 12:37:31 +00:00
import { ReadableItem } from '../../lib/networking/queries/useGetLibraryItemsQuery'
import { UserBasicData } from '../../lib/networking/queries/useGetViewerQuery'
2023-06-27 03:51:12 +00:00
import {
autoUpdate,
offset,
size,
useFloating,
useHover,
useInteractions,
} from '@floating-ui/react'
import { HighlightHoverActions } from './HighlightHoverActions'
2022-02-11 17:24:33 +00:00
type HighlightViewProps = {
2023-06-23 12:37:31 +00:00
item: ReadableItem
viewer: UserBasicData
2022-02-11 17:24:33 +00:00
highlight: Highlight
author?: string
title?: string
2023-03-24 08:23:04 +00:00
updateHighlight: (highlight: Highlight) => void
2023-06-23 12:37:31 +00:00
viewInReader: (highlightId: string) => void
setLabelsTarget: (target: Highlight) => void
setShowConfirmDeleteHighlightId: (set: string) => void
2022-02-11 17:24:33 +00:00
}
const StyledQuote = styled(Blockquote, {
2023-06-27 03:51:12 +00:00
p: '0px',
margin: '0px 0px 0px 0px',
fontSize: '18px',
lineHeight: '27px',
2023-06-22 09:16:54 +00:00
borderRadius: '4px',
width: '100%',
})
2022-02-11 17:24:33 +00:00
export function HighlightView(props: HighlightViewProps): JSX.Element {
2023-03-23 08:14:04 +00:00
const [noteMode, setNoteMode] = useState<'preview' | 'edit'>('preview')
2023-06-27 03:51:12 +00:00
const [isOpen, setIsOpen] = useState(false)
const { refs, floatingStyles, context } = useFloating({
open: isOpen,
onOpenChange: setIsOpen,
middleware: [
offset({
mainAxis: -25,
}),
size(),
],
placement: 'top-end',
whileElementsMounted: autoUpdate,
})
const hover = useHover(context)
const { getReferenceProps, getFloatingProps } = useInteractions([hover])
2023-08-24 04:00:35 +00:00
const highlightColor = highlightColorVar(props.highlight.color)
2022-02-11 17:24:33 +00:00
return (
2023-06-23 12:37:31 +00:00
<VStack
2023-06-27 03:51:12 +00:00
ref={refs.setReference}
{...getReferenceProps()}
css={{
2023-06-23 12:37:31 +00:00
p: '0px',
width: '100%',
}}
>
2023-06-27 03:51:12 +00:00
<Box
ref={refs.setFloating}
style={floatingStyles}
{...getFloatingProps()}
2023-06-23 12:37:31 +00:00
>
2023-06-27 03:51:12 +00:00
<HighlightHoverActions
viewer={props.viewer}
highlight={props.highlight}
isHovered={isOpen ?? false}
viewInReader={props.viewInReader}
setLabelsTarget={props.setLabelsTarget}
setShowConfirmDeleteHighlightId={
props.setShowConfirmDeleteHighlightId
}
/>
2023-06-27 03:51:12 +00:00
</Box>
2023-03-31 05:23:01 +00:00
<VStack
css={{
width: '100%',
2023-06-22 09:16:54 +00:00
'@mdDown': {
padding: '0px',
},
2023-03-31 05:23:01 +00:00
}}
>
<StyledQuote>
2023-03-31 05:23:01 +00:00
<SpanBox
2023-03-23 08:14:04 +00:00
css={{
'> *': {
display: 'inline',
2023-08-24 04:00:35 +00:00
padding: '3px',
2023-08-24 09:25:46 +00:00
backgroundColor: `rgba(${highlightColor}, var(--colors-highlight_background_alpha))`,
2023-06-27 03:51:12 +00:00
boxDecorationBreak: 'clone',
borderRadius: '2px',
2023-03-31 05:23:01 +00:00
},
'> ul': {
display: 'block',
boxShadow: 'unset',
backgroundColor: 'unset',
},
fontSize: '15px',
lineHeight: 1.5,
2023-06-22 09:16:54 +00:00
color: '$thTextSubtle2',
2023-03-31 05:23:01 +00:00
img: {
display: 'block',
margin: '0.5em auto !important',
maxWidth: '100% !important',
height: 'auto',
},
2023-03-23 08:14:04 +00:00
}}
>
2023-08-08 08:55:58 +00:00
<ReactMarkdown
children={props.highlight.quote ?? ''}
remarkPlugins={[remarkGfm]}
2023-08-08 08:55:58 +00:00
/>
2023-03-31 05:23:01 +00:00
</SpanBox>
</StyledQuote>
<Box css={{ display: 'block', pt: '5px' }}>
{props.highlight.labels?.map(({ name, color }, index) => (
<LabelChip key={index} text={name || ''} color={color} />
2022-02-11 17:24:33 +00:00
))}
</Box>
2023-03-27 06:04:34 +00:00
<HStack
2023-06-22 09:16:54 +00:00
css={{
width: '100%',
pt: '15px',
'@mdDown': {
p: '10px',
},
}}
2023-03-27 06:04:34 +00:00
alignment="start"
distribution="start"
>
<HighlightViewNote
2023-06-22 09:16:54 +00:00
targetId={props.highlight.id}
2023-03-27 06:04:34 +00:00
text={props.highlight.annotation}
placeHolder="Add notes to this highlight..."
highlight={props.highlight}
mode={noteMode}
setEditMode={setNoteMode}
updateHighlight={props.updateHighlight}
/>
</HStack>
</VStack>
2023-06-23 12:37:31 +00:00
</VStack>
2022-02-11 17:24:33 +00:00
)
}