feat: multi-account system
This commit is contained in:
@ -1,13 +1,13 @@
|
||||
import { useState, useMemo, ChangeEvent } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { HexKey, TaggedRawEvent } from "@snort/nostr";
|
||||
|
||||
import Note from "Element/Note";
|
||||
import { RootState } from "State/Store";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { UserCache } from "Cache/UserCache";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
interface BookmarksProps {
|
||||
pubkey: HexKey;
|
||||
bookmarks: readonly TaggedRawEvent[];
|
||||
@ -16,7 +16,7 @@ interface BookmarksProps {
|
||||
|
||||
const Bookmarks = ({ pubkey, bookmarks, related }: BookmarksProps) => {
|
||||
const [onlyPubkey, setOnlyPubkey] = useState<HexKey | "all">("all");
|
||||
const loginPubKey = useSelector((s: RootState) => s.login.publicKey);
|
||||
const loginPubKey = useLogin().publicKey;
|
||||
const ps = useMemo(() => {
|
||||
return [...new Set(bookmarks.map(ev => ev.pubkey))];
|
||||
}, [bookmarks]);
|
||||
|
@ -1,17 +1,15 @@
|
||||
import "./DM.css";
|
||||
import { useEffect, useState } from "react";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { useIntl } from "react-intl";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { HexKey, TaggedRawEvent } from "@snort/nostr";
|
||||
import { TaggedRawEvent } from "@snort/nostr";
|
||||
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import NoteTime from "Element/NoteTime";
|
||||
import Text from "Element/Text";
|
||||
import { setLastReadDm } from "Pages/MessagesPage";
|
||||
import { RootState } from "State/Store";
|
||||
import { incDmInteraction } from "State/Login";
|
||||
import { unwrap } from "Util";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -20,8 +18,7 @@ export type DMProps = {
|
||||
};
|
||||
|
||||
export default function DM(props: DMProps) {
|
||||
const dispatch = useDispatch();
|
||||
const pubKey = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
||||
const pubKey = useLogin().publicKey;
|
||||
const publisher = useEventPublisher();
|
||||
const [content, setContent] = useState("Loading...");
|
||||
const [decrypted, setDecrypted] = useState(false);
|
||||
@ -35,7 +32,6 @@ export default function DM(props: DMProps) {
|
||||
setContent(decrypted || "<ERROR>");
|
||||
if (!isMe) {
|
||||
setLastReadDm(props.data.pubkey);
|
||||
dispatch(incDmInteraction());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
import "./FollowButton.css";
|
||||
import { useSelector } from "react-redux";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
import { RootState } from "State/Store";
|
||||
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { parseId } from "Util";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -15,7 +15,7 @@ export interface FollowButtonProps {
|
||||
export default function FollowButton(props: FollowButtonProps) {
|
||||
const pubkey = parseId(props.pubkey);
|
||||
const publiser = useEventPublisher();
|
||||
const isFollowing = useSelector<RootState, boolean>(s => s.login.follows?.includes(pubkey) ?? false);
|
||||
const isFollowing = useLogin().follows.item.includes(pubkey);
|
||||
const baseClassname = `${props.className} follow-button`;
|
||||
|
||||
async function follow(pubkey: HexKey) {
|
||||
|
@ -1,24 +1,22 @@
|
||||
import { useDispatch } from "react-redux";
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { logout } from "State/Login";
|
||||
|
||||
import { logout } from "Login";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import messages from "./messages";
|
||||
|
||||
export default function LogoutButton() {
|
||||
const dispatch = useDispatch();
|
||||
const navigate = useNavigate();
|
||||
const publicKey = useLogin().publicKey;
|
||||
|
||||
if (!publicKey) return;
|
||||
return (
|
||||
<button
|
||||
className="secondary"
|
||||
type="button"
|
||||
onClick={() => {
|
||||
dispatch(
|
||||
logout(() => {
|
||||
navigate("/");
|
||||
})
|
||||
);
|
||||
logout(publicKey);
|
||||
navigate("/");
|
||||
}}>
|
||||
<FormattedMessage {...messages.Logout} />
|
||||
</button>
|
||||
|
@ -1,14 +1,11 @@
|
||||
import { MixCloudRegex } from "Const";
|
||||
import { useSelector } from "react-redux";
|
||||
import { RootState } from "State/Store";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
const MixCloudEmbed = ({ link }: { link: string }) => {
|
||||
const feedPath = (MixCloudRegex.test(link) && RegExp.$1) + "%2F" + (MixCloudRegex.test(link) && RegExp.$2);
|
||||
|
||||
const lightTheme = useSelector<RootState, boolean>(s => s.login.preferences.theme === "light");
|
||||
|
||||
const lightTheme = useLogin().preferences.theme === "light";
|
||||
const lightParams = lightTheme ? "light=1" : "light=0";
|
||||
|
||||
return (
|
||||
<>
|
||||
<br />
|
||||
|
@ -1,7 +1,7 @@
|
||||
import "./Nip05.css";
|
||||
import { useQuery } from "react-query";
|
||||
import Icon from "Icons/Icon";
|
||||
import { HexKey } from "@snort/nostr";
|
||||
import Icon from "Icons/Icon";
|
||||
|
||||
interface NostrJson {
|
||||
names: Record<string, string>;
|
||||
|
@ -1,7 +1,7 @@
|
||||
import { useEffect, useMemo, useState, ChangeEvent } from "react";
|
||||
import { useIntl, FormattedMessage } from "react-intl";
|
||||
import { useSelector } from "react-redux";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { UserMetadata } from "@snort/nostr";
|
||||
|
||||
import { unwrap } from "Util";
|
||||
import { formatShort } from "Number";
|
||||
@ -20,10 +20,9 @@ import Copy from "Element/Copy";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { debounce } from "Util";
|
||||
import { UserMetadata } from "@snort/nostr";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
import messages from "./messages";
|
||||
import { RootState } from "State/Store";
|
||||
|
||||
type Nip05ServiceProps = {
|
||||
name: string;
|
||||
@ -40,7 +39,7 @@ export default function Nip5Service(props: Nip05ServiceProps) {
|
||||
const navigate = useNavigate();
|
||||
const { helpText = true } = props;
|
||||
const { formatMessage } = useIntl();
|
||||
const pubkey = useSelector((s: RootState) => s.login.publicKey);
|
||||
const pubkey = useLogin().publicKey;
|
||||
const user = useUserProfile(pubkey);
|
||||
const publisher = useEventPublisher();
|
||||
const svc = useMemo(() => new ServiceProvider(props.service), [props.service]);
|
||||
|
@ -1,7 +1,6 @@
|
||||
import "./Note.css";
|
||||
import React, { useMemo, useState, useLayoutEffect, ReactNode } from "react";
|
||||
import { useNavigate, Link } from "react-router-dom";
|
||||
import { useSelector, useDispatch } from "react-redux";
|
||||
import { useInView } from "react-intersection-observer";
|
||||
import { useIntl, FormattedMessage } from "react-intl";
|
||||
import { TaggedRawEvent, HexKey, EventKind, NostrPrefix } from "@snort/nostr";
|
||||
@ -25,13 +24,13 @@ import NoteFooter, { Translation } from "Element/NoteFooter";
|
||||
import NoteTime from "Element/NoteTime";
|
||||
import Reveal from "Element/Reveal";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
import { setPinned, setBookmarked } from "State/Login";
|
||||
import type { RootState } from "State/Store";
|
||||
import { UserCache } from "Cache/UserCache";
|
||||
import Poll from "Element/Poll";
|
||||
import { EventExt } from "System/EventExt";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { setBookmarked, setPinned } from "Login";
|
||||
|
||||
import messages from "./messages";
|
||||
import { EventExt } from "System/EventExt";
|
||||
|
||||
export interface NoteProps {
|
||||
data: TaggedRawEvent;
|
||||
@ -72,7 +71,6 @@ const HiddenNote = ({ children }: { children: React.ReactNode }) => {
|
||||
|
||||
export default function Note(props: NoteProps) {
|
||||
const navigate = useNavigate();
|
||||
const dispatch = useDispatch();
|
||||
const { data: ev, related, highlight, options: opt, ignoreModeration = false } = props;
|
||||
const [showReactions, setShowReactions] = useState(false);
|
||||
const deletions = useMemo(() => getReactions(related, ev.id, EventKind.Deletion), [related]);
|
||||
@ -82,7 +80,8 @@ export default function Note(props: NoteProps) {
|
||||
const [extendable, setExtendable] = useState<boolean>(false);
|
||||
const [showMore, setShowMore] = useState<boolean>(false);
|
||||
const baseClassName = `note card ${props.className ? props.className : ""}`;
|
||||
const { pinned, bookmarked } = useSelector((s: RootState) => s.login);
|
||||
const login = useLogin();
|
||||
const { pinned, bookmarked } = login;
|
||||
const publisher = useEventPublisher();
|
||||
const [translated, setTranslated] = useState<Translation>();
|
||||
const { formatMessage } = useIntl();
|
||||
@ -135,10 +134,12 @@ export default function Note(props: NoteProps) {
|
||||
async function unpin(id: HexKey) {
|
||||
if (options.canUnpin) {
|
||||
if (window.confirm(formatMessage(messages.ConfirmUnpin))) {
|
||||
const es = pinned.filter(e => e !== id);
|
||||
const es = pinned.item.filter(e => e !== id);
|
||||
const ev = await publisher.pinned(es);
|
||||
publisher.broadcast(ev);
|
||||
dispatch(setPinned({ keys: es, createdAt: new Date().getTime() }));
|
||||
if (ev) {
|
||||
publisher.broadcast(ev);
|
||||
setPinned(login, es, ev.created_at * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -146,10 +147,12 @@ export default function Note(props: NoteProps) {
|
||||
async function unbookmark(id: HexKey) {
|
||||
if (options.canUnbookmark) {
|
||||
if (window.confirm(formatMessage(messages.ConfirmUnbookmark))) {
|
||||
const es = bookmarked.filter(e => e !== id);
|
||||
const es = bookmarked.item.filter(e => e !== id);
|
||||
const ev = await publisher.bookmarked(es);
|
||||
publisher.broadcast(ev);
|
||||
dispatch(setBookmarked({ keys: es, createdAt: new Date().getTime() }));
|
||||
if (ev) {
|
||||
publisher.broadcast(ev);
|
||||
setBookmarked(login, es, ev.created_at * 1000);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,14 @@ import SendSats from "Element/SendSats";
|
||||
import { ParsedZap, ZapsSummary } from "Element/Zap";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { RootState } from "State/Store";
|
||||
import { UserPreferences, setPinned, setBookmarked } from "State/Login";
|
||||
import { setReplyTo, setShow, reset } from "State/NoteCreator";
|
||||
import useModeration from "Hooks/useModeration";
|
||||
import { SnortPubKey, TranslateHost } from "Const";
|
||||
import { LNURL } from "LNURL";
|
||||
import { DonateLNURL } from "Pages/DonatePage";
|
||||
import { useWallet } from "Wallet";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { setBookmarked, setPinned } from "Login";
|
||||
|
||||
import messages from "./messages";
|
||||
|
||||
@ -94,10 +95,9 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
const { ev, showReactions, setShowReactions, positive, negative, reposts, zaps } = props;
|
||||
const dispatch = useDispatch();
|
||||
const { formatMessage } = useIntl();
|
||||
const { pinned, bookmarked } = useSelector((s: RootState) => s.login);
|
||||
const login = useSelector<RootState, HexKey | undefined>(s => s.login.publicKey);
|
||||
const login = useLogin();
|
||||
const { pinned, bookmarked, publicKey, preferences: prefs } = login;
|
||||
const { mute, block } = useModeration();
|
||||
const prefs = useSelector<RootState, UserPreferences>(s => s.login.preferences);
|
||||
const author = useUserProfile(ev.pubkey);
|
||||
const publisher = useEventPublisher();
|
||||
const showNoteCreatorModal = useSelector((s: RootState) => s.noteCreator.show);
|
||||
@ -108,13 +108,13 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
const walletState = useWallet();
|
||||
const wallet = walletState.wallet;
|
||||
|
||||
const isMine = ev.pubkey === login;
|
||||
const isMine = ev.pubkey === publicKey;
|
||||
const lang = window.navigator.language;
|
||||
const langNames = new Intl.DisplayNames([...window.navigator.languages], {
|
||||
type: "language",
|
||||
});
|
||||
const zapTotal = zaps.reduce((acc, z) => acc + z.amount, 0);
|
||||
const didZap = ZapCache.has(ev.id) || zaps.some(a => a.sender === login);
|
||||
const didZap = ZapCache.has(ev.id) || zaps.some(a => a.sender === publicKey);
|
||||
const longPress = useLongPress(
|
||||
e => {
|
||||
e.stopPropagation();
|
||||
@ -126,11 +126,11 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
);
|
||||
|
||||
function hasReacted(emoji: string) {
|
||||
return positive?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === login);
|
||||
return positive?.some(({ pubkey, content }) => normalizeReaction(content) === emoji && pubkey === publicKey);
|
||||
}
|
||||
|
||||
function hasReposted() {
|
||||
return reposts.some(a => a.pubkey === login);
|
||||
return reposts.some(a => a.pubkey === publicKey);
|
||||
}
|
||||
|
||||
async function react(content: string) {
|
||||
@ -320,17 +320,21 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
}
|
||||
|
||||
async function pin(id: HexKey) {
|
||||
const es = [...pinned, id];
|
||||
const es = [...pinned.item, id];
|
||||
const ev = await publisher.pinned(es);
|
||||
publisher.broadcast(ev);
|
||||
dispatch(setPinned({ keys: es, createdAt: new Date().getTime() }));
|
||||
if (ev) {
|
||||
publisher.broadcast(ev);
|
||||
setPinned(login, es, ev.created_at * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
async function bookmark(id: HexKey) {
|
||||
const es = [...bookmarked, id];
|
||||
const es = [...bookmarked.item, id];
|
||||
const ev = await publisher.bookmarked(es);
|
||||
publisher.broadcast(ev);
|
||||
dispatch(setBookmarked({ keys: es, createdAt: new Date().getTime() }));
|
||||
if (ev) {
|
||||
publisher.broadcast(ev);
|
||||
setBookmarked(login, es, ev.created_at * 1000);
|
||||
}
|
||||
}
|
||||
|
||||
async function copyEvent() {
|
||||
@ -355,13 +359,13 @@ export default function NoteFooter(props: NoteFooterProps) {
|
||||
<Icon name="share" />
|
||||
<FormattedMessage {...messages.Share} />
|
||||
</MenuItem>
|
||||
{!pinned.includes(ev.id) && (
|
||||
{!pinned.item.includes(ev.id) && (
|
||||
<MenuItem onClick={() => pin(ev.id)}>
|
||||
<Icon name="pin" />
|
||||
<FormattedMessage {...messages.Pin} />
|
||||
</MenuItem>
|
||||
)}
|
||||
{!bookmarked.includes(ev.id) && (
|
||||
{!bookmarked.item.includes(ev.id) && (
|
||||
<MenuItem onClick={() => bookmark(ev.id)}>
|
||||
<Icon name="bookmark" />
|
||||
<FormattedMessage {...messages.Bookmark} />
|
||||
|
@ -1,12 +1,10 @@
|
||||
import { TaggedRawEvent } from "@snort/nostr";
|
||||
import { useState } from "react";
|
||||
import { useSelector } from "react-redux";
|
||||
import { FormattedMessage, FormattedNumber, useIntl } from "react-intl";
|
||||
|
||||
import { ParsedZap } from "Element/Zap";
|
||||
import Text from "Element/Text";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import { RootState } from "State/Store";
|
||||
import { useWallet } from "Wallet";
|
||||
import { useUserProfile } from "Hooks/useUserProfile";
|
||||
import { LNURL } from "LNURL";
|
||||
@ -14,6 +12,7 @@ import { unwrap } from "Util";
|
||||
import { formatShort } from "Number";
|
||||
import Spinner from "Icons/Spinner";
|
||||
import SendSats from "Element/SendSats";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
interface PollProps {
|
||||
ev: TaggedRawEvent;
|
||||
@ -24,8 +23,7 @@ export default function Poll(props: PollProps) {
|
||||
const { formatMessage } = useIntl();
|
||||
const publisher = useEventPublisher();
|
||||
const { wallet } = useWallet();
|
||||
const prefs = useSelector((s: RootState) => s.login.preferences);
|
||||
const myPubKey = useSelector((s: RootState) => s.login.publicKey);
|
||||
const { preferences: prefs, publicKey: myPubKey } = useLogin();
|
||||
const pollerProfile = useUserProfile(props.ev.pubkey);
|
||||
const [error, setError] = useState("");
|
||||
const [invoice, setInvoice] = useState("");
|
||||
|
@ -2,7 +2,6 @@ import "./Relay.css";
|
||||
import { useMemo } from "react";
|
||||
import { useIntl, FormattedMessage } from "react-intl";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useDispatch, useSelector } from "react-redux";
|
||||
import { FontAwesomeIcon } from "@fortawesome/react-fontawesome";
|
||||
import {
|
||||
faPlug,
|
||||
@ -16,35 +15,33 @@ import {
|
||||
import { RelaySettings } from "@snort/nostr";
|
||||
|
||||
import useRelayState from "Feed/RelayState";
|
||||
import { setRelays } from "State/Login";
|
||||
import { RootState } from "State/Store";
|
||||
import { System } from "System";
|
||||
import { getRelayName, unwrap } from "Util";
|
||||
import { getRelayName, unixNowMs, unwrap } from "Util";
|
||||
|
||||
import messages from "./messages";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
import { setRelays } from "Login";
|
||||
|
||||
export interface RelayProps {
|
||||
addr: string;
|
||||
}
|
||||
|
||||
export default function Relay(props: RelayProps) {
|
||||
const dispatch = useDispatch();
|
||||
const { formatMessage } = useIntl();
|
||||
const navigate = useNavigate();
|
||||
const allRelaySettings = useSelector<RootState, Record<string, RelaySettings>>(s => s.login.relays);
|
||||
const relaySettings = unwrap(allRelaySettings[props.addr] ?? System.Sockets.get(props.addr)?.Settings ?? {});
|
||||
const login = useLogin();
|
||||
const relaySettings = unwrap(login.relays.item[props.addr] ?? System.Sockets.get(props.addr)?.Settings ?? {});
|
||||
const state = useRelayState(props.addr);
|
||||
const name = useMemo(() => getRelayName(props.addr), [props.addr]);
|
||||
|
||||
function configure(o: RelaySettings) {
|
||||
dispatch(
|
||||
setRelays({
|
||||
relays: {
|
||||
...allRelaySettings,
|
||||
[props.addr]: o,
|
||||
},
|
||||
createdAt: Math.floor(new Date().getTime() / 1000),
|
||||
})
|
||||
setRelays(
|
||||
login,
|
||||
{
|
||||
...login.relays.item,
|
||||
[props.addr]: o,
|
||||
},
|
||||
unixNowMs()
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { FormattedMessage } from "react-intl";
|
||||
import { useSelector } from "react-redux";
|
||||
|
||||
import MediaLink from "Element/MediaLink";
|
||||
import Reveal from "Element/Reveal";
|
||||
import { RootState } from "State/Store";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
interface RevealMediaProps {
|
||||
creator: string;
|
||||
@ -11,11 +10,10 @@ interface RevealMediaProps {
|
||||
}
|
||||
|
||||
export default function RevealMedia(props: RevealMediaProps) {
|
||||
const pref = useSelector((s: RootState) => s.login.preferences);
|
||||
const follows = useSelector((s: RootState) => s.login.follows);
|
||||
const publicKey = useSelector((s: RootState) => s.login.publicKey);
|
||||
const login = useLogin();
|
||||
const { preferences: pref, follows, publicKey } = login;
|
||||
|
||||
const hideNonFollows = pref.autoLoadMedia === "follows-only" && !follows.includes(props.creator);
|
||||
const hideNonFollows = pref.autoLoadMedia === "follows-only" && !follows.item.includes(props.creator);
|
||||
const isMine = props.creator === publicKey;
|
||||
const hideMedia = pref.autoLoadMedia === "none" || (!isMine && hideNonFollows);
|
||||
const hostname = new URL(props.link).hostname;
|
||||
|
@ -1,11 +1,9 @@
|
||||
import "./SendSats.css";
|
||||
import React, { useEffect, useMemo, useState } from "react";
|
||||
import { useIntl, FormattedMessage } from "react-intl";
|
||||
import { useSelector } from "react-redux";
|
||||
import { HexKey, RawEvent } from "@snort/nostr";
|
||||
|
||||
import { formatShort } from "Number";
|
||||
import { RootState } from "State/Store";
|
||||
import Icon from "Icons/Icon";
|
||||
import useEventPublisher from "Feed/EventPublisher";
|
||||
import ProfileImage from "Element/ProfileImage";
|
||||
@ -18,6 +16,7 @@ import { useWallet } from "Wallet";
|
||||
import { EventExt } from "System/EventExt";
|
||||
|
||||
import messages from "./messages";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
enum ZapType {
|
||||
PublicZap = 1,
|
||||
@ -41,7 +40,7 @@ export interface SendSatsProps {
|
||||
export default function SendSats(props: SendSatsProps) {
|
||||
const onClose = props.onClose || (() => undefined);
|
||||
const { note, author, target } = props;
|
||||
const defaultZapAmount = useSelector((s: RootState) => s.login.preferences.defaultZapAmount);
|
||||
const defaultZapAmount = useLogin().preferences.defaultZapAmount;
|
||||
const amounts = [defaultZapAmount, 1_000, 5_000, 10_000, 20_000, 50_000, 100_000, 1_000_000];
|
||||
const emojis: Record<number, string> = {
|
||||
1_000: "👍",
|
||||
|
@ -13,6 +13,7 @@ import { findTag } from "Util";
|
||||
import { UserCache } from "Cache/UserCache";
|
||||
|
||||
import messages from "./messages";
|
||||
import useLogin from "Hooks/useLogin";
|
||||
|
||||
function getInvoice(zap: TaggedRawEvent): InvoiceDetails | undefined {
|
||||
const bolt11 = findTag(zap, "bolt11");
|
||||
@ -103,7 +104,7 @@ export interface ParsedZap {
|
||||
|
||||
const Zap = ({ zap, showZapped = true }: { zap: ParsedZap; showZapped?: boolean }) => {
|
||||
const { amount, content, sender, valid, receiver } = zap;
|
||||
const pubKey = useSelector((s: RootState) => s.login.publicKey);
|
||||
const pubKey = useLogin().publicKey;
|
||||
|
||||
return valid && sender ? (
|
||||
<div className="zap note card">
|
||||
|
Reference in New Issue
Block a user