mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-29 16:30:55 +00:00
feat: add instant zap
This commit is contained in:
parent
240fe8bc7c
commit
0e9418949b
@ -23,8 +23,12 @@ export function ActivitySingleText({ event }: { event: NDKEvent }) {
|
|||||||
<div className="max-w-xl mx-auto py-6">
|
<div className="max-w-xl mx-auto py-6">
|
||||||
{thread ? (
|
{thread ? (
|
||||||
<div className="flex flex-col gap-3 mb-1">
|
<div className="flex flex-col gap-3 mb-1">
|
||||||
<ActivityRootNote eventId={thread.rootEventId} />
|
{thread.rootEventId ? (
|
||||||
<ActivityRootNote eventId={thread.replyEventId} />
|
<ActivityRootNote eventId={thread.rootEventId} />
|
||||||
|
) : null}
|
||||||
|
{thread.replyEventId ? (
|
||||||
|
<ActivityRootNote eventId={thread.replyEventId} />
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="mt-3 flex flex-col gap-3">
|
<div className="mt-3 flex flex-col gap-3">
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { EyeOffIcon } from "@lume/icons";
|
import { EyeOffIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
import { useStorage } from "@lume/storage";
|
||||||
import { nip19 } from "nostr-tools";
|
import { nip19 } from "nostr-tools";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
|
|
||||||
export function BackupSettingScreen() {
|
export function BackupSettingScreen() {
|
||||||
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
|
|
||||||
const [privkey, setPrivkey] = useState(null);
|
const [privkey, setPrivkey] = useState(null);
|
||||||
@ -24,14 +26,10 @@ export function BackupSettingScreen() {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="mx-auto w-full max-w-lg">
|
<div className="mx-auto w-full max-w-lg">
|
||||||
<div className="mb-2 text-sm font-semibold">Private key</div>
|
|
||||||
<div>
|
<div>
|
||||||
{!privkey ? (
|
{privkey ? (
|
||||||
<div className="inline-flex h-24 w-full items-center justify-center rounded-lg bg-neutral-100 dark:bg-neutral-900">
|
<div>
|
||||||
You've stored private key on Lume
|
<div className="mb-2 text-sm font-semibold">Private key</div>
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<div className="relative">
|
<div className="relative">
|
||||||
<input
|
<input
|
||||||
readOnly
|
readOnly
|
||||||
@ -50,12 +48,12 @@ export function BackupSettingScreen() {
|
|||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => removePrivkey()}
|
onClick={() => removePrivkey()}
|
||||||
className="mt-2 inline-flex h-9 w-full items-center justify-center gap-2 rounded-lg bg-red-200 px-6 font-medium text-red-500 hover:bg-red-500 hover:text-white focus:outline-none dark:hover:text-white"
|
className="mt-2 inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg bg-red-200 px-6 font-medium text-red-500 hover:bg-red-500 hover:text-white focus:outline-none dark:hover:text-white"
|
||||||
>
|
>
|
||||||
Remove private key
|
Remove private key
|
||||||
</button>
|
</button>
|
||||||
</>
|
</div>
|
||||||
)}
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -151,7 +151,7 @@ export function GeneralSettingScreen() {
|
|||||||
<div className="flex flex-col gap-6">
|
<div className="flex flex-col gap-6">
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Update
|
Update
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Automatically download new update</div>
|
<div className="text-sm">Automatically download new update</div>
|
||||||
@ -166,7 +166,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Low Power
|
Low Power
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">
|
<div className="text-sm">
|
||||||
@ -183,7 +183,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Startup
|
Startup
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Launch Lume at Login</div>
|
<div className="text-sm">Launch Lume at Login</div>
|
||||||
@ -198,7 +198,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Media
|
Media
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Automatically load media</div>
|
<div className="text-sm">Automatically load media</div>
|
||||||
@ -213,7 +213,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Hashtag
|
Hashtag
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Show all hashtags in content</div>
|
<div className="text-sm">Show all hashtags in content</div>
|
||||||
@ -228,7 +228,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Notification
|
Notification
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Automatically send notification</div>
|
<div className="text-sm">Automatically send notification</div>
|
||||||
@ -244,7 +244,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
<div className="flex w-full items-center justify-between">
|
||||||
<div className="flex items-center gap-8">
|
<div className="flex items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Translation
|
Translation
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Translate text to your language</div>
|
<div className="text-sm">Translate text to your language</div>
|
||||||
@ -259,7 +259,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
{settings.translation ? (
|
{settings.translation ? (
|
||||||
<div className="flex w-full items-center gap-8">
|
<div className="flex w-full items-center gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
API Key
|
API Key
|
||||||
</div>
|
</div>
|
||||||
<div className="relative w-full">
|
<div className="relative w-full">
|
||||||
@ -283,7 +283,7 @@ export function GeneralSettingScreen() {
|
|||||||
</div>
|
</div>
|
||||||
) : null}
|
) : null}
|
||||||
<div className="flex w-full items-start gap-8">
|
<div className="flex w-full items-start gap-8">
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Appearance
|
Appearance
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-1 gap-6">
|
<div className="flex flex-1 gap-6">
|
||||||
|
@ -1,16 +1,55 @@
|
|||||||
import { webln } from "@getalby/sdk";
|
import { webln } from "@getalby/sdk";
|
||||||
import { useArk } from "@lume/ark";
|
import { useArk } from "@lume/ark";
|
||||||
import { CheckCircleIcon } from "@lume/icons";
|
|
||||||
import { useStorage } from "@lume/storage";
|
import { useStorage } from "@lume/storage";
|
||||||
|
import * as Switch from "@radix-ui/react-switch";
|
||||||
import { useEffect, useState } from "react";
|
import { useEffect, useState } from "react";
|
||||||
import { NWCForm } from "./components/walletConnectForm";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export function NWCScreen() {
|
export function NWCScreen() {
|
||||||
const ark = useArk();
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
|
|
||||||
|
const [settings, setSettings] = useState({
|
||||||
|
nwc: false,
|
||||||
|
instantZap: storage.settings.instantZap,
|
||||||
|
});
|
||||||
const [walletConnectURL, setWalletConnectURL] = useState<null | string>(null);
|
const [walletConnectURL, setWalletConnectURL] = useState<null | string>(null);
|
||||||
const [balance, setBalance] = useState(0);
|
const [amount, setAmount] = useState("21");
|
||||||
|
|
||||||
|
const saveNWC = async () => {
|
||||||
|
try {
|
||||||
|
if (!walletConnectURL.startsWith("nostr+walletconnect:")) {
|
||||||
|
return toast.error(
|
||||||
|
"Connect URI is required and must start with format nostr+walletconnect:, please check again",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const uriObj = new URL(walletConnectURL);
|
||||||
|
const params = new URLSearchParams(uriObj.search);
|
||||||
|
|
||||||
|
if (params.has("relay") && params.has("secret")) {
|
||||||
|
await storage.createPrivkey("Nostr Wallet Connect", walletConnectURL);
|
||||||
|
|
||||||
|
storage.nwc = walletConnectURL;
|
||||||
|
|
||||||
|
setWalletConnectURL(walletConnectURL);
|
||||||
|
setSettings((state) => ({ ...state, nwc: true }));
|
||||||
|
} else {
|
||||||
|
return toast.error("Connect URI is not valid, please check again");
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
toast.error(String(e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const toggleInstantZap = async () => {
|
||||||
|
await storage.createSetting("instantZap", String(+!settings.instantZap));
|
||||||
|
setSettings((state) => ({ ...state, instantZap: !settings.instantZap }));
|
||||||
|
};
|
||||||
|
|
||||||
|
const saveAmount = async () => {
|
||||||
|
await storage.createSetting("zapAmount", amount);
|
||||||
|
};
|
||||||
|
|
||||||
const remove = async () => {
|
const remove = async () => {
|
||||||
await storage.removePrivkey(`${ark.account.pubkey}-nwc`);
|
await storage.removePrivkey(`${ark.account.pubkey}-nwc`);
|
||||||
@ -24,130 +63,101 @@ export function NWCScreen() {
|
|||||||
await nwc.enable();
|
await nwc.enable();
|
||||||
|
|
||||||
const balanceResponse = await nwc.getBalance();
|
const balanceResponse = await nwc.getBalance();
|
||||||
setBalance(balanceResponse.balance);
|
|
||||||
|
|
||||||
nwc.close();
|
nwc.close();
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (walletConnectURL) loadBalance();
|
if (storage.nwc) {
|
||||||
}, [walletConnectURL]);
|
setSettings((state) => ({ ...state, nwc: true }));
|
||||||
|
setWalletConnectURL(storage.nwc);
|
||||||
useEffect(() => {
|
|
||||||
async function getNWC() {
|
|
||||||
const nwc = await storage.loadPrivkey(`${ark.account.pubkey}-nwc`);
|
|
||||||
if (nwc) setWalletConnectURL(nwc);
|
|
||||||
}
|
}
|
||||||
getNWC();
|
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div>
|
<div className="mx-auto w-full max-w-lg">
|
||||||
<div className="flex w-full flex-col gap-5">
|
<div className="flex flex-col gap-6">
|
||||||
<div className="text-center">
|
<div className="flex w-full items-center justify-between">
|
||||||
<h3 className="text-xl font-semibold leading-tight">
|
<div className="flex w-full items-center gap-8">
|
||||||
Nostr Wallet Connect
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
</h3>
|
Connection String
|
||||||
<p className="font-medium leading-snug text-neutral-600 dark:text-neutral-500">
|
</div>
|
||||||
Sending zap easily via Bitcoin Lightning.
|
<div className="relative w-full">
|
||||||
</p>
|
<input
|
||||||
|
type="password"
|
||||||
|
spellCheck={false}
|
||||||
|
value={walletConnectURL}
|
||||||
|
onChange={(e) => setWalletConnectURL(e.target.value)}
|
||||||
|
className="w-full border-transparent outline-none focus:outline-none focus:ring-0 focus:border-none h-9 rounded-lg ring-0 placeholder:text-neutral-600 bg-neutral-100 dark:bg-neutral-900"
|
||||||
|
/>
|
||||||
|
<div className="h-9 absolute right-0 top-0 inline-flex items-center justify-center">
|
||||||
|
{!settings.nwc ? (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={saveNWC}
|
||||||
|
className="mr-1 h-7 w-16 text-sm font-medium shrink-0 inline-flex items-center justify-center rounded-md bg-neutral-200 dark:bg-neutral-800 hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
) : (
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={remove}
|
||||||
|
className="mr-1 h-7 w-16 text-sm font-medium shrink-0 inline-flex items-center justify-center rounded-md bg-neutral-200 dark:bg-neutral-800 hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
||||||
|
>
|
||||||
|
Remove
|
||||||
|
</button>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="mx-auto w-full max-w-lg">
|
{settings.nwc ? (
|
||||||
{!walletConnectURL ? (
|
<>
|
||||||
<NWCForm setWalletConnectURL={setWalletConnectURL} />
|
<div className="flex w-full items-center justify-between">
|
||||||
) : (
|
<div className="flex items-center gap-8">
|
||||||
<div className="flex w-full flex-col gap-3 rounded-xl bg-neutral-100 p-3 dark:bg-neutral-900">
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
<div className="flex items-center justify-center gap-1.5 text-sm text-teal-500">
|
Instant Zap
|
||||||
<CheckCircleIcon className="h-4 w-4" />
|
</div>
|
||||||
<div>You're using nostr wallet connect</div>
|
<div className="text-sm">
|
||||||
|
Zap with default amount, no confirmation
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-3">
|
<Switch.Root
|
||||||
<textarea
|
checked={settings.instantZap}
|
||||||
readOnly
|
onClick={() => toggleInstantZap()}
|
||||||
value={`${walletConnectURL.substring(0, 120)}****`}
|
className="relative h-7 w-12 cursor-default rounded-full bg-neutral-200 outline-none data-[state=checked]:bg-blue-500 dark:bg-neutral-800"
|
||||||
className="h-40 w-full resize-none rounded-lg border-transparent bg-neutral-200 px-3 py-3 text-neutral-900 !outline-none placeholder:text-neutral-600 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:focus:ring-blue-800 dark:bg-neutral-800 dark:text-neutral-100 dark:placeholder:text-neutral-400"
|
>
|
||||||
/>
|
<Switch.Thumb className="block h-6 w-6 translate-x-0.5 rounded-full bg-white transition-transform duration-100 will-change-transform data-[state=checked]:translate-x-[19px]" />
|
||||||
<button
|
</Switch.Root>
|
||||||
type="button"
|
</div>
|
||||||
onClick={() => remove()}
|
<div className="flex w-full items-center justify-between">
|
||||||
className="inline-flex h-11 w-full items-center justify-center gap-2 rounded-lg bg-neutral-200 px-6 font-medium text-red-500 hover:bg-red-500 hover:text-white focus:outline-none dark:bg-neutral-800 dark:text-neutral-100"
|
<div className="flex w-full items-center gap-8">
|
||||||
>
|
<div className="w-36 shrink-0 text-end text-sm font-semibold">
|
||||||
Remove connection
|
Default amount
|
||||||
</button>
|
</div>
|
||||||
|
<div className="relative w-full">
|
||||||
|
<input
|
||||||
|
type="number"
|
||||||
|
spellCheck={false}
|
||||||
|
value={amount}
|
||||||
|
onChange={(e) => setAmount(e.target.value)}
|
||||||
|
className="w-full border-transparent outline-none focus:outline-none focus:ring-0 focus:border-none h-9 rounded-lg ring-0 placeholder:text-neutral-600 bg-neutral-100 dark:bg-neutral-900"
|
||||||
|
/>
|
||||||
|
<div className="h-9 absolute right-0 top-0 inline-flex items-center justify-center">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={saveAmount}
|
||||||
|
className="mr-1 h-7 w-16 text-sm font-medium shrink-0 inline-flex items-center justify-center rounded-md bg-neutral-200 dark:bg-neutral-800 hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
||||||
|
>
|
||||||
|
Save
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
)}
|
</>
|
||||||
{walletConnectURL ? (
|
) : null}
|
||||||
<div className="mt-5 flex flex-col">
|
|
||||||
<h3 className="font-medium text-neutral-600 dark:text-neutral-400">
|
|
||||||
Current balance
|
|
||||||
</h3>
|
|
||||||
<p className="text-2xl font-semibold">
|
|
||||||
{new Intl.NumberFormat().format(balance)} sats
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
<div className="mt-5 flex flex-col gap-4">
|
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<h5 className="font-semibold text-neutral-900 dark:text-neutral-100">
|
|
||||||
Introduction
|
|
||||||
</h5>
|
|
||||||
<p className="text-neutral-600 dark:text-neutral-400">
|
|
||||||
Nostr Wallet Connect (NWC) is a way for applications like
|
|
||||||
Nostr clients to access a remote Lightning wallet through a
|
|
||||||
standardized protocol.
|
|
||||||
</p>
|
|
||||||
<p className="text-neutral-600 dark:text-neutral-400">
|
|
||||||
To learn more about the details have a look at{" "}
|
|
||||||
<a
|
|
||||||
href="https://github.com/nostr-protocol/nips/blob/master/47.md"
|
|
||||||
target="_blank"
|
|
||||||
className="text-blue-500"
|
|
||||||
rel="noreferrer"
|
|
||||||
>
|
|
||||||
the specs (NIP47)
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<h5 className="font-semibold text-neutral-900 dark:text-neutral-100">
|
|
||||||
About zapping
|
|
||||||
</h5>
|
|
||||||
<p className="text-neutral-600 dark:text-neutral-400">
|
|
||||||
Lume doesn't take any commission or platform fees when
|
|
||||||
you zap someone. Lume doesn't hold your Bitcoin
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-1.5">
|
|
||||||
<h5 className="font-semibold text-neutral-900 dark:text-neutral-100">
|
|
||||||
Recommend wallet that support NWC
|
|
||||||
</h5>
|
|
||||||
<p className="text-neutral-600 dark:text-neutral-400">
|
|
||||||
- Mutiny Wallet:{" "}
|
|
||||||
<a
|
|
||||||
href="https://www.mutinywallet.com/"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="text-blue-500"
|
|
||||||
>
|
|
||||||
website
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
<p className="text-neutral-600 dark:text-neutral-400">
|
|
||||||
- Self hosted NWC on Umbrel :{" "}
|
|
||||||
<a
|
|
||||||
href="https://apps.umbrel.com/app/alby-nostr-wallet-connect"
|
|
||||||
target="_blank"
|
|
||||||
rel="noreferrer"
|
|
||||||
className="text-blue-500"
|
|
||||||
>
|
|
||||||
website
|
|
||||||
</a>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -305,9 +305,7 @@ export class Ark {
|
|||||||
public async getThreads(id: string) {
|
public async getThreads(id: string) {
|
||||||
const eventId = this.getCleanEventId(id);
|
const eventId = this.getCleanEventId(id);
|
||||||
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
||||||
const relayUrls = [...this.ndk.pool.relays.values()].map(
|
const relayUrls = Array.from(this.ndk.pool.relays.keys());
|
||||||
(item) => item.url,
|
|
||||||
);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rawEvents = (await fetcher.fetchAllEvents(
|
const rawEvents = (await fetcher.fetchAllEvents(
|
||||||
@ -357,9 +355,7 @@ export class Ark {
|
|||||||
|
|
||||||
public async getAllRelaysFromContacts({ signal }: { signal: AbortSignal }) {
|
public async getAllRelaysFromContacts({ signal }: { signal: AbortSignal }) {
|
||||||
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
||||||
const connectedRelays = this.ndk.pool
|
const connectedRelays = Array.from(this.ndk.pool.relays.keys());
|
||||||
.connectedRelays()
|
|
||||||
.map((item) => item.url);
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const relayMap = new Map<string, string[]>();
|
const relayMap = new Map<string, string[]>();
|
||||||
@ -373,8 +369,6 @@ export class Ark {
|
|||||||
{ abortSignal: signal },
|
{ abortSignal: signal },
|
||||||
);
|
);
|
||||||
|
|
||||||
console.log(relayEvents);
|
|
||||||
|
|
||||||
for await (const { author, events } of relayEvents) {
|
for await (const { author, events } of relayEvents) {
|
||||||
if (events.length) {
|
if (events.length) {
|
||||||
const relayTags = events[0].tags.filter((item) => item[0] === "r");
|
const relayTags = events[0].tags.filter((item) => item[0] === "r");
|
||||||
@ -411,9 +405,7 @@ export class Ark {
|
|||||||
dedup?: boolean;
|
dedup?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(this.ndk));
|
||||||
const relayUrls = [...this.ndk.pool.relays.values()].map(
|
const relayUrls = Array.from(this.ndk.pool.relays.keys());
|
||||||
(item) => item.url,
|
|
||||||
);
|
|
||||||
const seenIds = new Set<string>();
|
const seenIds = new Set<string>();
|
||||||
const dedupQueue = new Set<string>();
|
const dedupQueue = new Set<string>();
|
||||||
|
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
import { webln } from "@getalby/sdk";
|
import { webln } from "@getalby/sdk";
|
||||||
import { SendPaymentResponse } from "@getalby/sdk/dist/types";
|
import { type SendPaymentResponse } from "@getalby/sdk/dist/types";
|
||||||
import { CancelIcon, ZapIcon } from "@lume/icons";
|
import { CancelIcon, LoaderIcon, ZapIcon } from "@lume/icons";
|
||||||
import {
|
import { useStorage } from "@lume/storage";
|
||||||
compactNumber,
|
import { cn, compactNumber, displayNpub } from "@lume/utils";
|
||||||
displayNpub,
|
|
||||||
sendNativeNotification,
|
|
||||||
} from "@lume/utils";
|
|
||||||
import * as Dialog from "@radix-ui/react-dialog";
|
import * as Dialog from "@radix-ui/react-dialog";
|
||||||
import * as Tooltip from "@radix-ui/react-tooltip";
|
import * as Tooltip from "@radix-ui/react-tooltip";
|
||||||
import { invoke } from "@tauri-apps/api/core";
|
import { useState } from "react";
|
||||||
import { QRCodeSVG } from "qrcode.react";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import CurrencyInput from "react-currency-input-field";
|
import CurrencyInput from "react-currency-input-field";
|
||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
import { useArk } from "../../../hooks/useArk";
|
import { useArk } from "../../../hooks/useArk";
|
||||||
@ -18,83 +13,98 @@ import { useProfile } from "../../../hooks/useProfile";
|
|||||||
import { useNoteContext } from "../provider";
|
import { useNoteContext } from "../provider";
|
||||||
|
|
||||||
export function NoteZap() {
|
export function NoteZap() {
|
||||||
const [walletConnectURL, setWalletConnectURL] = useState<string>(null);
|
const ark = useArk();
|
||||||
|
const storage = useStorage();
|
||||||
|
const event = useNoteContext();
|
||||||
|
|
||||||
const [amount, setAmount] = useState<string>("21");
|
const [amount, setAmount] = useState<string>("21");
|
||||||
const [zapMessage, setZapMessage] = useState<string>("");
|
const [zapMessage, setZapMessage] = useState<string>("");
|
||||||
const [invoice, setInvoice] = useState<null | string>(null);
|
|
||||||
const [isOpen, setIsOpen] = useState(false);
|
const [isOpen, setIsOpen] = useState(false);
|
||||||
const [isCompleted, setIsCompleted] = useState(false);
|
const [isCompleted, setIsCompleted] = useState(false);
|
||||||
const [isLoading, setIsLoading] = useState(false);
|
const [isLoading, setIsLoading] = useState(false);
|
||||||
|
|
||||||
const ark = useArk();
|
|
||||||
const event = useNoteContext();
|
|
||||||
|
|
||||||
const { user } = useProfile(event.pubkey);
|
const { user } = useProfile(event.pubkey);
|
||||||
|
|
||||||
const createZapRequest = async () => {
|
const createZapRequest = async (instant?: boolean) => {
|
||||||
|
if (!storage.nwc) return;
|
||||||
|
|
||||||
let nwc: webln.NostrWebLNProvider = undefined;
|
let nwc: webln.NostrWebLNProvider = undefined;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
// start loading
|
||||||
|
setIsLoading(true);
|
||||||
|
|
||||||
const zapAmount = parseInt(amount) * 1000;
|
const zapAmount = parseInt(amount) * 1000;
|
||||||
const res = await event.zap(zapAmount, zapMessage);
|
const res = await event.zap(zapAmount, zapMessage);
|
||||||
|
|
||||||
if (!res) return toast.error("Cannot create zap request");
|
|
||||||
|
|
||||||
// user don't connect nwc, create QR Code for invoice
|
|
||||||
if (!walletConnectURL) return setInvoice(res);
|
|
||||||
|
|
||||||
// user connect nwc
|
// user connect nwc
|
||||||
nwc = new webln.NostrWebLNProvider({
|
nwc = new webln.NostrWebLNProvider({
|
||||||
nostrWalletConnectUrl: walletConnectURL,
|
nostrWalletConnectUrl: storage.nwc,
|
||||||
});
|
});
|
||||||
await nwc.enable();
|
await nwc.enable();
|
||||||
|
|
||||||
// start loading
|
|
||||||
setIsLoading(true);
|
|
||||||
|
|
||||||
// send payment via nwc
|
// send payment via nwc
|
||||||
const send: SendPaymentResponse = await nwc.sendPayment(res);
|
const send: SendPaymentResponse = await nwc.sendPayment(res);
|
||||||
|
|
||||||
if (send) {
|
if (send) {
|
||||||
await sendNativeNotification(
|
toast.success(
|
||||||
`You've zapped ${compactNumber.format(send.amount)} sats to ${
|
`You've zapped ${compactNumber.format(send.amount)} sats to ${
|
||||||
user?.name || user?.displayName || "anon"
|
user?.name || user?.displayName || "anon"
|
||||||
}`,
|
}`,
|
||||||
);
|
);
|
||||||
|
|
||||||
// eose
|
|
||||||
nwc.close();
|
|
||||||
setIsCompleted(true);
|
|
||||||
setIsLoading(false);
|
|
||||||
|
|
||||||
// reset after 1.5 secs
|
// reset after 1.5 secs
|
||||||
const timeout = setTimeout(() => setIsCompleted(false), 1500);
|
if (!instant) {
|
||||||
clearTimeout(timeout);
|
const timeout = setTimeout(() => setIsCompleted(false), 1500);
|
||||||
|
clearTimeout(timeout);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
|
// eose
|
||||||
nwc.close();
|
nwc.close();
|
||||||
|
|
||||||
|
// update state
|
||||||
|
setIsCompleted(true);
|
||||||
|
setIsLoading(false);
|
||||||
|
} catch (e) {
|
||||||
|
nwc?.close();
|
||||||
setIsLoading(false);
|
setIsLoading(false);
|
||||||
toast.error(String(e));
|
toast.error(String(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
if (storage.settings.instantZap) {
|
||||||
async function getWalletConnectURL() {
|
return (
|
||||||
const uri: string = await invoke("secure_load", {
|
<Tooltip.Provider>
|
||||||
key: `${ark.account.pubkey}-nwc`,
|
<Tooltip.Root delayDuration={150}>
|
||||||
});
|
<Tooltip.Trigger asChild>
|
||||||
if (uri) setWalletConnectURL(uri);
|
<button
|
||||||
}
|
type="button"
|
||||||
|
onClick={() => createZapRequest(true)}
|
||||||
if (isOpen) getWalletConnectURL();
|
className="inline-flex items-center justify-center group size-7 text-neutral-600 dark:text-neutral-400"
|
||||||
|
>
|
||||||
return () => {
|
{isLoading ? (
|
||||||
setAmount("21");
|
<LoaderIcon className="size-4 animate-spin" />
|
||||||
setZapMessage("");
|
) : (
|
||||||
setIsCompleted(false);
|
<ZapIcon
|
||||||
setIsLoading(false);
|
className={cn(
|
||||||
};
|
"size-5 group-hover:text-blue-500",
|
||||||
}, [isOpen]);
|
isCompleted ? "text-blue-500" : "",
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</Tooltip.Trigger>
|
||||||
|
<Tooltip.Portal>
|
||||||
|
<Tooltip.Content className="inline-flex h-7 select-none text-neutral-50 dark:text-neutral-950 items-center justify-center rounded-md bg-neutral-950 dark:bg-neutral-50 px-3.5 text-sm will-change-[transform,opacity] data-[state=delayed-open]:data-[side=bottom]:animate-slideUpAndFade data-[state=delayed-open]:data-[side=left]:animate-slideRightAndFade data-[state=delayed-open]:data-[side=right]:animate-slideLeftAndFade data-[state=delayed-open]:data-[side=top]:animate-slideDownAndFade">
|
||||||
|
Zap
|
||||||
|
<Tooltip.Arrow className="fill-neutral-950 dark:fill-neutral-50" />
|
||||||
|
</Tooltip.Content>
|
||||||
|
</Tooltip.Portal>
|
||||||
|
</Tooltip.Root>
|
||||||
|
</Tooltip.Provider>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
|
<Dialog.Root open={isOpen} onOpenChange={setIsOpen}>
|
||||||
@ -135,129 +145,99 @@ export function NoteZap() {
|
|||||||
</Dialog.Close>
|
</Dialog.Close>
|
||||||
</div>
|
</div>
|
||||||
<div className="px-5 pb-5 overflow-x-hidden overflow-y-auto">
|
<div className="px-5 pb-5 overflow-x-hidden overflow-y-auto">
|
||||||
{!invoice ? (
|
<div className="relative flex flex-col h-40">
|
||||||
<>
|
<div className="inline-flex items-center justify-center flex-1 h-full gap-1">
|
||||||
<div className="relative flex flex-col h-40">
|
<CurrencyInput
|
||||||
<div className="inline-flex items-center justify-center flex-1 h-full gap-1">
|
placeholder="0"
|
||||||
<CurrencyInput
|
defaultValue={"21"}
|
||||||
placeholder="0"
|
value={amount}
|
||||||
defaultValue={"21"}
|
decimalsLimit={2}
|
||||||
value={amount}
|
min={0} // 0 sats
|
||||||
decimalsLimit={2}
|
max={10000} // 1M sats
|
||||||
min={0} // 0 sats
|
maxLength={10000} // 1M sats
|
||||||
max={10000} // 1M sats
|
onValueChange={(value) => setAmount(value)}
|
||||||
maxLength={10000} // 1M sats
|
className="flex-1 w-full text-4xl font-semibold text-right bg-transparent border-none placeholder:text-neutral-600 focus:outline-none focus:ring-0 dark:text-neutral-400"
|
||||||
onValueChange={(value) => setAmount(value)}
|
/>
|
||||||
className="flex-1 w-full text-4xl font-semibold text-right bg-transparent border-none placeholder:text-neutral-600 focus:outline-none focus:ring-0 dark:text-neutral-400"
|
<span className="flex-1 w-full text-4xl font-semibold text-left text-neutral-500 dark:text-neutral-400">
|
||||||
/>
|
sats
|
||||||
<span className="flex-1 w-full text-4xl font-semibold text-left text-neutral-500 dark:text-neutral-400">
|
</span>
|
||||||
sats
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="inline-flex items-center justify-center gap-2">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setAmount("69")}
|
|
||||||
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
69 sats
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setAmount("100")}
|
|
||||||
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
100 sats
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setAmount("200")}
|
|
||||||
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
200 sats
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setAmount("500")}
|
|
||||||
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
500 sats
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => setAmount("1000")}
|
|
||||||
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
|
||||||
>
|
|
||||||
1K sats
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col w-full gap-2 mt-4">
|
|
||||||
<input
|
|
||||||
name="zapMessage"
|
|
||||||
value={zapMessage}
|
|
||||||
onChange={(e) => setZapMessage(e.target.value)}
|
|
||||||
spellCheck={false}
|
|
||||||
autoComplete="off"
|
|
||||||
autoCorrect="off"
|
|
||||||
autoCapitalize="off"
|
|
||||||
placeholder="Enter message (optional)"
|
|
||||||
className="w-full resize-none rounded-lg border-transparent bg-neutral-100 px-3 py-3 !outline-none placeholder:text-neutral-600 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:bg-neutral-900 dark:text-neutral-400"
|
|
||||||
/>
|
|
||||||
<div className="flex flex-col gap-2">
|
|
||||||
{walletConnectURL ? (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => createZapRequest()}
|
|
||||||
className="inline-flex items-center justify-center w-full px-4 font-medium text-white bg-blue-500 rounded-lg h-11 hover:bg-blue-600"
|
|
||||||
>
|
|
||||||
{isCompleted ? (
|
|
||||||
<p className="leading-tight">Successfully zapped</p>
|
|
||||||
) : isLoading ? (
|
|
||||||
<span className="flex flex-col">
|
|
||||||
<p className="leading-tight">
|
|
||||||
Waiting for approval
|
|
||||||
</p>
|
|
||||||
<p className="text-xs leading-tight text-neutral-100">
|
|
||||||
Go to your wallet and approve payment request
|
|
||||||
</p>
|
|
||||||
</span>
|
|
||||||
) : (
|
|
||||||
<span className="flex flex-col">
|
|
||||||
<p className="leading-tight">Send zap</p>
|
|
||||||
<p className="text-xs leading-tight text-neutral-100">
|
|
||||||
You're using nostr wallet connect
|
|
||||||
</p>
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => createZapRequest()}
|
|
||||||
className="inline-flex items-center justify-center w-full px-4 font-medium text-white bg-blue-500 rounded-lg h-11 hover:bg-blue-600"
|
|
||||||
>
|
|
||||||
Create Lightning invoice
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
) : (
|
|
||||||
<div className="flex flex-col items-center justify-center gap-4 mt-3">
|
|
||||||
<div className="p-3 rounded-md bg-neutral-100 dark:bg-neutral-900">
|
|
||||||
<QRCodeSVG value={invoice} size={256} />
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col items-center gap-1">
|
|
||||||
<h3 className="text-lg font-medium">Scan to zap</h3>
|
|
||||||
<span className="text-sm text-center text-neutral-600 dark:text-neutral-400">
|
|
||||||
You must use Bitcoin wallet which support Lightning
|
|
||||||
<br />
|
|
||||||
such as: Blue Wallet, Bitkit, Phoenix,...
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div className="inline-flex items-center justify-center gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setAmount("69")}
|
||||||
|
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||||
|
>
|
||||||
|
69 sats
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setAmount("100")}
|
||||||
|
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||||
|
>
|
||||||
|
100 sats
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setAmount("200")}
|
||||||
|
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||||
|
>
|
||||||
|
200 sats
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setAmount("500")}
|
||||||
|
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||||
|
>
|
||||||
|
500 sats
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => setAmount("1000")}
|
||||||
|
className="w-max rounded-full bg-neutral-100 px-2.5 py-1 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||||
|
>
|
||||||
|
1K sats
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-col w-full gap-2 mt-4">
|
||||||
|
<input
|
||||||
|
name="zapMessage"
|
||||||
|
value={zapMessage}
|
||||||
|
onChange={(e) => setZapMessage(e.target.value)}
|
||||||
|
spellCheck={false}
|
||||||
|
autoComplete="off"
|
||||||
|
autoCorrect="off"
|
||||||
|
autoCapitalize="off"
|
||||||
|
placeholder="Enter message (optional)"
|
||||||
|
className="w-full resize-none rounded-lg border-transparent bg-neutral-100 px-3 py-3 !outline-none placeholder:text-neutral-600 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:bg-neutral-900 dark:text-neutral-400"
|
||||||
|
/>
|
||||||
|
<div className="flex flex-col gap-2">
|
||||||
|
<button
|
||||||
|
type="button"
|
||||||
|
onClick={() => createZapRequest()}
|
||||||
|
className="inline-flex items-center justify-center w-full px-4 font-medium text-white bg-blue-500 rounded-lg h-11 hover:bg-blue-600"
|
||||||
|
>
|
||||||
|
{isCompleted ? (
|
||||||
|
<p className="leading-tight">Successfully zapped</p>
|
||||||
|
) : isLoading ? (
|
||||||
|
<span className="flex flex-col">
|
||||||
|
<p className="leading-tight">Waiting for approval</p>
|
||||||
|
<p className="text-xs leading-tight text-neutral-100">
|
||||||
|
Go to your wallet and approve payment request
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
) : (
|
||||||
|
<span className="flex flex-col">
|
||||||
|
<p className="leading-tight">Send zap</p>
|
||||||
|
<p className="text-xs leading-tight text-neutral-100">
|
||||||
|
You're using nostr wallet connect
|
||||||
|
</p>
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</Dialog.Content>
|
</Dialog.Content>
|
||||||
|
@ -38,7 +38,7 @@ export function NoteContent({
|
|||||||
|
|
||||||
const [content, setContent] = useState(event.content);
|
const [content, setContent] = useState(event.content);
|
||||||
const [translate, setTranslate] = useState({
|
const [translate, setTranslate] = useState({
|
||||||
translatable: true,
|
translatable: false,
|
||||||
translated: false,
|
translated: false,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ export function LinkPreview({ url }: { url: string }) {
|
|||||||
to={url}
|
to={url}
|
||||||
target="_blank"
|
target="_blank"
|
||||||
rel="noreferrer"
|
rel="noreferrer"
|
||||||
className="flex flex-col w-full my-1 overflow-hidden rounded-lg bg-neutral-100 dark:bg-neutral-900"
|
className="flex flex-col w-full my-1 overflow-hidden rounded-lg bg-neutral-100 dark:bg-neutral-900 border border-black/5 dark:border-white/5"
|
||||||
>
|
>
|
||||||
{isImage(data.image) ? (
|
{isImage(data.image) ? (
|
||||||
<img
|
<img
|
||||||
|
@ -12,7 +12,13 @@ export function VideoPreview({ url }: { url: string }) {
|
|||||||
return (
|
return (
|
||||||
<div className="my-1 w-full rounded-lg overflow-hidden">
|
<div className="my-1 w-full rounded-lg overflow-hidden">
|
||||||
<MediaController>
|
<MediaController>
|
||||||
<video slot="media" src={url} preload="auto" muted />
|
<video
|
||||||
|
slot="media"
|
||||||
|
src={url}
|
||||||
|
preload="auto"
|
||||||
|
muted
|
||||||
|
className="w-full h-auto"
|
||||||
|
/>
|
||||||
<MediaControlBar>
|
<MediaControlBar>
|
||||||
<MediaPlayButton />
|
<MediaPlayButton />
|
||||||
<MediaTimeRange />
|
<MediaTimeRange />
|
||||||
|
@ -6,13 +6,13 @@ export function ChildReply({
|
|||||||
}: { event: NDKEvent; rootEventId?: string }) {
|
}: { event: NDKEvent; rootEventId?: string }) {
|
||||||
return (
|
return (
|
||||||
<Note.Provider event={event}>
|
<Note.Provider event={event}>
|
||||||
<Note.Root className="pl-6">
|
<Note.Root className="py-2">
|
||||||
<div className="flex items-center justify-between h-14">
|
<div className="flex items-center justify-between h-14">
|
||||||
<Note.User className="flex-1" />
|
<Note.User className="flex-1" />
|
||||||
<Note.Menu />
|
<Note.Menu />
|
||||||
</div>
|
</div>
|
||||||
<Note.Content />
|
<Note.Content />
|
||||||
<div className="flex items-center justify-end gap-10 mt-4">
|
<div className="flex items-center justify-end gap-4 mt-2">
|
||||||
<Note.Repost />
|
<Note.Repost />
|
||||||
<Note.Zap />
|
<Note.Zap />
|
||||||
</div>
|
</div>
|
||||||
|
@ -37,14 +37,20 @@ export function Reply({
|
|||||||
) : (
|
) : (
|
||||||
<div />
|
<div />
|
||||||
)}
|
)}
|
||||||
<div className="inline-flex items-center gap-10">
|
<div className="inline-flex items-center gap-4">
|
||||||
<Note.Repost />
|
<Note.Repost />
|
||||||
<Note.Zap />
|
<Note.Zap />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className={cn("", open ? "pb-3" : "")}>
|
<div
|
||||||
|
className={cn(
|
||||||
|
open
|
||||||
|
? "pb-3 border-t border-neutral-100 dark:border-neutral-900"
|
||||||
|
: "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
{event.replies?.length > 0 ? (
|
{event.replies?.length > 0 ? (
|
||||||
<Collapsible.Content>
|
<Collapsible.Content className="divide-y divide-neutral-100 dark:divide-neutral-900 pl-6">
|
||||||
{event.replies?.map((childEvent) => (
|
{event.replies?.map((childEvent) => (
|
||||||
<ChildReply key={childEvent.id} event={childEvent} />
|
<ChildReply key={childEvent.id} event={childEvent} />
|
||||||
))}
|
))}
|
||||||
|
@ -32,7 +32,7 @@ export function ThreadNote({ eventId }: { eventId: string }) {
|
|||||||
<Note.Content className="min-w-0 px-3" />
|
<Note.Content className="min-w-0 px-3" />
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
<div className="flex items-center justify-between px-3 h-14">
|
||||||
<Note.Pin />
|
<Note.Pin />
|
||||||
<div className="inline-flex items-center gap-10">
|
<div className="inline-flex items-center gap-4">
|
||||||
<Note.Repost />
|
<Note.Repost />
|
||||||
<Note.Zap />
|
<Note.Zap />
|
||||||
</div>
|
</div>
|
||||||
|
@ -19,6 +19,7 @@ export class LumeStorage {
|
|||||||
readonly platform: Platform;
|
readonly platform: Platform;
|
||||||
readonly locale: string;
|
readonly locale: string;
|
||||||
public currentUser: Account;
|
public currentUser: Account;
|
||||||
|
public nwc: string;
|
||||||
public settings: {
|
public settings: {
|
||||||
autoupdate: boolean;
|
autoupdate: boolean;
|
||||||
nsecbunker: boolean;
|
nsecbunker: boolean;
|
||||||
@ -29,12 +30,14 @@ export class LumeStorage {
|
|||||||
lowPower: boolean;
|
lowPower: boolean;
|
||||||
translation: boolean;
|
translation: boolean;
|
||||||
translateApiKey: string;
|
translateApiKey: string;
|
||||||
|
instantZap: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
constructor(db: Database, platform: Platform, locale: string) {
|
constructor(db: Database, platform: Platform, locale: string) {
|
||||||
this.#db = db;
|
this.#db = db;
|
||||||
this.locale = locale;
|
this.locale = locale;
|
||||||
this.platform = platform;
|
this.platform = platform;
|
||||||
|
this.nwc = null;
|
||||||
this.settings = {
|
this.settings = {
|
||||||
autoupdate: false,
|
autoupdate: false,
|
||||||
nsecbunker: false,
|
nsecbunker: false,
|
||||||
@ -45,6 +48,7 @@ export class LumeStorage {
|
|||||||
lowPower: false,
|
lowPower: false,
|
||||||
translation: false,
|
translation: false,
|
||||||
translateApiKey: "",
|
translateApiKey: "",
|
||||||
|
instantZap: false,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,6 +65,8 @@ export class LumeStorage {
|
|||||||
|
|
||||||
const account = await this.getActiveAccount();
|
const account = await this.getActiveAccount();
|
||||||
if (account) this.currentUser = account;
|
if (account) this.currentUser = account;
|
||||||
|
|
||||||
|
this.nwc = await this.loadPrivkey("Nostr Wallet Connect");
|
||||||
}
|
}
|
||||||
|
|
||||||
async #keyring_save(key: string, value: string) {
|
async #keyring_save(key: string, value: string) {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
import {
|
import {
|
||||||
AdvancedSettingsIcon,
|
AdvancedSettingsIcon,
|
||||||
InfoIcon,
|
InfoIcon,
|
||||||
NwcIcon,
|
|
||||||
SecureIcon,
|
SecureIcon,
|
||||||
SettingsIcon,
|
SettingsIcon,
|
||||||
UserIcon,
|
UserIcon,
|
||||||
|
ZapIcon,
|
||||||
} from "@lume/icons";
|
} from "@lume/icons";
|
||||||
import { cn } from "@lume/utils";
|
import { cn } from "@lume/utils";
|
||||||
import { NavLink, Outlet } from "react-router-dom";
|
import { NavLink, Outlet } from "react-router-dom";
|
||||||
@ -13,7 +13,7 @@ export function SettingsLayout() {
|
|||||||
return (
|
return (
|
||||||
<div className="flex h-full min-h-0 w-full flex-col rounded-xl overflow-y-auto">
|
<div className="flex h-full min-h-0 w-full flex-col rounded-xl overflow-y-auto">
|
||||||
<div className="flex h-24 shrink-0 w-full items-center justify-center px-2 bg-white/50 backdrop-blur-xl dark:bg-black/50">
|
<div className="flex h-24 shrink-0 w-full items-center justify-center px-2 bg-white/50 backdrop-blur-xl dark:bg-black/50">
|
||||||
<div className="flex items-center gap-0.5">
|
<div className="flex items-center gap-2">
|
||||||
<NavLink
|
<NavLink
|
||||||
end
|
end
|
||||||
to="/settings/"
|
to="/settings/"
|
||||||
@ -55,8 +55,8 @@ export function SettingsLayout() {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
<NwcIcon className="size-6" />
|
<ZapIcon className="size-6" />
|
||||||
<p className="text-sm font-medium">Wallet</p>
|
<p className="text-sm font-medium">Zap</p>
|
||||||
</NavLink>
|
</NavLink>
|
||||||
<NavLink
|
<NavLink
|
||||||
to="/settings/backup"
|
to="/settings/backup"
|
||||||
|
484
pnpm-lock.yaml
484
pnpm-lock.yaml
@ -258,25 +258,25 @@ importers:
|
|||||||
version: 0.15.0(@nostr-dev-kit/ndk@2.3.3)(nostr-fetch@0.15.0)
|
version: 0.15.0(@nostr-dev-kit/ndk@2.3.3)(nostr-fetch@0.15.0)
|
||||||
'@radix-ui/react-avatar':
|
'@radix-ui/react-avatar':
|
||||||
specifier: ^1.0.4
|
specifier: ^1.0.4
|
||||||
version: 1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-collapsible':
|
'@radix-ui/react-collapsible':
|
||||||
specifier: ^1.0.3
|
specifier: ^1.0.3
|
||||||
version: 1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-dialog':
|
'@radix-ui/react-dialog':
|
||||||
specifier: ^1.0.5
|
specifier: ^1.0.5
|
||||||
version: 1.0.5(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-dropdown-menu':
|
'@radix-ui/react-dropdown-menu':
|
||||||
specifier: ^2.0.6
|
specifier: ^2.0.6
|
||||||
version: 2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 2.0.6(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-hover-card':
|
'@radix-ui/react-hover-card':
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-popover':
|
'@radix-ui/react-popover':
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@radix-ui/react-tooltip':
|
'@radix-ui/react-tooltip':
|
||||||
specifier: ^1.0.7
|
specifier: ^1.0.7
|
||||||
version: 1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.17.15
|
specifier: ^5.17.15
|
||||||
version: 5.17.15(react@18.2.0)
|
version: 5.17.15(react@18.2.0)
|
||||||
@ -1884,6 +1884,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-arrow@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-wSP+pHsB/jQRaL6voubsQ/ZlrGBHHrOjmBnr19hxYgtS0WvAFwZhK2WP/YY5yF9uKECCEEDGxuLxq1NBK51wFA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-avatar@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-avatar@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1908,6 +1928,29 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-avatar@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-collapsible@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1936,6 +1979,33 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-collapsible@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-collection@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1960,6 +2030,29 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-collection@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2022,6 +2115,39 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dialog@1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-GjWJX/AUpB703eEBanuBnIWdIXg6NvJFCXcNlSZk4xdszCdhrJgBoUd1cGk67vFO+WdA2pfI/plOpqz/5GUP6Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
aria-hidden: 1.2.3
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-direction@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
/@radix-ui/react-direction@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
|
resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2061,6 +2187,30 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dismissable-layer@1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-aJeDjQhywg9LBu2t/At58hCvr7pEm0o2Ke1x33B+MhjNmmZ17sy4KImo0KPLgsnc/zN7GPdce8Cnn0SWvwZO7g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-dropdown-menu@2.0.6(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==}
|
resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2088,6 +2238,32 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dropdown-menu@2.0.6(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-i6TuFOoWmLWq+M/eCLGd/bQ2HfAX1RJgvrBQ6AQLmzfvsLdefxbWu8G9zczcPFfcSPehz9GcpF6K9QYreFV8hA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-menu': 2.0.6(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2125,6 +2301,28 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-focus-scope@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-sL04Mgvf+FmyvZeYfNu1EPAaaxD+aw7cYeIB9L9Fvq8+urhltTRaEo5ysKOpHuKPclsZcSUMKlN05x4u+CINpA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-hover-card@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-hover-card@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==}
|
resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2154,6 +2352,34 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-hover-card@1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-id@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
/@radix-ui/react-id@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2207,6 +2433,43 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-menu@2.0.6(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-BVkFLS+bUC8HcImkRKPSiVumA1VPOOEC5WBMiT+QAVsPzW1FJzI9KnqgGxVDPBcql5xXrHkD3JOVoXWEXD8SYA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-collection': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-roving-focus': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
aria-hidden: 1.2.3
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
|
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2242,6 +2505,40 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-popover@1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-shtvVnlsxT6faMnK/a7n0wptwBD23xc1Z5mdrtKLwVEfsEMXodS0r5s0/g5P0hX//EKYZS2sxUjqfzlg52ZSnQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
aria-hidden: 1.2.3
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
react-remove-scroll: 2.5.5(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2272,6 +2569,35 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-popper@1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-cKpopj/5RHZWjrbF2846jBNacjQVwkP068DfmgrNJXpvVWrOvlAmE9xSiy5OqeE+Gi8D9fP+oDhUnPqNMY8/5w==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@floating-ui/react-dom': 2.0.6(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-arrow': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/rect': 1.0.1
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-portal@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2293,6 +2619,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-portal@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-Qki+C/EuGUVCQTOTD5vzJzJuMUlewbzuKyUy+/iHM2uwGiru9gZeBJtHAPKAEkB5KWGi9mP/CHKcY0wt1aW45Q==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-presence@1.0.1(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2315,6 +2661,27 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-presence@1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-primitive@1.0.3(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2336,6 +2703,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-primitive@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-yi58uVyoAcK/Nq1inRY56ZSjKypBNKTa/1mcL8qdl6oJeEaDbOldlzrGn7P6Q3Id5d+SYNGc5AJgc4vGhjs5+g==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-roving-focus@1.0.4(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==}
|
resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2365,6 +2752,34 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-roving-focus@1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-2mUg5Mgcu001VkGy+FfzZyzbmuUWzgWkj3rvv4yu+mLw03+mTzbxZHvfcGyFp2b8EkQeMkpRQ5FiA2Vr2O6TeQ==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-collection': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
/@radix-ui/react-select@2.0.0(@types/react-dom@18.2.18)(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==}
|
resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2480,6 +2895,37 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-tooltip@1.0.7(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-lPh5iKNFVQ/jav/j6ZrWq3blfDJ0OH9R6FlNUHPMqdLuQ9vwDgFsRxvl8b7Asuy5c8xmoojHUxKHQSOAvMHxyw==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/primitive': 1.0.1
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.48)(react@18.2.0)
|
||||||
|
'@radix-ui/react-visually-hidden': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.48)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
|
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2603,6 +3049,26 @@ packages:
|
|||||||
react-dom: 18.2.0(react@18.2.0)
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-visually-hidden@1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0):
|
||||||
|
resolution: {integrity: sha512-D4w41yN5YRKtu464TLnByKzMDG/JlMPHtfZgQAu9v6mNakUqGUI9vUrfQKz8NK41VMm/xbZbh76NUTVtIYqOMA==}
|
||||||
|
peerDependencies:
|
||||||
|
'@types/react': '*'
|
||||||
|
'@types/react-dom': '*'
|
||||||
|
react: ^16.8 || ^17.0 || ^18.0
|
||||||
|
react-dom: ^16.8 || ^17.0 || ^18.0
|
||||||
|
peerDependenciesMeta:
|
||||||
|
'@types/react':
|
||||||
|
optional: true
|
||||||
|
'@types/react-dom':
|
||||||
|
optional: true
|
||||||
|
dependencies:
|
||||||
|
'@babel/runtime': 7.23.8
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.48)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.48
|
||||||
|
react: 18.2.0
|
||||||
|
react-dom: 18.2.0(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/rect@1.0.1:
|
/@radix-ui/rect@1.0.1:
|
||||||
resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
|
resolution: {integrity: sha512-fyrgCaedtvMg9NK3en0pnOYJdtfwxUcNolezkNPUsoX57X8oQk+NkqcvzHXD2uKNij6GXmWU9NDru2IWjrO4BQ==}
|
||||||
dependencies:
|
dependencies:
|
||||||
@ -2741,14 +3207,14 @@ packages:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@noble/curves': 1.1.0
|
'@noble/curves': 1.1.0
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.1
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.5
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@scure/bip39@1.2.1:
|
/@scure/bip39@1.2.1:
|
||||||
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
|
resolution: {integrity: sha512-Z3/Fsz1yr904dduJD0NpiyRHhRYHdcnyh73FZWiV+/qhWi83wNJ3NWolYqCEN+ZWsUz2TWwajJggcRE9r1zUYg==}
|
||||||
dependencies:
|
dependencies:
|
||||||
'@noble/hashes': 1.3.1
|
'@noble/hashes': 1.3.1
|
||||||
'@scure/base': 1.1.1
|
'@scure/base': 1.1.5
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/@swc/core-darwin-arm64@1.3.103:
|
/@swc/core-darwin-arm64@1.3.103:
|
||||||
|
Loading…
Reference in New Issue
Block a user