PDF Markings #114

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

View File

@ -139,7 +139,7 @@ export const DrawPDFFields = (props: Props) => {
* Drawing is finished, resets all the variables used to draw
* @param event Mouse event
*/
const onMouseUp = (event: MouseEvent) => {
const onMouseUp = () => {
setMouseState((prev) => {
return {
...prev,
@ -187,7 +187,7 @@ export const DrawPDFFields = (props: Props) => {
* @param event Mouse event
* @param drawnField Which we are moving
*/
const onDrawnFieldMouseDown = (event: any, drawnField: DrawnField) => {
const onDrawnFieldMouseDown = (event: any) => {
event.stopPropagation()
// Proceed only if left click
@ -240,7 +240,7 @@ export const DrawPDFFields = (props: Props) => {
* @param event Mouse event
* @param drawnField which we are resizing
*/
const onResizeHandleMouseDown = (event: any, drawnField: DrawnField) => {
const onResizeHandleMouseDown = (event: any) => {
// Proceed only if left click
if (event.button !== 0) return
@ -377,7 +377,7 @@ export const DrawPDFFields = (props: Props) => {
return (
<div
key={drawnFieldIndex}
onMouseDown={(event) => { onDrawnFieldMouseDown(event, drawnField) }}
onMouseDown={onDrawnFieldMouseDown}
onMouseMove={(event) => { onDranwFieldMouseMove(event, drawnField)}}
className={styles.drawingRectangle}
style={{
@ -389,7 +389,7 @@ export const DrawPDFFields = (props: Props) => {
}}
>
<span
onMouseDown={(event) => {onResizeHandleMouseDown(event, drawnField)}}
onMouseDown={onResizeHandleMouseDown}
onMouseMove={(event) => {onResizeHandleMouseMove(event, drawnField)}}
className={styles.resizeHandle}
></span>
@ -400,7 +400,7 @@ export const DrawPDFFields = (props: Props) => {
<Close fontSize='small'/>
</span>
<div
onMouseDown={(event) => {onUserSelectHandleMouseDown(event)}}
onMouseDown={onUserSelectHandleMouseDown}
className={styles.userSelect}
>
<FormControl fullWidth size='small'>

View File

@ -10,6 +10,9 @@ interface PdfItemProps {
selectedMark: CurrentUserMark | null
}
/**
* Responsible for displaying pages of a single Pdf File.
*/
const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfItemProps) => {
const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => {
return marks.filter((m) => m.mark.location.page === page);

View File

@ -9,10 +9,9 @@ interface PdfMarkItemProps {
selectedMark: CurrentUserMark | null
}
//selectedMark represents the mark that the user is actively editing
// selectedMarkValue representsnthe edited value
// userMark is part of the overall currentUserMark array
/**
* Responsible for display an individual Pdf Mark.
*/
const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, userMark }: PdfMarkItemProps) => {
const { location } = userMark.mark;
const handleClick = () => handleMarkClick(userMark.mark.id);

View File

@ -4,7 +4,7 @@ import PdfView from './index.tsx'
import MarkFormField from '../../pages/sign/MarkFormField.tsx'
import { PdfFile } from '../../types/drawing.ts'
import { CurrentUserMark, Mark } from '../../types/mark.ts'
import { useState, useEffect } from 'react'
import React, { useState, useEffect } from 'react'
import {
findNextCurrentUserMark,
isCurrentUserMarksComplete,
@ -21,6 +21,12 @@ interface PdfMarkingProps {
setUpdatedMarks: (markToUpdate: Mark) => void
}
/**
* Top-level component responsible for displaying Pdfs, Pages, and Marks,
* as well as tracking if the document is ready to be signed.
* @param props
* @constructor
*/
const PdfMarking = (props: PdfMarkingProps) => {
const {
files,
@ -42,7 +48,7 @@ const PdfMarking = (props: PdfMarkingProps) => {
setSelectedMarkValue(nextMark?.mark.value ?? EMPTY);
}
const handleSubmit = (event: any) => {
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
event.preventDefault();
if (!selectedMarkValue || !selectedMark) return;
@ -64,7 +70,7 @@ const PdfMarking = (props: PdfMarkingProps) => {
setUpdatedMarks(updatedMark.mark)
}
const handleChange = (event: any) => setSelectedMarkValue(event.target.value)
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => setSelectedMarkValue(event.target.value)
return (
<>

View File

@ -10,6 +10,9 @@ interface PdfPageProps {
selectedMark: CurrentUserMark | null
}
/**
* Responsible for rendering a single Pdf Page and its Marks
*/
const PdfPageItem = ({ page, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfPageProps) => {
return (
<div

View File

@ -11,6 +11,9 @@ interface PdfViewProps {
selectedMark: CurrentUserMark | null
}
/**
* Responsible for rendering Pdf files.
*/
const PdfView = ({ files, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfViewProps) => {
const filterByFile = (currentUserMarks: CurrentUserMark[], hash: string): CurrentUserMark[] => {
return currentUserMarks.filter((currentUserMark) => currentUserMark.mark.pdfFileHash === hash)

View File

@ -63,7 +63,6 @@ import styles from './style.module.scss'
import { PdfFile } from '../../types/drawing'
import { DrawPDFFields } from '../../components/DrawPDFFields'
import { Mark } from '../../types/mark.ts'
import { v4 as uuidv4 } from 'uuid';
export const CreatePage = () => {
const navigate = useNavigate()
@ -341,7 +340,7 @@ export const CreatePage = () => {
return fileHashes
}
const createMarkConfig = (fileHashes: { [key: string]: string }) : Mark[] => {
const createMarks = (fileHashes: { [key: string]: string }) : Mark[] => {
return drawnPdfs.flatMap((drawnPdf) => {
const fileHash = fileHashes[drawnPdf.file.name];
return drawnPdf.pages.flatMap((page, index) => {
@ -378,15 +377,13 @@ export const CreatePage = () => {
const generateZipFile = async (zip: JSZip): Promise<ArrayBuffer | null> => {
setLoadingSpinnerDesc('Generating zip file')
const arraybuffer = await zip
return await zip
.generateAsync({
type: 'arraybuffer',
compression: 'DEFLATE',
compressionOptions: { level: 6 }
})
.catch(handleZipError)
return arraybuffer
}
// Encrypt the zip file with the generated encryption key
@ -433,15 +430,13 @@ export const CreatePage = () => {
if (!arraybuffer) return null
const finalZipFile = new File(
return new File(
[new Blob([arraybuffer])],
`${unixNow}.sigit.zip`,
{
type: 'application/zip'
}
)
return finalZipFile
}
// Handle errors during file upload
@ -463,14 +458,12 @@ export const CreatePage = () => {
type: 'application/sigit'
})
const fileUrl = await uploadToFileStorage(file)
return await uploadToFileStorage(file)
.then((url) => {
toast.success('files.zip uploaded to file storage')
return url
})
.catch(handleUploadError)
return fileUrl
}
// Manage offline scenarios for signing or viewing the file
@ -494,15 +487,13 @@ export const CreatePage = () => {
zip.file(file.name, file)
})
const arraybuffer = await zip
return await zip
.generateAsync({
type: 'arraybuffer',
compression: 'DEFLATE',
compressionOptions: { level: 6 }
})
.catch(handleZipError)
return arraybuffer
}
const generateCreateSignature = async (
@ -513,9 +504,7 @@ export const CreatePage = () => {
) => {
const signers = users.filter((user) => user.role === UserRole.signer)
const viewers = users.filter((user) => user.role === UserRole.viewer)
const markConfig = createMarkConfig(fileHashes)
console.log('mark config: ', markConfig)
const markConfig = createMarks(fileHashes)
const content: CreateSignatureEventContent = {
signers: signers.map((signer) => hexToNpub(signer.pubkey)),
@ -555,11 +544,9 @@ export const CreatePage = () => {
: viewers.map((viewer) => viewer.pubkey)
).filter((receiver) => receiver !== usersPubkey)
const promises = receivers.map((receiver) =>
return receivers.map((receiver) =>
sendNotification(receiver, meta)
)
return promises
}
const handleCreate = async () => {

View File

@ -11,6 +11,11 @@ interface MarkFormFieldProps {
selectedMarkValue: string
}
/**
* Responsible for rendering a form field connected to a mark and keeping track of its value.
* @param props
* @constructor
*/
const MarkFormField = (props: MarkFormFieldProps) => {
const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props;
const getSubmitButton = () => selectedMark.isLast ? 'Complete' : 'Next';