@ -108,7 +108,6 @@ export const CreatePage = () => {
|
|||||||
const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
|
const [drawnFiles, setDrawnFiles] = useState<SigitFile[]>([])
|
||||||
|
|
||||||
const [selectedTool, setSelectedTool] = useState<DrawTool>()
|
const [selectedTool, setSelectedTool] = useState<DrawTool>()
|
||||||
const [toolbox] = useState<DrawTool[]>(DEFAULT_TOOLBOX)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Changes the drawing tool
|
* Changes the drawing tool
|
||||||
@ -833,20 +832,27 @@ export const CreatePage = () => {
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div className={`${styles.paperGroup} ${styles.toolbox}`}>
|
<div className={`${styles.paperGroup} ${styles.toolbox}`}>
|
||||||
{toolbox.map((drawTool: DrawTool, index: number) => {
|
{DEFAULT_TOOLBOX.filter((drawTool) => !drawTool.isHidden).map(
|
||||||
|
(drawTool: DrawTool, index: number) => {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={index}
|
key={index}
|
||||||
{...(drawTool.active && {
|
{...(!drawTool.isComingSoon && {
|
||||||
onClick: () => handleToolSelect(drawTool)
|
onClick: () => handleToolSelect(drawTool)
|
||||||
})}
|
})}
|
||||||
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${!drawTool.active ? styles.comingSoon : ''}
|
className={`${styles.toolItem} ${selectedTool?.identifier === drawTool.identifier ? styles.selected : ''} ${drawTool.isComingSoon ? styles.comingSoon : ''}
|
||||||
`}
|
`}
|
||||||
>
|
>
|
||||||
<FontAwesomeIcon fontSize={'15px'} icon={drawTool.icon} />
|
<FontAwesomeIcon
|
||||||
|
fontSize={'15px'}
|
||||||
|
icon={drawTool.icon}
|
||||||
|
/>
|
||||||
{drawTool.label}
|
{drawTool.label}
|
||||||
{drawTool.active ? (
|
{!drawTool.isComingSoon ? (
|
||||||
<FontAwesomeIcon fontSize={'15px'} icon={faEllipsis} />
|
<FontAwesomeIcon
|
||||||
|
fontSize={'15px'}
|
||||||
|
icon={faEllipsis}
|
||||||
|
/>
|
||||||
) : (
|
) : (
|
||||||
<span className={styles.comingSoonPlaceholder}>
|
<span className={styles.comingSoonPlaceholder}>
|
||||||
Coming soon
|
Coming soon
|
||||||
@ -854,7 +860,8 @@ export const CreatePage = () => {
|
|||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
})}
|
}
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button onClick={handleCreate} variant="contained">
|
<Button onClick={handleCreate} variant="contained">
|
||||||
|
@ -31,7 +31,10 @@ export interface DrawTool {
|
|||||||
icon: IconDefinition
|
icon: IconDefinition
|
||||||
defaultValue?: string
|
defaultValue?: string
|
||||||
selected?: boolean
|
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 {
|
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_RELAY = 'wss://relay.sigit.io'
|
||||||
|
|
||||||
|
export const SIGIT_BLOSSOM = 'https://blossom.sigit.io'
|
||||||
|
|
||||||
export const DEFAULT_LOOK_UP_RELAY_LIST = [
|
export const DEFAULT_LOOK_UP_RELAY_LIST = [
|
||||||
SIGIT_RELAY,
|
SIGIT_RELAY,
|
||||||
'wss://user.kindpag.es',
|
'wss://user.kindpag.es',
|
||||||
|
@ -3,14 +3,26 @@ import { hexToNpub } from './nostr.ts'
|
|||||||
import { Meta, SignedEventContent } from '../types'
|
import { Meta, SignedEventContent } from '../types'
|
||||||
import { Event } from 'nostr-tools'
|
import { Event } from 'nostr-tools'
|
||||||
import { EMPTY } from './const.ts'
|
import { EMPTY } from './const.ts'
|
||||||
import { MarkType } from '../types/drawing.ts'
|
import { DrawTool, MarkType } from '../types/drawing.ts'
|
||||||
import {
|
import {
|
||||||
faT,
|
faT,
|
||||||
faSignature,
|
faSignature,
|
||||||
faBriefcase,
|
faBriefcase,
|
||||||
faIdCard,
|
faIdCard,
|
||||||
faClock,
|
faClock,
|
||||||
fa1
|
fa1,
|
||||||
|
faCalendarDays,
|
||||||
|
faCheckDouble,
|
||||||
|
faCircleDot,
|
||||||
|
faCreditCard,
|
||||||
|
faHeading,
|
||||||
|
faImage,
|
||||||
|
faPaperclip,
|
||||||
|
faPhone,
|
||||||
|
faSquareCaretDown,
|
||||||
|
faSquareCheck,
|
||||||
|
faStamp,
|
||||||
|
faTableCellsLarge
|
||||||
} from '@fortawesome/free-solid-svg-icons'
|
} 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))
|
return marks.filter((mark) => mark.npub !== hexToNpub(pubkey))
|
||||||
}
|
}
|
||||||
|
|
||||||
export const DEFAULT_TOOLBOX = [
|
export const DEFAULT_TOOLBOX: DrawTool[] = [
|
||||||
{
|
{
|
||||||
identifier: MarkType.FULLNAME,
|
identifier: MarkType.FULLNAME,
|
||||||
icon: faIdCard,
|
icon: faIdCard,
|
||||||
label: 'Full Name',
|
label: 'Full Name',
|
||||||
active: false
|
isComingSoon: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: MarkType.JOBTITLE,
|
identifier: MarkType.JOBTITLE,
|
||||||
icon: faBriefcase,
|
icon: faBriefcase,
|
||||||
label: 'Job Title',
|
label: 'Job Title',
|
||||||
active: false
|
isComingSoon: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: MarkType.SIGNATURE,
|
identifier: MarkType.SIGNATURE,
|
||||||
icon: faSignature,
|
icon: faSignature,
|
||||||
label: 'Signature',
|
label: 'Signature',
|
||||||
active: false
|
isComingSoon: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: MarkType.DATETIME,
|
identifier: MarkType.DATETIME,
|
||||||
icon: faClock,
|
icon: faClock,
|
||||||
label: 'Date Time',
|
label: 'Date Time',
|
||||||
active: false
|
isComingSoon: true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
identifier: MarkType.TEXT,
|
identifier: MarkType.TEXT,
|
||||||
icon: faT,
|
icon: faT,
|
||||||
label: 'Text',
|
label: 'Text'
|
||||||
active: true
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
identifier: MarkType.NUMBER,
|
identifier: MarkType.NUMBER,
|
||||||
icon: fa1,
|
icon: fa1,
|
||||||
label: 'Number',
|
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) => {
|
export const getToolboxLabelByMarkType = (markType: MarkType) => {
|
||||||
|
@ -16,6 +16,8 @@ import { CreateSignatureEventContent, Meta } from '../types'
|
|||||||
import { hexToNpub, unixNow } from './nostr'
|
import { hexToNpub, unixNow } from './nostr'
|
||||||
import { parseJson } from './string'
|
import { parseJson } from './string'
|
||||||
import { hexToBytes } from '@noble/hashes/utils'
|
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.
|
* Uploads a file to a file storage service.
|
||||||
@ -25,12 +27,18 @@ import { hexToBytes } from '@noble/hashes/utils'
|
|||||||
*/
|
*/
|
||||||
export const uploadToFileStorage = async (file: File) => {
|
export const uploadToFileStorage = async (file: File) => {
|
||||||
// Define event metadata for authorization
|
// 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 = {
|
const event: EventTemplate = {
|
||||||
kind: 24242,
|
kind: 24242,
|
||||||
content: 'Authorize Upload',
|
content: 'Authorize Upload',
|
||||||
created_at: unixNow(),
|
created_at: unixNow(),
|
||||||
tags: [
|
tags: [
|
||||||
['t', 'upload'],
|
['t', 'upload'],
|
||||||
|
['x', hash],
|
||||||
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
||||||
['name', file.name],
|
['name', file.name],
|
||||||
['size', String(file.size)]
|
['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
|
// Sign the authorization event using the dedicated key stored in user app data
|
||||||
const authEvent = finalizeEvent(event, hexToBytes(key))
|
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
|
// 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: {
|
headers: {
|
||||||
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)), // Set authorization header
|
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)), // Set authorization header
|
||||||
'Content-Type': 'application/sigit' // Set content type header
|
'Content-Type': 'application/sigit' // Set content type header
|
||||||
|
@ -35,6 +35,7 @@ import { getDefaultRelayMap } from './relays'
|
|||||||
import { parseJson, removeLeadingSlash } from './string'
|
import { parseJson, removeLeadingSlash } from './string'
|
||||||
import { timeout } from './utils'
|
import { timeout } from './utils'
|
||||||
import { getHash } from './hash'
|
import { getHash } from './hash'
|
||||||
|
import { SIGIT_BLOSSOM } from './const.ts'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a `d` tag for userAppData
|
* Generates a `d` tag for userAppData
|
||||||
@ -723,6 +724,11 @@ const uploadUserAppDataToBlossom = async (
|
|||||||
type: 'application/octet-stream'
|
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
|
// Define event metadata for authorization
|
||||||
const event: EventTemplate = {
|
const event: EventTemplate = {
|
||||||
kind: 24242,
|
kind: 24242,
|
||||||
@ -730,6 +736,7 @@ const uploadUserAppDataToBlossom = async (
|
|||||||
created_at: unixNow(),
|
created_at: unixNow(),
|
||||||
tags: [
|
tags: [
|
||||||
['t', 'upload'],
|
['t', 'upload'],
|
||||||
|
['x', hash],
|
||||||
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
['expiration', String(unixNow() + 60 * 5)], // Set expiration time to 5 minutes from now
|
||||||
['name', file.name],
|
['name', file.name],
|
||||||
['size', String(file.size)]
|
['size', String(file.size)]
|
||||||
@ -739,11 +746,8 @@ const uploadUserAppDataToBlossom = async (
|
|||||||
// Finalize the event with the private key
|
// Finalize the event with the private key
|
||||||
const authEvent = finalizeEvent(event, hexToBytes(privateKey))
|
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
|
// 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: {
|
headers: {
|
||||||
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)) // Set authorization header
|
Authorization: 'Nostr ' + btoa(JSON.stringify(authEvent)) // Set authorization header
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user
Can we rely on the
active
flag rather than commenting out?The active flag is for
coming soon
currently, and instead of adding a new flag to differentiate between coming soon and visually hidden, I opted to comment out.Can you please add a comment to capture the difference in the codebase?
Okay, made it clearer with new property names,
isHidden
andisComingSoon
so there is no confusion as withactive
(also removed comments and usedisHidden
instead).