Compare commits
No commits in common. "37b0ae21e0248ae6f75d123e5439a035fb6164ec" and "d8395ef8b39ed91f2fc3dbab33333e0dd06a0195" have entirely different histories.
37b0ae21e0
...
d8395ef8b3
@ -139,7 +139,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
* Drawing is finished, resets all the variables used to draw
|
* Drawing is finished, resets all the variables used to draw
|
||||||
* @param event Mouse event
|
* @param event Mouse event
|
||||||
*/
|
*/
|
||||||
const onMouseUp = () => {
|
const onMouseUp = (event: MouseEvent) => {
|
||||||
setMouseState((prev) => {
|
setMouseState((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
@ -187,7 +187,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
* @param event Mouse event
|
* @param event Mouse event
|
||||||
* @param drawnField Which we are moving
|
* @param drawnField Which we are moving
|
||||||
*/
|
*/
|
||||||
const onDrawnFieldMouseDown = (event: any) => {
|
const onDrawnFieldMouseDown = (event: any, drawnField: DrawnField) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
// Proceed only if left click
|
// Proceed only if left click
|
||||||
@ -240,7 +240,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
* @param event Mouse event
|
* @param event Mouse event
|
||||||
* @param drawnField which we are resizing
|
* @param drawnField which we are resizing
|
||||||
*/
|
*/
|
||||||
const onResizeHandleMouseDown = (event: any) => {
|
const onResizeHandleMouseDown = (event: any, drawnField: DrawnField) => {
|
||||||
// Proceed only if left click
|
// Proceed only if left click
|
||||||
if (event.button !== 0) return
|
if (event.button !== 0) return
|
||||||
|
|
||||||
@ -377,7 +377,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={drawnFieldIndex}
|
key={drawnFieldIndex}
|
||||||
onMouseDown={onDrawnFieldMouseDown}
|
onMouseDown={(event) => { onDrawnFieldMouseDown(event, drawnField) }}
|
||||||
onMouseMove={(event) => { onDranwFieldMouseMove(event, drawnField)}}
|
onMouseMove={(event) => { onDranwFieldMouseMove(event, drawnField)}}
|
||||||
className={styles.drawingRectangle}
|
className={styles.drawingRectangle}
|
||||||
style={{
|
style={{
|
||||||
@ -389,7 +389,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
<span
|
<span
|
||||||
onMouseDown={onResizeHandleMouseDown}
|
onMouseDown={(event) => {onResizeHandleMouseDown(event, drawnField)}}
|
||||||
onMouseMove={(event) => {onResizeHandleMouseMove(event, drawnField)}}
|
onMouseMove={(event) => {onResizeHandleMouseMove(event, drawnField)}}
|
||||||
className={styles.resizeHandle}
|
className={styles.resizeHandle}
|
||||||
></span>
|
></span>
|
||||||
@ -400,7 +400,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
<Close fontSize='small'/>
|
<Close fontSize='small'/>
|
||||||
</span>
|
</span>
|
||||||
<div
|
<div
|
||||||
onMouseDown={onUserSelectHandleMouseDown}
|
onMouseDown={(event) => {onUserSelectHandleMouseDown(event)}}
|
||||||
className={styles.userSelect}
|
className={styles.userSelect}
|
||||||
>
|
>
|
||||||
<FormControl fullWidth size='small'>
|
<FormControl fullWidth size='small'>
|
||||||
|
@ -59,6 +59,8 @@
|
|||||||
.drawingRectangle {
|
.drawingRectangle {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border: 1px solid #01aaad;
|
border: 1px solid #01aaad;
|
||||||
|
//width: 40px;
|
||||||
|
//height: 40px;
|
||||||
z-index: 50;
|
z-index: 50;
|
||||||
background-color: #01aaad4b;
|
background-color: #01aaad4b;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
0
src/components/PDFView/Mark.tsx
Normal file
0
src/components/PDFView/Mark.tsx
Normal file
@ -10,9 +10,6 @@ interface PdfItemProps {
|
|||||||
selectedMark: CurrentUserMark | null
|
selectedMark: CurrentUserMark | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for displaying pages of a single Pdf File.
|
|
||||||
*/
|
|
||||||
const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfItemProps) => {
|
const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfItemProps) => {
|
||||||
const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => {
|
const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => {
|
||||||
return marks.filter((m) => m.mark.location.page === page);
|
return marks.filter((m) => m.mark.location.page === page);
|
||||||
|
@ -9,9 +9,10 @@ interface PdfMarkItemProps {
|
|||||||
selectedMark: CurrentUserMark | null
|
selectedMark: CurrentUserMark | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
//selectedMark represents the mark that the user is actively editing
|
||||||
* Responsible for display an individual Pdf Mark.
|
// selectedMarkValue representsnthe edited value
|
||||||
*/
|
// userMark is part of the overall currentUserMark array
|
||||||
|
|
||||||
const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, userMark }: PdfMarkItemProps) => {
|
const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, userMark }: PdfMarkItemProps) => {
|
||||||
const { location } = userMark.mark;
|
const { location } = userMark.mark;
|
||||||
const handleClick = () => handleMarkClick(userMark.mark.id);
|
const handleClick = () => handleMarkClick(userMark.mark.id);
|
||||||
|
@ -4,7 +4,7 @@ import PdfView from './index.tsx'
|
|||||||
import MarkFormField from '../../pages/sign/MarkFormField.tsx'
|
import MarkFormField from '../../pages/sign/MarkFormField.tsx'
|
||||||
import { PdfFile } from '../../types/drawing.ts'
|
import { PdfFile } from '../../types/drawing.ts'
|
||||||
import { CurrentUserMark, Mark } from '../../types/mark.ts'
|
import { CurrentUserMark, Mark } from '../../types/mark.ts'
|
||||||
import React, { useState, useEffect } from 'react'
|
import { useState, useEffect } from 'react'
|
||||||
import {
|
import {
|
||||||
findNextCurrentUserMark,
|
findNextCurrentUserMark,
|
||||||
isCurrentUserMarksComplete,
|
isCurrentUserMarksComplete,
|
||||||
@ -21,12 +21,6 @@ interface PdfMarkingProps {
|
|||||||
setUpdatedMarks: (markToUpdate: Mark) => void
|
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 PdfMarking = (props: PdfMarkingProps) => {
|
||||||
const {
|
const {
|
||||||
files,
|
files,
|
||||||
@ -48,7 +42,7 @@ const PdfMarking = (props: PdfMarkingProps) => {
|
|||||||
setSelectedMarkValue(nextMark?.mark.value ?? EMPTY);
|
setSelectedMarkValue(nextMark?.mark.value ?? EMPTY);
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleSubmit = (event: React.FormEvent<HTMLFormElement>) => {
|
const handleSubmit = (event: any) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
if (!selectedMarkValue || !selectedMark) return;
|
if (!selectedMarkValue || !selectedMark) return;
|
||||||
|
|
||||||
@ -70,7 +64,7 @@ const PdfMarking = (props: PdfMarkingProps) => {
|
|||||||
setUpdatedMarks(updatedMark.mark)
|
setUpdatedMarks(updatedMark.mark)
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => setSelectedMarkValue(event.target.value)
|
const handleChange = (event: any) => setSelectedMarkValue(event.target.value)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
|
@ -10,9 +10,6 @@ interface PdfPageProps {
|
|||||||
selectedMark: CurrentUserMark | null
|
selectedMark: CurrentUserMark | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for rendering a single Pdf Page and its Marks
|
|
||||||
*/
|
|
||||||
const PdfPageItem = ({ page, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfPageProps) => {
|
const PdfPageItem = ({ page, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfPageProps) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
|
@ -11,9 +11,6 @@ interface PdfViewProps {
|
|||||||
selectedMark: CurrentUserMark | null
|
selectedMark: CurrentUserMark | null
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for rendering Pdf files.
|
|
||||||
*/
|
|
||||||
const PdfView = ({ files, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfViewProps) => {
|
const PdfView = ({ files, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfViewProps) => {
|
||||||
const filterByFile = (currentUserMarks: CurrentUserMark[], hash: string): CurrentUserMark[] => {
|
const filterByFile = (currentUserMarks: CurrentUserMark[], hash: string): CurrentUserMark[] => {
|
||||||
return currentUserMarks.filter((currentUserMark) => currentUserMark.mark.pdfFileHash === hash)
|
return currentUserMarks.filter((currentUserMark) => currentUserMark.mark.pdfFileHash === hash)
|
||||||
|
@ -63,6 +63,7 @@ import styles from './style.module.scss'
|
|||||||
import { PdfFile } from '../../types/drawing'
|
import { PdfFile } from '../../types/drawing'
|
||||||
import { DrawPDFFields } from '../../components/DrawPDFFields'
|
import { DrawPDFFields } from '../../components/DrawPDFFields'
|
||||||
import { Mark } from '../../types/mark.ts'
|
import { Mark } from '../../types/mark.ts'
|
||||||
|
import { v4 as uuidv4 } from 'uuid';
|
||||||
|
|
||||||
export const CreatePage = () => {
|
export const CreatePage = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -340,7 +341,7 @@ export const CreatePage = () => {
|
|||||||
return fileHashes
|
return fileHashes
|
||||||
}
|
}
|
||||||
|
|
||||||
const createMarks = (fileHashes: { [key: string]: string }) : Mark[] => {
|
const createMarkConfig = (fileHashes: { [key: string]: string }) : Mark[] => {
|
||||||
return drawnPdfs.flatMap((drawnPdf) => {
|
return drawnPdfs.flatMap((drawnPdf) => {
|
||||||
const fileHash = fileHashes[drawnPdf.file.name];
|
const fileHash = fileHashes[drawnPdf.file.name];
|
||||||
return drawnPdf.pages.flatMap((page, index) => {
|
return drawnPdf.pages.flatMap((page, index) => {
|
||||||
@ -377,13 +378,15 @@ export const CreatePage = () => {
|
|||||||
const generateZipFile = async (zip: JSZip): Promise<ArrayBuffer | null> => {
|
const generateZipFile = async (zip: JSZip): Promise<ArrayBuffer | null> => {
|
||||||
setLoadingSpinnerDesc('Generating zip file')
|
setLoadingSpinnerDesc('Generating zip file')
|
||||||
|
|
||||||
return await zip
|
const arraybuffer = await zip
|
||||||
.generateAsync({
|
.generateAsync({
|
||||||
type: 'arraybuffer',
|
type: 'arraybuffer',
|
||||||
compression: 'DEFLATE',
|
compression: 'DEFLATE',
|
||||||
compressionOptions: { level: 6 }
|
compressionOptions: { level: 6 }
|
||||||
})
|
})
|
||||||
.catch(handleZipError)
|
.catch(handleZipError)
|
||||||
|
|
||||||
|
return arraybuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
// Encrypt the zip file with the generated encryption key
|
// Encrypt the zip file with the generated encryption key
|
||||||
@ -430,13 +433,15 @@ export const CreatePage = () => {
|
|||||||
|
|
||||||
if (!arraybuffer) return null
|
if (!arraybuffer) return null
|
||||||
|
|
||||||
return new File(
|
const finalZipFile = new File(
|
||||||
[new Blob([arraybuffer])],
|
[new Blob([arraybuffer])],
|
||||||
`${unixNow}.sigit.zip`,
|
`${unixNow}.sigit.zip`,
|
||||||
{
|
{
|
||||||
type: 'application/zip'
|
type: 'application/zip'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return finalZipFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle errors during file upload
|
// Handle errors during file upload
|
||||||
@ -458,12 +463,14 @@ export const CreatePage = () => {
|
|||||||
type: 'application/sigit'
|
type: 'application/sigit'
|
||||||
})
|
})
|
||||||
|
|
||||||
return await uploadToFileStorage(file)
|
const fileUrl = await uploadToFileStorage(file)
|
||||||
.then((url) => {
|
.then((url) => {
|
||||||
toast.success('files.zip uploaded to file storage')
|
toast.success('files.zip uploaded to file storage')
|
||||||
return url
|
return url
|
||||||
})
|
})
|
||||||
.catch(handleUploadError)
|
.catch(handleUploadError)
|
||||||
|
|
||||||
|
return fileUrl
|
||||||
}
|
}
|
||||||
|
|
||||||
// Manage offline scenarios for signing or viewing the file
|
// Manage offline scenarios for signing or viewing the file
|
||||||
@ -487,13 +494,15 @@ export const CreatePage = () => {
|
|||||||
zip.file(file.name, file)
|
zip.file(file.name, file)
|
||||||
})
|
})
|
||||||
|
|
||||||
return await zip
|
const arraybuffer = await zip
|
||||||
.generateAsync({
|
.generateAsync({
|
||||||
type: 'arraybuffer',
|
type: 'arraybuffer',
|
||||||
compression: 'DEFLATE',
|
compression: 'DEFLATE',
|
||||||
compressionOptions: { level: 6 }
|
compressionOptions: { level: 6 }
|
||||||
})
|
})
|
||||||
.catch(handleZipError)
|
.catch(handleZipError)
|
||||||
|
|
||||||
|
return arraybuffer
|
||||||
}
|
}
|
||||||
|
|
||||||
const generateCreateSignature = async (
|
const generateCreateSignature = async (
|
||||||
@ -504,7 +513,9 @@ export const CreatePage = () => {
|
|||||||
) => {
|
) => {
|
||||||
const signers = users.filter((user) => user.role === UserRole.signer)
|
const signers = users.filter((user) => user.role === UserRole.signer)
|
||||||
const viewers = users.filter((user) => user.role === UserRole.viewer)
|
const viewers = users.filter((user) => user.role === UserRole.viewer)
|
||||||
const markConfig = createMarks(fileHashes)
|
const markConfig = createMarkConfig(fileHashes)
|
||||||
|
|
||||||
|
console.log('mark config: ', markConfig)
|
||||||
|
|
||||||
const content: CreateSignatureEventContent = {
|
const content: CreateSignatureEventContent = {
|
||||||
signers: signers.map((signer) => hexToNpub(signer.pubkey)),
|
signers: signers.map((signer) => hexToNpub(signer.pubkey)),
|
||||||
@ -515,6 +526,8 @@ export const CreatePage = () => {
|
|||||||
title
|
title
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('content: ', content)
|
||||||
|
|
||||||
setLoadingSpinnerDesc('Signing nostr event for create signature')
|
setLoadingSpinnerDesc('Signing nostr event for create signature')
|
||||||
|
|
||||||
const createSignature = await signEventForMetaFile(
|
const createSignature = await signEventForMetaFile(
|
||||||
@ -544,9 +557,11 @@ export const CreatePage = () => {
|
|||||||
: viewers.map((viewer) => viewer.pubkey)
|
: viewers.map((viewer) => viewer.pubkey)
|
||||||
).filter((receiver) => receiver !== usersPubkey)
|
).filter((receiver) => receiver !== usersPubkey)
|
||||||
|
|
||||||
return receivers.map((receiver) =>
|
const promises = receivers.map((receiver) =>
|
||||||
sendNotification(receiver, meta)
|
sendNotification(receiver, meta)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return promises
|
||||||
}
|
}
|
||||||
|
|
||||||
const handleCreate = async () => {
|
const handleCreate = async () => {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { CurrentUserMark } from '../../types/mark.ts'
|
import { CurrentUserMark, Mark } from '../../types/mark.ts'
|
||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
import { Box, Button, TextField } from '@mui/material'
|
import { Box, Button, TextField } from '@mui/material'
|
||||||
|
|
||||||
@ -11,9 +11,6 @@ interface MarkFormFieldProps {
|
|||||||
selectedMarkValue: string
|
selectedMarkValue: string
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Responsible for rendering a form field connected to a mark and keeping track of its value.
|
|
||||||
*/
|
|
||||||
const MarkFormField = (props: MarkFormFieldProps) => {
|
const MarkFormField = (props: MarkFormFieldProps) => {
|
||||||
const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props;
|
const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props;
|
||||||
const getSubmitButton = () => selectedMark.isLast ? 'Complete' : 'Next';
|
const getSubmitButton = () => selectedMark.isLast ? 'Complete' : 'Next';
|
||||||
|
@ -319,6 +319,8 @@ export const SignPage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('processed files: ', files);
|
||||||
|
|
||||||
setFiles(files)
|
setFiles(files)
|
||||||
setCurrentFileHashes(fileHashes)
|
setCurrentFileHashes(fileHashes)
|
||||||
}
|
}
|
||||||
@ -337,13 +339,15 @@ export const SignPage = () => {
|
|||||||
|
|
||||||
if (!keysFileContent) return null
|
if (!keysFileContent) return null
|
||||||
|
|
||||||
return await parseJson<{ sender: string; keys: string[] }>(
|
const parsedJSON = await parseJson<{ sender: string; keys: string[] }>(
|
||||||
keysFileContent
|
keysFileContent
|
||||||
).catch((err) => {
|
).catch((err) => {
|
||||||
console.log(`Error parsing content of keys.json:`, err)
|
console.log(`Error parsing content of keys.json:`, err)
|
||||||
toast.error(err.message || `Error parsing content of keys.json`)
|
toast.error(err.message || `Error parsing content of keys.json`)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return parsedJSON
|
||||||
}
|
}
|
||||||
|
|
||||||
const decrypt = async (file: File) => {
|
const decrypt = async (file: File) => {
|
||||||
@ -451,6 +455,8 @@ export const SignPage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
console.log('processed files: ', files);
|
||||||
|
|
||||||
setFiles(files)
|
setFiles(files)
|
||||||
setCurrentFileHashes(fileHashes)
|
setCurrentFileHashes(fileHashes)
|
||||||
|
|
||||||
@ -534,6 +540,42 @@ export const SignPage = () => {
|
|||||||
return currentUserMarks.map(( { mark }: CurrentUserMark) => mark);
|
return currentUserMarks.map(( { mark }: CurrentUserMark) => mark);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// const handleMarkClick = (id: number) => {
|
||||||
|
// const nextMark = currentUserMarks.find(mark => mark.mark.id === id)
|
||||||
|
// setCurrentUserMark(nextMark!)
|
||||||
|
// setCurrentMarkValue(nextMark?.mark.value || "")
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const getMarkConfigPerUser = (markConfig: MarkConfig) => {
|
||||||
|
// if (!usersPubkey) return;
|
||||||
|
// return markConfig[hexToNpub(usersPubkey)];
|
||||||
|
// }
|
||||||
|
|
||||||
|
// const handleChange = (event: any) => setCurrentMarkValue(event.target.value);
|
||||||
|
//
|
||||||
|
// const handleSubmit = (event: any) => {
|
||||||
|
// event.preventDefault();
|
||||||
|
// if (!currentMarkValue || !currentUserMark) return;
|
||||||
|
//
|
||||||
|
// const curMark: Mark = {
|
||||||
|
// ...currentUserMark.mark,
|
||||||
|
// value: currentMarkValue
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// const updatedMarks: Mark[] = updateMarks(marks, curMark)
|
||||||
|
//
|
||||||
|
// setMarks(updatedMarks)
|
||||||
|
// setCurrentMarkValue("")
|
||||||
|
//
|
||||||
|
// // do the similar thing to the thing above
|
||||||
|
// const metaMarks = filterMarksByPubkey(updatedMarks, usersPubkey!)
|
||||||
|
// const signedMarks = extractMarksFromSignedMeta(meta!)
|
||||||
|
// const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks)
|
||||||
|
// setCurrentUserMarks(currentUserMarks)
|
||||||
|
// setCurrentUserMark(findNextCurrentUserMark(currentUserMarks) || null)
|
||||||
|
// setIsReadyToSign(isCurrentUserMarksComplete(currentUserMarks))
|
||||||
|
// }
|
||||||
|
|
||||||
// Update the meta signatures
|
// Update the meta signatures
|
||||||
const updateMetaSignatures = (meta: Meta, signedEvent: SignedEvent): Meta => {
|
const updateMetaSignatures = (meta: Meta, signedEvent: SignedEvent): Meta => {
|
||||||
const metaCopy = _.cloneDeep(meta)
|
const metaCopy = _.cloneDeep(meta)
|
||||||
@ -601,13 +643,15 @@ export const SignPage = () => {
|
|||||||
|
|
||||||
if (!arraybuffer) return null
|
if (!arraybuffer) return null
|
||||||
|
|
||||||
return new File(
|
const finalZipFile = new File(
|
||||||
[new Blob([arraybuffer])],
|
[new Blob([arraybuffer])],
|
||||||
`${unixNow}.sigit.zip`,
|
`${unixNow}.sigit.zip`,
|
||||||
{
|
{
|
||||||
type: 'application/zip'
|
type: 'application/zip'
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return finalZipFile
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle errors during zip file generation
|
// Handle errors during zip file generation
|
||||||
@ -926,4 +970,30 @@ export const SignPage = () => {
|
|||||||
setCurrentUserMarks={setCurrentUserMarks}
|
setCurrentUserMarks={setCurrentUserMarks}
|
||||||
setUpdatedMarks={setUpdatedMarks}
|
setUpdatedMarks={setUpdatedMarks}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
// return (
|
||||||
|
// <>
|
||||||
|
// <Box className={styles.container}>
|
||||||
|
// {
|
||||||
|
// marks.length > 0 && (
|
||||||
|
// <PdfView
|
||||||
|
// files={files}
|
||||||
|
// marks={marks}
|
||||||
|
// fileHashes={currentFileHashes}
|
||||||
|
// handleMarkClick={handleMarkClick}
|
||||||
|
// currentMarkValue={currentMarkValue}
|
||||||
|
// currentUserMark={currentUserMark}
|
||||||
|
// />)}
|
||||||
|
// {
|
||||||
|
// currentUserMark !== null && (
|
||||||
|
// <MarkFormField
|
||||||
|
// handleSubmit={handleSubmit}
|
||||||
|
// handleChange={handleChange}
|
||||||
|
// currentMark={currentUserMark}
|
||||||
|
// currentMarkValue={currentMarkValue}
|
||||||
|
// />
|
||||||
|
// )}
|
||||||
|
// </Box>
|
||||||
|
// </>
|
||||||
|
// )
|
||||||
}
|
}
|
||||||
|
@ -380,6 +380,10 @@ export const VerifyPage = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const handleExport = async () => {
|
const handleExport = async () => {
|
||||||
|
// const proverbialUrls = await addMarksV2(Object.values(files)[0].file, meta!)
|
||||||
|
// await convertToFinalPdf(proverbialUrls)
|
||||||
|
|
||||||
|
|
||||||
if (Object.entries(files).length === 0 ||!meta ||!usersPubkey) return;
|
if (Object.entries(files).length === 0 ||!meta ||!usersPubkey) return;
|
||||||
|
|
||||||
const usersNpub = hexToNpub(usersPubkey)
|
const usersNpub = hexToNpub(usersPubkey)
|
||||||
|
@ -1,5 +1,12 @@
|
|||||||
import { MarkType } from "./drawing";
|
import { MarkType } from "./drawing";
|
||||||
|
|
||||||
|
// export interface Mark {
|
||||||
|
// /**
|
||||||
|
// * @key png (pdf page) file hash
|
||||||
|
// */
|
||||||
|
// [key: string]: MarkConfigDetails[]
|
||||||
|
// }
|
||||||
|
|
||||||
export interface CurrentUserMark {
|
export interface CurrentUserMark {
|
||||||
mark: Mark
|
mark: Mark
|
||||||
isLast: boolean
|
isLast: boolean
|
||||||
@ -15,6 +22,40 @@ export interface Mark {
|
|||||||
value?: string;
|
value?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface MarkConfig {
|
||||||
|
/**
|
||||||
|
* @key user npub
|
||||||
|
*/
|
||||||
|
[key: string]: User
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface User {
|
||||||
|
/**
|
||||||
|
* @key png (pdf page) file hash
|
||||||
|
*/
|
||||||
|
[key: string]: MarkConfigDetails[]
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarkDetails {
|
||||||
|
/**
|
||||||
|
* @key coords in format X:10;Y:50
|
||||||
|
*/
|
||||||
|
[key: string]: MarkValue
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarkValue {
|
||||||
|
value: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface MarkConfigDetails {
|
||||||
|
type: MarkType;
|
||||||
|
/**
|
||||||
|
* Coordinates in format: X:10;Y:50
|
||||||
|
*/
|
||||||
|
location: MarkLocation;
|
||||||
|
value?: MarkValue
|
||||||
|
}
|
||||||
|
|
||||||
export interface MarkLocation {
|
export interface MarkLocation {
|
||||||
top: number;
|
top: number;
|
||||||
left: number;
|
left: number;
|
||||||
|
@ -6,4 +6,4 @@ export * from './nostr'
|
|||||||
export * from './string'
|
export * from './string'
|
||||||
export * from './zip'
|
export * from './zip'
|
||||||
export * from './utils'
|
export * from './utils'
|
||||||
export * from './mark'
|
export { extractMarksFromSignedMeta } from './mark.ts'
|
||||||
|
@ -85,7 +85,7 @@ const updateCurrentUserMarks = (currentUserMarks: CurrentUserMark[], markToUpdat
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
const isLast = <T>(index: number, arr: T[]) => (index === (arr.length -1))
|
const isLast = (index: number, arr: any[]) => (index === (arr.length -1))
|
||||||
|
|
||||||
export {
|
export {
|
||||||
getCurrentUserMarks,
|
getCurrentUserMarks,
|
||||||
|
@ -12,10 +12,11 @@ import { toast } from 'react-toastify'
|
|||||||
import { NostrController } from '../controllers'
|
import { NostrController } from '../controllers'
|
||||||
import { AuthState } from '../store/auth/types'
|
import { AuthState } from '../store/auth/types'
|
||||||
import store from '../store/store'
|
import store from '../store/store'
|
||||||
import { CreateSignatureEventContent, Meta } from '../types'
|
import { CreateSignatureEventContent, Meta, SignedEventContent } from '../types'
|
||||||
import { hexToNpub, now } from './nostr'
|
import { hexToNpub, now } from './nostr'
|
||||||
import { parseJson } from './string'
|
import { parseJson } from './string'
|
||||||
import { hexToBytes } from '@noble/hashes/utils'
|
import { hexToBytes } from '@noble/hashes/utils'
|
||||||
|
import { Mark } from '../types/mark.ts'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Uploads a file to a file storage service.
|
* Uploads a file to a file storage service.
|
||||||
@ -83,12 +84,14 @@ export const signEventForMetaFile = async (
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Sign the event
|
// Sign the event
|
||||||
return await nostrController.signEvent(event).catch((err) => {
|
const signedEvent = await nostrController.signEvent(event).catch((err) => {
|
||||||
console.error(err)
|
console.error(err)
|
||||||
toast.error(err.message || 'Error occurred in signing nostr event')
|
toast.error(err.message || 'Error occurred in signing nostr event')
|
||||||
setIsLoading(false) // Set loading state to false
|
setIsLoading(false) // Set loading state to false
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
return signedEvent // Return the signed event
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -262,3 +265,10 @@ export const extractZipUrlAndEncryptionKey = async (meta: Meta) => {
|
|||||||
|
|
||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export 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);
|
||||||
|
}
|
||||||
|
@ -22,9 +22,8 @@ const readContentOfZipEntry = async <T extends OutputType>(
|
|||||||
return null
|
return null
|
||||||
}
|
}
|
||||||
|
|
||||||
// Read and return the content of the zip entry asynchronously
|
// Read the content of the zip entry asynchronously
|
||||||
// or null if an error has occurred
|
const fileContent = await zipEntry.async(outputType).catch((err) => {
|
||||||
return await zipEntry.async(outputType).catch((err) => {
|
|
||||||
// Handle any errors that occur during the read operation
|
// Handle any errors that occur during the read operation
|
||||||
console.log(`Error reading content of ${filePath}:`, err)
|
console.log(`Error reading content of ${filePath}:`, err)
|
||||||
toast.error(
|
toast.error(
|
||||||
@ -32,6 +31,9 @@ const readContentOfZipEntry = async <T extends OutputType>(
|
|||||||
)
|
)
|
||||||
return null
|
return null
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Return the file content or null if an error occurred
|
||||||
|
return fileContent
|
||||||
}
|
}
|
||||||
|
|
||||||
const loadZip = async (data: InputFileFormat): Promise<JSZip | null> => {
|
const loadZip = async (data: InputFileFormat): Promise<JSZip | null> => {
|
||||||
|
Loading…
Reference in New Issue
Block a user