PDF Markings #114
@ -1,18 +1,18 @@
|
|||||||
import { PdfFile } from '../../types/drawing.ts'
|
import { PdfFile } from '../../types/drawing.ts'
|
||||||
import { CurrentUserMark, Mark, MarkConfigDetails } from '../../types/mark.ts'
|
import { CurrentUserMark } from '../../types/mark.ts'
|
||||||
import PdfPageItem from './PdfPageItem.tsx';
|
import PdfPageItem from './PdfPageItem.tsx';
|
||||||
|
|
||||||
interface PdfItemProps {
|
interface PdfItemProps {
|
||||||
pdfFile: PdfFile
|
pdfFile: PdfFile
|
||||||
marks: Mark[]
|
currentUserMarks: CurrentUserMark[]
|
||||||
handleMarkClick: (id: number) => void
|
handleMarkClick: (id: number) => void
|
||||||
currentMarkValue: string
|
currentMarkValue: string
|
||||||
currentUserMark: CurrentUserMark | null
|
currentUserMark: CurrentUserMark | null
|
||||||
}
|
}
|
||||||
|
|
||||||
const PdfItem = ({ pdfFile, marks, handleMarkClick, currentMarkValue, currentUserMark }: PdfItemProps) => {
|
const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, currentMarkValue, currentUserMark }: PdfItemProps) => {
|
||||||
const filterByPage = (marks: Mark[], page: number): Mark[] => {
|
const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => {
|
||||||
return marks.filter((mark) => mark.location.page === page);
|
return marks.filter((m) => m.mark.location.page === page);
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
pdfFile.pages.map((page, i) => {
|
pdfFile.pages.map((page, i) => {
|
||||||
@ -20,7 +20,7 @@ const PdfItem = ({ pdfFile, marks, handleMarkClick, currentMarkValue, currentUse
|
|||||||
<PdfPageItem
|
<PdfPageItem
|
||||||
page={page}
|
page={page}
|
||||||
key={i}
|
key={i}
|
||||||
marks={filterByPage(marks, i)}
|
marks={filterByPage(currentUserMarks, i)}
|
||||||
handleMarkClick={handleMarkClick}
|
handleMarkClick={handleMarkClick}
|
||||||
currentMarkValue={currentMarkValue}
|
currentMarkValue={currentMarkValue}
|
||||||
currentUserMark={currentUserMark}
|
currentUserMark={currentUserMark}
|
||||||
|
0
src/components/PDFView/PdfMarking.tsx
Normal file
0
src/components/PDFView/PdfMarking.tsx
Normal file
0
src/utils/const.ts
Normal file
0
src/utils/const.ts
Normal file
@ -6,3 +6,4 @@ export * from './nostr'
|
|||||||
export * from './string'
|
export * from './string'
|
||||||
export * from './zip'
|
export * from './zip'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
|
export { extractMarksFromSignedMeta } from './mark.ts'
|
||||||
|
98
src/utils/mark.ts
Normal file
98
src/utils/mark.ts
Normal file
@ -0,0 +1,98 @@
|
|||||||
|
import { CurrentUserMark, Mark } from '../types/mark.ts'
|
||||||
|
import { hexToNpub } from './nostr.ts'
|
||||||
|
import { Meta, SignedEventContent } from '../types'
|
||||||
|
import { Event } from 'nostr-tools'
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes in an array of Marks already filtered by User.
|
||||||
|
* Returns an array of CurrentUserMarks with correct values mix-and-matched.
|
||||||
|
* @param marks - default Marks extracted from Meta
|
||||||
|
* @param signedMetaMarks - signed user Marks extracted from DocSignatures
|
||||||
|
*/
|
||||||
|
const getCurrentUserMarks = (marks: Mark[], signedMetaMarks: Mark[]): CurrentUserMark[] => {
|
||||||
|
return marks.map((mark, index, arr) => {
|
||||||
|
const signedMark = signedMetaMarks.find((m) => m.id === mark.id);
|
||||||
|
if (signedMark && !!signedMark.value) {
|
||||||
|
mark.value = signedMark.value
|
||||||
|
}
|
||||||
|
return {
|
||||||
|
mark,
|
||||||
|
isLast: isLast(index, arr),
|
||||||
|
isCompleted: !!mark.value
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns next incomplete CurrentUserMark if there is one
|
||||||
|
* @param usersMarks
|
||||||
|
*/
|
||||||
|
const findNextCurrentUserMark = (usersMarks: CurrentUserMark[]): CurrentUserMark | undefined => {
|
||||||
|
return usersMarks.find((mark) => !mark.isCompleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns Marks that are assigned to a specific user
|
||||||
|
* @param marks
|
||||||
|
* @param pubkey
|
||||||
|
*/
|
||||||
|
const filterMarksByPubkey = (marks: Mark[], pubkey: string): Mark[] => {
|
||||||
|
return marks.filter(mark => mark.npub === hexToNpub(pubkey))
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Takes Signed Doc Signatures part of Meta and extracts
|
||||||
|
* all Marks into one flar array, regardless of the user.
|
||||||
|
* @param meta
|
||||||
|
*/
|
||||||
|
const extractMarksFromSignedMeta = (meta: Meta): Mark[] => {
|
||||||
|
return Object.values(meta.docSignatures)
|
||||||
|
.map((val: string) => JSON.parse(val as string))
|
||||||
|
.map((val: Event) => JSON.parse(val.content))
|
||||||
|
.flatMap((val: SignedEventContent) => val.marks)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks the CurrentUserMarks array that every element in that array has been
|
||||||
|
* marked as complete.
|
||||||
|
* @param currentUserMarks
|
||||||
|
*/
|
||||||
|
const isCurrentUserMarksComplete = (currentUserMarks: CurrentUserMark[]): boolean => {
|
||||||
|
return currentUserMarks.every((mark) => mark.isCompleted)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inserts an updated mark into an existing array of marks. Returns a copy of the
|
||||||
|
* existing array with a new value inserted
|
||||||
|
* @param marks
|
||||||
|
* @param markToUpdate
|
||||||
|
*/
|
||||||
|
const updateMarks = (marks: Mark[], markToUpdate: Mark): Mark[] => {
|
||||||
|
const indexToUpdate = marks.findIndex(mark => mark.id === markToUpdate.id);
|
||||||
|
return [
|
||||||
|
...marks.slice(0, indexToUpdate),
|
||||||
|
markToUpdate,
|
||||||
|
...marks.slice(indexToUpdate + 1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const updateCurrentUserMarks = (currentUserMarks: CurrentUserMark[], markToUpdate: CurrentUserMark): CurrentUserMark[] => {
|
||||||
|
const indexToUpdate = currentUserMarks.findIndex((m) => m.mark.id === markToUpdate.mark.id)
|
||||||
|
return [
|
||||||
|
...currentUserMarks.slice(0, indexToUpdate),
|
||||||
|
markToUpdate,
|
||||||
|
...currentUserMarks.slice(indexToUpdate + 1)
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
const isLast = (index: number, arr: any[]) => (index === (arr.length -1))
|
||||||
|
|
||||||
|
export {
|
||||||
|
getCurrentUserMarks,
|
||||||
|
filterMarksByPubkey,
|
||||||
|
extractMarksFromSignedMeta,
|
||||||
|
isCurrentUserMarksComplete,
|
||||||
|
findNextCurrentUserMark,
|
||||||
|
updateMarks,
|
||||||
|
updateCurrentUserMarks,
|
||||||
|
}
|
@ -1,3 +1,5 @@
|
|||||||
|
import { PdfFile } from '../types/drawing.ts'
|
||||||
|
|
||||||
export const compareObjects = (
|
export const compareObjects = (
|
||||||
obj1: object | null | undefined,
|
obj1: object | null | undefined,
|
||||||
obj2: object | null | undefined
|
obj2: object | null | undefined
|
||||||
@ -64,3 +66,17 @@ export const timeout = (ms: number = 60000) => {
|
|||||||
}, ms) // Timeout duration in milliseconds
|
}, ms) // Timeout duration in milliseconds
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
/**
|
||||||
|
* Creates a flat array where each object contains all required information about a Pdf File,
|
||||||
|
* including its name, hash, and content
|
||||||
|
* @param files
|
||||||
|
* @param fileHashes
|
||||||
|
*/
|
||||||
|
export const getFilesWithHashes = (
|
||||||
|
files: { [filename: string ]: PdfFile },
|
||||||
|
fileHashes: { [key: string]: string | null }
|
||||||
|
) => {
|
||||||
|
return Object.entries(files).map(([filename, pdfFile]) => {
|
||||||
|
return { pdfFile, filename, hash: fileHashes[filename] }
|
||||||
|
})
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user