PDF Markings #114
@ -16,10 +16,10 @@ import { State } from '../../store/rootReducer'
|
|||||||
import { CreateSignatureEventContent, Meta, SignedEvent } from '../../types'
|
import { CreateSignatureEventContent, Meta, SignedEvent } from '../../types'
|
||||||
import {
|
import {
|
||||||
decryptArrayBuffer,
|
decryptArrayBuffer,
|
||||||
encryptArrayBuffer,
|
encryptArrayBuffer, extractMarksFromSignedMeta,
|
||||||
extractZipUrlAndEncryptionKey,
|
extractZipUrlAndEncryptionKey,
|
||||||
generateEncryptionKey,
|
generateEncryptionKey,
|
||||||
generateKeysFile,
|
generateKeysFile, getFilesWithHashes,
|
||||||
getHash,
|
getHash,
|
||||||
hexToNpub,
|
hexToNpub,
|
||||||
isOnline, loadZip,
|
isOnline, loadZip,
|
||||||
@ -35,10 +35,15 @@ import { DisplayMeta } from './internal/displayMeta'
|
|||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
import { PdfFile } from '../../types/drawing.ts'
|
import { PdfFile } from '../../types/drawing.ts'
|
||||||
import { convertToPdfFile } from '../../utils/pdf.ts'
|
import { convertToPdfFile } from '../../utils/pdf.ts'
|
||||||
import PdfView from '../../components/PDFView'
|
// import PdfView from '../../components/PDFView'
|
||||||
import { CurrentUserMark, Mark, MarkConfig } from '../../types/mark.ts'
|
import { CurrentUserMark, Mark } from '../../types/mark.ts'
|
||||||
import MarkFormField from './MarkFormField.tsx'
|
|
||||||
import { getLastSignersSig } from '../../utils/sign.ts'
|
import { getLastSignersSig } from '../../utils/sign.ts'
|
||||||
|
import {
|
||||||
|
filterMarksByPubkey,
|
||||||
|
getCurrentUserMarks,
|
||||||
|
isCurrentUserMarksComplete, updateMarks
|
||||||
|
} from '../../utils/mark.ts'
|
||||||
|
import PdfMarking from '../../components/PDFView/PdfMarking.tsx'
|
||||||
enum SignedStatus {
|
enum SignedStatus {
|
||||||
Fully_Signed,
|
Fully_Signed,
|
||||||
User_Is_Next_Signer,
|
User_Is_Next_Signer,
|
||||||
@ -95,10 +100,8 @@ export const SignPage = () => {
|
|||||||
|
|
||||||
const [authUrl, setAuthUrl] = useState<string>()
|
const [authUrl, setAuthUrl] = useState<string>()
|
||||||
const nostrController = NostrController.getInstance()
|
const nostrController = NostrController.getInstance()
|
||||||
const [currentUserMark, setCurrentUserMark] = useState<CurrentUserMark | null>(null);
|
|
||||||
const [currentUserMarks, setCurrentUserMarks] = useState<CurrentUserMark[]>([]);
|
const [currentUserMarks, setCurrentUserMarks] = useState<CurrentUserMark[]>([]);
|
||||||
const [currentMarkValue, setCurrentMarkValue] = useState<string>('');
|
const [isReadyToSign, setIsReadyToSign] = useState(false);
|
||||||
const [isMarksCompleted, setIsMarksCompleted] = useState(false);
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (signers.length > 0) {
|
if (signers.length > 0) {
|
||||||
@ -191,22 +194,13 @@ export const SignPage = () => {
|
|||||||
setSubmittedBy(createSignatureEvent.pubkey)
|
setSubmittedBy(createSignatureEvent.pubkey)
|
||||||
setMarks(createSignatureContent.markConfig);
|
setMarks(createSignatureContent.markConfig);
|
||||||
|
|
||||||
console.log('createSignatureContent markConfig', createSignatureContent);
|
|
||||||
if (usersPubkey) {
|
if (usersPubkey) {
|
||||||
console.log('this runs behind users pubkey');
|
const metaMarks = filterMarksByPubkey(createSignatureContent.markConfig, usersPubkey!)
|
||||||
const curMarks = getCurrentUserMarks(createSignatureContent.markConfig, usersPubkey)
|
const signedMarks = extractMarksFromSignedMeta(meta)
|
||||||
if (curMarks.length === 0) {
|
const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks);
|
||||||
setIsMarksCompleted(true)
|
setCurrentUserMarks(currentUserMarks);
|
||||||
} else {
|
// setCurrentUserMark(findNextCurrentUserMark(currentUserMarks) || null)
|
||||||
const nextMark = findNextIncompleteMark(curMarks)
|
setIsReadyToSign(isCurrentUserMarksComplete(currentUserMarks))
|
||||||
if (!nextMark) {
|
|
||||||
setIsMarksCompleted(true)
|
|
||||||
} else {
|
|
||||||
setCurrentUserMark(nextMark)
|
|
||||||
setIsMarksCompleted(false)
|
|
||||||
}
|
|
||||||
setCurrentUserMarks(curMarks)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setSignedBy(Object.keys(meta.docSignatures) as `npub1${string}`[])
|
setSignedBy(Object.keys(meta.docSignatures) as `npub1${string}`[])
|
||||||
@ -218,6 +212,7 @@ export const SignPage = () => {
|
|||||||
}, [meta])
|
}, [meta])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
// online mode - from create and home page views
|
||||||
if (metaInNavState) {
|
if (metaInNavState) {
|
||||||
const processSigit = async () => {
|
const processSigit = async () => {
|
||||||
setIsLoading(true)
|
setIsLoading(true)
|
||||||
@ -239,7 +234,7 @@ export const SignPage = () => {
|
|||||||
.then((res) => {
|
.then((res) => {
|
||||||
handleArrayBufferFromBlossom(res.data, encryptionKey)
|
handleArrayBufferFromBlossom(res.data, encryptionKey)
|
||||||
setMeta(metaInNavState)
|
setMeta(metaInNavState)
|
||||||
console.log('meta in nav state: ', metaInNavState)
|
console.log('meta in nav state runs.')
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err) => {
|
||||||
console.error(`error occurred in getting file from ${zipUrl}`, err)
|
console.error(`error occurred in getting file from ${zipUrl}`, err)
|
||||||
@ -330,6 +325,11 @@ export const SignPage = () => {
|
|||||||
setCurrentFileHashes(fileHashes)
|
setCurrentFileHashes(fileHashes)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setUpdatedMarks = (markToUpdate: Mark) => {
|
||||||
|
const updatedMarks = updateMarks(marks, markToUpdate)
|
||||||
|
setMarks(updatedMarks)
|
||||||
|
}
|
||||||
|
|
||||||
const parseKeysJson = async (zip: JSZip) => {
|
const parseKeysJson = async (zip: JSZip) => {
|
||||||
const keysFileContent = await readContentOfZipEntry(
|
const keysFileContent = await readContentOfZipEntry(
|
||||||
zip,
|
zip,
|
||||||
@ -540,56 +540,41 @@ export const SignPage = () => {
|
|||||||
return currentUserMarks.map(( { mark }: CurrentUserMark) => mark);
|
return currentUserMarks.map(( { mark }: CurrentUserMark) => mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleMarkClick = (id: number) => {
|
// const handleMarkClick = (id: number) => {
|
||||||
const nextMark = currentUserMarks.find(mark => mark.mark.id === id)
|
// const nextMark = currentUserMarks.find(mark => mark.mark.id === id)
|
||||||
setCurrentUserMark(nextMark!)
|
// setCurrentUserMark(nextMark!)
|
||||||
setCurrentMarkValue(nextMark?.mark.value || "")
|
// setCurrentMarkValue(nextMark?.mark.value || "")
|
||||||
}
|
// }
|
||||||
|
|
||||||
const getMarkConfigPerUser = (markConfig: MarkConfig) => {
|
// const getMarkConfigPerUser = (markConfig: MarkConfig) => {
|
||||||
if (!usersPubkey) return;
|
// if (!usersPubkey) return;
|
||||||
return markConfig[hexToNpub(usersPubkey)];
|
// return markConfig[hexToNpub(usersPubkey)];
|
||||||
}
|
// }
|
||||||
|
|
||||||
const handleChange = (event: any) => setCurrentMarkValue(event.target.value);
|
// const handleChange = (event: any) => setCurrentMarkValue(event.target.value);
|
||||||
|
//
|
||||||
const handleSubmit = (event: any) => {
|
// const handleSubmit = (event: any) => {
|
||||||
event.preventDefault();
|
// event.preventDefault();
|
||||||
if (!currentMarkValue || !currentUserMark) return;
|
// if (!currentMarkValue || !currentUserMark) return;
|
||||||
|
//
|
||||||
const curMark = {
|
// const curMark: Mark = {
|
||||||
...currentUserMark.mark,
|
// ...currentUserMark.mark,
|
||||||
value: currentMarkValue
|
// value: currentMarkValue
|
||||||
};
|
// };
|
||||||
|
//
|
||||||
const indexToUpdate = marks.findIndex(mark => mark.id === curMark.id);
|
// const updatedMarks: Mark[] = updateMarks(marks, curMark)
|
||||||
|
//
|
||||||
const updatedMarks: Mark[] = [
|
// setMarks(updatedMarks)
|
||||||
...marks.slice(0, indexToUpdate),
|
// setCurrentMarkValue("")
|
||||||
curMark,
|
//
|
||||||
...marks.slice(indexToUpdate + 1)
|
// // do the similar thing to the thing above
|
||||||
];
|
// const metaMarks = filterMarksByPubkey(updatedMarks, usersPubkey!)
|
||||||
|
// const signedMarks = extractMarksFromSignedMeta(meta!)
|
||||||
setMarks(updatedMarks)
|
// const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks)
|
||||||
setCurrentMarkValue("")
|
// setCurrentUserMarks(currentUserMarks)
|
||||||
|
// setCurrentUserMark(findNextCurrentUserMark(currentUserMarks) || null)
|
||||||
const updatedCurUserMarks = getCurrentUserMarks(updatedMarks, usersPubkey!)
|
// setIsReadyToSign(isCurrentUserMarksComplete(currentUserMarks))
|
||||||
console.log('updatedCurUserMarks: ', updatedCurUserMarks)
|
// }
|
||||||
setCurrentUserMarks(updatedCurUserMarks)
|
|
||||||
const nextMark = findNextIncompleteMark(updatedCurUserMarks)
|
|
||||||
console.log('next mark: ', nextMark)
|
|
||||||
if (!nextMark) {
|
|
||||||
setCurrentUserMark(null)
|
|
||||||
setIsMarksCompleted(true)
|
|
||||||
} else {
|
|
||||||
setCurrentUserMark(nextMark)
|
|
||||||
setIsMarksCompleted(false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const findNextIncompleteMark = (usersMarks: CurrentUserMark[]): CurrentUserMark | undefined => {
|
|
||||||
return usersMarks.find(mark => !mark.isCompleted);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the meta signatures
|
// Update the meta signatures
|
||||||
const updateMetaSignatures = (meta: Meta, signedEvent: SignedEvent): Meta => {
|
const updateMetaSignatures = (meta: Meta, signedEvent: SignedEvent): Meta => {
|
||||||
@ -599,7 +584,6 @@ export const SignPage = () => {
|
|||||||
[hexToNpub(signedEvent.pubkey)]: JSON.stringify(signedEvent, null, 2)
|
[hexToNpub(signedEvent.pubkey)]: JSON.stringify(signedEvent, null, 2)
|
||||||
}
|
}
|
||||||
metaCopy.modifiedAt = now()
|
metaCopy.modifiedAt = now()
|
||||||
console.log('meta copy: ', metaCopy);
|
|
||||||
return metaCopy
|
return metaCopy
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -724,7 +708,6 @@ export const SignPage = () => {
|
|||||||
await Promise.all(promises)
|
await Promise.all(promises)
|
||||||
.then(() => {
|
.then(() => {
|
||||||
toast.success('Notifications sent successfully')
|
toast.success('Notifications sent successfully')
|
||||||
console.log('meta: ', meta);
|
|
||||||
setMeta(meta)
|
setMeta(meta)
|
||||||
})
|
})
|
||||||
.catch(() => {
|
.catch(() => {
|
||||||
@ -816,25 +799,6 @@ export const SignPage = () => {
|
|||||||
navigate(appPublicRoutes.verify)
|
navigate(appPublicRoutes.verify)
|
||||||
}
|
}
|
||||||
|
|
||||||
const getCurrentUserMarks = (marks: Mark[], pubkey: string): CurrentUserMark[] => {
|
|
||||||
console.log('marks: ', marks);
|
|
||||||
|
|
||||||
const filteredMarks = marks
|
|
||||||
.filter(mark => mark.npub === hexToNpub(pubkey))
|
|
||||||
const currentMarks = filteredMarks
|
|
||||||
.map((mark, index, arr) => {
|
|
||||||
return {
|
|
||||||
mark,
|
|
||||||
isLast: isLast(index, arr),
|
|
||||||
isCompleted: !!mark.value
|
|
||||||
}
|
|
||||||
})
|
|
||||||
console.log('current marks: ', currentMarks)
|
|
||||||
return currentMarks;
|
|
||||||
}
|
|
||||||
|
|
||||||
const isLast = (index: number, arr: any[]) => (index === (arr.length -1))
|
|
||||||
|
|
||||||
const handleExportSigit = async () => {
|
const handleExportSigit = async () => {
|
||||||
if (Object.entries(files).length === 0 || !meta) return
|
if (Object.entries(files).length === 0 || !meta) return
|
||||||
|
|
||||||
@ -925,105 +889,111 @@ export const SignPage = () => {
|
|||||||
return <LoadingSpinner desc={loadingSpinnerDesc} />
|
return <LoadingSpinner desc={loadingSpinnerDesc} />
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!isMarksCompleted) {
|
if (isReadyToSign) {
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<Box className={styles.container}>
|
<Box className={styles.container}>
|
||||||
{
|
{displayInput && (
|
||||||
marks.length > 0 && (
|
<>
|
||||||
<PdfView
|
<Typography component="label" variant="h6">
|
||||||
files={files}
|
Select sigit file
|
||||||
marks={marks}
|
</Typography>
|
||||||
fileHashes={currentFileHashes}
|
|
||||||
handleMarkClick={handleMarkClick}
|
<Box className={styles.inputBlock}>
|
||||||
currentMarkValue={currentMarkValue}
|
<MuiFileInput
|
||||||
currentUserMark={currentUserMark}
|
placeholder="Select file"
|
||||||
/>)}
|
inputProps={{ accept: '.sigit.zip' }}
|
||||||
{
|
value={selectedFile}
|
||||||
currentUserMark !== null && (
|
onChange={(value) => setSelectedFile(value)}
|
||||||
<MarkFormField
|
/>
|
||||||
handleSubmit={handleSubmit}
|
</Box>
|
||||||
handleChange={handleChange}
|
|
||||||
currentMark={currentUserMark}
|
{selectedFile && (
|
||||||
currentMarkValue={currentMarkValue}
|
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'center' }}>
|
||||||
/>
|
<Button onClick={handleDecrypt} variant="contained">
|
||||||
|
Decrypt
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{submittedBy && Object.entries(files).length > 0 && meta && (
|
||||||
|
<>
|
||||||
|
<DisplayMeta
|
||||||
|
meta={meta}
|
||||||
|
files={files}
|
||||||
|
submittedBy={submittedBy}
|
||||||
|
signers={signers}
|
||||||
|
viewers={viewers}
|
||||||
|
creatorFileHashes={creatorFileHashes}
|
||||||
|
currentFileHashes={currentFileHashes}
|
||||||
|
signedBy={signedBy}
|
||||||
|
nextSigner={nextSinger}
|
||||||
|
getPrevSignersSig={getPrevSignersSig}
|
||||||
|
/>
|
||||||
|
|
||||||
|
{signedStatus === SignedStatus.Fully_Signed && (
|
||||||
|
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Button onClick={handleExport} variant="contained">
|
||||||
|
Export
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{signedStatus === SignedStatus.User_Is_Next_Signer && (
|
||||||
|
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Button onClick={handleSign} variant="contained">
|
||||||
|
Sign
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
|
||||||
|
{isSignerOrCreator && (
|
||||||
|
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
||||||
|
<Button onClick={handleExportSigit} variant="contained">
|
||||||
|
Export Sigit
|
||||||
|
</Button>
|
||||||
|
</Box>
|
||||||
|
)}
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</Box>
|
</Box>
|
||||||
</>
|
</>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
)}
|
return <PdfMarking
|
||||||
|
files={getFilesWithHashes(files, currentFileHashes)}
|
||||||
|
currentUserMarks={currentUserMarks}
|
||||||
|
setIsReadyToSign={setIsReadyToSign}
|
||||||
|
setCurrentUserMarks={setCurrentUserMarks}
|
||||||
|
setUpdatedMarks={setUpdatedMarks}
|
||||||
|
/>
|
||||||
|
|
||||||
return (
|
// return (
|
||||||
<>
|
// <>
|
||||||
<Box className={styles.container}>
|
// <Box className={styles.container}>
|
||||||
{displayInput && (
|
// {
|
||||||
<>
|
// marks.length > 0 && (
|
||||||
<Typography component="label" variant="h6">
|
// <PdfView
|
||||||
Select sigit file
|
// files={files}
|
||||||
</Typography>
|
// marks={marks}
|
||||||
|
// fileHashes={currentFileHashes}
|
||||||
<Box className={styles.inputBlock}>
|
// handleMarkClick={handleMarkClick}
|
||||||
<MuiFileInput
|
// currentMarkValue={currentMarkValue}
|
||||||
placeholder="Select file"
|
// currentUserMark={currentUserMark}
|
||||||
inputProps={{ accept: '.sigit.zip' }}
|
// />)}
|
||||||
value={selectedFile}
|
// {
|
||||||
onChange={(value) => setSelectedFile(value)}
|
// currentUserMark !== null && (
|
||||||
/>
|
// <MarkFormField
|
||||||
</Box>
|
// handleSubmit={handleSubmit}
|
||||||
|
// handleChange={handleChange}
|
||||||
{selectedFile && (
|
// currentMark={currentUserMark}
|
||||||
<Box sx={{ mt: 2, display: 'flex', justifyContent: 'center' }}>
|
// currentMarkValue={currentMarkValue}
|
||||||
<Button onClick={handleDecrypt} variant="contained">
|
// />
|
||||||
Decrypt
|
// )}
|
||||||
</Button>
|
// </Box>
|
||||||
</Box>
|
// </>
|
||||||
)}
|
// )
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{submittedBy && Object.entries(files).length > 0 && meta && (
|
|
||||||
<>
|
|
||||||
<DisplayMeta
|
|
||||||
meta={meta}
|
|
||||||
files={files}
|
|
||||||
submittedBy={submittedBy}
|
|
||||||
signers={signers}
|
|
||||||
viewers={viewers}
|
|
||||||
creatorFileHashes={creatorFileHashes}
|
|
||||||
currentFileHashes={currentFileHashes}
|
|
||||||
signedBy={signedBy}
|
|
||||||
nextSigner={nextSinger}
|
|
||||||
getPrevSignersSig={getPrevSignersSig}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{signedStatus === SignedStatus.Fully_Signed && (
|
|
||||||
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
|
||||||
<Button onClick={handleExport} variant="contained">
|
|
||||||
Export
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{signedStatus === SignedStatus.User_Is_Next_Signer && (
|
|
||||||
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
|
||||||
<Button onClick={handleSign} variant="contained">
|
|
||||||
Sign
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
|
|
||||||
{isSignerOrCreator && (
|
|
||||||
<Box sx={{ mt: 1, display: 'flex', justifyContent: 'center' }}>
|
|
||||||
<Button onClick={handleExportSigit} variant="contained">
|
|
||||||
Export Sigit
|
|
||||||
</Button>
|
|
||||||
</Box>
|
|
||||||
)}
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
|
|
||||||
|
|
||||||
</Box>
|
|
||||||
</>
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user