fix: note creator mobile
All checks were successful
continuous-integration/drone/push Build is passing
continuous-integration/drone/tag Build is passing

This commit is contained in:
Kieran 2023-10-21 22:26:04 +01:00
parent 63950f1e6b
commit c2991b8e26
Signed by: Kieran
GPG Key ID: DE71CEB3925BE941
6 changed files with 23 additions and 31 deletions

View File

@ -1,7 +1,6 @@
import Icon from "Icons/Icon";
import useLoading from "Hooks/useLoading";
import Spinner from "Icons/Spinner";
import classNames from "classnames";
export type AsyncIconProps = React.HTMLProps<HTMLDivElement> & {
iconName: string;
@ -17,7 +16,7 @@ export function AsyncIcon(props: AsyncIconProps) {
delete mergedProps["iconSize"];
delete mergedProps["loading"];
return (
<div {...mergedProps} onClick={handle} className={classNames("button-icon-sm", props.className)}>
<div {...mergedProps} onClick={handle} className={props.className}>
{loading ? <Spinner /> : <Icon name={props.iconName} size={props.iconSize} />}
{props.children}
</div>

View File

@ -34,7 +34,7 @@ export default function DmWindow({ id }: { id: string }) {
<div>
<div className="flex flex-col">{chat && <DmChatSelected chat={chat} />}</div>
</div>
<div>
<div className="flex g8">
<WriteMessage chat={chat} />
</div>
</div>

View File

@ -1,17 +1,14 @@
import { useState } from "react";
import { NostrEvent, NostrLink, NostrPrefix } from "@snort/system";
import useEventPublisher from "Hooks/useEventPublisher";
import Icon from "Icons/Icon";
import Spinner from "Icons/Spinner";
import { useState } from "react";
import useFileUpload from "Upload";
import { openFile } from "SnortUtils";
import Textarea from "../Textarea";
import { Chat } from "chat";
import { AsyncIcon } from "Element/AsyncIcon";
export default function WriteMessage({ chat }: { chat: Chat }) {
const [msg, setMsg] = useState("");
const [sending, setSending] = useState(false);
const [uploading, setUploading] = useState(false);
const [otherEvents, setOtherEvents] = useState<Array<NostrEvent>>([]);
const [error, setError] = useState("");
const { publisher, system } = useEventPublisher();
@ -31,7 +28,6 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
}
async function uploadFile(file: File | Blob) {
setUploading(true);
try {
if (file) {
const rx = await uploader.upload(file, file.name);
@ -51,26 +47,20 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
if (e instanceof Error) {
setError(e.message);
}
} finally {
setUploading(false);
}
}
async function sendMessage() {
if (msg && publisher && chat) {
setSending(true);
const ev = await chat.createMessage(msg, publisher);
await chat.sendMessage(ev, system);
setMsg("");
setSending(false);
}
}
function onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
if (!sending) {
setMsg(e.target.value);
}
}
async function onEnter(e: React.KeyboardEvent<HTMLTextAreaElement>) {
const isEnter = e.code === "Enter";
@ -82,10 +72,8 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
return (
<>
<button className="circle flex items-center" onClick={() => attachFile()}>
{uploading ? <Spinner width={20} /> : <Icon name="attachment" size={20} />}
</button>
<div className="w-max">
<AsyncIcon className="circle flex items-center button" iconName="attachment" onClick={() => attachFile()} />
<div className="grow">
<Textarea
autoFocus={true}
placeholder=""
@ -99,9 +87,7 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
/>
{error && <b className="error">{error}</b>}
</div>
<button className="circle flex items-center" onClick={() => sendMessage()}>
{sending ? <Spinner width={20} /> : <Icon name="arrow-right" size={20} />}
</button>
<AsyncIcon className="circle flex items-center button" iconName="arrow-right" onClick={() => sendMessage()} />
</>
);
}

View File

@ -16,6 +16,7 @@
.note-creator-modal .note.card {
padding: 0;
border: none;
min-height: unset;
}
.note-creator-modal .note.card.note-quote {

View File

@ -465,7 +465,9 @@ export function NoteCreator() {
onClick={() => note.update(v => (v.advanced = !v.advanced))}
className={classNames("note-creator-icon", { active: note.advanced })}
/>
<span className="sm:inline hidden">
<FormattedMessage defaultMessage="Preview" />
</span>
<ToggleSwitch
onClick={() => loadPreview()}
size={40}
@ -546,10 +548,10 @@ export function NoteCreator() {
)}
{note.preview && getPreviewNote()}
{!note.preview && (
<div onPaste={handlePaste} className={`note-creator${note.pollOptions ? " poll" : ""}`}>
<div onPaste={handlePaste} className={classNames("note-creator", { poll: Boolean(note.pollOptions) })}>
<Textarea
autoFocus
className={`textarea ${note.active ? "textarea--focused" : ""}`}
className={classNames("textarea", { "textarea--focused": note.active })}
onChange={c => onChange(c)}
value={note.note}
onFocus={() => note.update(v => (v.active = true))}

View File

@ -241,10 +241,7 @@ small {
line-height: 22px; /* 157.143% */
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
.button {
position: relative;
cursor: pointer;
padding: 10px 16px;
@ -257,6 +254,13 @@ button,
outline: none;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
@apply button;
}
.btn,
input,
select {
@ -809,7 +813,7 @@ button.tall {
}
}
.rta__textarea {
.note-creator-modal .rta__textarea {
/* Fix width calculation to account for 32px padding on input */
width: calc(100% - 32px) !important;
font-size: 15px !important;