Note creator improvements #193

Merged
verbiricha merged 1 commits from reply into main 2023-02-05 12:11:47 +00:00
4 changed files with 104 additions and 16 deletions

View File

@ -1,9 +1,10 @@
.note-creator { .note-creator {
margin-bottom: 10px; margin-bottom: 10px;
background-color: var(--note-bg); background-color: var(--note-bg);
border: 1px solid var(--gray); border: none;
border-radius: 10px; border-radius: 10px;
padding: 6px; padding: 6px;
position: relative;
} }
.note-reply { .note-reply {
@ -15,10 +16,25 @@
resize: none; resize: none;
background-color: var(--note-bg); background-color: var(--note-bg);
border-radius: 10px 10px 0 0; border-radius: 10px 10px 0 0;
min-height: 120px;
max-width: stretch; max-width: stretch;
min-width: stretch; min-width: stretch;
} }
.note-creator textarea::placeholder {
color: var(--font-secondary-color);
font-size: var(--font-size);
line-height: 24px;
}
@media (min-width: 520px) {
.note-creator textarea { min-height: 210px; }
}
@media (min-width: 720px) {
.note-creator textarea { min-height: 321px; }
}
.note-creator-actions { .note-creator-actions {
width: 100%; width: 100%;
display: flex; display: flex;
@ -30,17 +46,44 @@
.note-creator .attachment { .note-creator .attachment {
cursor: pointer; cursor: pointer;
margin-left: auto; position: absolute;
right: 16px;
bottom: 12px;
width: 48px;
height: 36px;
background: var(--gray-dark);
color: white;
border-radius: 100px;
display: flex;
align-items: center;
justify-content: center;
}
.note-creator .attachment:hover {
background: var(--font-color);
color: var(--gray-dark);
}
.light .note-creator .attachment {
background: var(--gray-light);
}
.light .note-creator .attachment:hover {
background: var(--gray-dark);
color: white;
} }
.note-creator-actions button:not(:last-child) { .note-creator-actions button:not(:last-child) {
margin-right: 4px; margin-right: 4px;
} }
.note-creator .attachment .error { .note-creator .error {
font-weight: normal; position: absolute;
margin-right: 5px; left: 16px;
font-size: 14px; bottom: 12px;
font-color: var(--error);
margin-right: 12px;
font-size: 16px;
} }
.note-creator .btn { .note-creator .btn {
@ -77,6 +120,10 @@
} }
} }
.note-creator-modal .modal-body {
background: var(--modal-bg-color);
}
@media (max-width: 720px) { @media (max-width: 720px) {
.note-creator-modal { .note-creator-modal {
align-items: flex-start; align-items: flex-start;
@ -85,3 +132,13 @@
margin-top: 20vh; margin-top: 20vh;
} }
} }
.note-preview {
word-break: break-all;
}
.note-preview-body {
text-overflow: ellipsis;
padding: 4px 4px 0 56px;
font-size: 14px;
}

View File

@ -1,17 +1,33 @@
import { useState } from "react";
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
import { faPaperclip } from "@fortawesome/free-solid-svg-icons";
import "./NoteCreator.css"; import "./NoteCreator.css";
import { useState } from "react";
import Attachment from "Icons/Attachment";
import Plus from "Icons/Plus"; import Plus from "Icons/Plus";
import useEventPublisher from "Feed/EventPublisher"; import useEventPublisher from "Feed/EventPublisher";
import { openFile } from "Util"; import { openFile } from "Util";
import Textarea from "Element/Textarea"; import Textarea from "Element/Textarea";
import Modal from "Element/Modal"; import Modal from "Element/Modal";
import ProfileImage from "Element/ProfileImage";
import { default as NEvent } from "Nostr/Event"; import { default as NEvent } from "Nostr/Event";
import useFileUpload from "Upload"; import useFileUpload from "Upload";
interface NotePreviewProps {
note: NEvent
}
function NotePreview({ note }: NotePreviewProps) {
return (
<div className="note-preview">
<ProfileImage pubkey={note.PubKey} />
<div className="note-preview-body">
{note.Content.slice(0, 136)}
{note.Content.length > 140 && '...'}
</div>
</div>
)
}
export interface NoteCreatorProps { export interface NoteCreatorProps {
show: boolean show: boolean
setShow: (s: boolean) => void setShow: (s: boolean) => void
@ -27,6 +43,7 @@ export function NoteCreator(props: NoteCreatorProps) {
const [error, setError] = useState<string>(); const [error, setError] = useState<string>();
const [active, setActive] = useState<boolean>(false); const [active, setActive] = useState<boolean>(false);
const uploader = useFileUpload(); const uploader = useFileUpload();
const hasErrors = (error?.length ?? 0) > 0
async function sendNote() { async function sendNote() {
if (note) { if (note) {
@ -88,6 +105,9 @@ export function NoteCreator(props: NoteCreatorProps) {
className="note-creator-modal" className="note-creator-modal"
onClose={() => setShow(false)} onClose={() => setShow(false)}
> >
{replyTo && (
<NotePreview note={replyTo} />
)}
<div className={`flex note-creator ${replyTo ? 'note-reply' : ''}`}> <div className={`flex note-creator ${replyTo ? 'note-reply' : ''}`}>
<div className="flex f-col mr10 f-grow"> <div className="flex f-col mr10 f-grow">
<Textarea <Textarea
@ -97,11 +117,11 @@ export function NoteCreator(props: NoteCreatorProps) {
value={note} value={note}
onFocus={() => setActive(true)} onFocus={() => setActive(true)}
/> />
<div className="attachment"> <button type="button" className="attachment" onClick={(e) => attachFile()}>
{(error?.length ?? 0) > 0 ? <b className="error">{error}</b> : null} <Attachment />
<FontAwesomeIcon icon={faPaperclip} size="xl" onClick={(e) => attachFile()} /> </button>
</div>
</div> </div>
{hasErrors && <span className="error">{error}</span>}
</div> </div>
<div className="note-creator-actions"> <div className="note-creator-actions">
<button className="secondary" type="button" onClick={cancel}> <button className="secondary" type="button" onClick={cancel}>

View File

@ -61,7 +61,7 @@ const Textarea = ({ users, onChange, ...rest }: any) => {
<ReactTextareaAutocomplete <ReactTextareaAutocomplete
{...rest} {...rest}
loadingComponent={() => <span>Loading....</span>} loadingComponent={() => <span>Loading....</span>}
placeholder="Say something!" placeholder="What's on your mind?"
onChange={onChange} onChange={onChange}
textAreaComponent={TextareaAutosize} textAreaComponent={TextareaAutosize}
trigger={{ trigger={{

11
src/Icons/Attachment.tsx Normal file
View File

@ -0,0 +1,11 @@
import IconProps from './IconProps'
const Attachment = (props: IconProps) => {
return (
<svg width="21" height="22" viewBox="0 0 21 22" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M19.1525 9.89945L10.1369 18.9151C8.08662 20.9653 4.7625 20.9653 2.71225 18.9151C0.661997 16.8648 0.661998 13.5407 2.71225 11.4904L11.7279 2.47483C13.0947 1.108 15.3108 1.108 16.6776 2.47483C18.0444 3.84167 18.0444 6.05775 16.6776 7.42458L8.01555 16.0866C7.33213 16.7701 6.22409 16.7701 5.54068 16.0866C4.85726 15.4032 4.85726 14.2952 5.54068 13.6118L13.1421 6.01037" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"/>
</svg>
)
}
export default Attachment