Compare commits
No commits in common. "2e1d48168a93471cae72db9c5c78287809b23f58" and "9bae5b9ba236ac1119ca6715ff04e8c346718a5d" have entirely different histories.
2e1d48168a
...
9bae5b9ba2
@ -28,9 +28,9 @@ import {
|
|||||||
} from '../../routes'
|
} from '../../routes'
|
||||||
import {
|
import {
|
||||||
clearAuthToken,
|
clearAuthToken,
|
||||||
getProfileUsername,
|
|
||||||
hexToNpub,
|
hexToNpub,
|
||||||
saveNsecBunkerDelegatedKey
|
saveNsecBunkerDelegatedKey,
|
||||||
|
shorten
|
||||||
} from '../../utils'
|
} from '../../utils'
|
||||||
import styles from './style.module.scss'
|
import styles from './style.module.scss'
|
||||||
import { setUserRobotImage } from '../../store/userRobotImage/action'
|
import { setUserRobotImage } from '../../store/userRobotImage/action'
|
||||||
@ -58,8 +58,9 @@ export const AppBar = () => {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (metadataState) {
|
if (metadataState) {
|
||||||
if (metadataState.content) {
|
if (metadataState.content) {
|
||||||
const profileMetadata = JSON.parse(metadataState.content)
|
const { picture, display_name, name } = JSON.parse(
|
||||||
const { picture } = profileMetadata
|
metadataState.content
|
||||||
|
)
|
||||||
|
|
||||||
if (picture || userRobotImage) {
|
if (picture || userRobotImage) {
|
||||||
setUserAvatar(picture || userRobotImage)
|
setUserAvatar(picture || userRobotImage)
|
||||||
@ -69,7 +70,7 @@ export const AppBar = () => {
|
|||||||
? hexToNpub(authState.usersPubkey)
|
? hexToNpub(authState.usersPubkey)
|
||||||
: ''
|
: ''
|
||||||
|
|
||||||
setUsername(getProfileUsername(npub, profileMetadata))
|
setUsername(shorten(display_name || name || npub, 7))
|
||||||
} else {
|
} else {
|
||||||
setUserAvatar(userRobotImage || '')
|
setUserAvatar(userRobotImage || '')
|
||||||
setUsername('')
|
setUsername('')
|
||||||
|
@ -11,16 +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 { hexToNpub, npubToHex, getProfileUsername } from '../../utils'
|
import { truncate } from 'lodash'
|
||||||
import { SigitFile } from '../../utils/file'
|
import { settleAllFullfilfedPromises, hexToNpub, npubToHex } from '../../utils'
|
||||||
|
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 { UserAvatar } from '../UserAvatar'
|
import { LoadingSpinner } from '../LoadingSpinner'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
const DEFAULT_START_SIZE = {
|
const DEFAULT_START_SIZE = {
|
||||||
width: 140,
|
width: 140,
|
||||||
@ -28,50 +28,55 @@ 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 }
|
||||||
sigitFiles: SigitFile[]
|
onDrawFieldsChange: (sigitFiles: SigitFile[]) => void
|
||||||
setSigitFiles: React.Dispatch<React.SetStateAction<SigitFile[]>>
|
|
||||||
selectedTool?: DrawTool
|
selectedTool?: DrawTool
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DrawPDFFields = (props: Props) => {
|
export const DrawPDFFields = (props: Props) => {
|
||||||
const { selectedTool, sigitFiles, setSigitFiles, users } = props
|
const { selectedFiles, selectedTool, onDrawFieldsChange, 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)
|
||||||
/**
|
|
||||||
* 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 { to, from } = useScale()
|
const { to, from } = useScale()
|
||||||
|
|
||||||
|
const [sigitFiles, setSigitFiles] = useState<SigitFile[]>([])
|
||||||
|
const [parsingPdf, setIsParsing] = useState<boolean>(false)
|
||||||
|
|
||||||
const [mouseState, setMouseState] = useState<MouseState>({
|
const [mouseState, setMouseState] = useState<MouseState>({
|
||||||
clicked: false
|
clicked: false
|
||||||
})
|
})
|
||||||
|
|
||||||
const [activeDrawnField, setActiveDrawnField] = useState<{
|
const [activeDrawField, setActiveDrawField] = useState<number>()
|
||||||
fileIndex: number
|
|
||||||
pageIndex: number
|
useEffect(() => {
|
||||||
drawnFieldIndex: number
|
if (selectedFiles) {
|
||||||
}>()
|
/**
|
||||||
const isActiveDrawnField = (
|
* Reads the binary files and converts to internal file type
|
||||||
fileIndex: number,
|
* and sets to a state (adds images if it's a PDF)
|
||||||
pageIndex: number,
|
*/
|
||||||
drawnFieldIndex: number
|
const parsePages = async () => {
|
||||||
) =>
|
const files = await settleAllFullfilfedPromises(
|
||||||
activeDrawnField?.fileIndex === fileIndex &&
|
selectedFiles,
|
||||||
activeDrawnField?.pageIndex === pageIndex &&
|
getSigitFile
|
||||||
activeDrawnField?.drawnFieldIndex === drawnFieldIndex
|
)
|
||||||
|
|
||||||
|
setSigitFiles(files)
|
||||||
|
}
|
||||||
|
|
||||||
|
setIsParsing(true)
|
||||||
|
|
||||||
|
parsePages().finally(() => {
|
||||||
|
setIsParsing(false)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}, [selectedFiles])
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (sigitFiles) onDrawFieldsChange(sigitFiles)
|
||||||
|
}, [onDrawFieldsChange, sigitFiles])
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Drawing events
|
* Drawing events
|
||||||
@ -98,12 +103,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
* @param event Pointer event
|
* @param event Pointer event
|
||||||
* @param page PdfPage where press happened
|
* @param page PdfPage where press happened
|
||||||
*/
|
*/
|
||||||
const handlePointerDown = (
|
const handlePointerDown = (event: React.PointerEvent, page: PdfPage) => {
|
||||||
event: React.PointerEvent,
|
|
||||||
page: PdfPage,
|
|
||||||
fileIndex: number,
|
|
||||||
pageIndex: number
|
|
||||||
) => {
|
|
||||||
// Proceed only if left click
|
// Proceed only if left click
|
||||||
if (event.button !== 0) return
|
if (event.button !== 0) return
|
||||||
|
|
||||||
@ -118,17 +118,12 @@ 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: getAvailableSigner(lastSigner, defaultSignerNpub),
|
counterpart: lastSigner,
|
||||||
type: selectedTool.identifier
|
type: selectedTool.identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
page.drawnFields.push(newField)
|
page.drawnFields.push(newField)
|
||||||
|
|
||||||
setActiveDrawnField({
|
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex: page.drawnFields.length - 1
|
|
||||||
})
|
|
||||||
setMouseState((prev) => {
|
setMouseState((prev) => {
|
||||||
return {
|
return {
|
||||||
...prev,
|
...prev,
|
||||||
@ -197,8 +192,6 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
*/
|
*/
|
||||||
const handleDrawnFieldPointerDown = (
|
const handleDrawnFieldPointerDown = (
|
||||||
event: React.PointerEvent,
|
event: React.PointerEvent,
|
||||||
fileIndex: number,
|
|
||||||
pageIndex: number,
|
|
||||||
drawnFieldIndex: number
|
drawnFieldIndex: number
|
||||||
) => {
|
) => {
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
@ -208,7 +201,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
|
|
||||||
const drawingRectangleCoords = getPointerCoordinates(event)
|
const drawingRectangleCoords = getPointerCoordinates(event)
|
||||||
|
|
||||||
setActiveDrawnField({ fileIndex, pageIndex, drawnFieldIndex })
|
setActiveDrawField(drawnFieldIndex)
|
||||||
setMouseState({
|
setMouseState({
|
||||||
dragging: true,
|
dragging: true,
|
||||||
clicked: false,
|
clicked: false,
|
||||||
@ -264,15 +257,13 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
*/
|
*/
|
||||||
const handleResizePointerDown = (
|
const handleResizePointerDown = (
|
||||||
event: React.PointerEvent,
|
event: React.PointerEvent,
|
||||||
fileIndex: number,
|
|
||||||
pageIndex: number,
|
|
||||||
drawnFieldIndex: number
|
drawnFieldIndex: number
|
||||||
) => {
|
) => {
|
||||||
// Proceed only if left click
|
// Proceed only if left click
|
||||||
if (event.button !== 0) return
|
if (event.button !== 0) return
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
|
|
||||||
setActiveDrawnField({ fileIndex, pageIndex, drawnFieldIndex })
|
setActiveDrawField(drawnFieldIndex)
|
||||||
setMouseState({
|
setMouseState({
|
||||||
resizing: true
|
resizing: true
|
||||||
})
|
})
|
||||||
@ -381,7 +372,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
handlePointerMove(event, page)
|
handlePointerMove(event, page)
|
||||||
}}
|
}}
|
||||||
onPointerDown={(event) => {
|
onPointerDown={(event) => {
|
||||||
handlePointerDown(event, page, fileIndex, pageIndex)
|
handlePointerDown(event, page)
|
||||||
}}
|
}}
|
||||||
draggable="false"
|
draggable="false"
|
||||||
src={page.image}
|
src={page.image}
|
||||||
@ -393,12 +384,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
<div
|
<div
|
||||||
key={drawnFieldIndex}
|
key={drawnFieldIndex}
|
||||||
onPointerDown={(event) =>
|
onPointerDown={(event) =>
|
||||||
handleDrawnFieldPointerDown(
|
handleDrawnFieldPointerDown(event, drawnFieldIndex)
|
||||||
event,
|
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onPointerMove={(event) => {
|
onPointerMove={(event) => {
|
||||||
handleDrawnFieldPointerMove(event, drawnField, page.width)
|
handleDrawnFieldPointerMove(event, drawnField, page.width)
|
||||||
@ -419,11 +405,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
touchAction: 'none',
|
touchAction: 'none',
|
||||||
opacity:
|
opacity:
|
||||||
mouseState.dragging &&
|
mouseState.dragging &&
|
||||||
isActiveDrawnField(
|
activeDrawField === drawnFieldIndex
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
)
|
|
||||||
? 0.8
|
? 0.8
|
||||||
: undefined
|
: undefined
|
||||||
}}
|
}}
|
||||||
@ -440,12 +422,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
</div>
|
</div>
|
||||||
<span
|
<span
|
||||||
onPointerDown={(event) =>
|
onPointerDown={(event) =>
|
||||||
handleResizePointerDown(
|
handleResizePointerDown(event, drawnFieldIndex)
|
||||||
event,
|
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
onPointerMove={(event) => {
|
onPointerMove={(event) => {
|
||||||
handleResizePointerMove(event, drawnField, page.width)
|
handleResizePointerMove(event, drawnField, page.width)
|
||||||
@ -454,11 +431,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
style={{
|
style={{
|
||||||
background:
|
background:
|
||||||
mouseState.resizing &&
|
mouseState.resizing &&
|
||||||
isActiveDrawnField(
|
activeDrawField === drawnFieldIndex
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
)
|
|
||||||
? 'var(--primary-main)'
|
? 'var(--primary-main)'
|
||||||
: undefined
|
: undefined
|
||||||
}}
|
}}
|
||||||
@ -476,23 +449,6 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
>
|
>
|
||||||
<Close fontSize="small" />
|
<Close fontSize="small" />
|
||||||
</span>
|
</span>
|
||||||
{!isActiveDrawnField(
|
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
) &&
|
|
||||||
!!drawnField.counterpart && (
|
|
||||||
<div className={styles.counterpartAvatar}>
|
|
||||||
<UserAvatar
|
|
||||||
pubkey={npubToHex(drawnField.counterpart)!}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
{isActiveDrawnField(
|
|
||||||
fileIndex,
|
|
||||||
pageIndex,
|
|
||||||
drawnFieldIndex
|
|
||||||
) && (
|
|
||||||
<div
|
<div
|
||||||
onPointerDown={handleUserSelectPointerDown}
|
onPointerDown={handleUserSelectPointerDown}
|
||||||
className={styles.userSelect}
|
className={styles.userSelect}
|
||||||
@ -500,7 +456,12 @@ 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={getAvailableSigner(drawnField.counterpart)}
|
value={
|
||||||
|
drawnField.counterpart ||
|
||||||
|
lastSigner ||
|
||||||
|
defaultSignerNpub ||
|
||||||
|
''
|
||||||
|
}
|
||||||
onChange={(event) => {
|
onChange={(event) => {
|
||||||
drawnField.counterpart = event.target.value
|
drawnField.counterpart = event.target.value
|
||||||
setLastSigner(event.target.value)
|
setLastSigner(event.target.value)
|
||||||
@ -511,17 +472,27 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
sx={{
|
sx={{
|
||||||
background: 'white'
|
background: 'white'
|
||||||
}}
|
}}
|
||||||
renderValue={(value) =>
|
renderValue={(value) => renderCounterpartValue(value)}
|
||||||
renderCounterpartValue(value)
|
|
||||||
}
|
|
||||||
>
|
>
|
||||||
{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) {
|
||||||
|
displayValue = truncate(
|
||||||
|
metadata.name ||
|
||||||
|
metadata.display_name ||
|
||||||
|
metadata.username ||
|
||||||
npub,
|
npub,
|
||||||
metadata
|
{
|
||||||
|
length: 16
|
||||||
|
}
|
||||||
)
|
)
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<MenuItem key={index} value={npub}>
|
<MenuItem key={index} value={npub}>
|
||||||
@ -547,7 +518,6 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
</Select>
|
</Select>
|
||||||
</FormControl>
|
</FormControl>
|
||||||
</div>
|
</div>
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
@ -559,15 +529,24 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const renderCounterpartValue = (npub: string) => {
|
const renderCounterpartValue = (npub: string) => {
|
||||||
let displayValue = _.truncate(npub, { length: 16 })
|
let displayValue = truncate(npub, {
|
||||||
|
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]
|
||||||
displayValue = getProfileUsername(npub, metadata)
|
if (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}
|
||||||
@ -581,13 +560,21 @@ 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) => {
|
||||||
@ -606,7 +593,7 @@ export const DrawPDFFields = (props: Props) => {
|
|||||||
<ExtensionFileBox extension={file.extension} />
|
<ExtensionFileBox extension={file.extension} />
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
{i < sigitFiles.length - 1 && <FileDivider />}
|
{i < selectedFiles.length - 1 && <FileDivider />}
|
||||||
</React.Fragment>
|
</React.Fragment>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
@ -84,14 +84,3 @@
|
|||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.counterpartSelectValue {
|
|
||||||
display: flex;
|
|
||||||
}
|
|
||||||
|
|
||||||
.counterpartAvatar {
|
|
||||||
img {
|
|
||||||
width: 21px;
|
|
||||||
height: 21px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -5,7 +5,7 @@ import { AvatarIconButton } from '../UserAvatarIconButton'
|
|||||||
import { Link } from 'react-router-dom'
|
import { Link } from 'react-router-dom'
|
||||||
import { useProfileMetadata } from '../../hooks/useProfileMetadata'
|
import { useProfileMetadata } from '../../hooks/useProfileMetadata'
|
||||||
import { Tooltip } from '@mui/material'
|
import { Tooltip } from '@mui/material'
|
||||||
import { getProfileUsername } from '../../utils'
|
import { shorten } from '../../utils'
|
||||||
import { TooltipChild } from '../TooltipChild'
|
import { TooltipChild } from '../TooltipChild'
|
||||||
|
|
||||||
interface UserAvatarProps {
|
interface UserAvatarProps {
|
||||||
@ -22,7 +22,7 @@ export const UserAvatar = ({
|
|||||||
isNameVisible = false
|
isNameVisible = false
|
||||||
}: UserAvatarProps) => {
|
}: UserAvatarProps) => {
|
||||||
const profile = useProfileMetadata(pubkey)
|
const profile = useProfileMetadata(pubkey)
|
||||||
const name = getProfileUsername(pubkey, profile)
|
const name = profile?.display_name || profile?.name || shorten(pubkey)
|
||||||
const image = profile?.picture
|
const image = profile?.picture
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -39,8 +39,7 @@ 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'
|
||||||
@ -61,8 +60,7 @@ import {
|
|||||||
faTrash,
|
faTrash,
|
||||||
faUpload
|
faUpload
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} from '@fortawesome/free-solid-svg-icons'
|
||||||
import { getSigitFile, SigitFile } from '../../utils/file.ts'
|
import { SigitFile } from '../../utils/file.ts'
|
||||||
import _ from 'lodash'
|
|
||||||
|
|
||||||
export const CreatePage = () => {
|
export const CreatePage = () => {
|
||||||
const navigate = useNavigate()
|
const navigate = useNavigate()
|
||||||
@ -108,29 +106,6 @@ 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>()
|
||||||
|
|
||||||
@ -306,19 +281,6 @@ 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)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -761,6 +723,10 @@ export const CreatePage = () => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const onDrawFieldsChange = (sigitFiles: SigitFile[]) => {
|
||||||
|
setDrawnFiles(sigitFiles)
|
||||||
|
}
|
||||||
|
|
||||||
if (authUrl) {
|
if (authUrl) {
|
||||||
return (
|
return (
|
||||||
<iframe
|
<iframe
|
||||||
@ -919,17 +885,13 @@ export const CreatePage = () => {
|
|||||||
centerIcon={faFile}
|
centerIcon={faFile}
|
||||||
rightIcon={faToolbox}
|
rightIcon={faToolbox}
|
||||||
>
|
>
|
||||||
{parsingPdf ? (
|
|
||||||
<LoadingSpinner variant="small" />
|
|
||||||
) : (
|
|
||||||
<DrawPDFFields
|
<DrawPDFFields
|
||||||
users={users}
|
|
||||||
metadata={metadata}
|
metadata={metadata}
|
||||||
|
users={users}
|
||||||
|
selectedFiles={selectedFiles}
|
||||||
|
onDrawFieldsChange={onDrawFieldsChange}
|
||||||
selectedTool={selectedTool}
|
selectedTool={selectedTool}
|
||||||
sigitFiles={drawnFiles}
|
|
||||||
setSigitFiles={setDrawnFiles}
|
|
||||||
/>
|
/>
|
||||||
)}
|
|
||||||
</StickySideColumns>
|
</StickySideColumns>
|
||||||
</Container>
|
</Container>
|
||||||
</>
|
</>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import ContentCopyIcon from '@mui/icons-material/ContentCopy'
|
import ContentCopyIcon from '@mui/icons-material/ContentCopy'
|
||||||
import EditIcon from '@mui/icons-material/Edit'
|
import EditIcon from '@mui/icons-material/Edit'
|
||||||
import { Box, IconButton, SxProps, Theme, Typography } from '@mui/material'
|
import { Box, IconButton, SxProps, Theme, Typography } from '@mui/material'
|
||||||
|
import { truncate } from 'lodash'
|
||||||
import { Event, VerifiedEvent, kinds, nip19 } from 'nostr-tools'
|
import { Event, VerifiedEvent, kinds, nip19 } from 'nostr-tools'
|
||||||
import { useEffect, useMemo, useState } from 'react'
|
import { useEffect, useMemo, useState } from 'react'
|
||||||
import { useSelector } from 'react-redux'
|
import { useSelector } from 'react-redux'
|
||||||
@ -13,7 +14,6 @@ import { State } from '../../store/rootReducer'
|
|||||||
import { NostrJoiningBlock, ProfileMetadata } from '../../types'
|
import { NostrJoiningBlock, ProfileMetadata } from '../../types'
|
||||||
import {
|
import {
|
||||||
getNostrJoiningBlockNumber,
|
getNostrJoiningBlockNumber,
|
||||||
getProfileUsername,
|
|
||||||
getRoboHashPicture,
|
getRoboHashPicture,
|
||||||
hexToNpub,
|
hexToNpub,
|
||||||
shorten
|
shorten
|
||||||
@ -42,7 +42,15 @@ export const ProfilePage = () => {
|
|||||||
const [isLoading, setIsLoading] = useState(true)
|
const [isLoading, setIsLoading] = useState(true)
|
||||||
const [loadingSpinnerDesc] = useState('Fetching metadata')
|
const [loadingSpinnerDesc] = useState('Fetching metadata')
|
||||||
|
|
||||||
const profileName = pubkey && getProfileUsername(pubkey, profileMetadata)
|
const profileName =
|
||||||
|
pubkey &&
|
||||||
|
profileMetadata &&
|
||||||
|
truncate(
|
||||||
|
profileMetadata.display_name || profileMetadata.name || hexToNpub(pubkey),
|
||||||
|
{
|
||||||
|
length: 16
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (npub) {
|
if (npub) {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
export interface ProfileMetadata {
|
export interface ProfileMetadata {
|
||||||
name?: string
|
name?: string
|
||||||
display_name?: string
|
display_name?: string
|
||||||
/** @deprecated use name instead */
|
|
||||||
username?: string
|
username?: string
|
||||||
picture?: string
|
picture?: string
|
||||||
banner?: string
|
banner?: string
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
|
import { bytesToHex, hexToBytes } from '@noble/hashes/utils'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import _, { truncate } from 'lodash'
|
import _ from 'lodash'
|
||||||
import {
|
import {
|
||||||
Event,
|
Event,
|
||||||
EventTemplate,
|
EventTemplate,
|
||||||
@ -30,7 +30,7 @@ import {
|
|||||||
import { AuthState, Keys } from '../store/auth/types'
|
import { AuthState, Keys } from '../store/auth/types'
|
||||||
import { RelaysState } from '../store/relays/types'
|
import { RelaysState } from '../store/relays/types'
|
||||||
import store from '../store/store'
|
import store from '../store/store'
|
||||||
import { Meta, ProfileMetadata, SignedEvent, UserAppData } from '../types'
|
import { Meta, SignedEvent, UserAppData } from '../types'
|
||||||
import { getDefaultRelayMap } from './relays'
|
import { getDefaultRelayMap } from './relays'
|
||||||
import { parseJson, removeLeadingSlash } from './string'
|
import { parseJson, removeLeadingSlash } from './string'
|
||||||
import { timeout } from './utils'
|
import { timeout } from './utils'
|
||||||
@ -974,16 +974,3 @@ export const sendNotification = async (receiver: string, meta: Meta) => {
|
|||||||
throw err
|
throw err
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Show user's name, first available in order: display_name, name, or npub as fallback
|
|
||||||
* @param npub User identifier, it can be either pubkey or npub1 (we only show npub)
|
|
||||||
* @param profile User profile
|
|
||||||
*/
|
|
||||||
export const getProfileUsername = (
|
|
||||||
npub: `npub1${string}` | string,
|
|
||||||
profile?: ProfileMetadata
|
|
||||||
) =>
|
|
||||||
truncate(profile?.display_name || profile?.name || hexToNpub(npub), {
|
|
||||||
length: 16
|
|
||||||
})
|
|
||||||
|
Loading…
Reference in New Issue
Block a user