mirror of
https://github.com/omnivore-app/omnivore.git
synced 2026-03-11 08:54:26 +00:00
Fix deleting highlights from the PDF notebook modal
This commit is contained in:
parent
a3396997b2
commit
23615db32a
4 changed files with 86 additions and 15 deletions
|
|
@ -29,6 +29,7 @@ export function HighlightView(props: HighlightViewProps): JSX.Element {
|
|||
|
||||
return (
|
||||
<VStack css={{ width: '100%', boxSizing: 'border-box' }}>
|
||||
{props.highlight.highlightPositionPercent}%
|
||||
<StyledQuote
|
||||
onClick={() => {
|
||||
if (props.scrollToHighlight) {
|
||||
|
|
|
|||
|
|
@ -2,7 +2,13 @@ import { ArticleAttributes } from '../../../lib/networking/queries/useGetArticle
|
|||
import { Box } from '../../elements/LayoutPrimitives'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { nanoid } from 'nanoid'
|
||||
import { useState, useEffect, useCallback, useRef } from 'react'
|
||||
import {
|
||||
useState,
|
||||
useEffect,
|
||||
useCallback,
|
||||
useRef,
|
||||
ReactComponentElement,
|
||||
} from 'react'
|
||||
import { isDarkTheme } from '../../../lib/themeUpdater'
|
||||
import PSPDFKit from 'pspdfkit'
|
||||
import { Instance, HighlightAnnotation, List, Annotation, Rect } from 'pspdfkit'
|
||||
|
|
@ -17,6 +23,7 @@ import { webBaseURL } from '../../../lib/appConfig'
|
|||
import { pspdfKitKey } from '../../../lib/appConfig'
|
||||
import { NotebookModal } from './NotebookModal'
|
||||
import { HighlightNoteModal } from './HighlightNoteModal'
|
||||
import { showErrorToast } from '../../../lib/toastHelpers'
|
||||
|
||||
export type PdfArticleContainerProps = {
|
||||
viewerUsername: string
|
||||
|
|
@ -32,11 +39,11 @@ export default function PdfArticleContainer(
|
|||
const [shareTarget, setShareTarget] = useState<Highlight | undefined>(
|
||||
undefined
|
||||
)
|
||||
const [notebookKey, setNotebookKey] = useState<string>(uuidv4())
|
||||
const [noteTarget, setNoteTarget] = useState<Highlight | undefined>(undefined)
|
||||
const [noteTargetPageIndex, setNoteTargetPageIndex] = useState<
|
||||
number | undefined
|
||||
>(undefined)
|
||||
|
||||
const highlightsRef = useRef<Highlight[]>([])
|
||||
const canShareNative = useCanShareNative()
|
||||
|
||||
|
|
@ -84,6 +91,18 @@ export default function PdfArticleContainer(
|
|||
(i) => ALLOWED_TOOLBAR_ITEM_TYPES.indexOf(i.type) !== -1
|
||||
)
|
||||
|
||||
const positionPercentForAnnotation = (annotation: Annotation) => {
|
||||
let totalSize = 0
|
||||
let sizeBefore = 0
|
||||
for (let idx = 0; idx < annotation.pageIndex; idx++) {
|
||||
sizeBefore += instance.pageInfoForIndex(idx)?.height ?? 0
|
||||
}
|
||||
for (let idx = 0; idx < instance.totalPageCount; idx++) {
|
||||
totalSize += instance.pageInfoForIndex(idx)?.height ?? 0
|
||||
}
|
||||
return (sizeBefore + annotation.boundingBox.top) / totalSize
|
||||
}
|
||||
|
||||
const annotationTooltipCallback = (annotation: Annotation) => {
|
||||
const highlightAnnotation = annotation as HighlightAnnotation
|
||||
const copy = {
|
||||
|
|
@ -105,17 +124,22 @@ export default function PdfArticleContainer(
|
|||
id: 'tooltip-remove-annotation',
|
||||
className: 'TooltipItem-Remove',
|
||||
onPress: () => {
|
||||
instance.delete(annotation).then(() => {
|
||||
if (
|
||||
annotation.customData &&
|
||||
annotation.customData.omnivoreHighlight &&
|
||||
(annotation.customData.omnivoreHighlight as Highlight).id
|
||||
) {
|
||||
const data = annotation.customData
|
||||
.omnivoreHighlight as Highlight
|
||||
deleteHighlightMutation(data.id)
|
||||
}
|
||||
})
|
||||
instance
|
||||
.delete(annotation)
|
||||
.then(() => {
|
||||
if (
|
||||
annotation.customData &&
|
||||
annotation.customData.omnivoreHighlight &&
|
||||
(annotation.customData.omnivoreHighlight as Highlight).id
|
||||
) {
|
||||
const data = annotation.customData
|
||||
.omnivoreHighlight as Highlight
|
||||
return deleteHighlightMutation(data.id)
|
||||
}
|
||||
})
|
||||
.catch((err) => {
|
||||
showErrorToast('Error deleting highlight: ' + err)
|
||||
})
|
||||
},
|
||||
}
|
||||
const note = {
|
||||
|
|
@ -185,7 +209,7 @@ export default function PdfArticleContainer(
|
|||
}),
|
||||
})
|
||||
|
||||
instance.addEventListener('annotations.willChange', (event) => {
|
||||
instance.addEventListener('annotations.willChange', async (event) => {
|
||||
const annotation = event.annotations.get(0)
|
||||
if (event.reason !== PSPDFKit.AnnotationsWillChangeReason.DELETE_END) {
|
||||
return
|
||||
|
|
@ -197,7 +221,7 @@ export default function PdfArticleContainer(
|
|||
(annotation.customData.omnivoreHighlight as Highlight).id
|
||||
) {
|
||||
const data = annotation.customData.omnivoreHighlight as Highlight
|
||||
deleteHighlightMutation(data.id)
|
||||
await deleteHighlightMutation(data.id)
|
||||
}
|
||||
})
|
||||
|
||||
|
|
@ -302,6 +326,7 @@ export default function PdfArticleContainer(
|
|||
PSPDFKit.Annotations.toSerializableObject(annotation)
|
||||
|
||||
if (overlapping.size === 0) {
|
||||
const positionPercent = positionPercentForAnnotation(annotation)
|
||||
const result = await createHighlightMutation({
|
||||
id: id,
|
||||
shortId: shortId,
|
||||
|
|
@ -310,6 +335,8 @@ export default function PdfArticleContainer(
|
|||
prefix: surroundingText.prefix,
|
||||
suffix: surroundingText.suffix,
|
||||
patch: JSON.stringify(serialized),
|
||||
highlightPositionPercent: positionPercent * 100,
|
||||
highlightPositionAnchorIndex: annotation.pageIndex,
|
||||
})
|
||||
if (result) {
|
||||
highlightsRef.current.push(result)
|
||||
|
|
@ -344,6 +371,7 @@ export default function PdfArticleContainer(
|
|||
const mergedIds = overlapping.map(
|
||||
(ha) => (ha.customData?.omnivoreHighlight as Highlight).id
|
||||
)
|
||||
const positionPercent = positionPercentForAnnotation(annotation)
|
||||
const result = await mergeHighlightMutation({
|
||||
quote,
|
||||
id,
|
||||
|
|
@ -353,6 +381,8 @@ export default function PdfArticleContainer(
|
|||
suffix: surroundingText.suffix,
|
||||
articleId: props.article.id,
|
||||
overlapHighlightIdList: mergedIds.toArray(),
|
||||
highlightPositionPercent: positionPercent * 100,
|
||||
highlightPositionAnchorIndex: annotation.pageIndex,
|
||||
})
|
||||
if (result) {
|
||||
highlightsRef.current.push(result)
|
||||
|
|
@ -380,6 +410,35 @@ export default function PdfArticleContainer(
|
|||
)
|
||||
})()
|
||||
|
||||
document.addEventListener('deleteHighlightbyId', async (event) => {
|
||||
const annotationId = (event as CustomEvent).detail as string
|
||||
for (let pageIdx = 0; pageIdx < instance.totalPageCount; pageIdx++) {
|
||||
const annotations = await instance.getAnnotations(pageIdx)
|
||||
for (let annIdx = 0; annIdx < annotations.size; annIdx++) {
|
||||
const annotation = annotations.get(annIdx)
|
||||
if (
|
||||
annotation &&
|
||||
annotation.customData &&
|
||||
annotation.customData.omnivoreHighlight &&
|
||||
(annotation.customData.omnivoreHighlight as Highlight).id ==
|
||||
annotationId
|
||||
) {
|
||||
await instance.delete(annotation)
|
||||
await deleteHighlightMutation(annotationId)
|
||||
|
||||
const highlightIdx = highlightsRef.current.findIndex((value) => {
|
||||
return value.id == annotationId
|
||||
})
|
||||
if (highlightIdx > -1) {
|
||||
highlightsRef.current.splice(highlightIdx, 1)
|
||||
}
|
||||
// This is needed to force the notebook to reload the highlights
|
||||
setNotebookKey(uuidv4())
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
|
||||
return () => {
|
||||
PSPDFKit && container && PSPDFKit.unload(container)
|
||||
}
|
||||
|
|
@ -426,10 +485,17 @@ export default function PdfArticleContainer(
|
|||
)}
|
||||
{props.showHighlightsModal && (
|
||||
<NotebookModal
|
||||
key={notebookKey}
|
||||
highlights={highlightsRef.current}
|
||||
onOpenChange={() => props.setShowHighlightsModal(false)}
|
||||
/* eslint-disable @typescript-eslint/no-empty-function */
|
||||
updateHighlight={() => {}}
|
||||
deleteHighlightAction={(highlightId: string) => {
|
||||
const event = new CustomEvent('deleteHighlightbyId', {
|
||||
detail: highlightId,
|
||||
})
|
||||
document.dispatchEvent(event)
|
||||
}}
|
||||
/>
|
||||
)}
|
||||
</Box>
|
||||
|
|
|
|||
|
|
@ -10,6 +10,8 @@ export type CreateHighlightInput = {
|
|||
shortId: string
|
||||
patch: string
|
||||
articleId: string
|
||||
highlightPositionPercent?: number
|
||||
highlightPositionAnchorIndex?: number
|
||||
}
|
||||
|
||||
type CreateHighlightOutput = {
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ export type MergeHighlightInput = {
|
|||
suffix?: string
|
||||
annotation?: string
|
||||
overlapHighlightIdList: string[]
|
||||
highlightPositionPercent?: number
|
||||
highlightPositionAnchorIndex?: number
|
||||
}
|
||||
|
||||
export type MergeHighlightOutput = {
|
||||
|
|
|
|||
Loading…
Reference in a new issue