Release to main #216

Merged
b merged 23 commits from staging into main 2024-10-01 20:19:09 +00:00
2 changed files with 81 additions and 90 deletions
Showing only changes of commit e05d3e53a2 - Show all commits

View File

@ -11,17 +11,16 @@ import styles from './style.module.scss'
import React, { useEffect, useState } from 'react' import React, { useEffect, useState } from 'react'
import { ProfileMetadata, User, UserRole } from '../../types' import { ProfileMetadata, User, UserRole } from '../../types'
import { MouseState, PdfPage, DrawnField, DrawTool } from '../../types/drawing' import { MouseState, PdfPage, DrawnField, DrawTool } from '../../types/drawing'
import { truncate } from 'lodash' import { hexToNpub, npubToHex, getProfileUsername } from '../../utils'
import { settleAllFullfilfedPromises, hexToNpub, npubToHex } from '../../utils' import { SigitFile } from '../../utils/file'
import { getSigitFile, SigitFile } from '../../utils/file'
import { getToolboxLabelByMarkType } from '../../utils/mark' import { getToolboxLabelByMarkType } from '../../utils/mark'
import { FileDivider } from '../FileDivider' import { FileDivider } from '../FileDivider'
import { ExtensionFileBox } from '../ExtensionFileBox' import { ExtensionFileBox } from '../ExtensionFileBox'
import { FONT_SIZE, FONT_TYPE, inPx } from '../../utils/pdf' import { FONT_SIZE, FONT_TYPE, inPx } from '../../utils/pdf'
import { useScale } from '../../hooks/useScale' import { useScale } from '../../hooks/useScale'
import { AvatarIconButton } from '../UserAvatarIconButton' import { AvatarIconButton } from '../UserAvatarIconButton'
import { LoadingSpinner } from '../LoadingSpinner'
import { UserAvatar } from '../UserAvatar' import { UserAvatar } from '../UserAvatar'
import _ from 'lodash'
const DEFAULT_START_SIZE = { const DEFAULT_START_SIZE = {
width: 140, width: 140,
@ -29,22 +28,32 @@ const DEFAULT_START_SIZE = {
} as const } as const
interface Props { interface Props {
selectedFiles: File[]
users: User[] users: User[]
metadata: { [key: string]: ProfileMetadata } metadata: { [key: string]: ProfileMetadata }
onDrawFieldsChange: (sigitFiles: SigitFile[]) => void sigitFiles: SigitFile[]
setSigitFiles: React.Dispatch<React.SetStateAction<SigitFile[]>>
selectedTool?: DrawTool selectedTool?: DrawTool
} }
export const DrawPDFFields = (props: Props) => { export const DrawPDFFields = (props: Props) => {
const { selectedFiles, selectedTool, onDrawFieldsChange, users } = props const { selectedTool, sigitFiles, setSigitFiles, users } = props
const signers = users.filter((u) => u.role === UserRole.signer) const signers = users.filter((u) => u.role === UserRole.signer)
const defaultSignerNpub = signers.length ? hexToNpub(signers[0].pubkey) : '' const defaultSignerNpub = signers.length ? hexToNpub(signers[0].pubkey) : ''
const [lastSigner, setLastSigner] = useState(defaultSignerNpub) const [lastSigner, setLastSigner] = useState(defaultSignerNpub)
const { to, from } = useScale() /**
* Return first pubkey that is present in the signers list
* @param pubkeys
* @returns available pubkey or empty string
*/
const getAvailableSigner = (...pubkeys: string[]) => {
const availableSigner: string | undefined = pubkeys.find((pubkey) =>
signers.some((s) => s.pubkey === npubToHex(pubkey))
)
return availableSigner || ''
}
const [sigitFiles, setSigitFiles] = useState<SigitFile[]>([]) const { to, from } = useScale()
const [parsingPdf, setIsParsing] = useState<boolean>(false)
const [mouseState, setMouseState] = useState<MouseState>({ const [mouseState, setMouseState] = useState<MouseState>({
clicked: false clicked: false
@ -64,33 +73,6 @@ export const DrawPDFFields = (props: Props) => {
activeDrawnField?.pageIndex === pageIndex && activeDrawnField?.pageIndex === pageIndex &&
activeDrawnField?.drawnFieldIndex === drawnFieldIndex activeDrawnField?.drawnFieldIndex === drawnFieldIndex
useEffect(() => {
if (selectedFiles) {
/**
* Reads the binary files and converts to internal file type
* and sets to a state (adds images if it's a PDF)
*/
const parsePages = async () => {
const files = await settleAllFullfilfedPromises(
selectedFiles,
getSigitFile
)
setSigitFiles(files)
}
setIsParsing(true)
parsePages().finally(() => {
setIsParsing(false)
})
}
}, [selectedFiles])
useEffect(() => {
if (sigitFiles) onDrawFieldsChange(sigitFiles)
}, [onDrawFieldsChange, sigitFiles])
/** /**
* Drawing events * Drawing events
*/ */
@ -136,7 +118,7 @@ export const DrawPDFFields = (props: Props) => {
top: to(page.width, y), top: to(page.width, y),
width: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.width, width: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.width,
height: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.height, height: event.pointerType === 'mouse' ? 0 : DEFAULT_START_SIZE.height,
counterpart: lastSigner, counterpart: getAvailableSigner(lastSigner, defaultSignerNpub),
type: selectedTool.identifier type: selectedTool.identifier
} }
@ -518,7 +500,7 @@ export const DrawPDFFields = (props: Props) => {
<FormControl fullWidth size="small"> <FormControl fullWidth size="small">
<InputLabel id="counterparts">Counterpart</InputLabel> <InputLabel id="counterparts">Counterpart</InputLabel>
<Select <Select
value={drawnField.counterpart} value={getAvailableSigner(drawnField.counterpart)}
onChange={(event) => { onChange={(event) => {
drawnField.counterpart = event.target.value drawnField.counterpart = event.target.value
setLastSigner(event.target.value) setLastSigner(event.target.value)
@ -535,23 +517,11 @@ export const DrawPDFFields = (props: Props) => {
> >
{signers.map((signer, index) => { {signers.map((signer, index) => {
const npub = hexToNpub(signer.pubkey) const npub = hexToNpub(signer.pubkey)
let displayValue = truncate(npub, {
length: 16
})
const metadata = props.metadata[signer.pubkey] const metadata = props.metadata[signer.pubkey]
const displayValue = getProfileUsername(
if (metadata) { npub,
displayValue = truncate( metadata
metadata.name || )
metadata.display_name ||
metadata.username ||
npub,
{
length: 16
}
)
}
return ( return (
<MenuItem key={index} value={npub}> <MenuItem key={index} value={npub}>
@ -589,24 +559,15 @@ export const DrawPDFFields = (props: Props) => {
} }
const renderCounterpartValue = (npub: string) => { const renderCounterpartValue = (npub: string) => {
let displayValue = truncate(npub, { let displayValue = _.truncate(npub, { length: 16 })
length: 16
})
const signer = signers.find((u) => u.pubkey === npubToHex(npub)) const signer = signers.find((u) => u.pubkey === npubToHex(npub))
if (signer) { if (signer) {
const metadata = props.metadata[signer.pubkey] const metadata = props.metadata[signer.pubkey]
if (metadata) { displayValue = getProfileUsername(npub, metadata)
displayValue = truncate(
metadata.display_name || metadata.name || npub,
{
length: 16
}
)
}
return ( return (
<> <div className={styles.counterpartSelectValue}>
<AvatarIconButton <AvatarIconButton
src={props.metadata[signer.pubkey]?.picture} src={props.metadata[signer.pubkey]?.picture}
hexKey={signer.pubkey || undefined} hexKey={signer.pubkey || undefined}
@ -620,21 +581,13 @@ export const DrawPDFFields = (props: Props) => {
}} }}
/> />
{displayValue} {displayValue}
</> </div>
) )
} }
return displayValue return displayValue
} }
if (parsingPdf) {
return <LoadingSpinner variant="small" />
}
if (!sigitFiles.length) {
return ''
}
return ( return (
<div className="files-wrapper"> <div className="files-wrapper">
{sigitFiles.map((file, i) => { {sigitFiles.map((file, i) => {
@ -653,7 +606,7 @@ export const DrawPDFFields = (props: Props) => {
<ExtensionFileBox extension={file.extension} /> <ExtensionFileBox extension={file.extension} />
)} )}
</div> </div>
{i < selectedFiles.length - 1 && <FileDivider />} {i < sigitFiles.length - 1 && <FileDivider />}
</React.Fragment> </React.Fragment>
) )
})} })}

View File

@ -39,7 +39,8 @@ import {
signEventForMetaFile, signEventForMetaFile,
updateUsersAppData, updateUsersAppData,
uploadToFileStorage, uploadToFileStorage,
DEFAULT_TOOLBOX DEFAULT_TOOLBOX,
settleAllFullfilfedPromises
} from '../../utils' } from '../../utils'
import { Container } from '../../components/Container' import { Container } from '../../components/Container'
import fileListStyles from '../../components/FileList/style.module.scss' import fileListStyles from '../../components/FileList/style.module.scss'
@ -60,7 +61,8 @@ import {
faTrash, faTrash,
faUpload faUpload
} from '@fortawesome/free-solid-svg-icons' } from '@fortawesome/free-solid-svg-icons'
import { SigitFile } from '../../utils/file.ts' import { getSigitFile, SigitFile } from '../../utils/file.ts'
import _ from 'lodash'
export const CreatePage = () => { export const CreatePage = () => {
const navigate = useNavigate() const navigate = useNavigate()
@ -106,6 +108,29 @@ export const CreatePage = () => {
{} {}
) )
const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([]) const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
const [parsingPdf, setIsParsing] = useState<boolean>(false)
useEffect(() => {
if (selectedFiles) {
/**
* Reads the binary files and converts to internal file type
* and sets to a state (adds images if it's a PDF)
*/
const parsePages = async () => {
const files = await settleAllFullfilfedPromises(
selectedFiles,
getSigitFile
)
setDrawnFiles(files)
}
setIsParsing(true)
parsePages().finally(() => {
setIsParsing(false)
})
}
}, [selectedFiles])
const [selectedTool, setSelectedTool] = useState<DrawTool>() const [selectedTool, setSelectedTool] = useState<DrawTool>()
@ -281,6 +306,19 @@ export const CreatePage = () => {
const handleRemoveUser = (pubkey: string) => { const handleRemoveUser = (pubkey: string) => {
setUsers((prev) => prev.filter((user) => user.pubkey !== pubkey)) setUsers((prev) => prev.filter((user) => user.pubkey !== pubkey))
// Set counterpart to ''
const drawnFilesCopy = _.cloneDeep(drawnFiles)
drawnFilesCopy.forEach((s) => {
s.pages?.forEach((p) => {
p.drawnFields.forEach((d) => {
if (d.counterpart === hexToNpub(pubkey)) {
d.counterpart = ''
}
})
})
})
setDrawnFiles(drawnFilesCopy)
} }
/** /**
@ -723,10 +761,6 @@ export const CreatePage = () => {
} }
} }
const onDrawFieldsChange = (sigitFiles: SigitFile[]) => {
setDrawnFiles(sigitFiles)
}
if (authUrl) { if (authUrl) {
return ( return (
<iframe <iframe
@ -885,13 +919,17 @@ export const CreatePage = () => {
centerIcon={faFile} centerIcon={faFile}
rightIcon={faToolbox} rightIcon={faToolbox}
> >
<DrawPDFFields {parsingPdf ? (
metadata={metadata} <LoadingSpinner variant="small" />
users={users} ) : (
selectedFiles={selectedFiles} <DrawPDFFields
onDrawFieldsChange={onDrawFieldsChange} users={users}
selectedTool={selectedTool} metadata={metadata}
/> selectedTool={selectedTool}
sigitFiles={drawnFiles}
setSigitFiles={setDrawnFiles}
/>
)}
</StickySideColumns> </StickySideColumns>
</Container> </Container>
</> </>