feat: preview note
This commit is contained in:
parent
0b00310212
commit
b4f37b1ed3
@ -46,6 +46,7 @@ export interface NoteProps {
|
|||||||
showReactionsLink?: boolean;
|
showReactionsLink?: boolean;
|
||||||
canUnpin?: boolean;
|
canUnpin?: boolean;
|
||||||
canUnbookmark?: boolean;
|
canUnbookmark?: boolean;
|
||||||
|
canClick?: boolean;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -177,7 +178,7 @@ export default function Note(props: NoteProps) {
|
|||||||
eTarget: TaggedRawEvent,
|
eTarget: TaggedRawEvent,
|
||||||
isTargetAllowed: boolean = e.target === e.currentTarget
|
isTargetAllowed: boolean = e.target === e.currentTarget
|
||||||
) {
|
) {
|
||||||
if (!isTargetAllowed) {
|
if (!isTargetAllowed || opt?.canClick === false) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -280,7 +281,12 @@ export default function Note(props: NoteProps) {
|
|||||||
<>
|
<>
|
||||||
{options.showHeader && (
|
{options.showHeader && (
|
||||||
<div className="header flex">
|
<div className="header flex">
|
||||||
<ProfileImage autoWidth={false} pubkey={ev.pubkey} subHeader={replyTag() ?? undefined} />
|
<ProfileImage
|
||||||
|
autoWidth={false}
|
||||||
|
pubkey={ev.pubkey}
|
||||||
|
subHeader={replyTag() ?? undefined}
|
||||||
|
linkToProfile={opt?.canClick === undefined}
|
||||||
|
/>
|
||||||
{(options.showTime || options.showBookmarked) && (
|
{(options.showTime || options.showBookmarked) && (
|
||||||
<div className="info">
|
<div className="info">
|
||||||
{options.showBookmarked && (
|
{options.showBookmarked && (
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
import "./NoteCreator.css";
|
import "./NoteCreator.css";
|
||||||
import { useState } from "react";
|
import { useState } from "react";
|
||||||
import { FormattedMessage } from "react-intl";
|
import { FormattedMessage } from "react-intl";
|
||||||
import { TaggedRawEvent } from "@snort/nostr";
|
import { RawEvent, TaggedRawEvent } from "@snort/nostr";
|
||||||
|
|
||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import useEventPublisher from "Feed/EventPublisher";
|
import useEventPublisher from "Feed/EventPublisher";
|
||||||
@ -10,6 +10,7 @@ import Textarea from "Element/Textarea";
|
|||||||
import Modal from "Element/Modal";
|
import Modal from "Element/Modal";
|
||||||
import ProfileImage from "Element/ProfileImage";
|
import ProfileImage from "Element/ProfileImage";
|
||||||
import useFileUpload from "Upload";
|
import useFileUpload from "Upload";
|
||||||
|
import Note from "Element/Note";
|
||||||
|
|
||||||
import messages from "./messages";
|
import messages from "./messages";
|
||||||
|
|
||||||
@ -40,11 +41,11 @@ export interface NoteCreatorProps {
|
|||||||
export function NoteCreator(props: NoteCreatorProps) {
|
export function NoteCreator(props: NoteCreatorProps) {
|
||||||
const { show, setShow, replyTo, onSend, autoFocus } = props;
|
const { show, setShow, replyTo, onSend, autoFocus } = props;
|
||||||
const publisher = useEventPublisher();
|
const publisher = useEventPublisher();
|
||||||
const [note, setNote] = useState<string>("");
|
const [note, setNote] = useState("");
|
||||||
const [error, setError] = useState<string>();
|
const [error, setError] = useState("");
|
||||||
const [active, setActive] = useState<boolean>(false);
|
const [active, setActive] = useState(false);
|
||||||
|
const [preview, setPreview] = useState<RawEvent>();
|
||||||
const uploader = useFileUpload();
|
const uploader = useFileUpload();
|
||||||
const hasErrors = (error?.length ?? 0) > 0;
|
|
||||||
|
|
||||||
async function sendNote() {
|
async function sendNote() {
|
||||||
if (note) {
|
if (note) {
|
||||||
@ -98,27 +99,59 @@ export function NoteCreator(props: NoteCreatorProps) {
|
|||||||
sendNote().catch(console.warn);
|
sendNote().catch(console.warn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function loadPreview() {
|
||||||
|
if (preview) {
|
||||||
|
setPreview(undefined);
|
||||||
|
} else {
|
||||||
|
const tmpNote = await publisher.note(note);
|
||||||
|
if (tmpNote) {
|
||||||
|
setPreview(tmpNote);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function getPreviewNote() {
|
||||||
|
if (preview) {
|
||||||
|
return (
|
||||||
|
<Note
|
||||||
|
data={preview as TaggedRawEvent}
|
||||||
|
related={[]}
|
||||||
|
options={{
|
||||||
|
showFooter: false,
|
||||||
|
canClick: false,
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{show && (
|
{show && (
|
||||||
<Modal className="note-creator-modal" onClose={() => setShow(false)}>
|
<Modal className="note-creator-modal" onClose={() => setShow(false)}>
|
||||||
{replyTo && <NotePreview note={replyTo} />}
|
{replyTo && <NotePreview note={replyTo} />}
|
||||||
<div className={`flex note-creator ${replyTo ? "note-reply" : ""}`}>
|
{preview && getPreviewNote()}
|
||||||
<div className="flex f-col mr10 f-grow">
|
{!preview && (
|
||||||
<Textarea
|
<div className={`flex note-creator ${replyTo ? "note-reply" : ""}`}>
|
||||||
autoFocus={autoFocus}
|
<div className="flex f-col mr10 f-grow">
|
||||||
className={`textarea ${active ? "textarea--focused" : ""}`}
|
<Textarea
|
||||||
onChange={onChange}
|
autoFocus={autoFocus}
|
||||||
value={note}
|
className={`textarea ${active ? "textarea--focused" : ""}`}
|
||||||
onFocus={() => setActive(true)}
|
onChange={onChange}
|
||||||
/>
|
value={note}
|
||||||
<button type="button" className="attachment" onClick={attachFile}>
|
onFocus={() => setActive(true)}
|
||||||
<Icon name="attachment" />
|
/>
|
||||||
</button>
|
<button type="button" className="attachment" onClick={attachFile}>
|
||||||
|
<Icon name="attachment" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
{error && <span className="error">{error}</span>}
|
||||||
</div>
|
</div>
|
||||||
{hasErrors && <span className="error">{error}</span>}
|
)}
|
||||||
</div>
|
|
||||||
<div className="note-creator-actions">
|
<div className="note-creator-actions">
|
||||||
|
<button className="secondary" type="button" onClick={loadPreview}>
|
||||||
|
<FormattedMessage defaultMessage="Toggle Preview" />
|
||||||
|
</button>
|
||||||
<button className="secondary" type="button" onClick={cancel}>
|
<button className="secondary" type="button" onClick={cancel}>
|
||||||
<FormattedMessage {...messages.Cancel} />
|
<FormattedMessage {...messages.Cancel} />
|
||||||
</button>
|
</button>
|
||||||
|
@ -51,6 +51,9 @@
|
|||||||
"1c4YST": {
|
"1c4YST": {
|
||||||
"defaultMessage": "Connected to: {node} 🎉"
|
"defaultMessage": "Connected to: {node} 🎉"
|
||||||
},
|
},
|
||||||
|
"1iQ8GN": {
|
||||||
|
"defaultMessage": "Toggle Preview"
|
||||||
|
},
|
||||||
"1nYUGC": {
|
"1nYUGC": {
|
||||||
"defaultMessage": "{n} Following"
|
"defaultMessage": "{n} Following"
|
||||||
},
|
},
|
||||||
|
@ -16,6 +16,7 @@
|
|||||||
"1A7TZk": "What is Snort and how does it work?",
|
"1A7TZk": "What is Snort and how does it work?",
|
||||||
"1Mo59U": "Are you sure you want to remove this note from bookmarks?",
|
"1Mo59U": "Are you sure you want to remove this note from bookmarks?",
|
||||||
"1c4YST": "Connected to: {node} 🎉",
|
"1c4YST": "Connected to: {node} 🎉",
|
||||||
|
"1iQ8GN": "Toggle Preview",
|
||||||
"1nYUGC": "{n} Following",
|
"1nYUGC": "{n} Following",
|
||||||
"1udzha": "Conversations",
|
"1udzha": "Conversations",
|
||||||
"2/2yg+": "Add",
|
"2/2yg+": "Add",
|
||||||
@ -320,4 +321,4 @@
|
|||||||
"zjJZBd": "You're ready!",
|
"zjJZBd": "You're ready!",
|
||||||
"zonsdq": "Failed to load LNURL service",
|
"zonsdq": "Failed to load LNURL service",
|
||||||
"zvCDao": "Automatically show latest notes"
|
"zvCDao": "Automatically show latest notes"
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user