snort/src/Element/NoteCreator.tsx

119 lines
3.7 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";
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 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-23 17:36:49 +00:00
import useFileUpload from "Feed/FileUpload";
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,
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-23 17:36:49 +00:00
const uploader = useFileUpload();
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("");
2023-01-25 18:16:24 +00:00
setShow(false);
2023-01-16 18:30:08 +00:00
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) {
2023-01-23 17:36:49 +00:00
let rx = await uploader.upload(file, file.name);
if (rx.url) {
setNote(n => `${n ? `${n}\n` : ""}${rx.url}`);
2023-01-23 17:36:49 +00:00
} else if (rx?.error) {
setError(rx.error);
2023-01-16 17:48:25 +00:00
}
}
} 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 && (
2023-01-28 22:07:37 +00:00
<Modal
className="note-creator-modal"
onClose={() => setShow(false)}
>
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
}