mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-11 05:09:36 +02:00
show existing accounts on sign in view
This commit is contained in:
parent
073cc52ea1
commit
3b8c4f2134
@ -9,7 +9,7 @@ import { removeCoordinateTag, addCoordinateTag } from "applesauce-factory/operat
|
||||
import useFavoriteFeeds, { FAVORITE_FEEDS_IDENTIFIER } from "../../hooks/use-favorite-feeds";
|
||||
import { usePublishEvent } from "../../providers/global/publish-provider";
|
||||
import { StarEmptyIcon, StarFullIcon } from "../icons";
|
||||
import useAsyncErrorHandler from "../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../hooks/use-async-error-handler";
|
||||
|
||||
export default function DVMFeedFavoriteButton({
|
||||
pointer,
|
||||
@ -20,7 +20,7 @@ export default function DVMFeedFavoriteButton({
|
||||
const { favorites } = useFavoriteFeeds();
|
||||
const isFavorite = !!favorites && isAddressPointerInList(favorites, pointer);
|
||||
|
||||
const toggle = useAsyncErrorHandler(async () => {
|
||||
const toggle = useAsyncAction(async () => {
|
||||
const prev = favorites || {
|
||||
kind: kinds.Application,
|
||||
tags: [["d", FAVORITE_FEEDS_IDENTIFIER]],
|
||||
|
@ -21,7 +21,7 @@ import useUserSets from "../../hooks/use-user-lists";
|
||||
import { getListName } from "../../helpers/nostr/lists";
|
||||
import { getEventCoordinate } from "../../helpers/nostr/event";
|
||||
import useUserContactList from "../../hooks/use-user-contact-list";
|
||||
import useAsyncErrorHandler from "../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../hooks/use-async-error-handler";
|
||||
import NewSetModal from "../../views/lists/components/new-set-modal";
|
||||
import useUserMuteActions from "../../hooks/use-user-mute-actions";
|
||||
import { useMuteModalContext } from "../../providers/route/mute-modal-provider";
|
||||
@ -37,7 +37,7 @@ function UsersLists({ pubkey }: { pubkey: string }) {
|
||||
|
||||
const inLists = lists.filter((list) => isProfilePointerInList(list, { pubkey }));
|
||||
|
||||
const handleChange = useAsyncErrorHandler(
|
||||
const handleChange = useAsyncAction(
|
||||
async (cords: string | string[]) => {
|
||||
if (!Array.isArray(cords)) return;
|
||||
|
||||
@ -98,7 +98,7 @@ export function UserFollowButton({ pubkey, showLists, ...props }: UserFollowButt
|
||||
|
||||
const isFollowing = !!contacts && isProfilePointerInList(contacts, pubkey);
|
||||
|
||||
const toggleFollow = useAsyncErrorHandler(async () => {
|
||||
const toggleFollow = useAsyncAction(async () => {
|
||||
if (isFollowing) {
|
||||
await actions.exec(UnfollowUser, pubkey).forEach((e) => publish("Unfollow user", e));
|
||||
} else {
|
||||
|
@ -1,17 +1,19 @@
|
||||
import { useToast } from "@chakra-ui/react";
|
||||
import { DependencyList, useCallback, useState } from "react";
|
||||
import { DependencyList, useCallback, useRef, useState } from "react";
|
||||
|
||||
export default function useAsyncErrorHandler<Args extends Array<any>, T = any>(
|
||||
export default function useAsyncAction<Args extends Array<any>, T = any>(
|
||||
fn: (...args: Args) => Promise<T>,
|
||||
deps: DependencyList,
|
||||
deps: DependencyList = [],
|
||||
): { loading: boolean; run: (...args: Args) => Promise<T | undefined> } {
|
||||
const toast = useToast();
|
||||
const ref = useRef(fn);
|
||||
ref.current = fn;
|
||||
|
||||
const toast = useToast();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const run = useCallback<(...args: Args) => Promise<T | undefined>>(async (...args: Args) => {
|
||||
setLoading(true);
|
||||
try {
|
||||
return await fn(...args);
|
||||
return await ref.current(...args);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
|
@ -8,7 +8,7 @@ import {
|
||||
pruneExpiredPubkeys,
|
||||
} from "../helpers/nostr/mute-list";
|
||||
import { usePublishEvent } from "../providers/global/publish-provider";
|
||||
import useAsyncErrorHandler from "./use-async-error-handler";
|
||||
import useAsyncAction from "./use-async-error-handler";
|
||||
import useUserMuteList from "./use-user-mute-list";
|
||||
|
||||
export default function useUserMuteActions(pubkey: string) {
|
||||
@ -19,12 +19,12 @@ export default function useUserMuteActions(pubkey: string) {
|
||||
const isMuted = isPubkeyInList(muteList, pubkey);
|
||||
const expiration = muteList ? getPubkeyExpiration(muteList, pubkey) : 0;
|
||||
|
||||
const { run: mute } = useAsyncErrorHandler(async () => {
|
||||
const { run: mute } = useAsyncAction(async () => {
|
||||
let draft = muteListAddPubkey(muteList || createEmptyMuteList(), pubkey);
|
||||
draft = pruneExpiredPubkeys(draft);
|
||||
await publish("Mute", draft, undefined, false);
|
||||
}, [publish, muteList]);
|
||||
const { run: unmute } = useAsyncErrorHandler(async () => {
|
||||
const { run: unmute } = useAsyncAction(async () => {
|
||||
let draft = muteListRemovePubkey(muteList || createEmptyMuteList(), pubkey);
|
||||
draft = pruneExpiredPubkeys(draft);
|
||||
await publish("Unmute", draft, undefined, false);
|
||||
|
@ -6,7 +6,7 @@ import { nip19 } from "nostr-tools";
|
||||
import UserAvatar from "../../../components/user/user-avatar";
|
||||
import UserDnsIdentity from "../../../components/user/user-dns-identity";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import { useActiveAccount, useEventFactory } from "applesauce-react/hooks";
|
||||
import { UserFollowButton } from "../../../components/user/user-follow-button";
|
||||
import { usePublishEvent } from "../../../providers/global/publish-provider";
|
||||
@ -19,7 +19,7 @@ export default function UserCard({ pubkey, relay, list, ...props }: UserCardProp
|
||||
const publish = usePublishEvent();
|
||||
const factory = useEventFactory();
|
||||
|
||||
const remove = useAsyncErrorHandler(async () => {
|
||||
const remove = useAsyncAction(async () => {
|
||||
const draft = await factory.modifyTags(list, removePubkeyTag(pubkey));
|
||||
const signed = await factory.sign(draft);
|
||||
await publish("Remove from list", signed);
|
||||
|
@ -2,7 +2,7 @@ import { Button, Flex, Heading, Link, useToast } from "@chakra-ui/react";
|
||||
import { PasswordSigner, SerialPortSigner, SimpleSigner } from "applesauce-signers";
|
||||
import { useState } from "react";
|
||||
|
||||
import useAsyncErrorHandler from "../../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../../hooks/use-async-error-handler";
|
||||
import { useAccountManager, useActiveAccount } from "applesauce-react/hooks";
|
||||
import accountService from "../../../../services/accounts";
|
||||
import { SerialPortAccount } from "applesauce-accounts/accounts";
|
||||
@ -15,7 +15,7 @@ export default function MigrateAccountToDevice() {
|
||||
const [loading, setLoading] = useState(false);
|
||||
const manager = useAccountManager();
|
||||
|
||||
const { run: migrate } = useAsyncErrorHandler(async () => {
|
||||
const { run: migrate } = useAsyncAction(async () => {
|
||||
try {
|
||||
setLoading(true);
|
||||
if (!current?.signer) throw new Error("Account missing signer");
|
||||
|
@ -3,7 +3,7 @@ import { Button, Flex, Heading, IconButton, Input, Link, Select, Switch, Text }
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useObservable } from "applesauce-react/hooks";
|
||||
|
||||
import useAsyncErrorHandler from "../../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../../hooks/use-async-error-handler";
|
||||
import { controlApi$ } from "../../../../services/bakery";
|
||||
import RelayFavicon from "../../../../components/relay-favicon";
|
||||
import { isSafeRelayURL, normalizeURL } from "applesauce-core/helpers";
|
||||
@ -11,7 +11,7 @@ import { isSafeRelayURL, normalizeURL } from "applesauce-core/helpers";
|
||||
function BroadcastRelay({ relay }: { relay: string }) {
|
||||
const controlApi = useObservable(controlApi$);
|
||||
const config = useObservable(controlApi?.config);
|
||||
const remove = useAsyncErrorHandler(async () => {
|
||||
const remove = useAsyncAction(async () => {
|
||||
if (!config) return;
|
||||
|
||||
await controlApi?.setConfigField(
|
||||
|
@ -10,7 +10,7 @@ import { useActiveAccount } from "applesauce-react/hooks";
|
||||
import { InboxIcon, OutboxIcon } from "../../../components/icons";
|
||||
import MediaServerFavicon from "../../../components/favicon/media-server-favicon";
|
||||
import { NostrEvent } from "../../../types/nostr-event";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import { usePublishEvent } from "../../../providers/global/publish-provider";
|
||||
import { addRelayModeToMailbox, removeRelayModeFromMailbox } from "../../../helpers/nostr/mailbox";
|
||||
import AddRelayForm from "../relays/add-relay-form";
|
||||
@ -22,7 +22,7 @@ import { RelayMode } from "../../../services/app-relays";
|
||||
|
||||
function RelayLine({ relay, mode, list }: { relay: string; mode: RelayMode; list?: NostrEvent }) {
|
||||
const publish = usePublishEvent();
|
||||
const remove = useAsyncErrorHandler(async () => {
|
||||
const remove = useAsyncAction(async () => {
|
||||
const draft = removeRelayModeFromMailbox(list, relay, mode);
|
||||
await publish("Remove relay", draft, COMMON_CONTACT_RELAYS);
|
||||
}, [relay, mode, list, publish]);
|
||||
|
@ -25,7 +25,7 @@ import useUsersMediaServers from "../../../hooks/use-user-media-servers";
|
||||
import DebugEventButton from "../../../components/debug-modal/debug-event-button";
|
||||
import { cloneEvent } from "../../../helpers/nostr/event";
|
||||
import useAppSettings from "../../../hooks/use-user-app-settings";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import { isServerTag } from "../../../helpers/nostr/blossom";
|
||||
import { USER_BLOSSOM_SERVER_LIST_KIND, areServersEqual } from "blossom-client-sdk";
|
||||
import SimpleView from "../../../components/layout/presets/simple-view";
|
||||
@ -64,7 +64,7 @@ function MediaServersPage() {
|
||||
await publish("Remove media server", draft);
|
||||
};
|
||||
|
||||
const { run: switchToBlossom } = useAsyncErrorHandler(async () => {
|
||||
const { run: switchToBlossom } = useAsyncAction(async () => {
|
||||
await updateSettings({ mediaUploadService: "blossom" });
|
||||
}, [updateSettings]);
|
||||
|
||||
|
@ -1,9 +1,21 @@
|
||||
import { lazy, useState } from "react";
|
||||
import { Button, ButtonGroup, Divider, Flex, IconButton, Link, Spinner, Text, useToast } from "@chakra-ui/react";
|
||||
import {
|
||||
Box,
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Card,
|
||||
Divider,
|
||||
Flex,
|
||||
IconButton,
|
||||
Link,
|
||||
Spinner,
|
||||
Text,
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { Link as RouterLink, useLocation } from "react-router-dom";
|
||||
import { AmberClipboardAccount, ExtensionAccount, SerialPortAccount } from "applesauce-accounts/accounts";
|
||||
import { AmberClipboardSigner, ExtensionSigner, SerialPortSigner } from "applesauce-signers";
|
||||
import { useAccountManager } from "applesauce-react/hooks";
|
||||
import { useAccountManager, useAccounts } from "applesauce-react/hooks";
|
||||
|
||||
import Key01 from "../../components/icons/key-01";
|
||||
import Diamond01 from "../../components/icons/diamond-01";
|
||||
@ -14,6 +26,12 @@ import { CAP_IS_ANDROID, CAP_IS_WEB } from "../../env";
|
||||
import { AtIcon } from "../../components/icons";
|
||||
import Package from "../../components/icons/package";
|
||||
import Eye from "../../components/icons/eye";
|
||||
import useAsyncAction from "../../hooks/use-async-error-handler";
|
||||
import UserAvatar from "../../components/user/user-avatar";
|
||||
import UserName from "../../components/user/user-name";
|
||||
import UserDnsIdentity from "../../components/user/user-dns-identity";
|
||||
import { CloseIcon } from "@chakra-ui/icons";
|
||||
import AccountTypeBadge from "../../components/accounts/account-info-badge";
|
||||
const AndroidNativeSigners = lazy(() => import("./native"));
|
||||
|
||||
export default function LoginStartView() {
|
||||
@ -21,64 +39,47 @@ export default function LoginStartView() {
|
||||
const toast = useToast();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const manager = useAccountManager();
|
||||
const accounts = useAccounts();
|
||||
|
||||
const signinWithExtension = async () => {
|
||||
if (window.nostr) {
|
||||
try {
|
||||
setLoading(true);
|
||||
const extension = useAsyncAction(async () => {
|
||||
if (!window.nostr) throw new Error("Missing NIP-07 signer extension");
|
||||
|
||||
const signer = new ExtensionSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const signer = new ExtensionSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
|
||||
const account = new ExtensionAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
setLoading(false);
|
||||
} else {
|
||||
toast({ status: "warning", title: "Cant find extension" });
|
||||
}
|
||||
};
|
||||
const account = new ExtensionAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
});
|
||||
|
||||
const signinWithSerial = async () => {
|
||||
if (SerialPortSigner.SUPPORTED) {
|
||||
try {
|
||||
setLoading(true);
|
||||
const serial = useAsyncAction(async () => {
|
||||
if (!SerialPortSigner.SUPPORTED) throw new Error("Serial is not supported");
|
||||
|
||||
const signer = new SerialPortSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const account = new SerialPortAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
setLoading(false);
|
||||
} else {
|
||||
toast({ status: "warning", title: "Serial is not supported" });
|
||||
}
|
||||
};
|
||||
const signer = new SerialPortSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const account = new SerialPortAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
});
|
||||
|
||||
const signinWithAmber = async () => {
|
||||
try {
|
||||
const signer = new AmberClipboardSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const account = new AmberClipboardAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
} catch (e) {
|
||||
if (e instanceof Error) toast({ description: e.message, status: "error" });
|
||||
}
|
||||
};
|
||||
|
||||
if (loading) return <Spinner />;
|
||||
const amber = useAsyncAction(async () => {
|
||||
const signer = new AmberClipboardSigner();
|
||||
const pubkey = await signer.getPublicKey();
|
||||
const account = new AmberClipboardAccount(pubkey, signer);
|
||||
manager.addAccount(account);
|
||||
manager.setActive(account);
|
||||
});
|
||||
|
||||
return (
|
||||
<>
|
||||
{window.nostr && (
|
||||
<Button onClick={signinWithExtension} leftIcon={<Key01 boxSize={6} />} w="full" colorScheme="primary">
|
||||
<Button
|
||||
onClick={extension.run}
|
||||
isLoading={extension.loading}
|
||||
leftIcon={<Key01 boxSize={6} />}
|
||||
w="full"
|
||||
colorScheme="primary"
|
||||
>
|
||||
Sign in with extension
|
||||
</Button>
|
||||
)}
|
||||
@ -94,7 +95,7 @@ export default function LoginStartView() {
|
||||
</Button>
|
||||
{SerialPortSigner.SUPPORTED && (
|
||||
<ButtonGroup colorScheme="purple">
|
||||
<Button onClick={signinWithSerial} leftIcon={<UsbFlashDrive boxSize={6} />} w="xs">
|
||||
<Button onClick={serial.run} isLoading={serial.loading} leftIcon={<UsbFlashDrive boxSize={6} />} w="xs">
|
||||
Use Signing Device
|
||||
</Button>
|
||||
<IconButton
|
||||
@ -109,7 +110,7 @@ export default function LoginStartView() {
|
||||
)}
|
||||
{CAP_IS_WEB && AmberClipboardSigner.SUPPORTED && (
|
||||
<ButtonGroup colorScheme="orange" w="full">
|
||||
<Button onClick={signinWithAmber} leftIcon={<Diamond01 boxSize={6} />} flex={1}>
|
||||
<Button onClick={amber.run} isLoading={amber.loading} leftIcon={<Diamond01 boxSize={6} />} flex={1}>
|
||||
Use Amber
|
||||
</Button>
|
||||
<IconButton
|
||||
@ -166,6 +167,37 @@ export default function LoginStartView() {
|
||||
Public key
|
||||
</Button>
|
||||
</Flex>
|
||||
{accounts.length > 0 && (
|
||||
<>
|
||||
<Text fontWeight="bold" mt="4">
|
||||
Existing accounts
|
||||
</Text>
|
||||
|
||||
{accounts.map((account) => (
|
||||
<Card key={account.id} p="2" display="flex" direction="row" gap="2" alignItems="center" w="full" maxW="md">
|
||||
<UserAvatar pubkey={account.pubkey} size="md" />
|
||||
<Box>
|
||||
<UserName pubkey={account.pubkey} />
|
||||
<br />
|
||||
<AccountTypeBadge account={account} />
|
||||
</Box>
|
||||
|
||||
<ButtonGroup ms="auto">
|
||||
<Button variant="ghost" onClick={() => manager.setActive(account)}>
|
||||
Sign in
|
||||
</Button>
|
||||
<IconButton
|
||||
aria-label="Delete account"
|
||||
icon={<CloseIcon />}
|
||||
variant="ghost"
|
||||
colorScheme="red"
|
||||
onClick={() => manager.removeAccount(account)}
|
||||
/>
|
||||
</ButtonGroup>
|
||||
</Card>
|
||||
))}
|
||||
</>
|
||||
)}
|
||||
<Text fontWeight="bold" mt="4">
|
||||
Don't have an account?
|
||||
</Text>
|
||||
|
@ -5,7 +5,7 @@ import { NostrEvent } from "nostr-tools";
|
||||
import { ExternalLinkIcon } from "../../../components/icons";
|
||||
import useShareableEventAddress from "../../../hooks/use-shareable-event-address";
|
||||
import { AppHandlerContext } from "../../../providers/route/app-handler-provider";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
|
||||
export type StreamOpenButtonProps = Omit<IconButtonProps, "onClick" | "aria-label"> & {
|
||||
stream: NostrEvent;
|
||||
@ -21,7 +21,7 @@ export default function StreamOpenButton({
|
||||
const { openAddress } = useContext(AppHandlerContext);
|
||||
const address = useShareableEventAddress(stream);
|
||||
|
||||
const { run: handleClick } = useAsyncErrorHandler(async () => {
|
||||
const { run: handleClick } = useAsyncAction(async () => {
|
||||
if (!address) throw new Error("Failed to get address");
|
||||
openAddress(address);
|
||||
}, [address]);
|
||||
|
@ -3,14 +3,14 @@ import { ConsolidateTokens } from "applesauce-wallet/actions";
|
||||
import { useActionHub, useActiveAccount } from "applesauce-react/hooks";
|
||||
|
||||
import useUserWallet from "../../../hooks/use-user-wallet";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
|
||||
export default function ConsolidateTokensButton({ children, ...props }: Omit<ButtonProps, "onClick" | "isLoading">) {
|
||||
const account = useActiveAccount()!;
|
||||
const wallet = useUserWallet(account.pubkey);
|
||||
const actions = useActionHub();
|
||||
|
||||
const consolidate = useAsyncErrorHandler(async () => {
|
||||
const consolidate = useAsyncAction(async () => {
|
||||
if (!wallet) throw new Error("Missing wallet");
|
||||
await actions.run(ConsolidateTokens);
|
||||
}, [wallet, actions]);
|
||||
|
@ -3,14 +3,14 @@ import { useActionHub, useActiveAccount } from "applesauce-react/hooks";
|
||||
import { UnlockWallet } from "applesauce-wallet/actions";
|
||||
|
||||
import useUserWallet from "../../../hooks/use-user-wallet";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
|
||||
export default function WalletUnlockButton({ children, ...props }: Omit<ButtonProps, "onClick" | "isLoading">) {
|
||||
const account = useActiveAccount()!;
|
||||
const wallet = useUserWallet(account.pubkey);
|
||||
|
||||
const actions = useActionHub();
|
||||
const unlock = useAsyncErrorHandler(async () => {
|
||||
const unlock = useAsyncAction(async () => {
|
||||
if (!wallet) throw new Error("Missing wallet");
|
||||
if (wallet.locked === false) return;
|
||||
|
||||
|
@ -8,7 +8,7 @@ import SimpleView from "../../../components/layout/presets/simple-view";
|
||||
import RouterLink from "../../../components/router-link";
|
||||
import CashuMintFavicon from "../../../components/cashu/cashu-mint-favicon";
|
||||
import CashuMintName from "../../../components/cashu/cashu-mint-name";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import { getCashuWallet } from "../../../services/cashu-mints";
|
||||
|
||||
export default function WalletReceiveTokenView() {
|
||||
@ -24,7 +24,7 @@ export default function WalletReceiveTokenView() {
|
||||
const decoded = getDecodedToken(token);
|
||||
const originalAmount = decoded.proofs.reduce((t, p) => t + p.amount, 0);
|
||||
|
||||
const receive = useAsyncErrorHandler(async () => {
|
||||
const receive = useAsyncAction(async () => {
|
||||
try {
|
||||
// swap tokens
|
||||
const wallet = await getCashuWallet(decoded.mint);
|
||||
@ -46,7 +46,7 @@ export default function WalletReceiveTokenView() {
|
||||
}
|
||||
}, [decoded, originalAmount, actions, navigate, toast]);
|
||||
|
||||
const swap = useAsyncErrorHandler(async () => {}, [decoded, originalAmount, actions, navigate, toast]);
|
||||
const swap = useAsyncAction(async () => {}, [decoded, originalAmount, actions, navigate, toast]);
|
||||
|
||||
return (
|
||||
<SimpleView title="Receive Token" maxW="xl" center>
|
||||
|
@ -27,7 +27,7 @@ import DebugEventButton from "../../../components/debug-modal/debug-event-button
|
||||
import ArrowBlockUp from "../../../components/icons/arrow-block-up";
|
||||
import ArrowBlockDown from "../../../components/icons/arrow-block-down";
|
||||
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import { useDeleteEventContext } from "../../../providers/route/delete-event-provider";
|
||||
import { ChevronDownIcon, ChevronUpIcon, TrashIcon } from "../../../components/icons";
|
||||
import useEventUpdate from "../../../hooks/use-event-update";
|
||||
@ -53,7 +53,7 @@ function HistoryEntry({ entry }: { entry: NostrEvent }) {
|
||||
const redeemedIds = getHistoryRedeemed(entry);
|
||||
const redeemed = useSingleEvents(redeemedIds);
|
||||
|
||||
const { run: unlock } = useAsyncErrorHandler(async () => {
|
||||
const { run: unlock } = useAsyncAction(async () => {
|
||||
await unlockHistoryContent(entry, account);
|
||||
eventStore.update(entry);
|
||||
}, [entry, account, eventStore]);
|
||||
@ -136,7 +136,7 @@ export default function WalletHistoryTab() {
|
||||
const history = useStoreQuery(WalletHistoryQuery, [account.pubkey]) ?? [];
|
||||
const locked = useStoreQuery(WalletHistoryQuery, [account.pubkey, true]) ?? [];
|
||||
|
||||
const { run: unlock } = useAsyncErrorHandler(async () => {
|
||||
const { run: unlock } = useAsyncAction(async () => {
|
||||
for (const entry of locked) {
|
||||
if (!isHistoryContentLocked(entry)) continue;
|
||||
await unlockHistoryContent(entry, account);
|
||||
@ -144,7 +144,7 @@ export default function WalletHistoryTab() {
|
||||
}
|
||||
}, [locked, account, eventStore]);
|
||||
|
||||
const clear = useAsyncErrorHandler(async () => {
|
||||
const clear = useAsyncAction(async () => {
|
||||
if (confirm("Are you sure you want to clear history?") !== true) return;
|
||||
const draft = await factory.delete(history);
|
||||
await publish("Clear history", draft);
|
||||
|
@ -19,7 +19,7 @@ import { getTokenContent, isTokenContentLocked, unlockTokenContent } from "apple
|
||||
import { NostrEvent } from "nostr-tools";
|
||||
import { getEncodedToken, ProofState } from "@cashu/cashu-ts";
|
||||
|
||||
import useAsyncErrorHandler from "../../../hooks/use-async-error-handler";
|
||||
import useAsyncAction from "../../../hooks/use-async-error-handler";
|
||||
import useEventUpdate from "../../../hooks/use-event-update";
|
||||
import useEventIntersectionRef from "../../../hooks/use-event-intersection-ref";
|
||||
import {
|
||||
@ -52,7 +52,7 @@ function TokenEvent({ token }: { token: NostrEvent }) {
|
||||
const amount = details?.proofs.reduce((t, p) => t + p.amount, 0);
|
||||
|
||||
const [spentState, setSpentState] = useState<ProofState[]>();
|
||||
const { run: check } = useAsyncErrorHandler(async () => {
|
||||
const { run: check } = useAsyncAction(async () => {
|
||||
if (!details) return;
|
||||
const wallet = await getCashuWallet(details.mint);
|
||||
const state = await wallet.checkProofsStates(details.proofs);
|
||||
@ -62,7 +62,7 @@ function TokenEvent({ token }: { token: NostrEvent }) {
|
||||
|
||||
const { deleteEvent } = useDeleteEventContext();
|
||||
|
||||
const { run: unlock } = useAsyncErrorHandler(async () => {
|
||||
const { run: unlock } = useAsyncAction(async () => {
|
||||
if (!account) return;
|
||||
await unlockTokenContent(token, account);
|
||||
eventStore.update(token);
|
||||
@ -153,7 +153,7 @@ export default function WalletTokensTab({ ...props }: Omit<FlexProps, "children"
|
||||
const tokens = useStoreQuery(WalletTokensQuery, [account.pubkey]) ?? [];
|
||||
const locked = useStoreQuery(WalletTokensQuery, [account.pubkey, true]) ?? [];
|
||||
|
||||
const { run: unlock } = useAsyncErrorHandler(async () => {
|
||||
const { run: unlock } = useAsyncAction(async () => {
|
||||
if (!locked) return;
|
||||
for (const token of locked) {
|
||||
await unlockTokenContent(token, account);
|
||||
|
Loading…
x
Reference in New Issue
Block a user