Responsiveness and tabs #179
@ -1,7 +1,5 @@
|
||||
import { Close } from '@mui/icons-material'
|
||||
import {
|
||||
Box,
|
||||
CircularProgress,
|
||||
FormControl,
|
||||
InputLabel,
|
||||
ListItemIcon,
|
||||
@ -22,6 +20,7 @@ import { ExtensionFileBox } from '../ExtensionFileBox'
|
||||
import { inPx } from '../../utils/pdf'
|
||||
import { useScale } from '../../hooks/useScale'
|
||||
import { AvatarIconButton } from '../UserAvatarIconButton'
|
||||
import { LoadingSpinner } from '../LoadingSpinner'
|
||||
|
||||
PDFJS.GlobalWorkerOptions.workerSrc = new URL(
|
||||
'pdfjs-dist/build/pdf.worker.min.mjs',
|
||||
@ -530,11 +529,7 @@ export const DrawPDFFields = (props: Props) => {
|
||||
}
|
||||
|
||||
if (parsingPdf) {
|
||||
return (
|
||||
<Box sx={{ width: '100%', textAlign: 'center' }}>
|
||||
<CircularProgress />
|
||||
</Box>
|
||||
)
|
||||
return <LoadingSpinner variant="small" />
|
||||
}
|
||||
|
||||
if (!sigitFiles.length) {
|
||||
|
@ -1,18 +1,31 @@
|
||||
import styles from './style.module.scss'
|
||||
|
||||
interface Props {
|
||||
desc: string
|
||||
desc?: string
|
||||
variant?: 'small' | 'default'
|
||||
}
|
||||
|
||||
export const LoadingSpinner = (props: Props) => {
|
||||
const { desc } = props
|
||||
const { desc, variant = 'default' } = props
|
||||
|
||||
return (
|
||||
<div className={styles.loadingSpinnerOverlay}>
|
||||
<div className={styles.loadingSpinnerContainer}>
|
||||
<div className={styles.loadingSpinner}></div>
|
||||
{desc && <span className={styles.loadingSpinnerDesc}>{desc}</span>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
switch (variant) {
|
||||
case 'small':
|
||||
return (
|
||||
<div
|
||||
className={`${styles.loadingSpinnerContainer} ${styles.withHeight}`}
|
||||
>
|
||||
<div className={styles.loadingSpinner}></div>
|
||||
</div>
|
||||
)
|
||||
|
||||
default:
|
||||
return (
|
||||
<div className={styles.loadingSpinnerOverlay}>
|
||||
<div className={styles.loadingSpinnerContainer}>
|
||||
<div className={styles.loadingSpinner}></div>
|
||||
{desc && <span className={styles.loadingSpinnerDesc}>{desc}</span>}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -11,22 +11,26 @@
|
||||
justify-content: center;
|
||||
background-color: rgba(0, 0, 0, 0.5);
|
||||
z-index: 9999;
|
||||
}
|
||||
|
||||
.loadingSpinnerContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
}
|
||||
.loadingSpinnerContainer {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
|
||||
.loadingSpinner {
|
||||
background: url('/favicon.png') no-repeat center / cover;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
&.withHeight {
|
||||
min-height: 250px;
|
||||
}
|
||||
}
|
||||
|
||||
.loadingSpinner {
|
||||
background: url('/favicon.png') no-repeat center / cover;
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
animation: spin 1s linear infinite;
|
||||
}
|
||||
|
||||
.loadingSpinnerDesc {
|
||||
color: white;
|
||||
margin-top: 13px;
|
||||
|
@ -4,6 +4,7 @@ import { CurrentUserFile } from '../../types/file.ts'
|
||||
import { useEffect, useRef } from 'react'
|
||||
import { FileDivider } from '../FileDivider.tsx'
|
||||
import React from 'react'
|
||||
import { LoadingSpinner } from '../LoadingSpinner/index.tsx'
|
||||
|
||||
interface PdfViewProps {
|
||||
currentFile: CurrentUserFile | null
|
||||
@ -48,30 +49,34 @@ const PdfView = ({
|
||||
index !== files.length - 1
|
||||
return (
|
||||
<div className="files-wrapper">
|
||||
{files.map((currentUserFile, index, arr) => {
|
||||
const { hash, file, id } = currentUserFile
|
||||
{files.length > 0 ? (
|
||||
files.map((currentUserFile, index, arr) => {
|
||||
const { hash, file, id } = currentUserFile
|
||||
|
||||
if (!hash) return
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<div
|
||||
id={file.name}
|
||||
className="file-wrapper"
|
||||
ref={(el) => (pdfRefs.current[id] = el)}
|
||||
>
|
||||
<PdfItem
|
||||
file={file}
|
||||
currentUserMarks={filterByFile(currentUserMarks, hash)}
|
||||
selectedMark={selectedMark}
|
||||
handleMarkClick={handleMarkClick}
|
||||
selectedMarkValue={selectedMarkValue}
|
||||
otherUserMarks={filterMarksByFile(otherUserMarks, hash)}
|
||||
/>
|
||||
</div>
|
||||
{isNotLastPdfFile(index, arr) && <FileDivider />}
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
if (!hash) return
|
||||
return (
|
||||
<React.Fragment key={index}>
|
||||
<div
|
||||
id={file.name}
|
||||
className="file-wrapper"
|
||||
ref={(el) => (pdfRefs.current[id] = el)}
|
||||
>
|
||||
<PdfItem
|
||||
file={file}
|
||||
currentUserMarks={filterByFile(currentUserMarks, hash)}
|
||||
selectedMark={selectedMark}
|
||||
handleMarkClick={handleMarkClick}
|
||||
selectedMarkValue={selectedMarkValue}
|
||||
otherUserMarks={filterMarksByFile(otherUserMarks, hash)}
|
||||
/>
|
||||
</div>
|
||||
{isNotLastPdfFile(index, arr) && <FileDivider />}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<LoadingSpinner variant="small" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
@ -79,74 +79,80 @@ const SlimPdfView = ({
|
||||
}, [currentFile])
|
||||
return (
|
||||
<div className="files-wrapper">
|
||||
{files.map((currentUserFile, i) => {
|
||||
const { hash, file, id } = currentUserFile
|
||||
const signatureEvents = Object.keys(parsedSignatureEvents)
|
||||
if (!hash) return
|
||||
return (
|
||||
<React.Fragment key={file.name}>
|
||||
<div
|
||||
id={file.name}
|
||||
ref={(el) => (pdfRefs.current[id] = el)}
|
||||
className="file-wrapper"
|
||||
>
|
||||
{file.isPdf &&
|
||||
file.pages?.map((page, i) => {
|
||||
const marks: Mark[] = []
|
||||
{files.length > 0 ? (
|
||||
files.map((currentUserFile, i) => {
|
||||
const { hash, file, id } = currentUserFile
|
||||
const signatureEvents = Object.keys(parsedSignatureEvents)
|
||||
if (!hash) return
|
||||
return (
|
||||
<React.Fragment key={file.name}>
|
||||
<div
|
||||
id={file.name}
|
||||
ref={(el) => (pdfRefs.current[id] = el)}
|
||||
className="file-wrapper"
|
||||
>
|
||||
{file.isPdf &&
|
||||
file.pages?.map((page, i) => {
|
||||
const marks: Mark[] = []
|
||||
|
||||
signatureEvents.forEach((e) => {
|
||||
const m = parsedSignatureEvents[
|
||||
e as `npub1${string}`
|
||||
].parsedContent?.marks.filter(
|
||||
(m) => m.pdfFileHash == hash && m.location.page == i
|
||||
signatureEvents.forEach((e) => {
|
||||
const m = parsedSignatureEvents[
|
||||
e as `npub1${string}`
|
||||
].parsedContent?.marks.filter(
|
||||
(m) => m.pdfFileHash == hash && m.location.page == i
|
||||
)
|
||||
if (m) {
|
||||
marks.push(...m)
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div className="image-wrapper" key={i}>
|
||||
<img
|
||||
draggable="false"
|
||||
src={page.image}
|
||||
alt={`page ${i} of ${file.name}`}
|
||||
/>
|
||||
{marks.map((m) => {
|
||||
return (
|
||||
<div
|
||||
className={`file-mark ${styles.mark}`}
|
||||
key={m.id}
|
||||
style={{
|
||||
left: inPx(from(page.width, m.location.left)),
|
||||
top: inPx(from(page.width, m.location.top)),
|
||||
width: inPx(from(page.width, m.location.width)),
|
||||
height: inPx(
|
||||
from(page.width, m.location.height)
|
||||
),
|
||||
fontFamily: FONT_TYPE,
|
||||
fontSize: inPx(from(page.width, FONT_SIZE))
|
||||
}}
|
||||
>
|
||||
{m.value}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
if (m) {
|
||||
marks.push(...m)
|
||||
}
|
||||
})
|
||||
return (
|
||||
<div className="image-wrapper" key={i}>
|
||||
<img
|
||||
draggable="false"
|
||||
src={page.image}
|
||||
alt={`page ${i} of ${file.name}`}
|
||||
/>
|
||||
{marks.map((m) => {
|
||||
return (
|
||||
<div
|
||||
className={`file-mark ${styles.mark}`}
|
||||
key={m.id}
|
||||
style={{
|
||||
left: inPx(from(page.width, m.location.left)),
|
||||
top: inPx(from(page.width, m.location.top)),
|
||||
width: inPx(from(page.width, m.location.width)),
|
||||
height: inPx(from(page.width, m.location.height)),
|
||||
fontFamily: FONT_TYPE,
|
||||
fontSize: inPx(from(page.width, FONT_SIZE))
|
||||
}}
|
||||
>
|
||||
{m.value}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
{file.isImage && (
|
||||
<img
|
||||
className="file-image"
|
||||
src={file.objectUrl}
|
||||
alt={file.name}
|
||||
/>
|
||||
)}
|
||||
{!(file.isPdf || file.isImage) && (
|
||||
<ExtensionFileBox extension={file.extension} />
|
||||
)}
|
||||
</div>
|
||||
{i < files.length - 1 && <FileDivider />}
|
||||
</React.Fragment>
|
||||
)
|
||||
})}
|
||||
})}
|
||||
{file.isImage && (
|
||||
<img
|
||||
className="file-image"
|
||||
src={file.objectUrl}
|
||||
alt={file.name}
|
||||
/>
|
||||
)}
|
||||
{!(file.isPdf || file.isImage) && (
|
||||
<ExtensionFileBox extension={file.extension} />
|
||||
)}
|
||||
</div>
|
||||
{i < files.length - 1 && <FileDivider />}
|
||||
</React.Fragment>
|
||||
)
|
||||
})
|
||||
) : (
|
||||
<LoadingSpinner variant="small" />
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user