2023-01-16 17:48:25 +00:00
|
|
|
import { useState } from "react";
|
|
|
|
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
|
|
|
import { faPaperclip } from "@fortawesome/free-solid-svg-icons";
|
|
|
|
|
|
|
|
import "./NoteCreator.css";
|
|
|
|
|
2023-01-25 18:08:53 +00:00
|
|
|
import Plus from "Icons/Plus";
|
2023-01-20 11:11:50 +00:00
|
|
|
import useEventPublisher from "Feed/EventPublisher";
|
|
|
|
import { openFile } from "Util";
|
|
|
|
import VoidUpload from "Feed/VoidUpload";
|
|
|
|
import { FileExtensionRegex } from "Const";
|
|
|
|
import Textarea from "Element/Textarea";
|
2023-01-25 18:08:53 +00:00
|
|
|
import Modal from "Element/Modal";
|
|
|
|
import { default as NEvent } from "Nostr/Event";
|
2023-01-16 17:48:25 +00:00
|
|
|
|
|
|
|
export interface NoteCreatorProps {
|
2023-01-25 18:08:53 +00:00
|
|
|
show: boolean
|
|
|
|
setShow: (s: boolean) => void
|
2023-01-16 17:48:25 +00:00
|
|
|
replyTo?: NEvent,
|
|
|
|
onSend?: Function,
|
2023-01-25 18:08:53 +00:00
|
|
|
onClose?(): void
|
2023-01-16 17:48:25 +00:00
|
|
|
autoFocus: boolean
|
|
|
|
}
|
|
|
|
|
|
|
|
export function NoteCreator(props: NoteCreatorProps) {
|
2023-01-25 18:08:53 +00:00
|
|
|
const { show, setShow } = props
|
2023-01-16 17:48:25 +00:00
|
|
|
const publisher = useEventPublisher();
|
2023-01-16 18:30:08 +00:00
|
|
|
const [note, setNote] = useState<string>();
|
|
|
|
const [error, setError] = useState<string>();
|
|
|
|
const [active, setActive] = useState<boolean>(false);
|
2023-01-16 17:48:25 +00:00
|
|
|
|
|
|
|
async function sendNote() {
|
2023-01-16 18:30:08 +00:00
|
|
|
if (note) {
|
|
|
|
let ev = props.replyTo ? await publisher.reply(props.replyTo, note) : await publisher.note(note);
|
|
|
|
console.debug("Sending note: ", ev);
|
|
|
|
publisher.broadcast(ev);
|
|
|
|
setNote("");
|
|
|
|
if (typeof props.onSend === "function") {
|
|
|
|
props.onSend();
|
|
|
|
}
|
|
|
|
setActive(false);
|
2023-01-16 17:48:25 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
async function attachFile() {
|
|
|
|
try {
|
|
|
|
let file = await openFile();
|
|
|
|
if (file) {
|
|
|
|
let rx = await VoidUpload(file, file.name);
|
|
|
|
if (rx?.ok && rx?.file) {
|
|
|
|
let ext = file.name.match(FileExtensionRegex);
|
|
|
|
|
|
|
|
// extension tricks note parser to embed the content
|
|
|
|
let url = rx.file.meta?.url ?? `https://void.cat/d/${rx.file.id}${ext ? `.${ext[1]}` : ""}`;
|
|
|
|
|
|
|
|
setNote(n => `${n}\n${url}`);
|
|
|
|
} else if (rx?.errorMessage) {
|
|
|
|
setError(rx.errorMessage);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} catch (error: any) {
|
|
|
|
setError(error?.message)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function onChange(ev: any) {
|
|
|
|
const { value } = ev.target
|
|
|
|
setNote(value)
|
|
|
|
if (value) {
|
|
|
|
setActive(true)
|
|
|
|
} else {
|
|
|
|
setActive(false)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-01-25 18:08:53 +00:00
|
|
|
function cancel(ev: any) {
|
|
|
|
setShow(false)
|
|
|
|
setNote("")
|
|
|
|
}
|
|
|
|
|
2023-01-16 17:48:25 +00:00
|
|
|
function onSubmit(ev: React.MouseEvent<HTMLButtonElement>) {
|
|
|
|
ev.stopPropagation();
|
|
|
|
sendNote().catch(console.warn);
|
|
|
|
}
|
|
|
|
|
|
|
|
return (
|
|
|
|
<>
|
2023-01-25 18:08:53 +00:00
|
|
|
<button className="note-create-button" type="button" onClick={() => setShow(!show)}>
|
|
|
|
<Plus />
|
|
|
|
</button>
|
|
|
|
{show && (
|
|
|
|
<Modal onClose={props.onClose}>
|
2023-01-16 17:48:25 +00:00
|
|
|
<div className={`flex note-creator ${props.replyTo ? 'note-reply' : ''}`}>
|
|
|
|
<div className="flex f-col mr10 f-grow">
|
|
|
|
<Textarea
|
|
|
|
autoFocus={props.autoFocus}
|
|
|
|
className={`textarea ${active ? "textarea--focused" : ""}`}
|
|
|
|
onChange={onChange}
|
|
|
|
value={note}
|
|
|
|
onFocus={() => setActive(true)}
|
|
|
|
/>
|
2023-01-25 18:08:53 +00:00
|
|
|
<div className="attachment">
|
|
|
|
{(error?.length ?? 0) > 0 ? <b className="error">{error}</b> : null}
|
|
|
|
<FontAwesomeIcon icon={faPaperclip} size="xl" onClick={(e) => attachFile()} />
|
2023-01-16 17:48:25 +00:00
|
|
|
</div>
|
2023-01-25 18:08:53 +00:00
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
<div className="note-creator-actions">
|
|
|
|
<button className="secondary" type="button" onClick={cancel}>
|
|
|
|
Cancel
|
|
|
|
</button>
|
|
|
|
<button type="button" onClick={onSubmit}>
|
|
|
|
{props.replyTo ? 'Reply' : 'Send'}
|
|
|
|
</button>
|
2023-01-16 17:48:25 +00:00
|
|
|
</div>
|
2023-01-25 18:08:53 +00:00
|
|
|
</Modal>
|
|
|
|
)}
|
2023-01-16 17:48:25 +00:00
|
|
|
</>
|
|
|
|
);
|
2023-01-18 23:31:34 +00:00
|
|
|
}
|