@ -108,7 +108,6 @@ export const CreatePage = () => {
|
||||
const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
|
||||
|
||||
const [selectedTool, setSelectedTool] = useState<DrawTool>()
|
||||
const [toolbox] = useState<DrawTool[]>(DEFAULT_TOOLBOX)
|
||||
|
||||
/**
|
||||
* Changes the drawing tool
|
||||
@ -833,28 +832,36 @@ export const CreatePage = () => {
|
||||
</div>
|
||||
|
||||
<div className={`${styles.paperGroup} ${styles.toolbox}`}>
|
||||
{toolbox.map((drawTool: DrawTool, index: number) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
{...(drawTool.active && {
|
||||
onClick: () => handleToolSelect(drawTool)
|
||||
})}
|
||||
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${!drawTool.active ? styles.comingSoon : ''}
|
||||
{DEFAULT_TOOLBOX.filter((drawTool) => !drawTool.isHidden).map(
|
||||
(drawTool: DrawTool, index: number) => {
|
||||
return (
|
||||
<div
|
||||
key={index}
|
||||
{...(!drawTool.isComingSoon && {
|
||||
onClick: () => handleToolSelect(drawTool)
|
||||
})}
|
||||
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${drawTool.isComingSoon ? styles.comingSoon : ''}
|
||||
`}
|
||||
>
|
||||
<FontAwesomeIcon fontSize={'15px'} icon={drawTool.icon} />
|
||||
{drawTool.label}
|
||||
{drawTool.active ? (
|
||||
<FontAwesomeIcon fontSize={'15px'} icon={faEllipsis} />
|
||||
) : (
|
||||
<span className={styles.comingSoonPlaceholder}>
|
||||
Coming soon
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
})}
|
||||
>
|
||||
<FontAwesomeIcon
|
||||
fontSize={'15px'}
|
||||
icon={drawTool.icon}
|
||||
/>
|
||||
{drawTool.label}
|
||||
{!drawTool.isComingSoon ? (
|
||||
<FontAwesomeIcon
|
||||
fontSize={'15px'}
|
||||
icon={faEllipsis}
|
||||
/>
|
||||
) : (
|
||||
<span className={styles.comingSoonPlaceholder}>
|
||||
Coming soon
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
)}
|
||||
</div>
|
||||
|
||||
<Button onClick={handleCreate} variant="contained">
|
||||
|
@ -31,7 +31,10 @@ export interface DrawTool {
|
||||
icon: IconDefinition
|
||||
defaultValue?: string
|
||||
selected?: boolean
|
||||
active?: boolean
|
||||
/** show or hide the toolbox item */
|
||||
isHidden?: boolean
|
||||
/** show or hide "coming soon" message on the toolbox item */
|
||||
isComingSoon?: boolean
|
||||
}
|
||||
|
||||
export enum MarkType {
|
||||
|
@ -21,6 +21,8 @@ export const ONE_DAY_IN_MS = 24 * 60 * 60 * 1000
|
||||
|
||||
export const SIGIT_RELAY = 'wss://relay.sigit.io'
|
||||
|
||||
export const SIGIT_BLOSSOM = 'https://blossom.sigit.io'
|
||||
|
||||
export const DEFAULT_LOOK_UP_RELAY_LIST = [
|
||||
SIGIT_RELAY,
|
||||
'wss://user.kindpag.es',
|
||||
|
@ -3,14 +3,26 @@ import { hexToNpub } from './nostr.ts'
|
||||
import { Meta, SignedEventContent } from '../types'
|
||||
import { Event } from 'nostr-tools'
|
||||
import { EMPTY } from './const.ts'
|
||||
import { MarkType } from '../types/drawing.ts'
|
||||
import { DrawTool, MarkType } from '../types/drawing.ts'
|
||||
import {
|
||||
faT,
|
||||
faSignature,
|
||||
faBriefcase,
|
||||
faIdCard,
|
||||
faClock,
|
||||
fa1
|
||||
fa1,
|
||||
faCalendarDays,
|
||||
faCheckDouble,
|
||||
faCircleDot,
|
||||
faCreditCard,
|
||||
faHeading,
|
||||
faImage,
|
||||
faPaperclip,
|
||||
faPhone,
|
||||
faSquareCaretDown,
|
||||
faSquareCheck,
|
||||
faStamp,
|
||||
faTableCellsLarge
|
||||
} from '@fortawesome/free-solid-svg-icons'
|
||||
|
||||
/**
|
||||
@ -140,115 +152,114 @@ const findOtherUserMarks = (marks: Mark[], pubkey: string): Mark[] => {
|
||||
return marks.filter((mark) => mark.npub !== hexToNpub(pubkey))
|
||||
}
|
||||
|
||||
export const DEFAULT_TOOLBOX = [
|
||||
export const DEFAULT_TOOLBOX: DrawTool[] = [
|
||||
{
|
||||
identifier: MarkType.FULLNAME,
|
||||
icon: faIdCard,
|
||||
label: 'Full Name',
|
||||
active: false
|
||||
isComingSoon: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.JOBTITLE,
|
||||
icon: faBriefcase,
|
||||
label: 'Job Title',
|
||||
active: false
|
||||
isComingSoon: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.SIGNATURE,
|
||||
icon: faSignature,
|
||||
label: 'Signature',
|
||||
active: false
|
||||
isComingSoon: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.DATETIME,
|
||||
icon: faClock,
|
||||
label: 'Date Time',
|
||||
active: false
|
||||
isComingSoon: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.TEXT,
|
||||
icon: faT,
|
||||
label: 'Text',
|
||||
active: true
|
||||
label: 'Text'
|
||||
},
|
||||
{
|
||||
identifier: MarkType.NUMBER,
|
||||
icon: fa1,
|
||||
label: 'Number',
|
||||
active: false
|
||||
isComingSoon: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.INITIALS,
|
||||
icon: faHeading,
|
||||
label: 'Initials',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.DATE,
|
||||
icon: faCalendarDays,
|
||||
label: 'Date',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.IMAGES,
|
||||
icon: faImage,
|
||||
label: 'Images',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.CHECKBOX,
|
||||
icon: faSquareCheck,
|
||||
label: 'Checkbox',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.MULTIPLE,
|
||||
icon: faCheckDouble,
|
||||
label: 'Multiple',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.FILE,
|
||||
icon: faPaperclip,
|
||||
label: 'File',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.RADIO,
|
||||
icon: faCircleDot,
|
||||
label: 'Radio',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.SELECT,
|
||||
icon: faSquareCaretDown,
|
||||
label: 'Select',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.CELLS,
|
||||
icon: faTableCellsLarge,
|
||||
label: 'Cells',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.STAMP,
|
||||
icon: faStamp,
|
||||
label: 'Stamp',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.PAYMENT,
|
||||
icon: faCreditCard,
|
||||
label: 'Payment',
|
||||
isHidden: true
|
||||
},
|
||||
{
|
||||
identifier: MarkType.PHONE,
|
||||
icon: faPhone,
|
||||
label: 'Phone',
|
||||
isHidden: true
|
||||
}
|
||||
// {
|
||||
// identifier: MarkType.INITIALS,
|
||||
// icon: faHeading,
|
||||
// label: 'Initials',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.DATE,
|
||||
// icon: faCalendarDays,
|
||||
// label: 'Date',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.IMAGES,
|
||||
// icon: faImage,
|
||||
// label: 'Images',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.CHECKBOX,
|
||||
// icon: faSquareCheck,
|
||||
// label: 'Checkbox',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.MULTIPLE,
|
||||
// icon: faCheckDouble,
|
||||
// label: 'Multiple',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.FILE,
|
||||
// icon: faPaperclip,
|
||||
// label: 'File',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.RADIO,
|
||||
// icon: faCircleDot,
|
||||
// label: 'Radio',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.SELECT,
|
||||
// icon: faSquareCaretDown,
|
||||
// label: 'Select',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.CELLS,
|
||||
// icon: faTableCellsLarge,
|
||||
// label: 'Cells',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.STAMP,
|
||||
// icon: faStamp,
|
||||
// label: 'Stamp',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.PAYMENT,
|
||||
// icon: faCreditCard,
|
||||
// label: 'Payment',
|
||||
// active: false
|
||||
// },
|
||||
// {
|
||||
// identifier: MarkType.PHONE,
|
||||
// icon: faPhone,
|
||||
// label: 'Phone',
|
||||
// active: false
|
||||
// }
|
||||
]
|
||||
|
||||
export const getToolboxLabelByMarkType = (markType: MarkType) => {
|
||||
|
@ -16,6 +16,8 @@ import { CreateSignatureEventContent, Meta } from '../types'
|
||||
import { hexToNpub, unixNow } from './nostr'
|
||||
import { parseJson } from './string'
|
||||
import { hexToBytes } from '@noble/hashes/utils'
|
||||
import { getHash } from './hash.ts'
|
||||
import { SIGIT_BLOSSOM } from './const.ts'
|
||||
|
||||
/**
|
||||
* Uploads a file to a file storage service.
|
||||
@ -25,12 +27,18 @@ import { hexToBytes } from '@noble/hashes/utils'
|
||||
*/
|
||||
export const uploadToFileStorage = async (file: File) => {
|
||||
// Define event metadata for authorization
|
||||
const hash = await getHash(await file.arrayBuffer())
|
||||
if (!hash) {
|
||||
throw new Error("Can't get file hash.")
|
||||
}
|
||||
|
||||
const event: EventTemplate = {
|
||||
kind: 24242,
|
||||
content: 'Authorize Upload',
|
||||
created_at: unixNow(),
|
||||
tags: [
|
||||
['t', 'upload'],
|
||||
['x', hash],
|
||||
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
||||
['name', file.name],
|
||||
['size', String(file.size)]
|
||||
@ -47,11 +55,8 @@ export const uploadToFileStorage = async (file: File) => {
|
||||
// Sign the authorization event using the dedicated key stored in user app data
|
||||
const authEvent = finalizeEvent(event, hexToBytes(key))
|
||||
|
||||
// URL of the file storage service
|
||||
const FILE_STORAGE_URL = 'https://blossom.sigit.io' // REFACTOR: should be an env
|
||||
|
||||
// Upload the file to the file storage service using Axios
|
||||
const response = await axios.put(`${FILE_STORAGE_URL}/upload`, file, {
|
||||
const response = await axios.put(`${SIGIT_BLOSSOM}/upload`, file, {
|
||||
headers: {
|
||||
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)), // Set authorization header
|
||||
'Content-Type': 'application/sigit' // Set content type header
|
||||
|
@ -35,6 +35,7 @@ import { getDefaultRelayMap } from './relays'
|
||||
import { parseJson, removeLeadingSlash } from './string'
|
||||
import { timeout } from './utils'
|
||||
import { getHash } from './hash'
|
||||
import { SIGIT_BLOSSOM } from './const.ts'
|
||||
|
||||
/**
|
||||
* Generates a `d` tag for userAppData
|
||||
@ -723,6 +724,11 @@ const uploadUserAppDataToBlossom = async (
|
||||
type: 'application/octet-stream'
|
||||
})
|
||||
|
||||
const hash = await getHash(await file.arrayBuffer())
|
||||
if (!hash) {
|
||||
throw new Error("Can't get file hash.")
|
||||
}
|
||||
|
||||
// Define event metadata for authorization
|
||||
const event: EventTemplate = {
|
||||
kind: 24242,
|
||||
@ -730,6 +736,7 @@ const uploadUserAppDataToBlossom = async (
|
||||
created_at: unixNow(),
|
||||
tags: [
|
||||
['t', 'upload'],
|
||||
['x', hash],
|
||||
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
||||
['name', file.name],
|
||||
['size', String(file.size)]
|
||||
@ -739,11 +746,8 @@ const uploadUserAppDataToBlossom = async (
|
||||
// Finalize the event with the private key
|
||||
const authEvent = finalizeEvent(event, hexToBytes(privateKey))
|
||||
|
||||
// URL of the file storage service
|
||||
const FILE_STORAGE_URL = 'https://blossom.sigit.io'
|
||||
|
||||
// Upload the file to the file storage service using Axios
|
||||
const response = await axios.put(`${FILE_STORAGE_URL}/upload`, file, {
|
||||
const response = await axios.put(`${SIGIT_BLOSSOM}/upload`, file, {
|
||||
headers: {
|
||||
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)) // Set authorization header
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user