fix: note creator mobile
This commit is contained in:
parent
63950f1e6b
commit
c2991b8e26
@ -1,7 +1,6 @@
|
|||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import useLoading from "Hooks/useLoading";
|
import useLoading from "Hooks/useLoading";
|
||||||
import Spinner from "Icons/Spinner";
|
import Spinner from "Icons/Spinner";
|
||||||
import classNames from "classnames";
|
|
||||||
|
|
||||||
export type AsyncIconProps = React.HTMLProps<HTMLDivElement> & {
|
export type AsyncIconProps = React.HTMLProps<HTMLDivElement> & {
|
||||||
iconName: string;
|
iconName: string;
|
||||||
@ -17,7 +16,7 @@ export function AsyncIcon(props: AsyncIconProps) {
|
|||||||
delete mergedProps["iconSize"];
|
delete mergedProps["iconSize"];
|
||||||
delete mergedProps["loading"];
|
delete mergedProps["loading"];
|
||||||
return (
|
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} />}
|
{loading ? <Spinner /> : <Icon name={props.iconName} size={props.iconSize} />}
|
||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
|
@ -34,7 +34,7 @@ export default function DmWindow({ id }: { id: string }) {
|
|||||||
<div>
|
<div>
|
||||||
<div className="flex flex-col">{chat && <DmChatSelected chat={chat} />}</div>
|
<div className="flex flex-col">{chat && <DmChatSelected chat={chat} />}</div>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div className="flex g8">
|
||||||
<WriteMessage chat={chat} />
|
<WriteMessage chat={chat} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,17 +1,14 @@
|
|||||||
|
import { useState } from "react";
|
||||||
import { NostrEvent, NostrLink, NostrPrefix } from "@snort/system";
|
import { NostrEvent, NostrLink, NostrPrefix } from "@snort/system";
|
||||||
import useEventPublisher from "Hooks/useEventPublisher";
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
import Icon from "Icons/Icon";
|
|
||||||
import Spinner from "Icons/Spinner";
|
|
||||||
import { useState } from "react";
|
|
||||||
import useFileUpload from "Upload";
|
import useFileUpload from "Upload";
|
||||||
import { openFile } from "SnortUtils";
|
import { openFile } from "SnortUtils";
|
||||||
import Textarea from "../Textarea";
|
import Textarea from "../Textarea";
|
||||||
import { Chat } from "chat";
|
import { Chat } from "chat";
|
||||||
|
import { AsyncIcon } from "Element/AsyncIcon";
|
||||||
|
|
||||||
export default function WriteMessage({ chat }: { chat: Chat }) {
|
export default function WriteMessage({ chat }: { chat: Chat }) {
|
||||||
const [msg, setMsg] = useState("");
|
const [msg, setMsg] = useState("");
|
||||||
const [sending, setSending] = useState(false);
|
|
||||||
const [uploading, setUploading] = useState(false);
|
|
||||||
const [otherEvents, setOtherEvents] = useState<Array<NostrEvent>>([]);
|
const [otherEvents, setOtherEvents] = useState<Array<NostrEvent>>([]);
|
||||||
const [error, setError] = useState("");
|
const [error, setError] = useState("");
|
||||||
const { publisher, system } = useEventPublisher();
|
const { publisher, system } = useEventPublisher();
|
||||||
@ -31,7 +28,6 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async function uploadFile(file: File | Blob) {
|
async function uploadFile(file: File | Blob) {
|
||||||
setUploading(true);
|
|
||||||
try {
|
try {
|
||||||
if (file) {
|
if (file) {
|
||||||
const rx = await uploader.upload(file, file.name);
|
const rx = await uploader.upload(file, file.name);
|
||||||
@ -51,26 +47,20 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
|
|||||||
if (e instanceof Error) {
|
if (e instanceof Error) {
|
||||||
setError(e.message);
|
setError(e.message);
|
||||||
}
|
}
|
||||||
} finally {
|
|
||||||
setUploading(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function sendMessage() {
|
async function sendMessage() {
|
||||||
if (msg && publisher && chat) {
|
if (msg && publisher && chat) {
|
||||||
setSending(true);
|
|
||||||
const ev = await chat.createMessage(msg, publisher);
|
const ev = await chat.createMessage(msg, publisher);
|
||||||
await chat.sendMessage(ev, system);
|
await chat.sendMessage(ev, system);
|
||||||
setMsg("");
|
setMsg("");
|
||||||
setSending(false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
|
function onChange(e: React.ChangeEvent<HTMLTextAreaElement>) {
|
||||||
if (!sending) {
|
|
||||||
setMsg(e.target.value);
|
setMsg(e.target.value);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
async function onEnter(e: React.KeyboardEvent<HTMLTextAreaElement>) {
|
async function onEnter(e: React.KeyboardEvent<HTMLTextAreaElement>) {
|
||||||
const isEnter = e.code === "Enter";
|
const isEnter = e.code === "Enter";
|
||||||
@ -82,10 +72,8 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button className="circle flex items-center" onClick={() => attachFile()}>
|
<AsyncIcon className="circle flex items-center button" iconName="attachment" onClick={() => attachFile()} />
|
||||||
{uploading ? <Spinner width={20} /> : <Icon name="attachment" size={20} />}
|
<div className="grow">
|
||||||
</button>
|
|
||||||
<div className="w-max">
|
|
||||||
<Textarea
|
<Textarea
|
||||||
autoFocus={true}
|
autoFocus={true}
|
||||||
placeholder=""
|
placeholder=""
|
||||||
@ -99,9 +87,7 @@ export default function WriteMessage({ chat }: { chat: Chat }) {
|
|||||||
/>
|
/>
|
||||||
{error && <b className="error">{error}</b>}
|
{error && <b className="error">{error}</b>}
|
||||||
</div>
|
</div>
|
||||||
<button className="circle flex items-center" onClick={() => sendMessage()}>
|
<AsyncIcon className="circle flex items-center button" iconName="arrow-right" onClick={() => sendMessage()} />
|
||||||
{sending ? <Spinner width={20} /> : <Icon name="arrow-right" size={20} />}
|
|
||||||
</button>
|
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
.note-creator-modal .note.card {
|
.note-creator-modal .note.card {
|
||||||
padding: 0;
|
padding: 0;
|
||||||
border: none;
|
border: none;
|
||||||
|
min-height: unset;
|
||||||
}
|
}
|
||||||
|
|
||||||
.note-creator-modal .note.card.note-quote {
|
.note-creator-modal .note.card.note-quote {
|
||||||
|
@ -465,7 +465,9 @@ export function NoteCreator() {
|
|||||||
onClick={() => note.update(v => (v.advanced = !v.advanced))}
|
onClick={() => note.update(v => (v.advanced = !v.advanced))}
|
||||||
className={classNames("note-creator-icon", { active: note.advanced })}
|
className={classNames("note-creator-icon", { active: note.advanced })}
|
||||||
/>
|
/>
|
||||||
|
<span className="sm:inline hidden">
|
||||||
<FormattedMessage defaultMessage="Preview" />
|
<FormattedMessage defaultMessage="Preview" />
|
||||||
|
</span>
|
||||||
<ToggleSwitch
|
<ToggleSwitch
|
||||||
onClick={() => loadPreview()}
|
onClick={() => loadPreview()}
|
||||||
size={40}
|
size={40}
|
||||||
@ -546,10 +548,10 @@ export function NoteCreator() {
|
|||||||
)}
|
)}
|
||||||
{note.preview && getPreviewNote()}
|
{note.preview && getPreviewNote()}
|
||||||
{!note.preview && (
|
{!note.preview && (
|
||||||
<div onPaste={handlePaste} className={`note-creator${note.pollOptions ? " poll" : ""}`}>
|
<div onPaste={handlePaste} className={classNames("note-creator", { poll: Boolean(note.pollOptions) })}>
|
||||||
<Textarea
|
<Textarea
|
||||||
autoFocus
|
autoFocus
|
||||||
className={`textarea ${note.active ? "textarea--focused" : ""}`}
|
className={classNames("textarea", { "textarea--focused": note.active })}
|
||||||
onChange={c => onChange(c)}
|
onChange={c => onChange(c)}
|
||||||
value={note.note}
|
value={note.note}
|
||||||
onFocus={() => note.update(v => (v.active = true))}
|
onFocus={() => note.update(v => (v.active = true))}
|
||||||
|
@ -241,10 +241,7 @@ small {
|
|||||||
line-height: 22px; /* 157.143% */
|
line-height: 22px; /* 157.143% */
|
||||||
}
|
}
|
||||||
|
|
||||||
button,
|
.button {
|
||||||
[type="button"],
|
|
||||||
[type="reset"],
|
|
||||||
[type="submit"] {
|
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
padding: 10px 16px;
|
padding: 10px 16px;
|
||||||
@ -257,6 +254,13 @@ button,
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button,
|
||||||
|
[type="button"],
|
||||||
|
[type="reset"],
|
||||||
|
[type="submit"] {
|
||||||
|
@apply button;
|
||||||
|
}
|
||||||
|
|
||||||
.btn,
|
.btn,
|
||||||
input,
|
input,
|
||||||
select {
|
select {
|
||||||
@ -809,7 +813,7 @@ button.tall {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.rta__textarea {
|
.note-creator-modal .rta__textarea {
|
||||||
/* Fix width calculation to account for 32px padding on input */
|
/* Fix width calculation to account for 32px padding on input */
|
||||||
width: calc(100% - 32px) !important;
|
width: calc(100% - 32px) !important;
|
||||||
font-size: 15px !important;
|
font-size: 15px !important;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user