import { useNavigate } from "@solidjs/router"; import { Check, PlugZap, X } from "lucide-solid"; import { createEffect, createResource, createSignal, For, Show } from "solid-js"; import { ButtonCard, GenericItem, InfoBox, NiceP } from "~/components"; import { useI18n } from "~/i18n/context"; import { useMegaStore } from "~/state/megaStore"; import { createDeepSignal, eify, veryShortTimeStamp, vibrateSuccess } from "~/utils"; type PendingItem = { id: string; name_of_connection: string; date?: bigint; amount_sats?: bigint; image?: string; }; export function PendingNwc() { const i18n = useI18n(); const [state, _actions, sw] = useMegaStore(); const [error, setError] = createSignal(); const navigate = useNavigate(); const [hasPreConfiguredNWC, setHasPreConfiguredNWC] = createSignal(false); async function fetchPendingRequests() { const profiles = await sw.get_nwc_profiles(); setHasPreConfiguredNWC(!!profiles && profiles.length > 0); if (!profiles) return []; const contacts = await sw.get_contacts_sorted(); if (!contacts) return []; const pending = await sw.get_pending_nwc_invoices(); if (!pending) return []; const pendingItems: PendingItem[] = []; for (const p of pending) { const profile = profiles.find((pro) => pro.index === p.index); if (profile) { pendingItems.push({ id: p.id, name_of_connection: profile.name, date: p.expiry, amount_sats: p.amount_sats }); } else { const contact = contacts.find((c) => c.npub === p.npub); if (contact) { pendingItems.push({ id: p.id, name_of_connection: contact.name, image: contact.image_url, date: p.expiry, amount_sats: p.amount_sats }); } } } return pendingItems; } const [pendingRequests, { refetch }] = createResource( fetchPendingRequests, // Create deepsignal so we don't get flicker on refresh { storage: createDeepSignal } ); const [payList, setPayList] = createSignal([]); async function payItem(item: PendingItem) { try { // setPaying(item.id); setPayList([...payList(), item.id]); await sw.approve_invoice(item.id); await vibrateSuccess(); } catch (e) { const err = eify(e); // If we've already paid this invoice, just ignore the error // we just want to remove it from the list and continue if (err.message === "An invoice must not get payed twice.") { // wrap in try/catch so we don't crash if the invoice is already gone try { await sw.deny_invoice(item.id); } catch (_e) { // do nothing } } else { setError(err); console.error(e); } } finally { setPayList(payList().filter((id) => id !== item.id)); refetch(); } } async function approveAll() { // clone the list so it doesn't update in place const toApprove = [...pendingRequests()!]; for (const item of toApprove) { await payItem(item); } } async function denyAll() { try { await sw.deny_all_pending_nwc(); } catch (e) { setError(eify(e)); console.error(e); } finally { refetch(); } } async function rejectItem(item: PendingItem) { try { setPayList([...payList(), item.id]); await sw.deny_invoice(item.id); } catch (e) { setError(eify(e)); console.error(e); } finally { setPayList(payList().filter((id) => id !== item.id)); refetch(); } } createEffect(() => { // When there's an error wait five seconds and then clear it if (error()) { setTimeout(() => { setError(undefined); }, 5000); } }); createEffect(() => { // Refetch on the sync interval if (!state.is_syncing) { refetch(); } }); return ( <> navigate("/settings/connections")}>
{hasPreConfiguredNWC() ? i18n.t("home.connection_edit") : i18n.t("home.connection")}
0 } >
{error()?.message} {(pendingItem) => ( payItem(pendingItem)} rejectAction={() => rejectItem(pendingItem)} shouldSpinny={payList().includes( pendingItem.id )} /> )}
); }