PDF Markings #114

Merged
eugene merged 33 commits from issue-99 into staging 2024-08-06 10:02:04 +00:00
6 changed files with 121 additions and 6 deletions
Showing only changes of commit 651d576eea - Show all commits

View File

@ -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}

View File

0
src/utils/const.ts Normal file
View File

View 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
View 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,
}

View File

@ -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] }
})
}