snort/src/element/NoteCreator.tsx

104 lines
3.5 KiB
TypeScript
Raw Normal View History

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";
import useEventPublisher from "../feed/EventPublisher";
import { openFile } from "../Util";
import VoidUpload from "../feed/VoidUpload";
import { FileExtensionRegex } from "../Const";
import Textarea from "../element/Textarea";
import Event, { default as NEvent } from "../nostr/Event";
export interface NoteCreatorProps {
replyTo?: NEvent,
onSend?: Function,
show: boolean,
autoFocus: boolean
}
export function NoteCreator(props: NoteCreatorProps) {
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)
}
}
function onSubmit(ev: React.MouseEvent<HTMLButtonElement>) {
ev.stopPropagation();
sendNote().catch(console.warn);
}
if (!props.show) return null;
return (
<>
<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)}
/>
{active && note && (
<div className="actions flex f-row">
<div className="attachment flex f-row">
2023-01-16 18:30:08 +00:00
{(error?.length ?? 0) > 0 ? <b className="error">{error}</b> : null}
2023-01-16 17:48:25 +00:00
<FontAwesomeIcon icon={faPaperclip} size="xl" onClick={(e) => attachFile()} />
</div>
<button type="button" className="btn" onClick={onSubmit}>
{props.replyTo ? 'Reply' : 'Send'}
</button>
</div>
)}
</div>
</div>
</>
);
2023-01-18 23:31:34 +00:00
}