diff --git a/src/components/PDFView/PdfItem.tsx b/src/components/PDFView/PdfItem.tsx index 76c1b8b..d9fae3d 100644 --- a/src/components/PDFView/PdfItem.tsx +++ b/src/components/PDFView/PdfItem.tsx @@ -1,18 +1,18 @@ 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'; interface PdfItemProps { pdfFile: PdfFile - marks: Mark[] + currentUserMarks: CurrentUserMark[] handleMarkClick: (id: number) => void currentMarkValue: string currentUserMark: CurrentUserMark | null } -const PdfItem = ({ pdfFile, marks, handleMarkClick, currentMarkValue, currentUserMark }: PdfItemProps) => { - const filterByPage = (marks: Mark[], page: number): Mark[] => { - return marks.filter((mark) => mark.location.page === page); +const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, currentMarkValue, currentUserMark }: PdfItemProps) => { + const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => { + return marks.filter((m) => m.mark.location.page === page); } return ( pdfFile.pages.map((page, i) => { @@ -20,7 +20,7 @@ const PdfItem = ({ pdfFile, marks, handleMarkClick, currentMarkValue, currentUse { + 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, +} diff --git a/src/utils/utils.ts b/src/utils/utils.ts index 929af78..ed830a2 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -1,3 +1,5 @@ +import { PdfFile } from '../types/drawing.ts' + export const compareObjects = ( obj1: object | null | undefined, obj2: object | null | undefined @@ -64,3 +66,17 @@ export const timeout = (ms: number = 60000) => { }, 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] } + }) +}