File uploads in note creator

This commit is contained in:
Kieran 2023-01-03 16:55:51 +00:00
parent bc082ec203
commit 554859f4b6
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
5 changed files with 62 additions and 20 deletions

11
src/Util.js Normal file
View File

@ -0,0 +1,11 @@
export async function openFile() {
return new Promise((resolve, reject) => {
let elm = document.createElement("input");
elm.type = "file";
elm.onchange = (e) => {
resolve(e.target.files[0]);
};
elm.click();
});
}

View File

@ -0,0 +1,18 @@
.note-creator {
margin-bottom: 10px;
}
.note-creator textarea {
min-height: 40px;
max-height: 300px;
border-radius: 10px 10px 0 0;
max-width: -webkit-fill-available;
min-width: -webkit-fill-available;
}
.note-creator .actions {
cursor: pointer;
padding: 5px 10px;
border-radius: 0 0 10px 10px;
background-color: #222;
}

View File

@ -1,11 +1,18 @@
import "./NoteCreator.css";
import { useState } from "react";
import useEventPublisher from "../feed/EventPublisher";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPaperclip } from "@fortawesome/free-solid-svg-icons";
import { openFile } from "../Util";
import VoidUpload from "../feed/VoidUpload";
import { FileExtensionRegex } from "../Const";
export function NoteCreator(props) {
const replyTo = props.replyTo;
const onSend = props.onSend;
const publisher = useEventPublisher();
const [note, setNote] = useState("");
const [error, setError] = useState("");
async function sendNote() {
let ev = replyTo ?
@ -15,16 +22,33 @@ export function NoteCreator(props) {
console.debug("Sending note: ", ev);
publisher.broadcast(ev);
setNote("");
if(typeof onSend === "function") {
if (typeof onSend === "function") {
onSend();
}
}
async function attachFile() {
let file = await openFile();
let rsp = await VoidUpload(file);
let ext = file.name.match(FileExtensionRegex)[1];
// extension tricks note parser to embed the content
let url = rsp.metadata.url ?? `https://void.cat/d/${rsp.id}.${ext}`;
setNote(n => `${n}\n{url}`);
}
return (
<>
{replyTo ? <small>{`Reply to: ${replyTo.Id.substring(0, 8)}`}</small> : null}
<div className="flex">
<input type="text" placeholder="Sup?" value={note} onChange={(e) => setNote(e.target.value)} className="f-grow mr10"></input>
<div className="flex note-creator">
<div className="flex f-col mr10 f-grow">
<textarea placeholder="Say something!" value={note} onChange={(e) => setNote(e.target.value)} />
<div className="actions">
<FontAwesomeIcon icon={faPaperclip} size="xl" onClick={(e) => attachFile()}/>
{error.length > 0 ? <b className="error">{error}</b> : null}
</div>
</div>
<div className="btn" onClick={() => sendNote()}>Send</div>
</div>
</>

View File

@ -1,9 +1,8 @@
.profile {
display: flex;
align-items: flex-start;
}
.profile > div:last-child {
flex-grow: 1;
margin-left: 10px;
}

View File

@ -17,6 +17,7 @@ import Modal from "../element/Modal";
import { logout } from "../state/Login";
import FollowButton from "../element/FollowButton";
import VoidUpload from "../feed/VoidUpload";
import { openFile } from "../Util";
export default function ProfilePage() {
const dispatch = useDispatch();
@ -101,7 +102,7 @@ export default function ProfilePage() {
// trim empty string fields
Object.keys(userCopy).forEach(k => {
if(userCopy[k] === "") {
if (userCopy[k] === "") {
delete userCopy[k];
}
});
@ -112,17 +113,6 @@ export default function ProfilePage() {
publisher.broadcast(ev);
}
async function openFile() {
return new Promise((resolve, reject) => {
let elm = document.createElement("input");
elm.type = "file";
elm.onchange = (e) => {
resolve(e.target.files[0]);
};
elm.click();
});
}
async function setNewAvatar() {
let file = await openFile();
console.log(file);
@ -195,7 +185,7 @@ export default function ProfilePage() {
<div className="btn" onClick={(e) => setShowLnQr(true)}>
<FontAwesomeIcon icon={faQrcode} size="xl" />
</div>
<div>&nbsp; {lud16}</div>
<div className="f-ellipsis">&nbsp; {lud16.length > 20 ? lud16.substring(0, 20) : lud16}</div>
</div> : null}
{showLnQr === true ?
<Modal onClose={() => setShowLnQr(false)}>
@ -208,7 +198,7 @@ export default function ProfilePage() {
return (
<>
<div className="profile">
<div className="profile flex">
<div>
<div style={{ backgroundImage: `url(${picture.length === 0 ? Nostrich : picture})` }} className="avatar">
{isMe ?
@ -219,7 +209,7 @@ export default function ProfilePage() {
}
</div>
</div>
<div>
<div className="f-grow">
{isMe ? editor() : details()}
</div>
</div>