From 92b62a3cbed8461cbbb25cb841bec9063f11e90d Mon Sep 17 00:00:00 2001 From: SwiftHawk Date: Thu, 13 Jun 2024 11:47:28 +0500 Subject: [PATCH] feat: navigate to different pages based on uploaded file --- src/pages/create/index.tsx | 11 ++++++- src/pages/home/index.tsx | 60 ++++++++++++++++++++++++++++++++++++-- src/pages/sign/index.tsx | 20 +++++++++++-- src/pages/verify/index.tsx | 13 +++++++-- 4 files changed, 96 insertions(+), 8 deletions(-) diff --git a/src/pages/create/index.tsx b/src/pages/create/index.tsx index 24538fb..84ad3bf 100644 --- a/src/pages/create/index.tsx +++ b/src/pages/create/index.tsx @@ -22,7 +22,7 @@ import JSZip from 'jszip' import { MuiFileInput } from 'mui-file-input' import { useEffect, useRef, useState } from 'react' import { useSelector } from 'react-redux' -import { useNavigate } from 'react-router-dom' +import { useLocation, useNavigate } from 'react-router-dom' import { toast } from 'react-toastify' import { LoadingSpinner } from '../../components/LoadingSpinner' import { UserComponent } from '../../components/username' @@ -54,6 +54,9 @@ import { Event, kinds } from 'nostr-tools' export const CreatePage = () => { const navigate = useNavigate() + const location = useLocation() + const { uploadedFile } = location.state || {} + const [isLoading, setIsLoading] = useState(false) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('') @@ -72,6 +75,12 @@ export const CreatePage = () => { const nostrController = NostrController.getInstance() + useEffect(() => { + if (uploadedFile) { + setSelectedFiles([uploadedFile]) + } + }, [uploadedFile]) + useEffect(() => { if (usersPubkey) { setUsers((prev) => { diff --git a/src/pages/home/index.tsx b/src/pages/home/index.tsx index 9cf4508..181b67d 100644 --- a/src/pages/home/index.tsx +++ b/src/pages/home/index.tsx @@ -7,11 +7,61 @@ import { } from '@mui/icons-material' import { Box, Button, Tooltip, Typography } from '@mui/material' import { useNavigate } from 'react-router-dom' -import { appPrivateRoutes } from '../../routes' +import { appPrivateRoutes, appPublicRoutes } from '../../routes' import styles from './style.module.scss' +import { useRef } from 'react' +import JSZip from 'jszip' +import { toast } from 'react-toastify' export const HomePage = () => { const navigate = useNavigate() + const fileInputRef = useRef(null) + + const handleUploadClick = () => { + if (fileInputRef.current) { + fileInputRef.current.click() + } + } + + const handleFileChange = async ( + event: React.ChangeEvent + ) => { + const file = event.target.files?.[0] + if (file) { + // Check if the file extension is .sigit.zip + const fileName = file.name + const fileExtension = fileName.slice(-10) // ".sigit.zip" has 10 characters + if (fileExtension === '.sigit.zip') { + const zip = await JSZip.loadAsync(file).catch((err) => { + console.log('err in loading zip file :>> ', err) + toast.error(err.message || 'An error occurred in loading zip file.') + return null + }) + + if (!zip) return + + // navigate to sign page if zip contains keys.json + if ('keys.json' in zip.files) { + return navigate(appPrivateRoutes.sign, { + state: { uploadedZip: file } + }) + } + + // navigate to verify page if zip contains meta.json + if ('meta.json' in zip.files) { + return navigate(appPublicRoutes.verify, { + state: { uploadedZip: file } + }) + } + + toast.error('Invalid zip file') + return + } + + // navigate to create page + navigate(appPrivateRoutes.create, { state: { uploadedFile: file } }) + } + } return ( @@ -29,10 +79,16 @@ export const HomePage = () => { } }} > + diff --git a/src/pages/sign/index.tsx b/src/pages/sign/index.tsx index 2a8ca9a..b49d11e 100644 --- a/src/pages/sign/index.tsx +++ b/src/pages/sign/index.tsx @@ -40,7 +40,8 @@ enum SignedStatus { export const SignPage = () => { const navigate = useNavigate() const location = useLocation() - const { arrayBuffer: decryptedArrayBuffer } = location.state || {} + const { arrayBuffer: decryptedArrayBuffer, uploadedZip } = + location.state || {} const [searchParams, setSearchParams] = useSearchParams() @@ -200,11 +201,23 @@ export const SignPage = () => { handleDecryptedArrayBuffer(decryptedArrayBuffer).finally(() => setIsLoading(false) ) + } else if (uploadedZip) { + decrypt(uploadedZip) + .then((arrayBuffer) => { + if (arrayBuffer) handleDecryptedArrayBuffer(arrayBuffer) + }) + .catch((err) => { + console.error(`error occurred in decryption`, err) + toast.error(err.message || `error occurred in decryption`) + }) + .finally(() => { + setIsLoading(false) + }) } else { setIsLoading(false) setDisplayInput(true) } - }, [searchParams, decryptedArrayBuffer]) + }, [searchParams, decryptedArrayBuffer, uploadedZip]) const parseKeysJson = async (zip: JSZip) => { const keysFileContent = await readContentOfZipEntry( @@ -768,7 +781,8 @@ export const SignPage = () => { if (!arrayBuffer) return const blob = new Blob([arrayBuffer]) - saveAs(blob, 'exported.zip') + const unixNow = Math.floor(Date.now() / 1000) + saveAs(blob, `exported-${unixNow}.sigit.zip`) setIsLoading(false) diff --git a/src/pages/verify/index.tsx b/src/pages/verify/index.tsx index a8e0d1f..53aea4a 100644 --- a/src/pages/verify/index.tsx +++ b/src/pages/verify/index.tsx @@ -32,14 +32,17 @@ import { } from '../../utils' import styles from './style.module.scss' import { Cancel, CheckCircle } from '@mui/icons-material' +import { useLocation } from 'react-router-dom' export const VerifyPage = () => { const theme = useTheme() - const textColor = theme.palette.getContrastText( theme.palette.background.paper ) + const location = useLocation() + const { uploadedZip } = location.state || {} + const [isLoading, setIsLoading] = useState(false) const [loadingSpinnerDesc, setLoadingSpinnerDesc] = useState('') @@ -62,6 +65,12 @@ export const VerifyPage = () => { {} ) + useEffect(() => { + if (uploadedZip) { + setSelectedFile(uploadedZip) + } + }, [uploadedZip]) + useEffect(() => { if (zip) { const generateCurrentFileHashes = async () => { @@ -364,7 +373,7 @@ export const VerifyPage = () => { onChange={(value) => setSelectedFile(value)} InputProps={{ inputProps: { - accept: '.zip' + accept: '.sigit.zip' } }} />