From 52fe523196986d651c7fa14224e2b4324683a6f4 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 15:52:14 +0300 Subject: [PATCH 1/6] fix: amends the relay look up method to return default relay set --- src/controllers/MetadataController.ts | 119 ++++++-------------------- src/utils/const.ts | 8 +- src/utils/relays.ts | 108 +++++++++++++++++++++++ 3 files changed, 141 insertions(+), 94 deletions(-) create mode 100644 src/utils/relays.ts diff --git a/src/controllers/MetadataController.ts b/src/controllers/MetadataController.ts index 88f8a75..e2f6852 100644 --- a/src/controllers/MetadataController.ts +++ b/src/controllers/MetadataController.ts @@ -16,6 +16,12 @@ import { queryNip05 } from '../utils' import NDK, { NDKEvent, NDKSubscription } from '@nostr-dev-kit/ndk' import { EventEmitter } from 'tseep' import { localCache } from '../services' +import { + findRelayListAndUpdateCache, + findRelayListInCache, + getDefaultRelaySet, + getUserRelaySet +} from '../utils/relays.ts' export class MetadataController extends EventEmitter { private nostrController: NostrController @@ -144,100 +150,27 @@ export class MetadataController extends EventEmitter { return this.checkForMoreRecentMetadata(hexKey, null) } - public findRelayListMetadata = async (hexKey: string) => { - let relayEvent: Event | null = null + /** + * Based on the hexKey of the current user, this method attempts to retrieve a relay set. + * @func findRelayListInCache first checks if there is already an up-to-date + * relay list available in cache; if not - + * @func findRelayListAndUpdateCache checks if the relevant relay event is available from + * the purple pages relay; + * @func findRelayListAndUpdateCache will run again if the previous two calls return null and + * check if the relevant relay event can be obtained from 'most popular relays' + * If relay event is found, it will be saved in cache for future use + * @param hexKey of the current user + * @return RelaySet which will contain either relays extracted from the user Relay Event + * or a fallback RelaySet with Sigit's Relay + */ + public findRelayListMetadata = async (hexKey: string): Promise => { + const relayEvent = await findRelayListInCache(hexKey) + || await findRelayListAndUpdateCache([this.specialMetadataRelay], hexKey) + || await findRelayListAndUpdateCache(await this.nostrController.getMostPopularRelays(), hexKey) - // Attempt to retrieve the metadata event from the local cache - const cachedRelayListMetadataEvent = - await localCache.getUserRelayListMetadata(hexKey) - - if (cachedRelayListMetadataEvent) { - const oneWeekInMS = 7 * 24 * 60 * 60 * 1000 // Number of milliseconds in one week - - // Check if the cached event is not older than one week - if (Date.now() - cachedRelayListMetadataEvent.cachedAt < oneWeekInMS) { - relayEvent = cachedRelayListMetadataEvent.event - } - } - - // define filter for relay list - const eventFilter: Filter = { - kinds: [kinds.RelayList], - authors: [hexKey] - } - - const pool = new SimplePool() - - // Try to get the relayList event from a special relay (wss://purplepag.es) - if (!relayEvent) { - relayEvent = await pool - .get([this.specialMetadataRelay], eventFilter) - .then((event) => { - if (event) { - // update the event in local cache - localCache.addUserRelayListMetadata(event) - } - return event - }) - .catch((err) => { - console.error(err) - return null - }) - } - - if (!relayEvent) { - // If no valid relayList event is found from the special relay, get the most popular relays - const mostPopularRelays = - await this.nostrController.getMostPopularRelays() - - // Query the most popular relays for relayList event - relayEvent = await pool - .get(mostPopularRelays, eventFilter) - .then((event) => { - if (event) { - // update the event in local cache - localCache.addUserRelayListMetadata(event) - } - return event - }) - .catch((err) => { - console.error(err) - return null - }) - } - - if (relayEvent) { - const relaySet: RelaySet = { - read: [], - write: [] - } - - // a list of r tags with relay URIs and a read or write marker. - const relayTags = relayEvent.tags.filter((tag) => tag[0] === 'r') - - // Relays marked as read / write are called READ / WRITE relays, respectively - relayTags.forEach((tag) => { - if (tag.length >= 3) { - const marker = tag[2] - - if (marker === 'read') { - relaySet.read.push(tag[1]) - } else if (marker === 'write') { - relaySet.write.push(tag[1]) - } - } - - // If the marker is omitted, the relay is used for both purposes - if (tag.length === 2) { - relaySet.read.push(tag[1]) - relaySet.write.push(tag[1]) - } - }) - - return relaySet - } - - throw new Error('No relay list metadata found.') + return relayEvent + ? getUserRelaySet(relayEvent.tags) + : getDefaultRelaySet() } public extractProfileMetadataContent = (event: Event) => { diff --git a/src/utils/const.ts b/src/utils/const.ts index 4f8c233..aed1807 100644 --- a/src/utils/const.ts +++ b/src/utils/const.ts @@ -3,4 +3,10 @@ import { MarkType } from '../types/drawing.ts' export const EMPTY: string = '' export const MARK_TYPE_TRANSLATION: { [key: string]: string } = { [MarkType.FULLNAME.valueOf()]: 'Full Name' -} \ No newline at end of file +} +/** + * Number of milliseconds in one week. + * Calc based on: 7 * 24 * 60 * 60 * 1000 + */ +export const ONE_WEEK_IN_MS: number = 604800000 +export const SIGIT_RELAY: string = 'wss://relay.sigit.io' \ No newline at end of file diff --git a/src/utils/relays.ts b/src/utils/relays.ts new file mode 100644 index 0000000..676a59a --- /dev/null +++ b/src/utils/relays.ts @@ -0,0 +1,108 @@ +import { Filter, SimplePool } from 'nostr-tools' +import { RelayList } from 'nostr-tools/kinds' +import { Event } from 'nostr-tools' +import { localCache } from '../services' +import { ONE_WEEK_IN_MS, SIGIT_RELAY } from './const.ts' +import { RelayMap, RelaySet } from '../types' + +const READ_MARKER = "read" +const WRITE_MARKET = "write" + +/** + * Attempts to find a relay list from the provided lookUpRelays. + * If the relay list is found, it will be added to the user relay list metadata. + * @param lookUpRelays + * @param hexKey + * @return found relay list or null + */ +const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: string): Promise => { + try { + const eventFilter: Filter = { + kinds: [RelayList], + authors: [hexKey] + } + const pool = new SimplePool() + const event = await pool.get(lookUpRelays, eventFilter) + if (event) { + await localCache.addUserRelayListMetadata(event) + } + return event + } catch (error) { + console.error(error) + return null + } +} + +/** + * Attempts to find a relay list in cache. If it is present, it will check that the cached event is not + * older than one week. + * @param hexKey + * @return RelayList event if it's not older than a week; otherwise null + */ +const findRelayListInCache = async (hexKey: string): Promise => { + try { + // Attempt to retrieve the metadata event from the local cache + const cachedRelayListMetadataEvent = await localCache.getUserRelayListMetadata(hexKey) + + // Check if the cached event is not older than one week + if (cachedRelayListMetadataEvent && isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt)) { + return cachedRelayListMetadataEvent.event + } + + return null + } catch (error) { + console.error(error) + return null + } +} + +/** + * Transforms a list of relay tags from a Nostr Event to a RelaySet. + * @param tags + */ +const getUserRelaySet = (tags: string[][]): RelaySet => { + return tags + .filter(isRelayTag) + .reduce(toRelaySet, getDefaultRelaySet()) +} + +const getDefaultRelaySet = (): RelaySet => ({ + read: [SIGIT_RELAY], + write: [SIGIT_RELAY] +}) + +const getDefaultRelayMap = (): RelayMap => ({ + [SIGIT_RELAY]: { write: true, read: true } +}) + +const isOlderThanOneWeek = (cachedAt: number) => { + return Date.now() - cachedAt < ONE_WEEK_IN_MS +} + +const isRelayTag = (tag: string[]): boolean => tag[0] === 'r' + +const toRelaySet = (obj: RelaySet, tag: string[]): RelaySet => { + if (tag.length >= 3) { + const marker = tag[2] + + if (marker === READ_MARKER) { + obj.read.push(tag[1]) + } else if (marker === WRITE_MARKET) { + obj.write.push(tag[1]) + } + } + if (tag.length === 2) { + obj.read.push(tag[1]) + obj.write.push(tag[1]) + } + + return obj +} + +export { + findRelayListAndUpdateCache, + findRelayListInCache, + getUserRelaySet, + getDefaultRelaySet, + getDefaultRelayMap, +} \ No newline at end of file From 2355da02d2c760f94509bcb4e375e75b61a2ce9f Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 16:04:56 +0300 Subject: [PATCH 2/6] fix: amends RelayMap to return a default sigit relay when no other relays are found --- src/controllers/NostrController.ts | 5 +++-- src/pages/settings/relays/index.tsx | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/controllers/NostrController.ts b/src/controllers/NostrController.ts index 13787e5..fa558de 100644 --- a/src/controllers/NostrController.ts +++ b/src/controllers/NostrController.ts @@ -44,6 +44,7 @@ import { getNsecBunkerDelegatedKey, verifySignedEvent } from '../utils' +import { getDefaultRelayMap } from '../utils/relays.ts' export class NostrController extends EventEmitter { private static instance: NostrController @@ -650,7 +651,7 @@ export class NostrController extends EventEmitter { */ getRelayMap = async ( npub: string - ): Promise<{ map: RelayMap; mapUpdated: number }> => { + ): Promise<{ map: RelayMap; mapUpdated?: number }> => { const mostPopularRelays = await this.getMostPopularRelays() const pool = new SimplePool() @@ -691,7 +692,7 @@ export class NostrController extends EventEmitter { return Promise.resolve({ map: relaysMap, mapUpdated: event.created_at }) } else { - return Promise.reject('User relays were not found.') + return Promise.resolve({ map: getDefaultRelayMap() }) } } diff --git a/src/pages/settings/relays/index.tsx b/src/pages/settings/relays/index.tsx index 1894fc4..b06908a 100644 --- a/src/pages/settings/relays/index.tsx +++ b/src/pages/settings/relays/index.tsx @@ -91,7 +91,7 @@ export const RelaysPage = () => { if (isMounted) { if ( !relaysState?.mapUpdated || - newRelayMap.mapUpdated > relaysState?.mapUpdated + newRelayMap?.mapUpdated !== undefined && (newRelayMap?.mapUpdated > relaysState?.mapUpdated) ) { if ( !relaysState?.map || From ff1e12788825bce1a47974e5d5bff39c84cc4746 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 17:42:53 +0300 Subject: [PATCH 3/6] chore: fixes prettier rule --- src/utils/const.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/utils/const.ts b/src/utils/const.ts index aed1807..33befbf 100644 --- a/src/utils/const.ts +++ b/src/utils/const.ts @@ -9,4 +9,4 @@ export const MARK_TYPE_TRANSLATION: { [key: string]: string } = { * Calc based on: 7 * 24 * 60 * 60 * 1000 */ export const ONE_WEEK_IN_MS: number = 604800000 -export const SIGIT_RELAY: string = 'wss://relay.sigit.io' \ No newline at end of file +export const SIGIT_RELAY: string = 'wss://relay.sigit.io' From 7e420ef5832967ab89bef3faf430b4749395bf51 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 17:49:13 +0300 Subject: [PATCH 4/6] chore: prettier --- src/components/DrawPDFFields/index.tsx | 244 +++++++++++++++++-------- src/components/PDFView/PdfItem.tsx | 44 +++-- src/components/PDFView/PdfMarkItem.tsx | 20 +- src/components/PDFView/PdfMarking.tsx | 67 +++---- src/components/PDFView/PdfPageItem.tsx | 32 ++-- src/components/PDFView/index.tsx | 47 +++-- src/controllers/MetadataController.ts | 17 +- src/index.css | 18 +- src/pages/create/index.tsx | 55 +++--- src/pages/settings/relays/index.tsx | 3 +- src/pages/sign/MarkFormField.tsx | 6 +- src/pages/sign/index.tsx | 74 ++++---- src/pages/verify/index.tsx | 31 ++-- src/types/drawing.ts | 6 +- src/types/mark.ts | 24 +-- src/types/zip.ts | 24 +-- src/utils/mark.ts | 34 ++-- src/utils/pdf.ts | 143 ++++++++------- src/utils/relays.ts | 21 ++- src/utils/sign.ts | 11 +- src/utils/utils.ts | 4 +- src/utils/zip.ts | 11 +- 22 files changed, 549 insertions(+), 387 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index 148e70f..e7880e4 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -1,15 +1,43 @@ -import { AccessTime, CalendarMonth, ExpandMore, Gesture, PictureAsPdf, Badge, Work, Close } from '@mui/icons-material' -import { Box, Typography, Accordion, AccordionDetails, AccordionSummary, CircularProgress, FormControl, InputLabel, MenuItem, Select } from '@mui/material' +import { + AccessTime, + CalendarMonth, + ExpandMore, + Gesture, + PictureAsPdf, + Badge, + Work, + Close +} from '@mui/icons-material' +import { + Box, + Typography, + Accordion, + AccordionDetails, + AccordionSummary, + CircularProgress, + FormControl, + InputLabel, + MenuItem, + Select +} from '@mui/material' import styles from './style.module.scss' import { useEffect, useState } from 'react' -import * as PDFJS from "pdfjs-dist"; -import { ProfileMetadata, User } from '../../types'; -import { PdfFile, DrawTool, MouseState, PdfPage, DrawnField, MarkType } from '../../types/drawing'; -import { truncate } from 'lodash'; -import { hexToNpub } from '../../utils'; +import * as PDFJS from 'pdfjs-dist' +import { ProfileMetadata, User } from '../../types' +import { + PdfFile, + DrawTool, + MouseState, + PdfPage, + DrawnField, + MarkType +} from '../../types/drawing' +import { truncate } from 'lodash' +import { hexToNpub } from '../../utils' import { toPdfFiles } from '../../utils/pdf.ts' -PDFJS.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.mjs'; +PDFJS.GlobalWorkerOptions.workerSrc = + 'node_modules/pdfjs-dist/build/pdf.worker.mjs' interface Props { selectedFiles: File[] @@ -20,44 +48,43 @@ interface Props { export const DrawPDFFields = (props: Props) => { const { selectedFiles } = props - + const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) const [showDrawToolBox, setShowDrawToolBox] = useState(false) - + const [selectedTool, setSelectedTool] = useState() const [toolbox] = useState([ { identifier: MarkType.SIGNATURE, - icon: , + icon: , label: 'Signature', active: false - }, { identifier: MarkType.FULLNAME, - icon: , + icon: , label: 'Full Name', active: true }, { identifier: MarkType.JOBTITLE, - icon: , + icon: , label: 'Job Title', active: false }, { identifier: MarkType.DATE, - icon: , + icon: , label: 'Date', active: false }, { identifier: MarkType.DATETIME, - icon: , + icon: , label: 'Datetime', active: false - }, + } ]) const [mouseState, setMouseState] = useState({ @@ -67,7 +94,7 @@ export const DrawPDFFields = (props: Props) => { useEffect(() => { if (selectedFiles) { setParsingPdf(true) - + parsePdfPages().finally(() => { setParsingPdf(false) }) @@ -81,13 +108,13 @@ export const DrawPDFFields = (props: Props) => { /** * Drawing events */ - useEffect(() => { + useEffect(() => { // window.addEventListener('mousedown', onMouseDown); - window.addEventListener('mouseup', onMouseUp); - + window.addEventListener('mouseup', onMouseUp) + return () => { // window.removeEventListener('mousedown', onMouseDown); - window.removeEventListener('mouseup', onMouseUp); + window.removeEventListener('mouseup', onMouseUp) } }, []) @@ -106,7 +133,7 @@ export const DrawPDFFields = (props: Props) => { const onMouseDown = (event: any, page: PdfPage) => { // Proceed only if left click if (event.button !== 0) return - + // Only allow drawing if mouse is not over other drawn element const isOverPdfImageWrapper = event.target.tagName === 'IMG' @@ -158,11 +185,11 @@ export const DrawPDFFields = (props: Props) => { */ const onMouseMove = (event: any, page: PdfPage) => { if (mouseState.clicked && selectedTool) { - const lastElementIndex = page.drawnFields.length -1 + const lastElementIndex = page.drawnFields.length - 1 const lastDrawnField = page.drawnFields[lastElementIndex] const { mouseX, mouseY } = getMouseCoordinates(event) - + const width = mouseX - lastDrawnField.left const height = mouseY - lastDrawnField.top @@ -172,10 +199,10 @@ export const DrawPDFFields = (props: Props) => { const currentDrawnFields = page.drawnFields currentDrawnFields[lastElementIndex] = lastDrawnField - + refreshPdfFiles() } - } + } /** * Fired when event happens on the drawn element which will be moved @@ -189,7 +216,7 @@ export const DrawPDFFields = (props: Props) => { */ const onDrawnFieldMouseDown = (event: any) => { event.stopPropagation() - + // Proceed only if left click if (event.button !== 0) return @@ -212,7 +239,10 @@ export const DrawPDFFields = (props: Props) => { */ const onDranwFieldMouseMove = (event: any, drawnField: DrawnField) => { if (mouseState.dragging) { - const { mouseX, mouseY, rect } = getMouseCoordinates(event, event.target.parentNode) + const { mouseX, mouseY, rect } = getMouseCoordinates( + event, + event.target.parentNode + ) const coordsOffset = mouseState.coordsInWrapper if (coordsOffset) { @@ -258,8 +288,11 @@ export const DrawPDFFields = (props: Props) => { */ const onResizeHandleMouseMove = (event: any, drawnField: DrawnField) => { if (mouseState.resizing) { - const { mouseX, mouseY } = getMouseCoordinates(event, event.target.parentNode.parentNode) - + const { mouseX, mouseY } = getMouseCoordinates( + event, + event.target.parentNode.parentNode + ) + const width = mouseX - drawnField.left const height = mouseY - drawnField.top @@ -277,10 +310,18 @@ export const DrawPDFFields = (props: Props) => { * @param pdfPageIndex pdf page index * @param drawnFileIndex drawn file index */ - const onRemoveHandleMouseDown = (event: any, pdfFileIndex: number, pdfPageIndex: number, drawnFileIndex: number) => { + const onRemoveHandleMouseDown = ( + event: any, + pdfFileIndex: number, + pdfPageIndex: number, + drawnFileIndex: number + ) => { event.stopPropagation() - - pdfFiles[pdfFileIndex].pages[pdfPageIndex].drawnFields.splice(drawnFileIndex, 1) + + pdfFiles[pdfFileIndex].pages[pdfPageIndex].drawnFields.splice( + drawnFileIndex, + 1 + ) } /** @@ -300,9 +341,9 @@ export const DrawPDFFields = (props: Props) => { */ const getMouseCoordinates = (event: any, customTarget?: any) => { const target = customTarget ? customTarget : event.target - const rect = target.getBoundingClientRect(); - const mouseX = event.clientX - rect.left; //x position within the element. - const mouseY = event.clientY - rect.top; //y position within the element. + const rect = target.getBoundingClientRect() + const mouseX = event.clientX - rect.left //x position within the element. + const mouseY = event.clientY - rect.top //y position within the element. return { mouseX, @@ -316,8 +357,8 @@ export const DrawPDFFields = (props: Props) => { * creates the pdfFiles object and sets to a state */ const parsePdfPages = async () => { - const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles); - + const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles) + setPdfFiles(pdfFiles) } @@ -326,7 +367,7 @@ export const DrawPDFFields = (props: Props) => { * @returns if expanded pdf accordion is present */ const hasExpandedPdf = () => { - return !!pdfFiles.filter(pdfFile => !!pdfFile.expanded).length + return !!pdfFiles.filter((pdfFile) => !!pdfFile.expanded).length } const handleAccordionExpandChange = (expanded: boolean, pdfFile: PdfFile) => { @@ -355,9 +396,11 @@ export const DrawPDFFields = (props: Props) => { */ const getPdfPages = (pdfFile: PdfFile, pdfFileIndex: number) => { return ( - + {pdfFile.pages.map((page, pdfPageIndex: number) => { return (
{ marginBottom: '10px' }} className={`${styles.pdfImageWrapper} ${selectedTool ? styles.drawing : ''}`} - onMouseMove={(event) => {onMouseMove(event, page)}} - onMouseDown={(event) => {onMouseDown(event, page)}} + onMouseMove={(event) => { + onMouseMove(event, page) + }} + onMouseDown={(event) => { + onMouseDown(event, page) + }} > - + {page.drawnFields.map((drawnField, drawnFieldIndex: number) => { return (
{ onDranwFieldMouseMove(event, drawnField)}} + onMouseMove={(event) => { + onDranwFieldMouseMove(event, drawnField) + }} className={styles.drawingRectangle} style={{ left: `${drawnField.left}px`, @@ -389,41 +442,68 @@ export const DrawPDFFields = (props: Props) => { > {onResizeHandleMouseMove(event, drawnField)}} + onMouseMove={(event) => { + onResizeHandleMouseMove(event, drawnField) + }} className={styles.resizeHandle} > {onRemoveHandleMouseDown(event, pdfFileIndex, pdfPageIndex, drawnFieldIndex)}} + onMouseDown={(event) => { + onRemoveHandleMouseDown( + event, + pdfFileIndex, + pdfPageIndex, + drawnFieldIndex + ) + }} className={styles.removeHandle} > - + -
- + Counterpart @@ -435,13 +515,13 @@ export const DrawPDFFields = (props: Props) => { ) })} - ) + ) } if (parsingPdf) { return ( - + ) } @@ -454,22 +534,28 @@ export const DrawPDFFields = (props: Props) => { Draw fields on the PDFs: - + {pdfFiles.map((pdfFile, pdfFileIndex: number) => { return ( - {handleAccordionExpandChange(expanded, pdfFile)}}> + { + handleAccordionExpandChange(expanded, pdfFile) + }} + > } aria-controls={`panel${pdfFileIndex}-content`} id={`panel${pdfFileIndex}header`} > - + {pdfFile.file.name} {getPdfPages(pdfFile, pdfFileIndex)} - + ) })} @@ -477,16 +563,22 @@ export const DrawPDFFields = (props: Props) => { {showDrawToolBox && ( - {toolbox.filter(drawTool => drawTool.active).map((drawTool: DrawTool, index: number) => { - return ( - {handleToolSelect(drawTool)}} className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`}> - { drawTool.icon } - { drawTool.label } - - ) - })} + {toolbox + .filter((drawTool) => drawTool.active) + .map((drawTool: DrawTool, index: number) => { + return ( + { + handleToolSelect(drawTool) + }} + className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`} + > + {drawTool.icon} + {drawTool.label} + + ) + })} )} diff --git a/src/components/PDFView/PdfItem.tsx b/src/components/PDFView/PdfItem.tsx index eb5ceff..6e8aa64 100644 --- a/src/components/PDFView/PdfItem.tsx +++ b/src/components/PDFView/PdfItem.tsx @@ -1,6 +1,6 @@ import { PdfFile } from '../../types/drawing.ts' import { CurrentUserMark } from '../../types/mark.ts' -import PdfPageItem from './PdfPageItem.tsx'; +import PdfPageItem from './PdfPageItem.tsx' interface PdfItemProps { pdfFile: PdfFile @@ -13,23 +13,31 @@ interface PdfItemProps { /** * 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); +const PdfItem = ({ + pdfFile, + currentUserMarks, + handleMarkClick, + selectedMarkValue, + selectedMark +}: PdfItemProps) => { + const filterByPage = ( + marks: CurrentUserMark[], + page: number + ): CurrentUserMark[] => { + return marks.filter((m) => m.mark.location.page === page) } - return ( - pdfFile.pages.map((page, i) => { - return ( - - ) - })) + return pdfFile.pages.map((page, i) => { + return ( + + ) + }) } -export default PdfItem \ No newline at end of file +export default PdfItem diff --git a/src/components/PDFView/PdfMarkItem.tsx b/src/components/PDFView/PdfMarkItem.tsx index 7a2b24b..90caa87 100644 --- a/src/components/PDFView/PdfMarkItem.tsx +++ b/src/components/PDFView/PdfMarkItem.tsx @@ -12,14 +12,18 @@ interface PdfMarkItemProps { /** * Responsible for display an individual Pdf Mark. */ -const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, userMark }: PdfMarkItemProps) => { - const { location } = userMark.mark; - const handleClick = () => handleMarkClick(userMark.mark.id); - const getMarkValue = () => ( +const PdfMarkItem = ({ + selectedMark, + handleMarkClick, + selectedMarkValue, + userMark +}: PdfMarkItemProps) => { + const { location } = userMark.mark + const handleClick = () => handleMarkClick(userMark.mark.id) + const getMarkValue = () => selectedMark?.mark.id === userMark.mark.id ? selectedMarkValue : userMark.mark.value - ) return (
{getMarkValue()}
+ > + {getMarkValue()} +
) } -export default PdfMarkItem \ No newline at end of file +export default PdfMarkItem diff --git a/src/components/PDFView/PdfMarking.tsx b/src/components/PDFView/PdfMarking.tsx index a6dc1a4..0e47ab1 100644 --- a/src/components/PDFView/PdfMarking.tsx +++ b/src/components/PDFView/PdfMarking.tsx @@ -6,17 +6,17 @@ import React, { useState, useEffect } from 'react' import { findNextCurrentUserMark, isCurrentUserMarksComplete, - updateCurrentUserMarks, + updateCurrentUserMarks } from '../../utils' import { EMPTY } from '../../utils/const.ts' import { Container } from '../Container' import styles from '../../pages/sign/style.module.scss' interface PdfMarkingProps { - files: { pdfFile: PdfFile, filename: string, hash: string | null }[], - currentUserMarks: CurrentUserMark[], - setIsReadyToSign: (isReadyToSign: boolean) => void, - setCurrentUserMarks: (currentUserMarks: CurrentUserMark[]) => void, + files: { pdfFile: PdfFile; filename: string; hash: string | null }[] + currentUserMarks: CurrentUserMark[] + setIsReadyToSign: (isReadyToSign: boolean) => void + setCurrentUserMarks: (currentUserMarks: CurrentUserMark[]) => void setUpdatedMarks: (markToUpdate: Mark) => void } @@ -35,21 +35,21 @@ const PdfMarking = (props: PdfMarkingProps) => { setUpdatedMarks } = props const [selectedMark, setSelectedMark] = useState(null) - const [selectedMarkValue, setSelectedMarkValue] = useState("") + const [selectedMarkValue, setSelectedMarkValue] = useState('') useEffect(() => { setSelectedMark(findNextCurrentUserMark(currentUserMarks) || null) }, [currentUserMarks]) const handleMarkClick = (id: number) => { - const nextMark = currentUserMarks.find((mark) => mark.mark.id === id); - setSelectedMark(nextMark!); - setSelectedMarkValue(nextMark?.mark.value ?? EMPTY); + const nextMark = currentUserMarks.find((mark) => mark.mark.id === id) + setSelectedMark(nextMark!) + setSelectedMarkValue(nextMark?.mark.value ?? EMPTY) } const handleSubmit = (event: React.FormEvent) => { - event.preventDefault(); - if (!selectedMarkValue || !selectedMark) return; + event.preventDefault() + if (!selectedMarkValue || !selectedMark) return const updatedMark: CurrentUserMark = { ...selectedMark, @@ -61,7 +61,10 @@ const PdfMarking = (props: PdfMarkingProps) => { } setSelectedMarkValue(EMPTY) - const updatedCurrentUserMarks = updateCurrentUserMarks(currentUserMarks, updatedMark); + const updatedCurrentUserMarks = updateCurrentUserMarks( + currentUserMarks, + updatedMark + ) setCurrentUserMarks(updatedCurrentUserMarks) setSelectedMark(findNextCurrentUserMark(updatedCurrentUserMarks) || null) console.log(isCurrentUserMarksComplete(updatedCurrentUserMarks)) @@ -69,32 +72,32 @@ const PdfMarking = (props: PdfMarkingProps) => { setUpdatedMarks(updatedMark.mark) } - const handleChange = (event: React.ChangeEvent) => setSelectedMarkValue(event.target.value) + const handleChange = (event: React.ChangeEvent) => + setSelectedMarkValue(event.target.value) return ( <> - { - currentUserMarks?.length > 0 && ( - )} - { - selectedMark !== null && ( - - )} + {currentUserMarks?.length > 0 && ( + + )} + {selectedMark !== null && ( + + )} ) } -export default PdfMarking \ No newline at end of file +export default PdfMarking diff --git a/src/components/PDFView/PdfPageItem.tsx b/src/components/PDFView/PdfPageItem.tsx index d289a6e..241474e 100644 --- a/src/components/PDFView/PdfPageItem.tsx +++ b/src/components/PDFView/PdfPageItem.tsx @@ -13,7 +13,13 @@ interface PdfPageProps { /** * 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 (
- - { - currentUserMarks.map((m, i) => ( - + {currentUserMarks.map((m, i) => ( + ))}
) } -export default PdfPageItem \ No newline at end of file +export default PdfPageItem diff --git a/src/components/PDFView/index.tsx b/src/components/PDFView/index.tsx index 14834a3..8a14e55 100644 --- a/src/components/PDFView/index.tsx +++ b/src/components/PDFView/index.tsx @@ -4,7 +4,7 @@ import PdfItem from './PdfItem.tsx' import { CurrentUserMark } from '../../types/mark.ts' interface PdfViewProps { - files: { pdfFile: PdfFile, filename: string, hash: string | null }[] + files: { pdfFile: PdfFile; filename: string; hash: string | null }[] currentUserMarks: CurrentUserMark[] handleMarkClick: (id: number) => void selectedMarkValue: string @@ -14,29 +14,38 @@ interface PdfViewProps { /** * 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) +const PdfView = ({ + files, + currentUserMarks, + handleMarkClick, + selectedMarkValue, + selectedMark +}: PdfViewProps) => { + const filterByFile = ( + currentUserMarks: CurrentUserMark[], + hash: string + ): CurrentUserMark[] => { + return currentUserMarks.filter( + (currentUserMark) => currentUserMark.mark.pdfFileHash === hash + ) } return ( - { - files.map(({ pdfFile, hash }, i) => { - if (!hash) return - return ( - { + if (!hash) return + return ( + - ) - }) - } + ) + })} ) } -export default PdfView; \ No newline at end of file +export default PdfView diff --git a/src/controllers/MetadataController.ts b/src/controllers/MetadataController.ts index e2f6852..cd3d819 100644 --- a/src/controllers/MetadataController.ts +++ b/src/controllers/MetadataController.ts @@ -164,13 +164,18 @@ export class MetadataController extends EventEmitter { * or a fallback RelaySet with Sigit's Relay */ public findRelayListMetadata = async (hexKey: string): Promise => { - const relayEvent = await findRelayListInCache(hexKey) - || await findRelayListAndUpdateCache([this.specialMetadataRelay], hexKey) - || await findRelayListAndUpdateCache(await this.nostrController.getMostPopularRelays(), hexKey) + const relayEvent = + (await findRelayListInCache(hexKey)) || + (await findRelayListAndUpdateCache( + [this.specialMetadataRelay], + hexKey + )) || + (await findRelayListAndUpdateCache( + await this.nostrController.getMostPopularRelays(), + hexKey + )) - return relayEvent - ? getUserRelaySet(relayEvent.tags) - : getDefaultRelaySet() + return relayEvent ? getUserRelaySet(relayEvent.tags) : getDefaultRelaySet() } public extractProfileMetadataContent = (event: Event) => { diff --git a/src/index.css b/src/index.css index 6a734df..76373ff 100644 --- a/src/index.css +++ b/src/index.css @@ -111,7 +111,9 @@ button:disabled { /* Fonts */ @font-face { font-family: 'Roboto'; - src: local('Roboto Medium'), local('Roboto-Medium'), + src: + local('Roboto Medium'), + local('Roboto-Medium'), url('assets/fonts/roboto-medium.woff2') format('woff2'), url('assets/fonts/roboto-medium.woff') format('woff'); font-weight: 500; @@ -121,7 +123,9 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: local('Roboto Light'), local('Roboto-Light'), + src: + local('Roboto Light'), + local('Roboto-Light'), url('assets/fonts/roboto-light.woff2') format('woff2'), url('assets/fonts/roboto-light.woff') format('woff'); font-weight: 300; @@ -131,7 +135,9 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: local('Roboto Bold'), local('Roboto-Bold'), + src: + local('Roboto Bold'), + local('Roboto-Bold'), url('assets/fonts/roboto-bold.woff2') format('woff2'), url('assets/fonts/roboto-bold.woff') format('woff'); font-weight: bold; @@ -141,10 +147,12 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: local('Roboto'), local('Roboto-Regular'), + src: + local('Roboto'), + local('Roboto-Regular'), url('assets/fonts/roboto-regular.woff2') format('woff2'), url('assets/fonts/roboto-regular.woff') format('woff'); font-weight: normal; font-style: normal; font-display: swap; -} \ No newline at end of file +} diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 830f9ef..023dd02 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -341,29 +341,30 @@ export const CreatePage = () => { return fileHashes } - const createMarks = (fileHashes: { [key: string]: string }) : Mark[] => { - return drawnPdfs.flatMap((drawnPdf) => { - const fileHash = fileHashes[drawnPdf.file.name]; - return drawnPdf.pages.flatMap((page, index) => { - return page.drawnFields.map((drawnField) => { - return { - type: drawnField.type, - location: { - page: index, - top: drawnField.top, - left: drawnField.left, - height: drawnField.height, - width: drawnField.width, - }, - npub: drawnField.counterpart, - pdfFileHash: fileHash - } + const createMarks = (fileHashes: { [key: string]: string }): Mark[] => { + return drawnPdfs + .flatMap((drawnPdf) => { + const fileHash = fileHashes[drawnPdf.file.name] + return drawnPdf.pages.flatMap((page, index) => { + return page.drawnFields.map((drawnField) => { + return { + type: drawnField.type, + location: { + page: index, + top: drawnField.top, + left: drawnField.left, + height: drawnField.height, + width: drawnField.width + }, + npub: drawnField.counterpart, + pdfFileHash: fileHash + } + }) }) }) - }) .map((mark, index) => { - return {...mark, id: index } - }); + return { ...mark, id: index } + }) } // Handle errors during zip file generation @@ -431,13 +432,9 @@ export const CreatePage = () => { if (!arraybuffer) return null - return new File( - [new Blob([arraybuffer])], - `${unixNow}.sigit.zip`, - { - type: 'application/zip' - } - ) + return new File([new Blob([arraybuffer])], `${unixNow}.sigit.zip`, { + type: 'application/zip' + }) } // Handle errors during file upload @@ -545,9 +542,7 @@ export const CreatePage = () => { : viewers.map((viewer) => viewer.pubkey) ).filter((receiver) => receiver !== usersPubkey) - return receivers.map((receiver) => - sendNotification(receiver, meta) - ) + return receivers.map((receiver) => sendNotification(receiver, meta)) } const handleCreate = async () => { diff --git a/src/pages/settings/relays/index.tsx b/src/pages/settings/relays/index.tsx index b06908a..929a093 100644 --- a/src/pages/settings/relays/index.tsx +++ b/src/pages/settings/relays/index.tsx @@ -91,7 +91,8 @@ export const RelaysPage = () => { if (isMounted) { if ( !relaysState?.mapUpdated || - newRelayMap?.mapUpdated !== undefined && (newRelayMap?.mapUpdated > relaysState?.mapUpdated) + (newRelayMap?.mapUpdated !== undefined && + newRelayMap?.mapUpdated > relaysState?.mapUpdated) ) { if ( !relaysState?.map || diff --git a/src/pages/sign/MarkFormField.tsx b/src/pages/sign/MarkFormField.tsx index 4de82a4..4cb943b 100644 --- a/src/pages/sign/MarkFormField.tsx +++ b/src/pages/sign/MarkFormField.tsx @@ -15,8 +15,8 @@ interface MarkFormFieldProps { * Responsible for rendering a form field connected to a mark and keeping track of its value. */ const MarkFormField = (props: MarkFormFieldProps) => { - const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props; - const getSubmitButton = () => selectedMark.isLast ? 'Complete' : 'Next'; + const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props + const getSubmitButton = () => (selectedMark.isLast ? 'Complete' : 'Next') return (
@@ -34,4 +34,4 @@ const MarkFormField = (props: MarkFormFieldProps) => { ) } -export default MarkFormField; \ No newline at end of file +export default MarkFormField diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index 07c385e..6f3231b 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -16,13 +16,16 @@ import { State } from '../../store/rootReducer' import { CreateSignatureEventContent, Meta, SignedEvent } from '../../types' import { decryptArrayBuffer, - encryptArrayBuffer, extractMarksFromSignedMeta, + encryptArrayBuffer, + extractMarksFromSignedMeta, extractZipUrlAndEncryptionKey, generateEncryptionKey, - generateKeysFile, getFilesWithHashes, + generateKeysFile, + getFilesWithHashes, getHash, hexToNpub, - isOnline, loadZip, + isOnline, + loadZip, now, npubToHex, parseJson, @@ -41,7 +44,8 @@ import { getLastSignersSig } from '../../utils/sign.ts' import { filterMarksByPubkey, getCurrentUserMarks, - isCurrentUserMarksComplete, updateMarks + isCurrentUserMarksComplete, + updateMarks } from '../../utils' import PdfMarking from '../../components/PDFView/PdfMarking.tsx' enum SignedStatus { @@ -81,7 +85,7 @@ export const SignPage = () => { const [signers, setSigners] = useState<`npub1${string}`[]>([]) const [viewers, setViewers] = useState<`npub1${string}`[]>([]) - const [marks, setMarks] = useState([]) + const [marks, setMarks] = useState([]) const [creatorFileHashes, setCreatorFileHashes] = useState<{ [key: string]: string }>({}) @@ -100,8 +104,10 @@ export const SignPage = () => { const [authUrl, setAuthUrl] = useState() const nostrController = NostrController.getInstance() - const [currentUserMarks, setCurrentUserMarks] = useState([]); - const [isReadyToSign, setIsReadyToSign] = useState(false); + const [currentUserMarks, setCurrentUserMarks] = useState( + [] + ) + const [isReadyToSign, setIsReadyToSign] = useState(false) useEffect(() => { if (signers.length > 0) { @@ -192,13 +198,16 @@ export const SignPage = () => { setViewers(createSignatureContent.viewers) setCreatorFileHashes(createSignatureContent.fileHashes) setSubmittedBy(createSignatureEvent.pubkey) - setMarks(createSignatureContent.markConfig); + setMarks(createSignatureContent.markConfig) if (usersPubkey) { - const metaMarks = filterMarksByPubkey(createSignatureContent.markConfig, usersPubkey!) + const metaMarks = filterMarksByPubkey( + createSignatureContent.markConfig, + usersPubkey! + ) const signedMarks = extractMarksFromSignedMeta(meta) - const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks); - setCurrentUserMarks(currentUserMarks); + const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks) + setCurrentUserMarks(currentUserMarks) // setCurrentUserMark(findNextCurrentUserMark(currentUserMarks) || null) setIsReadyToSign(isCurrentUserMarksComplete(currentUserMarks)) } @@ -307,7 +316,7 @@ export const SignPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile(arrayBuffer, fileName); + files[fileName] = await convertToPdfFile(arrayBuffer, fileName) const hash = await getHash(arrayBuffer) if (hash) { @@ -348,7 +357,7 @@ export const SignPage = () => { const decrypt = async (file: File) => { setLoadingSpinnerDesc('Decrypting file') - const zip = await loadZip(file); + const zip = await loadZip(file) if (!zip) return const parsedKeysJson = await parseKeysJson(zip) @@ -439,7 +448,7 @@ export const SignPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile(arrayBuffer, fileName); + files[fileName] = await convertToPdfFile(arrayBuffer, fileName) const hash = await getHash(arrayBuffer) if (hash) { @@ -520,7 +529,10 @@ export const SignPage = () => { } // Sign the event for the meta file - const signEventForMeta = async (signerContent: { prevSig: string, marks: Mark[] }) => { + const signEventForMeta = async (signerContent: { + prevSig: string + marks: Mark[] + }) => { return await signEventForMetaFile( JSON.stringify(signerContent), nostrController, @@ -529,8 +541,8 @@ export const SignPage = () => { } const getSignerMarksForMeta = (): Mark[] | undefined => { - if (currentUserMarks.length === 0) return; - return currentUserMarks.map(( { mark }: CurrentUserMark) => mark); + if (currentUserMarks.length === 0) return + return currentUserMarks.map(({ mark }: CurrentUserMark) => mark) } // Update the meta signatures @@ -600,13 +612,9 @@ export const SignPage = () => { if (!arraybuffer) return null - return new File( - [new Blob([arraybuffer])], - `${unixNow}.sigit.zip`, - { - type: 'application/zip' - } - ) + return new File([new Blob([arraybuffer])], `${unixNow}.sigit.zip`, { + type: 'application/zip' + }) } // Handle errors during zip file generation @@ -694,7 +702,7 @@ export const SignPage = () => { setIsLoading(true) setLoadingSpinnerDesc('Signing nostr event') - if (!meta) return; + if (!meta) return const prevSig = getLastSignersSig(meta, signers) if (!prevSig) return @@ -918,11 +926,13 @@ export const SignPage = () => { ) } - return + return ( + + ) } diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index 6290c02..c5a0e8e 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -23,14 +23,17 @@ import { SignedEventContent } from '../../types' import { - decryptArrayBuffer, extractMarksFromSignedMeta, + decryptArrayBuffer, + extractMarksFromSignedMeta, extractZipUrlAndEncryptionKey, getHash, - hexToNpub, now, + hexToNpub, + now, npubToHex, parseJson, readContentOfZipEntry, - shorten, signEventForMetaFile + shorten, + signEventForMetaFile } from '../../utils' import styles from './style.module.scss' import { Cancel, CheckCircle } from '@mui/icons-material' @@ -41,7 +44,7 @@ import { addMarks, convertToPdfBlob, convertToPdfFile, - groupMarksByPage, + groupMarksByPage } from '../../utils/pdf.ts' import { State } from '../../store/rootReducer.ts' import { useSelector } from 'react-redux' @@ -78,7 +81,7 @@ export const VerifyPage = () => { const [currentFileHashes, setCurrentFileHashes] = useState<{ [key: string]: string | null }>({}) - const [files, setFiles] = useState<{ [filename: string]: PdfFile}>({}) + const [files, setFiles] = useState<{ [filename: string]: PdfFile }>({}) const [metadata, setMetadata] = useState<{ [key: string]: ProfileMetadata }>( {} @@ -155,7 +158,10 @@ export const VerifyPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile(arrayBuffer, fileName!) + files[fileName] = await convertToPdfFile( + arrayBuffer, + fileName! + ) const hash = await getHash(arrayBuffer) if (hash) { @@ -169,7 +175,6 @@ export const VerifyPage = () => { setCurrentFileHashes(fileHashes) setFiles(files) - setSigners(createSignatureContent.signers) setViewers(createSignatureContent.viewers) setCreatorFileHashes(createSignatureContent.fileHashes) @@ -177,8 +182,6 @@ export const VerifyPage = () => { setMeta(metaInNavState) setIsLoading(false) - - } }) .catch((err) => { @@ -381,7 +384,7 @@ export const VerifyPage = () => { } const handleExport = async () => { - if (Object.entries(files).length === 0 ||!meta ||!usersPubkey) return; + if (Object.entries(files).length === 0 || !meta || !usersPubkey) return const usersNpub = hexToNpub(usersPubkey) if ( @@ -395,10 +398,10 @@ export const VerifyPage = () => { setIsLoading(true) setLoadingSpinnerDesc('Signing nostr event') - if (!meta) return; + if (!meta) return const prevSig = getLastSignersSig(meta, signers) - if (!prevSig) return; + if (!prevSig) return const signedEvent = await signEventForMetaFile( JSON.stringify({ prevSig }), @@ -406,10 +409,10 @@ export const VerifyPage = () => { setIsLoading ) - if (!signedEvent) return; + if (!signedEvent) return const exportSignature = JSON.stringify(signedEvent, null, 2) - const updatedMeta = {...meta, exportSignature } + const updatedMeta = { ...meta, exportSignature } const stringifiedMeta = JSON.stringify(updatedMeta, null, 2) const zip = new JSZip() diff --git a/src/types/drawing.ts b/src/types/drawing.ts index 702343f..f14dbea 100644 --- a/src/types/drawing.ts +++ b/src/types/drawing.ts @@ -9,7 +9,7 @@ export interface MouseState { } export interface PdfFile { - file: File, + file: File pages: PdfPage[] expanded?: boolean } @@ -34,7 +34,7 @@ export interface DrawnField { export interface DrawTool { identifier: MarkType label: string - icon: JSX.Element, + icon: JSX.Element defaultValue?: string selected?: boolean active?: boolean @@ -46,4 +46,4 @@ export enum MarkType { FULLNAME = 'FULLNAME', DATE = 'DATE', DATETIME = 'DATETIME' -} \ No newline at end of file +} diff --git a/src/types/mark.ts b/src/types/mark.ts index 3184f95..9a6a545 100644 --- a/src/types/mark.ts +++ b/src/types/mark.ts @@ -1,4 +1,4 @@ -import { MarkType } from "./drawing"; +import { MarkType } from './drawing' export interface CurrentUserMark { mark: Mark @@ -7,18 +7,18 @@ export interface CurrentUserMark { } export interface Mark { - id: number; - npub: string; - pdfFileHash: string; - type: MarkType; - location: MarkLocation; - value?: string; + id: number + npub: string + pdfFileHash: string + type: MarkType + location: MarkLocation + value?: string } export interface MarkLocation { - top: number; - left: number; - height: number; - width: number; - page: number; + top: number + left: number + height: number + width: number + page: number } diff --git a/src/types/zip.ts b/src/types/zip.ts index b4c97ac..7405067 100644 --- a/src/types/zip.ts +++ b/src/types/zip.ts @@ -1,4 +1,4 @@ - export interface OutputByType { +export interface OutputByType { base64: string string: string text: string @@ -11,16 +11,18 @@ } interface InputByType { - base64: string; - string: string; - text: string; - binarystring: string; - array: number[]; - uint8array: Uint8Array; - arraybuffer: ArrayBuffer; - blob: Blob; - stream: NodeJS.ReadableStream; + base64: string + string: string + text: string + binarystring: string + array: number[] + uint8array: Uint8Array + arraybuffer: ArrayBuffer + blob: Blob + stream: NodeJS.ReadableStream } export type OutputType = keyof OutputByType -export type InputFileFormat = InputByType[keyof InputByType] | Promise; \ No newline at end of file +export type InputFileFormat = + | InputByType[keyof InputByType] + | Promise diff --git a/src/utils/mark.ts b/src/utils/mark.ts index 13cff84..60868be 100644 --- a/src/utils/mark.ts +++ b/src/utils/mark.ts @@ -9,9 +9,12 @@ import { Event } from 'nostr-tools' * @param marks - default Marks extracted from Meta * @param signedMetaMarks - signed user Marks extracted from DocSignatures */ -const getCurrentUserMarks = (marks: Mark[], signedMetaMarks: Mark[]): CurrentUserMark[] => { +const getCurrentUserMarks = ( + marks: Mark[], + signedMetaMarks: Mark[] +): CurrentUserMark[] => { return marks.map((mark, index, arr) => { - const signedMark = signedMetaMarks.find((m) => m.id === mark.id); + const signedMark = signedMetaMarks.find((m) => m.id === mark.id) if (signedMark && !!signedMark.value) { mark.value = signedMark.value } @@ -27,8 +30,10 @@ const getCurrentUserMarks = (marks: Mark[], signedMetaMarks: Mark[]): CurrentUse * Returns next incomplete CurrentUserMark if there is one * @param usersMarks */ -const findNextCurrentUserMark = (usersMarks: CurrentUserMark[]): CurrentUserMark | undefined => { - return usersMarks.find((mark) => !mark.isCompleted); +const findNextCurrentUserMark = ( + usersMarks: CurrentUserMark[] +): CurrentUserMark | undefined => { + return usersMarks.find((mark) => !mark.isCompleted) } /** @@ -37,7 +42,7 @@ const findNextCurrentUserMark = (usersMarks: CurrentUserMark[]): CurrentUserMark * @param pubkey */ const filterMarksByPubkey = (marks: Mark[], pubkey: string): Mark[] => { - return marks.filter(mark => mark.npub === hexToNpub(pubkey)) + return marks.filter((mark) => mark.npub === hexToNpub(pubkey)) } /** @@ -57,7 +62,9 @@ const extractMarksFromSignedMeta = (meta: Meta): Mark[] => { * marked as complete. * @param currentUserMarks */ -const isCurrentUserMarksComplete = (currentUserMarks: CurrentUserMark[]): boolean => { +const isCurrentUserMarksComplete = ( + currentUserMarks: CurrentUserMark[] +): boolean => { return currentUserMarks.every((mark) => mark.isCompleted) } @@ -68,7 +75,7 @@ const isCurrentUserMarksComplete = (currentUserMarks: CurrentUserMark[]): boolea * @param markToUpdate */ const updateMarks = (marks: Mark[], markToUpdate: Mark): Mark[] => { - const indexToUpdate = marks.findIndex(mark => mark.id === markToUpdate.id); + const indexToUpdate = marks.findIndex((mark) => mark.id === markToUpdate.id) return [ ...marks.slice(0, indexToUpdate), markToUpdate, @@ -76,8 +83,13 @@ const updateMarks = (marks: Mark[], markToUpdate: Mark): Mark[] => { ] } -const updateCurrentUserMarks = (currentUserMarks: CurrentUserMark[], markToUpdate: CurrentUserMark): CurrentUserMark[] => { - const indexToUpdate = currentUserMarks.findIndex((m) => m.mark.id === markToUpdate.mark.id) +const updateCurrentUserMarks = ( + currentUserMarks: CurrentUserMark[], + markToUpdate: CurrentUserMark +): CurrentUserMark[] => { + const indexToUpdate = currentUserMarks.findIndex( + (m) => m.mark.id === markToUpdate.mark.id + ) return [ ...currentUserMarks.slice(0, indexToUpdate), markToUpdate, @@ -85,7 +97,7 @@ const updateCurrentUserMarks = (currentUserMarks: CurrentUserMark[], markToUpdat ] } -const isLast = (index: number, arr: T[]) => (index === (arr.length -1)) +const isLast = (index: number, arr: T[]) => index === arr.length - 1 export { getCurrentUserMarks, @@ -94,5 +106,5 @@ export { isCurrentUserMarksComplete, findNextCurrentUserMark, updateMarks, - updateCurrentUserMarks, + updateCurrentUserMarks } diff --git a/src/utils/pdf.ts b/src/utils/pdf.ts index 70b6539..2263737 100644 --- a/src/utils/pdf.ts +++ b/src/utils/pdf.ts @@ -3,13 +3,14 @@ import * as PDFJS from 'pdfjs-dist' import { PDFDocument } from 'pdf-lib' import { Mark } from '../types/mark.ts' -PDFJS.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.mjs'; +PDFJS.GlobalWorkerOptions.workerSrc = + 'node_modules/pdfjs-dist/build/pdf.worker.mjs' /** * Scale between the PDF page's natural size and rendered size * @constant {number} */ -const SCALE: number = 3; +const SCALE: number = 3 /** * Defined font size used when generating a PDF. Currently it is difficult to fully * correlate font size used at the time of filling in / drawing on the PDF @@ -17,20 +18,20 @@ const SCALE: number = 3; * This should be fixed going forward. * Switching to PDF-Lib will most likely make this problem redundant. */ -const FONT_SIZE: number = 40; +const FONT_SIZE: number = 40 /** * Current font type used when generating a PDF. */ -const FONT_TYPE: string = 'Arial'; +const FONT_TYPE: string = 'Arial' /** * Converts a PDF ArrayBuffer to a generic PDF File * @param arrayBuffer of a PDF * @param fileName identifier of the pdf file */ -const toFile = (arrayBuffer: ArrayBuffer, fileName: string) : File => { - const blob = new Blob([arrayBuffer], { type: "application/pdf" }); - return new File([blob], fileName, { type: "application/pdf" }); +const toFile = (arrayBuffer: ArrayBuffer, fileName: string): File => { + const blob = new Blob([arrayBuffer], { type: 'application/pdf' }) + return new File([blob], fileName, { type: 'application/pdf' }) } /** @@ -50,42 +51,40 @@ const toPdfFile = async (file: File): Promise => { * @return PdfFile[] - an array of Sigit's internal Pdf File type */ const toPdfFiles = async (selectedFiles: File[]): Promise => { - return Promise.all(selectedFiles - .filter(isPdf) - .map(toPdfFile)); + return Promise.all(selectedFiles.filter(isPdf).map(toPdfFile)) } /** * A utility that transforms a drawing coordinate number into a CSS-compatible string * @param coordinate */ -const inPx = (coordinate: number): string => `${coordinate}px`; +const inPx = (coordinate: number): string => `${coordinate}px` /** * A utility that checks if a given file is of the pdf type * @param file */ -const isPdf = (file: File) => file.type.toLowerCase().includes('pdf'); +const isPdf = (file: File) => file.type.toLowerCase().includes('pdf') /** * Reads the pdf file binaries */ const readPdf = (file: File): Promise => { return new Promise((resolve, reject) => { - const reader = new FileReader(); + const reader = new FileReader() reader.onload = (e: any) => { const data = e.target.result resolve(data) - }; + } reader.onerror = (err) => { console.error('err', err) reject(err) - }; + } - reader.readAsDataURL(file); + reader.readAsDataURL(file) }) } @@ -94,26 +93,28 @@ const readPdf = (file: File): Promise => { * @param data pdf file bytes */ const pdfToImages = async (data: any): Promise => { - const images: string[] = []; - const pdf = await PDFJS.getDocument(data).promise; - const canvas = document.createElement("canvas"); + const images: string[] = [] + const pdf = await PDFJS.getDocument(data).promise + const canvas = document.createElement('canvas') for (let i = 0; i < pdf.numPages; i++) { - const page = await pdf.getPage(i + 1); - const viewport = page.getViewport({ scale: SCALE }); - const context = canvas.getContext("2d"); - canvas.height = viewport.height; - canvas.width = viewport.width; - await page.render({ canvasContext: context!, viewport: viewport }).promise; - images.push(canvas.toDataURL()); + const page = await pdf.getPage(i + 1) + const viewport = page.getViewport({ scale: SCALE }) + const context = canvas.getContext('2d') + canvas.height = viewport.height + canvas.width = viewport.width + await page.render({ canvasContext: context!, viewport: viewport }).promise + images.push(canvas.toDataURL()) } - return Promise.resolve(images.map((image) => { - return { - image, - drawnFields: [] - } - })) + return Promise.resolve( + images.map((image) => { + return { + image, + drawnFields: [] + } + }) + ) } /** @@ -121,34 +122,37 @@ const pdfToImages = async (data: any): Promise => { * Returns an array of encoded images where each image is a representation * of a PDF page with completed and signed marks from all users */ -const addMarks = async (file: File, marksPerPage: {[key: string]: Mark[]}) => { - const p = await readPdf(file); - const pdf = await PDFJS.getDocument(p).promise; - const canvas = document.createElement("canvas"); +const addMarks = async ( + file: File, + marksPerPage: { [key: string]: Mark[] } +) => { + const p = await readPdf(file) + const pdf = await PDFJS.getDocument(p).promise + const canvas = document.createElement('canvas') - const images: string[] = []; + const images: string[] = [] - for (let i = 0; i< pdf.numPages; i++) { - const page = await pdf.getPage(i+1) - const viewport = page.getViewport({ scale: SCALE }); - const context = canvas.getContext("2d"); - canvas.height = viewport.height; - canvas.width = viewport.width; - await page.render({ canvasContext: context!, viewport: viewport }).promise; + for (let i = 0; i < pdf.numPages; i++) { + const page = await pdf.getPage(i + 1) + const viewport = page.getViewport({ scale: SCALE }) + const context = canvas.getContext('2d') + canvas.height = viewport.height + canvas.width = viewport.width + await page.render({ canvasContext: context!, viewport: viewport }).promise - marksPerPage[i].forEach(mark => draw(mark, context!)) + marksPerPage[i].forEach((mark) => draw(mark, context!)) - images.push(canvas.toDataURL()); + images.push(canvas.toDataURL()) } - return Promise.resolve(images); + return Promise.resolve(images) } /** * Utility to scale mark in line with the PDF-to-PNG scale */ const scaleMark = (mark: Mark): Mark => { - const { location } = mark; + const { location } = mark return { ...mark, location: { @@ -165,7 +169,7 @@ const scaleMark = (mark: Mark): Mark => { * Utility to check if a Mark has value * @param mark */ -const hasValue = (mark: Mark): boolean => !!mark.value; +const hasValue = (mark: Mark): boolean => !!mark.value /** * Draws a Mark on a Canvas representation of a PDF Page @@ -173,14 +177,14 @@ const hasValue = (mark: Mark): boolean => !!mark.value; * @param ctx a Canvas representation of a specific PDF Page */ const draw = (mark: Mark, ctx: CanvasRenderingContext2D) => { - const { location } = mark; + const { location } = mark - ctx!.font = FONT_SIZE + 'px ' + FONT_TYPE; - ctx!.fillStyle = 'black'; - const textMetrics = ctx!.measureText(mark.value!); - const textX = location.left + (location.width - textMetrics.width) / 2; - const textY = location.top + (location.height + parseInt(ctx!.font)) / 2; - ctx!.fillText(mark.value!, textX, textY); + ctx!.font = FONT_SIZE + 'px ' + FONT_TYPE + ctx!.fillStyle = 'black' + const textMetrics = ctx!.measureText(mark.value!) + const textX = location.left + (location.width - textMetrics.width) / 2 + const textY = location.top + (location.height + parseInt(ctx!.font)) / 2 + ctx!.fillText(mark.value!, textX, textY) } /** @@ -188,7 +192,7 @@ const draw = (mark: Mark, ctx: CanvasRenderingContext2D) => { * @param markedPdfPages */ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { - const pdfDoc = await PDFDocument.create(); + const pdfDoc = await PDFDocument.create() for (const page of markedPdfPages) { const pngImage = await pdfDoc.embedPng(page) @@ -203,7 +207,6 @@ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { const pdfBytes = await pdfDoc.save() return new Blob([pdfBytes], { type: 'application/pdf' }) - } /** @@ -211,9 +214,12 @@ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { * @param arrayBuffer * @param fileName */ -const convertToPdfFile = async (arrayBuffer: ArrayBuffer, fileName: string): Promise => { - const file = toFile(arrayBuffer, fileName); - return toPdfFile(file); +const convertToPdfFile = async ( + arrayBuffer: ArrayBuffer, + fileName: string +): Promise => { + const file = toFile(arrayBuffer, fileName) + return toPdfFile(file) } /** @@ -226,7 +232,7 @@ const groupMarksByPage = (marks: Mark[]) => { return marks .filter(hasValue) .map(scaleMark) - .reduce<{[key: number]: Mark[]}>(byPage, {}) + .reduce<{ [key: number]: Mark[] }>(byPage, {}) } /** @@ -237,11 +243,10 @@ const groupMarksByPage = (marks: Mark[]) => { * @param obj - accumulator in the reducer callback * @param mark - current value, i.e. Mark being examined */ -const byPage = (obj: { [key: number]: Mark[]}, mark: Mark) => { - const key = mark.location.page; - const curGroup = obj[key] ?? []; - return { ...obj, [key]: [...curGroup, mark] - } +const byPage = (obj: { [key: number]: Mark[] }, mark: Mark) => { + const key = mark.location.page + const curGroup = obj[key] ?? [] + return { ...obj, [key]: [...curGroup, mark] } } export { @@ -252,5 +257,5 @@ export { convertToPdfFile, addMarks, convertToPdfBlob, - groupMarksByPage, -} \ No newline at end of file + groupMarksByPage +} diff --git a/src/utils/relays.ts b/src/utils/relays.ts index 676a59a..a3e7a9c 100644 --- a/src/utils/relays.ts +++ b/src/utils/relays.ts @@ -5,8 +5,8 @@ import { localCache } from '../services' import { ONE_WEEK_IN_MS, SIGIT_RELAY } from './const.ts' import { RelayMap, RelaySet } from '../types' -const READ_MARKER = "read" -const WRITE_MARKET = "write" +const READ_MARKER = 'read' +const WRITE_MARKET = 'write' /** * Attempts to find a relay list from the provided lookUpRelays. @@ -15,7 +15,10 @@ const WRITE_MARKET = "write" * @param hexKey * @return found relay list or null */ -const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: string): Promise => { +const findRelayListAndUpdateCache = async ( + lookUpRelays: string[], + hexKey: string +): Promise => { try { const eventFilter: Filter = { kinds: [RelayList], @@ -42,10 +45,14 @@ const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: strin const findRelayListInCache = async (hexKey: string): Promise => { try { // Attempt to retrieve the metadata event from the local cache - const cachedRelayListMetadataEvent = await localCache.getUserRelayListMetadata(hexKey) + const cachedRelayListMetadataEvent = + await localCache.getUserRelayListMetadata(hexKey) // Check if the cached event is not older than one week - if (cachedRelayListMetadataEvent && isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt)) { + if ( + cachedRelayListMetadataEvent && + isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt) + ) { return cachedRelayListMetadataEvent.event } @@ -104,5 +111,5 @@ export { findRelayListInCache, getUserRelaySet, getDefaultRelaySet, - getDefaultRelayMap, -} \ No newline at end of file + getDefaultRelayMap +} diff --git a/src/utils/sign.ts b/src/utils/sign.ts index 7b2dd84..3369c54 100644 --- a/src/utils/sign.ts +++ b/src/utils/sign.ts @@ -5,7 +5,10 @@ import { Meta } from '../types' * This function returns the signature of last signer * It will be used in the content of export signature's signedEvent */ -const getLastSignersSig = (meta: Meta, signers: `npub1${string}`[]): string | null => { +const getLastSignersSig = ( + meta: Meta, + signers: `npub1${string}`[] +): string | null => { // if there're no signers then use creator's signature if (signers.length === 0) { try { @@ -21,13 +24,11 @@ const getLastSignersSig = (meta: Meta, signers: `npub1${string}`[]): string | nu // get the signature of last signer try { - const lastSignatureEvent: Event = JSON.parse( - meta.docSignatures[lastSigner] - ) + const lastSignatureEvent: Event = JSON.parse(meta.docSignatures[lastSigner]) return lastSignatureEvent.sig } catch (error) { return null } } -export { getLastSignersSig } \ No newline at end of file +export { getLastSignersSig } diff --git a/src/utils/utils.ts b/src/utils/utils.ts index ed830a2..e68e687 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -73,9 +73,9 @@ export const timeout = (ms: number = 60000) => { * @param fileHashes */ export const getFilesWithHashes = ( - files: { [filename: string ]: PdfFile }, + files: { [filename: string]: PdfFile }, fileHashes: { [key: string]: string | null } - ) => { +) => { return Object.entries(files).map(([filename, pdfFile]) => { return { pdfFile, filename, hash: fileHashes[filename] } }) diff --git a/src/utils/zip.ts b/src/utils/zip.ts index 2d33aa5..7a7a49f 100644 --- a/src/utils/zip.ts +++ b/src/utils/zip.ts @@ -36,17 +36,12 @@ const readContentOfZipEntry = async ( const loadZip = async (data: InputFileFormat): Promise => { try { - return await JSZip.loadAsync(data); + return await JSZip.loadAsync(data) } catch (err: any) { console.log('err in loading zip file :>> ', err) toast.error(err.message || 'An error occurred in loading zip file.') - return null; + return null } } -export { - readContentOfZipEntry, - loadZip -} - - +export { readContentOfZipEntry, loadZip } From 8d683de88c210b8bad4a0b072dbb1ec925931e59 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 17:54:45 +0300 Subject: [PATCH 5/6] Revert "chore: prettier" This reverts commit 7e420ef5832967ab89bef3faf430b4749395bf51. --- src/components/DrawPDFFields/index.tsx | 244 ++++++++----------------- src/components/PDFView/PdfItem.tsx | 44 ++--- src/components/PDFView/PdfMarkItem.tsx | 20 +- src/components/PDFView/PdfMarking.tsx | 67 ++++--- src/components/PDFView/PdfPageItem.tsx | 32 ++-- src/components/PDFView/index.tsx | 47 ++--- src/controllers/MetadataController.ts | 17 +- src/index.css | 18 +- src/pages/create/index.tsx | 55 +++--- src/pages/settings/relays/index.tsx | 3 +- src/pages/sign/MarkFormField.tsx | 6 +- src/pages/sign/index.tsx | 74 ++++---- src/pages/verify/index.tsx | 31 ++-- src/types/drawing.ts | 6 +- src/types/mark.ts | 24 +-- src/types/zip.ts | 24 ++- src/utils/mark.ts | 34 ++-- src/utils/pdf.ts | 143 +++++++-------- src/utils/relays.ts | 21 +-- src/utils/sign.ts | 11 +- src/utils/utils.ts | 4 +- src/utils/zip.ts | 11 +- 22 files changed, 387 insertions(+), 549 deletions(-) diff --git a/src/components/DrawPDFFields/index.tsx b/src/components/DrawPDFFields/index.tsx index e7880e4..148e70f 100644 --- a/src/components/DrawPDFFields/index.tsx +++ b/src/components/DrawPDFFields/index.tsx @@ -1,43 +1,15 @@ -import { - AccessTime, - CalendarMonth, - ExpandMore, - Gesture, - PictureAsPdf, - Badge, - Work, - Close -} from '@mui/icons-material' -import { - Box, - Typography, - Accordion, - AccordionDetails, - AccordionSummary, - CircularProgress, - FormControl, - InputLabel, - MenuItem, - Select -} from '@mui/material' +import { AccessTime, CalendarMonth, ExpandMore, Gesture, PictureAsPdf, Badge, Work, Close } from '@mui/icons-material' +import { Box, Typography, Accordion, AccordionDetails, AccordionSummary, CircularProgress, FormControl, InputLabel, MenuItem, Select } from '@mui/material' import styles from './style.module.scss' import { useEffect, useState } from 'react' -import * as PDFJS from 'pdfjs-dist' -import { ProfileMetadata, User } from '../../types' -import { - PdfFile, - DrawTool, - MouseState, - PdfPage, - DrawnField, - MarkType -} from '../../types/drawing' -import { truncate } from 'lodash' -import { hexToNpub } from '../../utils' +import * as PDFJS from "pdfjs-dist"; +import { ProfileMetadata, User } from '../../types'; +import { PdfFile, DrawTool, MouseState, PdfPage, DrawnField, MarkType } from '../../types/drawing'; +import { truncate } from 'lodash'; +import { hexToNpub } from '../../utils'; import { toPdfFiles } from '../../utils/pdf.ts' -PDFJS.GlobalWorkerOptions.workerSrc = - 'node_modules/pdfjs-dist/build/pdf.worker.mjs' +PDFJS.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.mjs'; interface Props { selectedFiles: File[] @@ -48,43 +20,44 @@ interface Props { export const DrawPDFFields = (props: Props) => { const { selectedFiles } = props - + const [pdfFiles, setPdfFiles] = useState([]) const [parsingPdf, setParsingPdf] = useState(false) const [showDrawToolBox, setShowDrawToolBox] = useState(false) - + const [selectedTool, setSelectedTool] = useState() const [toolbox] = useState([ { identifier: MarkType.SIGNATURE, - icon: , + icon: , label: 'Signature', active: false + }, { identifier: MarkType.FULLNAME, - icon: , + icon: , label: 'Full Name', active: true }, { identifier: MarkType.JOBTITLE, - icon: , + icon: , label: 'Job Title', active: false }, { identifier: MarkType.DATE, - icon: , + icon: , label: 'Date', active: false }, { identifier: MarkType.DATETIME, - icon: , + icon: , label: 'Datetime', active: false - } + }, ]) const [mouseState, setMouseState] = useState({ @@ -94,7 +67,7 @@ export const DrawPDFFields = (props: Props) => { useEffect(() => { if (selectedFiles) { setParsingPdf(true) - + parsePdfPages().finally(() => { setParsingPdf(false) }) @@ -108,13 +81,13 @@ export const DrawPDFFields = (props: Props) => { /** * Drawing events */ - useEffect(() => { + useEffect(() => { // window.addEventListener('mousedown', onMouseDown); - window.addEventListener('mouseup', onMouseUp) - + window.addEventListener('mouseup', onMouseUp); + return () => { // window.removeEventListener('mousedown', onMouseDown); - window.removeEventListener('mouseup', onMouseUp) + window.removeEventListener('mouseup', onMouseUp); } }, []) @@ -133,7 +106,7 @@ export const DrawPDFFields = (props: Props) => { const onMouseDown = (event: any, page: PdfPage) => { // Proceed only if left click if (event.button !== 0) return - + // Only allow drawing if mouse is not over other drawn element const isOverPdfImageWrapper = event.target.tagName === 'IMG' @@ -185,11 +158,11 @@ export const DrawPDFFields = (props: Props) => { */ const onMouseMove = (event: any, page: PdfPage) => { if (mouseState.clicked && selectedTool) { - const lastElementIndex = page.drawnFields.length - 1 + const lastElementIndex = page.drawnFields.length -1 const lastDrawnField = page.drawnFields[lastElementIndex] const { mouseX, mouseY } = getMouseCoordinates(event) - + const width = mouseX - lastDrawnField.left const height = mouseY - lastDrawnField.top @@ -199,10 +172,10 @@ export const DrawPDFFields = (props: Props) => { const currentDrawnFields = page.drawnFields currentDrawnFields[lastElementIndex] = lastDrawnField - + refreshPdfFiles() } - } + } /** * Fired when event happens on the drawn element which will be moved @@ -216,7 +189,7 @@ export const DrawPDFFields = (props: Props) => { */ const onDrawnFieldMouseDown = (event: any) => { event.stopPropagation() - + // Proceed only if left click if (event.button !== 0) return @@ -239,10 +212,7 @@ export const DrawPDFFields = (props: Props) => { */ const onDranwFieldMouseMove = (event: any, drawnField: DrawnField) => { if (mouseState.dragging) { - const { mouseX, mouseY, rect } = getMouseCoordinates( - event, - event.target.parentNode - ) + const { mouseX, mouseY, rect } = getMouseCoordinates(event, event.target.parentNode) const coordsOffset = mouseState.coordsInWrapper if (coordsOffset) { @@ -288,11 +258,8 @@ export const DrawPDFFields = (props: Props) => { */ const onResizeHandleMouseMove = (event: any, drawnField: DrawnField) => { if (mouseState.resizing) { - const { mouseX, mouseY } = getMouseCoordinates( - event, - event.target.parentNode.parentNode - ) - + const { mouseX, mouseY } = getMouseCoordinates(event, event.target.parentNode.parentNode) + const width = mouseX - drawnField.left const height = mouseY - drawnField.top @@ -310,18 +277,10 @@ export const DrawPDFFields = (props: Props) => { * @param pdfPageIndex pdf page index * @param drawnFileIndex drawn file index */ - const onRemoveHandleMouseDown = ( - event: any, - pdfFileIndex: number, - pdfPageIndex: number, - drawnFileIndex: number - ) => { + const onRemoveHandleMouseDown = (event: any, pdfFileIndex: number, pdfPageIndex: number, drawnFileIndex: number) => { event.stopPropagation() - - pdfFiles[pdfFileIndex].pages[pdfPageIndex].drawnFields.splice( - drawnFileIndex, - 1 - ) + + pdfFiles[pdfFileIndex].pages[pdfPageIndex].drawnFields.splice(drawnFileIndex, 1) } /** @@ -341,9 +300,9 @@ export const DrawPDFFields = (props: Props) => { */ const getMouseCoordinates = (event: any, customTarget?: any) => { const target = customTarget ? customTarget : event.target - const rect = target.getBoundingClientRect() - const mouseX = event.clientX - rect.left //x position within the element. - const mouseY = event.clientY - rect.top //y position within the element. + const rect = target.getBoundingClientRect(); + const mouseX = event.clientX - rect.left; //x position within the element. + const mouseY = event.clientY - rect.top; //y position within the element. return { mouseX, @@ -357,8 +316,8 @@ export const DrawPDFFields = (props: Props) => { * creates the pdfFiles object and sets to a state */ const parsePdfPages = async () => { - const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles) - + const pdfFiles: PdfFile[] = await toPdfFiles(selectedFiles); + setPdfFiles(pdfFiles) } @@ -367,7 +326,7 @@ export const DrawPDFFields = (props: Props) => { * @returns if expanded pdf accordion is present */ const hasExpandedPdf = () => { - return !!pdfFiles.filter((pdfFile) => !!pdfFile.expanded).length + return !!pdfFiles.filter(pdfFile => !!pdfFile.expanded).length } const handleAccordionExpandChange = (expanded: boolean, pdfFile: PdfFile) => { @@ -396,11 +355,9 @@ export const DrawPDFFields = (props: Props) => { */ const getPdfPages = (pdfFile: PdfFile, pdfFileIndex: number) => { return ( - + {pdfFile.pages.map((page, pdfPageIndex: number) => { return (
{ marginBottom: '10px' }} className={`${styles.pdfImageWrapper} ${selectedTool ? styles.drawing : ''}`} - onMouseMove={(event) => { - onMouseMove(event, page) - }} - onMouseDown={(event) => { - onMouseDown(event, page) - }} + onMouseMove={(event) => {onMouseMove(event, page)}} + onMouseDown={(event) => {onMouseDown(event, page)}} > - + {page.drawnFields.map((drawnField, drawnFieldIndex: number) => { return (
{ - onDranwFieldMouseMove(event, drawnField) - }} + onMouseMove={(event) => { onDranwFieldMouseMove(event, drawnField)}} className={styles.drawingRectangle} style={{ left: `${drawnField.left}px`, @@ -442,68 +389,41 @@ export const DrawPDFFields = (props: Props) => { > { - onResizeHandleMouseMove(event, drawnField) - }} + onMouseMove={(event) => {onResizeHandleMouseMove(event, drawnField)}} className={styles.resizeHandle} > { - onRemoveHandleMouseDown( - event, - pdfFileIndex, - pdfPageIndex, - drawnFieldIndex - ) - }} + onMouseDown={(event) => {onRemoveHandleMouseDown(event, pdfFileIndex, pdfPageIndex, drawnFieldIndex)}} className={styles.removeHandle} > - + -
- + Counterpart @@ -515,13 +435,13 @@ export const DrawPDFFields = (props: Props) => { ) })} - ) + ) } if (parsingPdf) { return ( - + ) } @@ -534,28 +454,22 @@ export const DrawPDFFields = (props: Props) => { Draw fields on the PDFs: - + {pdfFiles.map((pdfFile, pdfFileIndex: number) => { return ( - { - handleAccordionExpandChange(expanded, pdfFile) - }} - > + {handleAccordionExpandChange(expanded, pdfFile)}}> } aria-controls={`panel${pdfFileIndex}-content`} id={`panel${pdfFileIndex}header`} > - + {pdfFile.file.name} {getPdfPages(pdfFile, pdfFileIndex)} - + ) })} @@ -563,22 +477,16 @@ export const DrawPDFFields = (props: Props) => { {showDrawToolBox && ( - {toolbox - .filter((drawTool) => drawTool.active) - .map((drawTool: DrawTool, index: number) => { - return ( - { - handleToolSelect(drawTool) - }} - className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`} - > - {drawTool.icon} - {drawTool.label} - - ) - })} + {toolbox.filter(drawTool => drawTool.active).map((drawTool: DrawTool, index: number) => { + return ( + {handleToolSelect(drawTool)}} className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''}`}> + { drawTool.icon } + { drawTool.label } + + ) + })} )} diff --git a/src/components/PDFView/PdfItem.tsx b/src/components/PDFView/PdfItem.tsx index 6e8aa64..eb5ceff 100644 --- a/src/components/PDFView/PdfItem.tsx +++ b/src/components/PDFView/PdfItem.tsx @@ -1,6 +1,6 @@ import { PdfFile } from '../../types/drawing.ts' import { CurrentUserMark } from '../../types/mark.ts' -import PdfPageItem from './PdfPageItem.tsx' +import PdfPageItem from './PdfPageItem.tsx'; interface PdfItemProps { pdfFile: PdfFile @@ -13,31 +13,23 @@ interface PdfItemProps { /** * 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) +const PdfItem = ({ pdfFile, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfItemProps) => { + const filterByPage = (marks: CurrentUserMark[], page: number): CurrentUserMark[] => { + return marks.filter((m) => m.mark.location.page === page); } - return pdfFile.pages.map((page, i) => { - return ( - - ) - }) + return ( + pdfFile.pages.map((page, i) => { + return ( + + ) + })) } -export default PdfItem +export default PdfItem \ No newline at end of file diff --git a/src/components/PDFView/PdfMarkItem.tsx b/src/components/PDFView/PdfMarkItem.tsx index 90caa87..7a2b24b 100644 --- a/src/components/PDFView/PdfMarkItem.tsx +++ b/src/components/PDFView/PdfMarkItem.tsx @@ -12,18 +12,14 @@ interface PdfMarkItemProps { /** * Responsible for display an individual Pdf Mark. */ -const PdfMarkItem = ({ - selectedMark, - handleMarkClick, - selectedMarkValue, - userMark -}: PdfMarkItemProps) => { - const { location } = userMark.mark - const handleClick = () => handleMarkClick(userMark.mark.id) - const getMarkValue = () => +const PdfMarkItem = ({ selectedMark, handleMarkClick, selectedMarkValue, userMark }: PdfMarkItemProps) => { + const { location } = userMark.mark; + const handleClick = () => handleMarkClick(userMark.mark.id); + const getMarkValue = () => ( selectedMark?.mark.id === userMark.mark.id ? selectedMarkValue : userMark.mark.value + ) return (
- {getMarkValue()} -
+ >{getMarkValue()}
) } -export default PdfMarkItem +export default PdfMarkItem \ No newline at end of file diff --git a/src/components/PDFView/PdfMarking.tsx b/src/components/PDFView/PdfMarking.tsx index 0e47ab1..a6dc1a4 100644 --- a/src/components/PDFView/PdfMarking.tsx +++ b/src/components/PDFView/PdfMarking.tsx @@ -6,17 +6,17 @@ import React, { useState, useEffect } from 'react' import { findNextCurrentUserMark, isCurrentUserMarksComplete, - updateCurrentUserMarks + updateCurrentUserMarks, } from '../../utils' import { EMPTY } from '../../utils/const.ts' import { Container } from '../Container' import styles from '../../pages/sign/style.module.scss' interface PdfMarkingProps { - files: { pdfFile: PdfFile; filename: string; hash: string | null }[] - currentUserMarks: CurrentUserMark[] - setIsReadyToSign: (isReadyToSign: boolean) => void - setCurrentUserMarks: (currentUserMarks: CurrentUserMark[]) => void + files: { pdfFile: PdfFile, filename: string, hash: string | null }[], + currentUserMarks: CurrentUserMark[], + setIsReadyToSign: (isReadyToSign: boolean) => void, + setCurrentUserMarks: (currentUserMarks: CurrentUserMark[]) => void, setUpdatedMarks: (markToUpdate: Mark) => void } @@ -35,21 +35,21 @@ const PdfMarking = (props: PdfMarkingProps) => { setUpdatedMarks } = props const [selectedMark, setSelectedMark] = useState(null) - const [selectedMarkValue, setSelectedMarkValue] = useState('') + const [selectedMarkValue, setSelectedMarkValue] = useState("") useEffect(() => { setSelectedMark(findNextCurrentUserMark(currentUserMarks) || null) }, [currentUserMarks]) const handleMarkClick = (id: number) => { - const nextMark = currentUserMarks.find((mark) => mark.mark.id === id) - setSelectedMark(nextMark!) - setSelectedMarkValue(nextMark?.mark.value ?? EMPTY) + const nextMark = currentUserMarks.find((mark) => mark.mark.id === id); + setSelectedMark(nextMark!); + setSelectedMarkValue(nextMark?.mark.value ?? EMPTY); } const handleSubmit = (event: React.FormEvent) => { - event.preventDefault() - if (!selectedMarkValue || !selectedMark) return + event.preventDefault(); + if (!selectedMarkValue || !selectedMark) return; const updatedMark: CurrentUserMark = { ...selectedMark, @@ -61,10 +61,7 @@ const PdfMarking = (props: PdfMarkingProps) => { } setSelectedMarkValue(EMPTY) - const updatedCurrentUserMarks = updateCurrentUserMarks( - currentUserMarks, - updatedMark - ) + const updatedCurrentUserMarks = updateCurrentUserMarks(currentUserMarks, updatedMark); setCurrentUserMarks(updatedCurrentUserMarks) setSelectedMark(findNextCurrentUserMark(updatedCurrentUserMarks) || null) console.log(isCurrentUserMarksComplete(updatedCurrentUserMarks)) @@ -72,32 +69,32 @@ const PdfMarking = (props: PdfMarkingProps) => { setUpdatedMarks(updatedMark.mark) } - const handleChange = (event: React.ChangeEvent) => - setSelectedMarkValue(event.target.value) + const handleChange = (event: React.ChangeEvent) => setSelectedMarkValue(event.target.value) return ( <> - {currentUserMarks?.length > 0 && ( - - )} - {selectedMark !== null && ( - - )} + { + currentUserMarks?.length > 0 && ( + )} + { + selectedMark !== null && ( + + )} ) } -export default PdfMarking +export default PdfMarking \ No newline at end of file diff --git a/src/components/PDFView/PdfPageItem.tsx b/src/components/PDFView/PdfPageItem.tsx index 241474e..d289a6e 100644 --- a/src/components/PDFView/PdfPageItem.tsx +++ b/src/components/PDFView/PdfPageItem.tsx @@ -13,13 +13,7 @@ interface PdfPageProps { /** * 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 (
- - {currentUserMarks.map((m, i) => ( - + { + currentUserMarks.map((m, i) => ( + ))}
) } -export default PdfPageItem +export default PdfPageItem \ No newline at end of file diff --git a/src/components/PDFView/index.tsx b/src/components/PDFView/index.tsx index 8a14e55..14834a3 100644 --- a/src/components/PDFView/index.tsx +++ b/src/components/PDFView/index.tsx @@ -4,7 +4,7 @@ import PdfItem from './PdfItem.tsx' import { CurrentUserMark } from '../../types/mark.ts' interface PdfViewProps { - files: { pdfFile: PdfFile; filename: string; hash: string | null }[] + files: { pdfFile: PdfFile, filename: string, hash: string | null }[] currentUserMarks: CurrentUserMark[] handleMarkClick: (id: number) => void selectedMarkValue: string @@ -14,38 +14,29 @@ interface PdfViewProps { /** * 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 - ) +const PdfView = ({ files, currentUserMarks, handleMarkClick, selectedMarkValue, selectedMark }: PdfViewProps) => { + const filterByFile = (currentUserMarks: CurrentUserMark[], hash: string): CurrentUserMark[] => { + return currentUserMarks.filter((currentUserMark) => currentUserMark.mark.pdfFileHash === hash) } return ( - {files.map(({ pdfFile, hash }, i) => { - if (!hash) return - return ( - { + if (!hash) return + return ( + - ) - })} + ) + }) + } ) } -export default PdfView +export default PdfView; \ No newline at end of file diff --git a/src/controllers/MetadataController.ts b/src/controllers/MetadataController.ts index cd3d819..e2f6852 100644 --- a/src/controllers/MetadataController.ts +++ b/src/controllers/MetadataController.ts @@ -164,18 +164,13 @@ export class MetadataController extends EventEmitter { * or a fallback RelaySet with Sigit's Relay */ public findRelayListMetadata = async (hexKey: string): Promise => { - const relayEvent = - (await findRelayListInCache(hexKey)) || - (await findRelayListAndUpdateCache( - [this.specialMetadataRelay], - hexKey - )) || - (await findRelayListAndUpdateCache( - await this.nostrController.getMostPopularRelays(), - hexKey - )) + const relayEvent = await findRelayListInCache(hexKey) + || await findRelayListAndUpdateCache([this.specialMetadataRelay], hexKey) + || await findRelayListAndUpdateCache(await this.nostrController.getMostPopularRelays(), hexKey) - return relayEvent ? getUserRelaySet(relayEvent.tags) : getDefaultRelaySet() + return relayEvent + ? getUserRelaySet(relayEvent.tags) + : getDefaultRelaySet() } public extractProfileMetadataContent = (event: Event) => { diff --git a/src/index.css b/src/index.css index 76373ff..6a734df 100644 --- a/src/index.css +++ b/src/index.css @@ -111,9 +111,7 @@ button:disabled { /* Fonts */ @font-face { font-family: 'Roboto'; - src: - local('Roboto Medium'), - local('Roboto-Medium'), + src: local('Roboto Medium'), local('Roboto-Medium'), url('assets/fonts/roboto-medium.woff2') format('woff2'), url('assets/fonts/roboto-medium.woff') format('woff'); font-weight: 500; @@ -123,9 +121,7 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: - local('Roboto Light'), - local('Roboto-Light'), + src: local('Roboto Light'), local('Roboto-Light'), url('assets/fonts/roboto-light.woff2') format('woff2'), url('assets/fonts/roboto-light.woff') format('woff'); font-weight: 300; @@ -135,9 +131,7 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: - local('Roboto Bold'), - local('Roboto-Bold'), + src: local('Roboto Bold'), local('Roboto-Bold'), url('assets/fonts/roboto-bold.woff2') format('woff2'), url('assets/fonts/roboto-bold.woff') format('woff'); font-weight: bold; @@ -147,12 +141,10 @@ button:disabled { @font-face { font-family: 'Roboto'; - src: - local('Roboto'), - local('Roboto-Regular'), + src: local('Roboto'), local('Roboto-Regular'), url('assets/fonts/roboto-regular.woff2') format('woff2'), url('assets/fonts/roboto-regular.woff') format('woff'); font-weight: normal; font-style: normal; font-display: swap; -} +} \ No newline at end of file diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 023dd02..830f9ef 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -341,30 +341,29 @@ export const CreatePage = () => { return fileHashes } - const createMarks = (fileHashes: { [key: string]: string }): Mark[] => { - return drawnPdfs - .flatMap((drawnPdf) => { - const fileHash = fileHashes[drawnPdf.file.name] - return drawnPdf.pages.flatMap((page, index) => { - return page.drawnFields.map((drawnField) => { - return { - type: drawnField.type, - location: { - page: index, - top: drawnField.top, - left: drawnField.left, - height: drawnField.height, - width: drawnField.width - }, - npub: drawnField.counterpart, - pdfFileHash: fileHash - } - }) + const createMarks = (fileHashes: { [key: string]: string }) : Mark[] => { + return drawnPdfs.flatMap((drawnPdf) => { + const fileHash = fileHashes[drawnPdf.file.name]; + return drawnPdf.pages.flatMap((page, index) => { + return page.drawnFields.map((drawnField) => { + return { + type: drawnField.type, + location: { + page: index, + top: drawnField.top, + left: drawnField.left, + height: drawnField.height, + width: drawnField.width, + }, + npub: drawnField.counterpart, + pdfFileHash: fileHash + } }) }) + }) .map((mark, index) => { - return { ...mark, id: index } - }) + return {...mark, id: index } + }); } // Handle errors during zip file generation @@ -432,9 +431,13 @@ export const CreatePage = () => { if (!arraybuffer) return null - return new File([new Blob([arraybuffer])], `${unixNow}.sigit.zip`, { - type: 'application/zip' - }) + return new File( + [new Blob([arraybuffer])], + `${unixNow}.sigit.zip`, + { + type: 'application/zip' + } + ) } // Handle errors during file upload @@ -542,7 +545,9 @@ export const CreatePage = () => { : viewers.map((viewer) => viewer.pubkey) ).filter((receiver) => receiver !== usersPubkey) - return receivers.map((receiver) => sendNotification(receiver, meta)) + return receivers.map((receiver) => + sendNotification(receiver, meta) + ) } const handleCreate = async () => { diff --git a/src/pages/settings/relays/index.tsx b/src/pages/settings/relays/index.tsx index 929a093..b06908a 100644 --- a/src/pages/settings/relays/index.tsx +++ b/src/pages/settings/relays/index.tsx @@ -91,8 +91,7 @@ export const RelaysPage = () => { if (isMounted) { if ( !relaysState?.mapUpdated || - (newRelayMap?.mapUpdated !== undefined && - newRelayMap?.mapUpdated > relaysState?.mapUpdated) + newRelayMap?.mapUpdated !== undefined && (newRelayMap?.mapUpdated > relaysState?.mapUpdated) ) { if ( !relaysState?.map || diff --git a/src/pages/sign/MarkFormField.tsx b/src/pages/sign/MarkFormField.tsx index 4cb943b..4de82a4 100644 --- a/src/pages/sign/MarkFormField.tsx +++ b/src/pages/sign/MarkFormField.tsx @@ -15,8 +15,8 @@ interface MarkFormFieldProps { * Responsible for rendering a form field connected to a mark and keeping track of its value. */ const MarkFormField = (props: MarkFormFieldProps) => { - const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props - const getSubmitButton = () => (selectedMark.isLast ? 'Complete' : 'Next') + const { handleSubmit, handleChange, selectedMark, selectedMarkValue } = props; + const getSubmitButton = () => selectedMark.isLast ? 'Complete' : 'Next'; return (
@@ -34,4 +34,4 @@ const MarkFormField = (props: MarkFormFieldProps) => { ) } -export default MarkFormField +export default MarkFormField; \ No newline at end of file diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index 6f3231b..07c385e 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -16,16 +16,13 @@ import { State } from '../../store/rootReducer' import { CreateSignatureEventContent, Meta, SignedEvent } from '../../types' import { decryptArrayBuffer, - encryptArrayBuffer, - extractMarksFromSignedMeta, + encryptArrayBuffer, extractMarksFromSignedMeta, extractZipUrlAndEncryptionKey, generateEncryptionKey, - generateKeysFile, - getFilesWithHashes, + generateKeysFile, getFilesWithHashes, getHash, hexToNpub, - isOnline, - loadZip, + isOnline, loadZip, now, npubToHex, parseJson, @@ -44,8 +41,7 @@ import { getLastSignersSig } from '../../utils/sign.ts' import { filterMarksByPubkey, getCurrentUserMarks, - isCurrentUserMarksComplete, - updateMarks + isCurrentUserMarksComplete, updateMarks } from '../../utils' import PdfMarking from '../../components/PDFView/PdfMarking.tsx' enum SignedStatus { @@ -85,7 +81,7 @@ export const SignPage = () => { const [signers, setSigners] = useState<`npub1${string}`[]>([]) const [viewers, setViewers] = useState<`npub1${string}`[]>([]) - const [marks, setMarks] = useState([]) + const [marks, setMarks] = useState([]) const [creatorFileHashes, setCreatorFileHashes] = useState<{ [key: string]: string }>({}) @@ -104,10 +100,8 @@ export const SignPage = () => { const [authUrl, setAuthUrl] = useState() const nostrController = NostrController.getInstance() - const [currentUserMarks, setCurrentUserMarks] = useState( - [] - ) - const [isReadyToSign, setIsReadyToSign] = useState(false) + const [currentUserMarks, setCurrentUserMarks] = useState([]); + const [isReadyToSign, setIsReadyToSign] = useState(false); useEffect(() => { if (signers.length > 0) { @@ -198,16 +192,13 @@ export const SignPage = () => { setViewers(createSignatureContent.viewers) setCreatorFileHashes(createSignatureContent.fileHashes) setSubmittedBy(createSignatureEvent.pubkey) - setMarks(createSignatureContent.markConfig) + setMarks(createSignatureContent.markConfig); if (usersPubkey) { - const metaMarks = filterMarksByPubkey( - createSignatureContent.markConfig, - usersPubkey! - ) + const metaMarks = filterMarksByPubkey(createSignatureContent.markConfig, usersPubkey!) const signedMarks = extractMarksFromSignedMeta(meta) - const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks) - setCurrentUserMarks(currentUserMarks) + const currentUserMarks = getCurrentUserMarks(metaMarks, signedMarks); + setCurrentUserMarks(currentUserMarks); // setCurrentUserMark(findNextCurrentUserMark(currentUserMarks) || null) setIsReadyToSign(isCurrentUserMarksComplete(currentUserMarks)) } @@ -316,7 +307,7 @@ export const SignPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile(arrayBuffer, fileName) + files[fileName] = await convertToPdfFile(arrayBuffer, fileName); const hash = await getHash(arrayBuffer) if (hash) { @@ -357,7 +348,7 @@ export const SignPage = () => { const decrypt = async (file: File) => { setLoadingSpinnerDesc('Decrypting file') - const zip = await loadZip(file) + const zip = await loadZip(file); if (!zip) return const parsedKeysJson = await parseKeysJson(zip) @@ -448,7 +439,7 @@ export const SignPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile(arrayBuffer, fileName) + files[fileName] = await convertToPdfFile(arrayBuffer, fileName); const hash = await getHash(arrayBuffer) if (hash) { @@ -529,10 +520,7 @@ export const SignPage = () => { } // Sign the event for the meta file - const signEventForMeta = async (signerContent: { - prevSig: string - marks: Mark[] - }) => { + const signEventForMeta = async (signerContent: { prevSig: string, marks: Mark[] }) => { return await signEventForMetaFile( JSON.stringify(signerContent), nostrController, @@ -541,8 +529,8 @@ export const SignPage = () => { } const getSignerMarksForMeta = (): Mark[] | undefined => { - if (currentUserMarks.length === 0) return - return currentUserMarks.map(({ mark }: CurrentUserMark) => mark) + if (currentUserMarks.length === 0) return; + return currentUserMarks.map(( { mark }: CurrentUserMark) => mark); } // Update the meta signatures @@ -612,9 +600,13 @@ export const SignPage = () => { if (!arraybuffer) return null - return new File([new Blob([arraybuffer])], `${unixNow}.sigit.zip`, { - type: 'application/zip' - }) + return new File( + [new Blob([arraybuffer])], + `${unixNow}.sigit.zip`, + { + type: 'application/zip' + } + ) } // Handle errors during zip file generation @@ -702,7 +694,7 @@ export const SignPage = () => { setIsLoading(true) setLoadingSpinnerDesc('Signing nostr event') - if (!meta) return + if (!meta) return; const prevSig = getLastSignersSig(meta, signers) if (!prevSig) return @@ -926,13 +918,11 @@ export const SignPage = () => { ) } - return ( - - ) + return } diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index c5a0e8e..6290c02 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -23,17 +23,14 @@ import { SignedEventContent } from '../../types' import { - decryptArrayBuffer, - extractMarksFromSignedMeta, + decryptArrayBuffer, extractMarksFromSignedMeta, extractZipUrlAndEncryptionKey, getHash, - hexToNpub, - now, + hexToNpub, now, npubToHex, parseJson, readContentOfZipEntry, - shorten, - signEventForMetaFile + shorten, signEventForMetaFile } from '../../utils' import styles from './style.module.scss' import { Cancel, CheckCircle } from '@mui/icons-material' @@ -44,7 +41,7 @@ import { addMarks, convertToPdfBlob, convertToPdfFile, - groupMarksByPage + groupMarksByPage, } from '../../utils/pdf.ts' import { State } from '../../store/rootReducer.ts' import { useSelector } from 'react-redux' @@ -81,7 +78,7 @@ export const VerifyPage = () => { const [currentFileHashes, setCurrentFileHashes] = useState<{ [key: string]: string | null }>({}) - const [files, setFiles] = useState<{ [filename: string]: PdfFile }>({}) + const [files, setFiles] = useState<{ [filename: string]: PdfFile}>({}) const [metadata, setMetadata] = useState<{ [key: string]: ProfileMetadata }>( {} @@ -158,10 +155,7 @@ export const VerifyPage = () => { ) if (arrayBuffer) { - files[fileName] = await convertToPdfFile( - arrayBuffer, - fileName! - ) + files[fileName] = await convertToPdfFile(arrayBuffer, fileName!) const hash = await getHash(arrayBuffer) if (hash) { @@ -175,6 +169,7 @@ export const VerifyPage = () => { setCurrentFileHashes(fileHashes) setFiles(files) + setSigners(createSignatureContent.signers) setViewers(createSignatureContent.viewers) setCreatorFileHashes(createSignatureContent.fileHashes) @@ -182,6 +177,8 @@ export const VerifyPage = () => { setMeta(metaInNavState) setIsLoading(false) + + } }) .catch((err) => { @@ -384,7 +381,7 @@ export const VerifyPage = () => { } const handleExport = async () => { - if (Object.entries(files).length === 0 || !meta || !usersPubkey) return + if (Object.entries(files).length === 0 ||!meta ||!usersPubkey) return; const usersNpub = hexToNpub(usersPubkey) if ( @@ -398,10 +395,10 @@ export const VerifyPage = () => { setIsLoading(true) setLoadingSpinnerDesc('Signing nostr event') - if (!meta) return + if (!meta) return; const prevSig = getLastSignersSig(meta, signers) - if (!prevSig) return + if (!prevSig) return; const signedEvent = await signEventForMetaFile( JSON.stringify({ prevSig }), @@ -409,10 +406,10 @@ export const VerifyPage = () => { setIsLoading ) - if (!signedEvent) return + if (!signedEvent) return; const exportSignature = JSON.stringify(signedEvent, null, 2) - const updatedMeta = { ...meta, exportSignature } + const updatedMeta = {...meta, exportSignature } const stringifiedMeta = JSON.stringify(updatedMeta, null, 2) const zip = new JSZip() diff --git a/src/types/drawing.ts b/src/types/drawing.ts index f14dbea..702343f 100644 --- a/src/types/drawing.ts +++ b/src/types/drawing.ts @@ -9,7 +9,7 @@ export interface MouseState { } export interface PdfFile { - file: File + file: File, pages: PdfPage[] expanded?: boolean } @@ -34,7 +34,7 @@ export interface DrawnField { export interface DrawTool { identifier: MarkType label: string - icon: JSX.Element + icon: JSX.Element, defaultValue?: string selected?: boolean active?: boolean @@ -46,4 +46,4 @@ export enum MarkType { FULLNAME = 'FULLNAME', DATE = 'DATE', DATETIME = 'DATETIME' -} +} \ No newline at end of file diff --git a/src/types/mark.ts b/src/types/mark.ts index 9a6a545..3184f95 100644 --- a/src/types/mark.ts +++ b/src/types/mark.ts @@ -1,4 +1,4 @@ -import { MarkType } from './drawing' +import { MarkType } from "./drawing"; export interface CurrentUserMark { mark: Mark @@ -7,18 +7,18 @@ export interface CurrentUserMark { } export interface Mark { - id: number - npub: string - pdfFileHash: string - type: MarkType - location: MarkLocation - value?: string + id: number; + npub: string; + pdfFileHash: string; + type: MarkType; + location: MarkLocation; + value?: string; } export interface MarkLocation { - top: number - left: number - height: number - width: number - page: number + top: number; + left: number; + height: number; + width: number; + page: number; } diff --git a/src/types/zip.ts b/src/types/zip.ts index 7405067..b4c97ac 100644 --- a/src/types/zip.ts +++ b/src/types/zip.ts @@ -1,4 +1,4 @@ -export interface OutputByType { + export interface OutputByType { base64: string string: string text: string @@ -11,18 +11,16 @@ export interface OutputByType { } interface InputByType { - base64: string - string: string - text: string - binarystring: string - array: number[] - uint8array: Uint8Array - arraybuffer: ArrayBuffer - blob: Blob - stream: NodeJS.ReadableStream + base64: string; + string: string; + text: string; + binarystring: string; + array: number[]; + uint8array: Uint8Array; + arraybuffer: ArrayBuffer; + blob: Blob; + stream: NodeJS.ReadableStream; } export type OutputType = keyof OutputByType -export type InputFileFormat = - | InputByType[keyof InputByType] - | Promise +export type InputFileFormat = InputByType[keyof InputByType] | Promise; \ No newline at end of file diff --git a/src/utils/mark.ts b/src/utils/mark.ts index 60868be..13cff84 100644 --- a/src/utils/mark.ts +++ b/src/utils/mark.ts @@ -9,12 +9,9 @@ import { Event } from 'nostr-tools' * @param marks - default Marks extracted from Meta * @param signedMetaMarks - signed user Marks extracted from DocSignatures */ -const getCurrentUserMarks = ( - marks: Mark[], - signedMetaMarks: Mark[] -): CurrentUserMark[] => { +const getCurrentUserMarks = (marks: Mark[], signedMetaMarks: Mark[]): CurrentUserMark[] => { return marks.map((mark, index, arr) => { - const signedMark = signedMetaMarks.find((m) => m.id === mark.id) + const signedMark = signedMetaMarks.find((m) => m.id === mark.id); if (signedMark && !!signedMark.value) { mark.value = signedMark.value } @@ -30,10 +27,8 @@ const getCurrentUserMarks = ( * Returns next incomplete CurrentUserMark if there is one * @param usersMarks */ -const findNextCurrentUserMark = ( - usersMarks: CurrentUserMark[] -): CurrentUserMark | undefined => { - return usersMarks.find((mark) => !mark.isCompleted) +const findNextCurrentUserMark = (usersMarks: CurrentUserMark[]): CurrentUserMark | undefined => { + return usersMarks.find((mark) => !mark.isCompleted); } /** @@ -42,7 +37,7 @@ const findNextCurrentUserMark = ( * @param pubkey */ const filterMarksByPubkey = (marks: Mark[], pubkey: string): Mark[] => { - return marks.filter((mark) => mark.npub === hexToNpub(pubkey)) + return marks.filter(mark => mark.npub === hexToNpub(pubkey)) } /** @@ -62,9 +57,7 @@ const extractMarksFromSignedMeta = (meta: Meta): Mark[] => { * marked as complete. * @param currentUserMarks */ -const isCurrentUserMarksComplete = ( - currentUserMarks: CurrentUserMark[] -): boolean => { +const isCurrentUserMarksComplete = (currentUserMarks: CurrentUserMark[]): boolean => { return currentUserMarks.every((mark) => mark.isCompleted) } @@ -75,7 +68,7 @@ const isCurrentUserMarksComplete = ( * @param markToUpdate */ const updateMarks = (marks: Mark[], markToUpdate: Mark): Mark[] => { - const indexToUpdate = marks.findIndex((mark) => mark.id === markToUpdate.id) + const indexToUpdate = marks.findIndex(mark => mark.id === markToUpdate.id); return [ ...marks.slice(0, indexToUpdate), markToUpdate, @@ -83,13 +76,8 @@ const updateMarks = (marks: Mark[], markToUpdate: Mark): Mark[] => { ] } -const updateCurrentUserMarks = ( - currentUserMarks: CurrentUserMark[], - markToUpdate: CurrentUserMark -): CurrentUserMark[] => { - const indexToUpdate = currentUserMarks.findIndex( - (m) => m.mark.id === markToUpdate.mark.id - ) +const updateCurrentUserMarks = (currentUserMarks: CurrentUserMark[], markToUpdate: CurrentUserMark): CurrentUserMark[] => { + const indexToUpdate = currentUserMarks.findIndex((m) => m.mark.id === markToUpdate.mark.id) return [ ...currentUserMarks.slice(0, indexToUpdate), markToUpdate, @@ -97,7 +85,7 @@ const updateCurrentUserMarks = ( ] } -const isLast = (index: number, arr: T[]) => index === arr.length - 1 +const isLast = (index: number, arr: T[]) => (index === (arr.length -1)) export { getCurrentUserMarks, @@ -106,5 +94,5 @@ export { isCurrentUserMarksComplete, findNextCurrentUserMark, updateMarks, - updateCurrentUserMarks + updateCurrentUserMarks, } diff --git a/src/utils/pdf.ts b/src/utils/pdf.ts index 2263737..70b6539 100644 --- a/src/utils/pdf.ts +++ b/src/utils/pdf.ts @@ -3,14 +3,13 @@ import * as PDFJS from 'pdfjs-dist' import { PDFDocument } from 'pdf-lib' import { Mark } from '../types/mark.ts' -PDFJS.GlobalWorkerOptions.workerSrc = - 'node_modules/pdfjs-dist/build/pdf.worker.mjs' +PDFJS.GlobalWorkerOptions.workerSrc = 'node_modules/pdfjs-dist/build/pdf.worker.mjs'; /** * Scale between the PDF page's natural size and rendered size * @constant {number} */ -const SCALE: number = 3 +const SCALE: number = 3; /** * Defined font size used when generating a PDF. Currently it is difficult to fully * correlate font size used at the time of filling in / drawing on the PDF @@ -18,20 +17,20 @@ const SCALE: number = 3 * This should be fixed going forward. * Switching to PDF-Lib will most likely make this problem redundant. */ -const FONT_SIZE: number = 40 +const FONT_SIZE: number = 40; /** * Current font type used when generating a PDF. */ -const FONT_TYPE: string = 'Arial' +const FONT_TYPE: string = 'Arial'; /** * Converts a PDF ArrayBuffer to a generic PDF File * @param arrayBuffer of a PDF * @param fileName identifier of the pdf file */ -const toFile = (arrayBuffer: ArrayBuffer, fileName: string): File => { - const blob = new Blob([arrayBuffer], { type: 'application/pdf' }) - return new File([blob], fileName, { type: 'application/pdf' }) +const toFile = (arrayBuffer: ArrayBuffer, fileName: string) : File => { + const blob = new Blob([arrayBuffer], { type: "application/pdf" }); + return new File([blob], fileName, { type: "application/pdf" }); } /** @@ -51,40 +50,42 @@ const toPdfFile = async (file: File): Promise => { * @return PdfFile[] - an array of Sigit's internal Pdf File type */ const toPdfFiles = async (selectedFiles: File[]): Promise => { - return Promise.all(selectedFiles.filter(isPdf).map(toPdfFile)) + return Promise.all(selectedFiles + .filter(isPdf) + .map(toPdfFile)); } /** * A utility that transforms a drawing coordinate number into a CSS-compatible string * @param coordinate */ -const inPx = (coordinate: number): string => `${coordinate}px` +const inPx = (coordinate: number): string => `${coordinate}px`; /** * A utility that checks if a given file is of the pdf type * @param file */ -const isPdf = (file: File) => file.type.toLowerCase().includes('pdf') +const isPdf = (file: File) => file.type.toLowerCase().includes('pdf'); /** * Reads the pdf file binaries */ const readPdf = (file: File): Promise => { return new Promise((resolve, reject) => { - const reader = new FileReader() + const reader = new FileReader(); reader.onload = (e: any) => { const data = e.target.result resolve(data) - } + }; reader.onerror = (err) => { console.error('err', err) reject(err) - } + }; - reader.readAsDataURL(file) + reader.readAsDataURL(file); }) } @@ -93,28 +94,26 @@ const readPdf = (file: File): Promise => { * @param data pdf file bytes */ const pdfToImages = async (data: any): Promise => { - const images: string[] = [] - const pdf = await PDFJS.getDocument(data).promise - const canvas = document.createElement('canvas') + const images: string[] = []; + const pdf = await PDFJS.getDocument(data).promise; + const canvas = document.createElement("canvas"); for (let i = 0; i < pdf.numPages; i++) { - const page = await pdf.getPage(i + 1) - const viewport = page.getViewport({ scale: SCALE }) - const context = canvas.getContext('2d') - canvas.height = viewport.height - canvas.width = viewport.width - await page.render({ canvasContext: context!, viewport: viewport }).promise - images.push(canvas.toDataURL()) + const page = await pdf.getPage(i + 1); + const viewport = page.getViewport({ scale: SCALE }); + const context = canvas.getContext("2d"); + canvas.height = viewport.height; + canvas.width = viewport.width; + await page.render({ canvasContext: context!, viewport: viewport }).promise; + images.push(canvas.toDataURL()); } - return Promise.resolve( - images.map((image) => { - return { - image, - drawnFields: [] - } - }) - ) + return Promise.resolve(images.map((image) => { + return { + image, + drawnFields: [] + } + })) } /** @@ -122,37 +121,34 @@ const pdfToImages = async (data: any): Promise => { * Returns an array of encoded images where each image is a representation * of a PDF page with completed and signed marks from all users */ -const addMarks = async ( - file: File, - marksPerPage: { [key: string]: Mark[] } -) => { - const p = await readPdf(file) - const pdf = await PDFJS.getDocument(p).promise - const canvas = document.createElement('canvas') +const addMarks = async (file: File, marksPerPage: {[key: string]: Mark[]}) => { + const p = await readPdf(file); + const pdf = await PDFJS.getDocument(p).promise; + const canvas = document.createElement("canvas"); - const images: string[] = [] + const images: string[] = []; - for (let i = 0; i < pdf.numPages; i++) { - const page = await pdf.getPage(i + 1) - const viewport = page.getViewport({ scale: SCALE }) - const context = canvas.getContext('2d') - canvas.height = viewport.height - canvas.width = viewport.width - await page.render({ canvasContext: context!, viewport: viewport }).promise + for (let i = 0; i< pdf.numPages; i++) { + const page = await pdf.getPage(i+1) + const viewport = page.getViewport({ scale: SCALE }); + const context = canvas.getContext("2d"); + canvas.height = viewport.height; + canvas.width = viewport.width; + await page.render({ canvasContext: context!, viewport: viewport }).promise; - marksPerPage[i].forEach((mark) => draw(mark, context!)) + marksPerPage[i].forEach(mark => draw(mark, context!)) - images.push(canvas.toDataURL()) + images.push(canvas.toDataURL()); } - return Promise.resolve(images) + return Promise.resolve(images); } /** * Utility to scale mark in line with the PDF-to-PNG scale */ const scaleMark = (mark: Mark): Mark => { - const { location } = mark + const { location } = mark; return { ...mark, location: { @@ -169,7 +165,7 @@ const scaleMark = (mark: Mark): Mark => { * Utility to check if a Mark has value * @param mark */ -const hasValue = (mark: Mark): boolean => !!mark.value +const hasValue = (mark: Mark): boolean => !!mark.value; /** * Draws a Mark on a Canvas representation of a PDF Page @@ -177,14 +173,14 @@ const hasValue = (mark: Mark): boolean => !!mark.value * @param ctx a Canvas representation of a specific PDF Page */ const draw = (mark: Mark, ctx: CanvasRenderingContext2D) => { - const { location } = mark + const { location } = mark; - ctx!.font = FONT_SIZE + 'px ' + FONT_TYPE - ctx!.fillStyle = 'black' - const textMetrics = ctx!.measureText(mark.value!) - const textX = location.left + (location.width - textMetrics.width) / 2 - const textY = location.top + (location.height + parseInt(ctx!.font)) / 2 - ctx!.fillText(mark.value!, textX, textY) + ctx!.font = FONT_SIZE + 'px ' + FONT_TYPE; + ctx!.fillStyle = 'black'; + const textMetrics = ctx!.measureText(mark.value!); + const textX = location.left + (location.width - textMetrics.width) / 2; + const textY = location.top + (location.height + parseInt(ctx!.font)) / 2; + ctx!.fillText(mark.value!, textX, textY); } /** @@ -192,7 +188,7 @@ const draw = (mark: Mark, ctx: CanvasRenderingContext2D) => { * @param markedPdfPages */ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { - const pdfDoc = await PDFDocument.create() + const pdfDoc = await PDFDocument.create(); for (const page of markedPdfPages) { const pngImage = await pdfDoc.embedPng(page) @@ -207,6 +203,7 @@ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { const pdfBytes = await pdfDoc.save() return new Blob([pdfBytes], { type: 'application/pdf' }) + } /** @@ -214,12 +211,9 @@ const convertToPdfBlob = async (markedPdfPages: string[]): Promise => { * @param arrayBuffer * @param fileName */ -const convertToPdfFile = async ( - arrayBuffer: ArrayBuffer, - fileName: string -): Promise => { - const file = toFile(arrayBuffer, fileName) - return toPdfFile(file) +const convertToPdfFile = async (arrayBuffer: ArrayBuffer, fileName: string): Promise => { + const file = toFile(arrayBuffer, fileName); + return toPdfFile(file); } /** @@ -232,7 +226,7 @@ const groupMarksByPage = (marks: Mark[]) => { return marks .filter(hasValue) .map(scaleMark) - .reduce<{ [key: number]: Mark[] }>(byPage, {}) + .reduce<{[key: number]: Mark[]}>(byPage, {}) } /** @@ -243,10 +237,11 @@ const groupMarksByPage = (marks: Mark[]) => { * @param obj - accumulator in the reducer callback * @param mark - current value, i.e. Mark being examined */ -const byPage = (obj: { [key: number]: Mark[] }, mark: Mark) => { - const key = mark.location.page - const curGroup = obj[key] ?? [] - return { ...obj, [key]: [...curGroup, mark] } +const byPage = (obj: { [key: number]: Mark[]}, mark: Mark) => { + const key = mark.location.page; + const curGroup = obj[key] ?? []; + return { ...obj, [key]: [...curGroup, mark] + } } export { @@ -257,5 +252,5 @@ export { convertToPdfFile, addMarks, convertToPdfBlob, - groupMarksByPage -} + groupMarksByPage, +} \ No newline at end of file diff --git a/src/utils/relays.ts b/src/utils/relays.ts index a3e7a9c..676a59a 100644 --- a/src/utils/relays.ts +++ b/src/utils/relays.ts @@ -5,8 +5,8 @@ import { localCache } from '../services' import { ONE_WEEK_IN_MS, SIGIT_RELAY } from './const.ts' import { RelayMap, RelaySet } from '../types' -const READ_MARKER = 'read' -const WRITE_MARKET = 'write' +const READ_MARKER = "read" +const WRITE_MARKET = "write" /** * Attempts to find a relay list from the provided lookUpRelays. @@ -15,10 +15,7 @@ const WRITE_MARKET = 'write' * @param hexKey * @return found relay list or null */ -const findRelayListAndUpdateCache = async ( - lookUpRelays: string[], - hexKey: string -): Promise => { +const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: string): Promise => { try { const eventFilter: Filter = { kinds: [RelayList], @@ -45,14 +42,10 @@ const findRelayListAndUpdateCache = async ( const findRelayListInCache = async (hexKey: string): Promise => { try { // Attempt to retrieve the metadata event from the local cache - const cachedRelayListMetadataEvent = - await localCache.getUserRelayListMetadata(hexKey) + const cachedRelayListMetadataEvent = await localCache.getUserRelayListMetadata(hexKey) // Check if the cached event is not older than one week - if ( - cachedRelayListMetadataEvent && - isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt) - ) { + if (cachedRelayListMetadataEvent && isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt)) { return cachedRelayListMetadataEvent.event } @@ -111,5 +104,5 @@ export { findRelayListInCache, getUserRelaySet, getDefaultRelaySet, - getDefaultRelayMap -} + getDefaultRelayMap, +} \ No newline at end of file diff --git a/src/utils/sign.ts b/src/utils/sign.ts index 3369c54..7b2dd84 100644 --- a/src/utils/sign.ts +++ b/src/utils/sign.ts @@ -5,10 +5,7 @@ import { Meta } from '../types' * This function returns the signature of last signer * It will be used in the content of export signature's signedEvent */ -const getLastSignersSig = ( - meta: Meta, - signers: `npub1${string}`[] -): string | null => { +const getLastSignersSig = (meta: Meta, signers: `npub1${string}`[]): string | null => { // if there're no signers then use creator's signature if (signers.length === 0) { try { @@ -24,11 +21,13 @@ const getLastSignersSig = ( // get the signature of last signer try { - const lastSignatureEvent: Event = JSON.parse(meta.docSignatures[lastSigner]) + const lastSignatureEvent: Event = JSON.parse( + meta.docSignatures[lastSigner] + ) return lastSignatureEvent.sig } catch (error) { return null } } -export { getLastSignersSig } +export { getLastSignersSig } \ No newline at end of file diff --git a/src/utils/utils.ts b/src/utils/utils.ts index e68e687..ed830a2 100644 --- a/src/utils/utils.ts +++ b/src/utils/utils.ts @@ -73,9 +73,9 @@ export const timeout = (ms: number = 60000) => { * @param fileHashes */ export const getFilesWithHashes = ( - files: { [filename: string]: PdfFile }, + files: { [filename: string ]: PdfFile }, fileHashes: { [key: string]: string | null } -) => { + ) => { return Object.entries(files).map(([filename, pdfFile]) => { return { pdfFile, filename, hash: fileHashes[filename] } }) diff --git a/src/utils/zip.ts b/src/utils/zip.ts index 7a7a49f..2d33aa5 100644 --- a/src/utils/zip.ts +++ b/src/utils/zip.ts @@ -36,12 +36,17 @@ const readContentOfZipEntry = async ( const loadZip = async (data: InputFileFormat): Promise => { try { - return await JSZip.loadAsync(data) + return await JSZip.loadAsync(data); } catch (err: any) { console.log('err in loading zip file :>> ', err) toast.error(err.message || 'An error occurred in loading zip file.') - return null + return null; } } -export { readContentOfZipEntry, loadZip } +export { + readContentOfZipEntry, + loadZip +} + + From 2acb353535ad88b672946550067638d7b0a09b03 Mon Sep 17 00:00:00 2001 From: Eugene Date: Wed, 7 Aug 2024 18:24:12 +0300 Subject: [PATCH 6/6] refactor: post-PR review changes --- src/controllers/MetadataController.ts | 24 ++++++++++++++---------- src/utils/relays.ts | 22 +++++++++++++++------- 2 files changed, 29 insertions(+), 17 deletions(-) diff --git a/src/controllers/MetadataController.ts b/src/controllers/MetadataController.ts index e2f6852..2360275 100644 --- a/src/controllers/MetadataController.ts +++ b/src/controllers/MetadataController.ts @@ -20,7 +20,8 @@ import { findRelayListAndUpdateCache, findRelayListInCache, getDefaultRelaySet, - getUserRelaySet + getUserRelaySet, + isOlderThanOneWeek } from '../utils/relays.ts' export class MetadataController extends EventEmitter { @@ -133,10 +134,8 @@ export class MetadataController extends EventEmitter { // If cached metadata is found, check its validity if (cachedMetadataEvent) { - const oneWeekInMS = 7 * 24 * 60 * 60 * 1000 // Number of milliseconds in one week - // Check if the cached metadata is older than one week - if (Date.now() - cachedMetadataEvent.cachedAt > oneWeekInMS) { + if (isOlderThanOneWeek(cachedMetadataEvent.cachedAt)) { // If older than one week, find the metadata from relays in background this.checkForMoreRecentMetadata(hexKey, cachedMetadataEvent.event) @@ -164,13 +163,18 @@ export class MetadataController extends EventEmitter { * or a fallback RelaySet with Sigit's Relay */ public findRelayListMetadata = async (hexKey: string): Promise => { - const relayEvent = await findRelayListInCache(hexKey) - || await findRelayListAndUpdateCache([this.specialMetadataRelay], hexKey) - || await findRelayListAndUpdateCache(await this.nostrController.getMostPopularRelays(), hexKey) + const relayEvent = + (await findRelayListInCache(hexKey)) || + (await findRelayListAndUpdateCache( + [this.specialMetadataRelay], + hexKey + )) || + (await findRelayListAndUpdateCache( + await this.nostrController.getMostPopularRelays(), + hexKey + )) - return relayEvent - ? getUserRelaySet(relayEvent.tags) - : getDefaultRelaySet() + return relayEvent ? getUserRelaySet(relayEvent.tags) : getDefaultRelaySet() } public extractProfileMetadataContent = (event: Event) => { diff --git a/src/utils/relays.ts b/src/utils/relays.ts index 676a59a..a7a8227 100644 --- a/src/utils/relays.ts +++ b/src/utils/relays.ts @@ -5,8 +5,8 @@ import { localCache } from '../services' import { ONE_WEEK_IN_MS, SIGIT_RELAY } from './const.ts' import { RelayMap, RelaySet } from '../types' -const READ_MARKER = "read" -const WRITE_MARKET = "write" +const READ_MARKER = 'read' +const WRITE_MARKER = 'write' /** * Attempts to find a relay list from the provided lookUpRelays. @@ -15,7 +15,10 @@ const WRITE_MARKET = "write" * @param hexKey * @return found relay list or null */ -const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: string): Promise => { +const findRelayListAndUpdateCache = async ( + lookUpRelays: string[], + hexKey: string +): Promise => { try { const eventFilter: Filter = { kinds: [RelayList], @@ -42,10 +45,14 @@ const findRelayListAndUpdateCache = async (lookUpRelays: string[], hexKey: strin const findRelayListInCache = async (hexKey: string): Promise => { try { // Attempt to retrieve the metadata event from the local cache - const cachedRelayListMetadataEvent = await localCache.getUserRelayListMetadata(hexKey) + const cachedRelayListMetadataEvent = + await localCache.getUserRelayListMetadata(hexKey) // Check if the cached event is not older than one week - if (cachedRelayListMetadataEvent && isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt)) { + if ( + cachedRelayListMetadataEvent && + isOlderThanOneWeek(cachedRelayListMetadataEvent.cachedAt) + ) { return cachedRelayListMetadataEvent.event } @@ -87,7 +94,7 @@ const toRelaySet = (obj: RelaySet, tag: string[]): RelaySet => { if (marker === READ_MARKER) { obj.read.push(tag[1]) - } else if (marker === WRITE_MARKET) { + } else if (marker === WRITE_MARKER) { obj.write.push(tag[1]) } } @@ -105,4 +112,5 @@ export { getUserRelaySet, getDefaultRelaySet, getDefaultRelayMap, -} \ No newline at end of file + isOlderThanOneWeek +}