forked from Kieran/snort
fix: note broadcaster bug / createPortal for modal
This commit is contained in:
parent
c1ea68b296
commit
0e3661afc6
@ -307,18 +307,18 @@ export function NoteCreator() {
|
|||||||
onChange={e => {
|
onChange={e => {
|
||||||
note.update(
|
note.update(
|
||||||
v =>
|
v =>
|
||||||
(v.selectedCustomRelays =
|
(v.selectedCustomRelays =
|
||||||
// set false if all relays selected
|
// set false if all relays selected
|
||||||
e.target.checked &&
|
e.target.checked &&
|
||||||
note.selectedCustomRelays &&
|
note.selectedCustomRelays &&
|
||||||
note.selectedCustomRelays.length == a.length - 1
|
note.selectedCustomRelays.length == a.length - 1
|
||||||
? undefined
|
? undefined
|
||||||
: // otherwise return selectedCustomRelays with target relay added / removed
|
: // otherwise return selectedCustomRelays with target relay added / removed
|
||||||
a.filter(el =>
|
a.filter(el =>
|
||||||
el === r
|
el === r
|
||||||
? e.target.checked
|
? e.target.checked
|
||||||
: !note.selectedCustomRelays || note.selectedCustomRelays.includes(el),
|
: !note.selectedCustomRelays || note.selectedCustomRelays.includes(el),
|
||||||
)),
|
)),
|
||||||
);
|
);
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -387,9 +387,9 @@ export function NoteCreator() {
|
|||||||
onChange={e =>
|
onChange={e =>
|
||||||
note.update(
|
note.update(
|
||||||
v =>
|
v =>
|
||||||
(v.zapSplits = arr.map((vv, ii) =>
|
(v.zapSplits = arr.map((vv, ii) =>
|
||||||
ii === i ? { ...vv, weight: Number(e.target.value) } : vv,
|
ii === i ? { ...vv, weight: Number(e.target.value) } : vv,
|
||||||
)),
|
)),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
/>
|
/>
|
||||||
@ -570,18 +570,20 @@ export function NoteCreator() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function reset() {
|
||||||
|
note.update(v => {
|
||||||
|
v.reset();
|
||||||
|
v.show = false;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (!note.show) return null;
|
if (!note.show) return null;
|
||||||
return (
|
return (
|
||||||
<Modal id="note-creator" className="note-creator-modal" onClose={() => note.update(v => (v.show = false))}>
|
<Modal id="note-creator" className="note-creator-modal" onClose={reset}>
|
||||||
{note.sending && (
|
{note.sending && (
|
||||||
<NoteBroadcaster
|
<NoteBroadcaster
|
||||||
evs={note.sending}
|
evs={note.sending}
|
||||||
onClose={() => {
|
onClose={reset}
|
||||||
note.update(n => {
|
|
||||||
n.reset();
|
|
||||||
n.show = false;
|
|
||||||
});
|
|
||||||
}}
|
|
||||||
customRelays={note.selectedCustomRelays}
|
customRelays={note.selectedCustomRelays}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import "./NoteCreatorButton.css";
|
import "./NoteCreatorButton.css";
|
||||||
import { useRef, useMemo } from "react";
|
import { useRef, useMemo } from "react";
|
||||||
import { useLocation } from "react-router-dom";
|
import { useLocation } from "react-router-dom";
|
||||||
|
import classNames from "classnames";
|
||||||
|
|
||||||
import { isFormElement } from "SnortUtils";
|
import { isFormElement } from "SnortUtils";
|
||||||
import useKeyboardShortcut from "Hooks/useKeyboardShortcut";
|
import useKeyboardShortcut from "Hooks/useKeyboardShortcut";
|
||||||
@ -8,7 +9,6 @@ import useLogin from "Hooks/useLogin";
|
|||||||
import Icon from "Icons/Icon";
|
import Icon from "Icons/Icon";
|
||||||
import { useNoteCreator } from "State/NoteCreator";
|
import { useNoteCreator } from "State/NoteCreator";
|
||||||
import { NoteCreator } from "./NoteCreator";
|
import { NoteCreator } from "./NoteCreator";
|
||||||
import classNames from "classnames";
|
|
||||||
|
|
||||||
export const NoteCreatorButton = ({ className }: { className?: string }) => {
|
export const NoteCreatorButton = ({ className }: { className?: string }) => {
|
||||||
const buttonRef = useRef<HTMLButtonElement>(null);
|
const buttonRef = useRef<HTMLButtonElement>(null);
|
||||||
@ -27,15 +27,14 @@ export const NoteCreatorButton = ({ className }: { className?: string }) => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
const shouldHideNoteCreator = useMemo(() => {
|
const shouldHideNoteCreator = useMemo(() => {
|
||||||
const isReplyNoteCreatorShowing = replyTo && show;
|
const isReply = replyTo && show;
|
||||||
const hideOn = ["/settings", "/messages", "/new", "/login", "/donate", "/e", "/subscribe"];
|
const hideOn = ["/settings", "/messages", "/new", "/login", "/donate", "/e", "/nevent", "/note1", "/naddr", "/subscribe"];
|
||||||
return readonly || isReplyNoteCreatorShowing || hideOn.some(a => location.pathname.startsWith(a));
|
return (readonly || hideOn.some(a => location.pathname.startsWith(a))) && !isReply;
|
||||||
}, [location, readonly]);
|
}, [location, readonly]);
|
||||||
|
|
||||||
if (shouldHideNoteCreator) return null;
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<button
|
{!shouldHideNoteCreator && <button
|
||||||
ref={buttonRef}
|
ref={buttonRef}
|
||||||
className={classNames("primary circle", className)}
|
className={classNames("primary circle", className)}
|
||||||
onClick={() =>
|
onClick={() =>
|
||||||
@ -45,7 +44,7 @@ export const NoteCreatorButton = ({ className }: { className?: string }) => {
|
|||||||
})
|
})
|
||||||
}>
|
}>
|
||||||
<Icon name="plus" size={16} />
|
<Icon name="plus" size={16} />
|
||||||
</button>
|
</button>}
|
||||||
<NoteCreator key="global-note-creator" />
|
<NoteCreator key="global-note-creator" />
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import React, { useEffect, useState } from "react";
|
import React, { forwardRef, useEffect, useState } from "react";
|
||||||
import { FormattedMessage, useIntl } from "react-intl";
|
import { FormattedMessage, useIntl } from "react-intl";
|
||||||
import { useLongPress } from "use-long-press";
|
import { useLongPress } from "use-long-press";
|
||||||
import { TaggedNostrEvent, ParsedZap, countLeadingZeros, NostrLink } from "@snort/system";
|
import { TaggedNostrEvent, ParsedZap, countLeadingZeros, NostrLink } from "@snort/system";
|
||||||
@ -10,7 +10,6 @@ import classNames from "classnames";
|
|||||||
import { formatShort } from "Number";
|
import { formatShort } from "Number";
|
||||||
import useEventPublisher from "Hooks/useEventPublisher";
|
import useEventPublisher from "Hooks/useEventPublisher";
|
||||||
import { delay, findTag, getDisplayName } from "SnortUtils";
|
import { delay, findTag, getDisplayName } from "SnortUtils";
|
||||||
import { NoteCreator } from "Element/Event/NoteCreator";
|
|
||||||
import SendSats from "Element/SendSats";
|
import SendSats from "Element/SendSats";
|
||||||
import { ZapsSummary } from "Element/Event/Zap";
|
import { ZapsSummary } from "Element/Event/Zap";
|
||||||
import { AsyncIcon, AsyncIconProps } from "Element/AsyncIcon";
|
import { AsyncIcon, AsyncIconProps } from "Element/AsyncIcon";
|
||||||
@ -58,7 +57,6 @@ export default function NoteFooter(props: NoteFooterProps) {
|
|||||||
const interactionCache = useInteractionCache(publicKey, ev.id);
|
const interactionCache = useInteractionCache(publicKey, ev.id);
|
||||||
const { publisher, system } = useEventPublisher();
|
const { publisher, system } = useEventPublisher();
|
||||||
const note = useNoteCreator(n => ({ show: n.show, replyTo: n.replyTo, update: n.update, quote: n.quote }));
|
const note = useNoteCreator(n => ({ show: n.show, replyTo: n.replyTo, update: n.update, quote: n.quote }));
|
||||||
const willRenderNoteCreator = note.show && (note.replyTo?.id === ev.id || note.quote);
|
|
||||||
const [tip, setTip] = useState(false);
|
const [tip, setTip] = useState(false);
|
||||||
const [zapping, setZapping] = useState(false);
|
const [zapping, setZapping] = useState(false);
|
||||||
const walletState = useWallet();
|
const walletState = useWallet();
|
||||||
@ -303,7 +301,6 @@ export default function NoteFooter(props: NoteFooterProps) {
|
|||||||
{tipButton()}
|
{tipButton()}
|
||||||
{powIcon()}
|
{powIcon()}
|
||||||
</div>
|
</div>
|
||||||
{willRenderNoteCreator && <NoteCreator key={`note-creator-${ev.id}`} />}
|
|
||||||
<SendSats targets={getZapTarget()} onClose={() => setTip(false)} show={tip} note={ev.id} allocatePool={true} />
|
<SendSats targets={getZapTarget()} onClose={() => setTip(false)} show={tip} note={ev.id} allocatePool={true} />
|
||||||
</div>
|
</div>
|
||||||
<ZapsSummary zaps={zaps} />
|
<ZapsSummary zaps={zaps} />
|
||||||
@ -311,7 +308,7 @@ export default function NoteFooter(props: NoteFooterProps) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function AsyncFooterIcon(props: AsyncIconProps & { value: number }) {
|
const AsyncFooterIcon = forwardRef((props: AsyncIconProps & { value: number }) => {
|
||||||
const mergedProps = {
|
const mergedProps = {
|
||||||
...props,
|
...props,
|
||||||
iconSize: 18,
|
iconSize: 18,
|
||||||
@ -322,4 +319,4 @@ function AsyncFooterIcon(props: AsyncIconProps & { value: number }) {
|
|||||||
{props.value > 0 && <div className="reaction-pill-number">{formatShort(props.value)}</div>}
|
{props.value > 0 && <div className="reaction-pill-number">{formatShort(props.value)}</div>}
|
||||||
</AsyncIcon>
|
</AsyncIcon>
|
||||||
);
|
);
|
||||||
}
|
});
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { createPortal } from "react-dom";
|
||||||
import "./Modal.css";
|
import "./Modal.css";
|
||||||
import { ReactNode, useEffect } from "react";
|
import { ReactNode, useEffect } from "react";
|
||||||
|
|
||||||
@ -26,7 +27,7 @@ export default function Modal(props: ModalProps) {
|
|||||||
};
|
};
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return createPortal(
|
||||||
<div className={`modal${props.className ? ` ${props.className}` : ""}`} onClick={props.onClose}>
|
<div className={`modal${props.className ? ` ${props.className}` : ""}`} onClick={props.onClose}>
|
||||||
<div className="modal-body" onClick={props.onClose}>
|
<div className="modal-body" onClick={props.onClose}>
|
||||||
<div
|
<div
|
||||||
@ -37,6 +38,5 @@ export default function Modal(props: ModalProps) {
|
|||||||
{props.children}
|
{props.children}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>, document.body);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
import { ReactNode, useSyncExternalStore } from "react";
|
import { ReactNode, useSyncExternalStore } from "react";
|
||||||
|
import { createPortal } from "react-dom";
|
||||||
import { v4 as uuid } from "uuid";
|
import { v4 as uuid } from "uuid";
|
||||||
import { ExternalStore, unixNow } from "@snort/shared";
|
import { ExternalStore, unixNow } from "@snort/shared";
|
||||||
|
|
||||||
@ -42,7 +43,7 @@ export default function Toaster() {
|
|||||||
() => Toastore.snapshot(),
|
() => Toastore.snapshot(),
|
||||||
);
|
);
|
||||||
|
|
||||||
return (
|
return createPortal(
|
||||||
<div className="toaster">
|
<div className="toaster">
|
||||||
{toast.map(a => (
|
{toast.map(a => (
|
||||||
<div className="card flex" key={a.id}>
|
<div className="card flex" key={a.id}>
|
||||||
@ -50,6 +51,5 @@ export default function Toaster() {
|
|||||||
{a.element}
|
{a.element}
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>, document.body);
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user