mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-29 16:30:55 +00:00
feat: polish
This commit is contained in:
parent
ab27bd5f44
commit
f908c46a19
@ -1,5 +1,6 @@
|
|||||||
module.exports = {
|
module.exports = {
|
||||||
plugins: {
|
plugins: {
|
||||||
tailwindcss: {},
|
tailwindcss: {},
|
||||||
|
autoprefixer: {},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -50,7 +50,6 @@ export function ActivityList() {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
staleTime: 360 * 1000,
|
staleTime: 360 * 1000,
|
||||||
refetchOnWindowFocus: false,
|
refetchOnWindowFocus: false,
|
||||||
refetchOnMount: false,
|
refetchOnMount: false,
|
||||||
|
@ -145,10 +145,11 @@ export function CreateAccountScreen() {
|
|||||||
|
|
||||||
// add account to storage
|
// add account to storage
|
||||||
await storage.createSetting("nsecbunker", "1");
|
await storage.createSetting("nsecbunker", "1");
|
||||||
await storage.createAccount({
|
const dbAccount = await storage.createAccount({
|
||||||
pubkey: account,
|
pubkey: account,
|
||||||
privkey: localSigner.privateKey,
|
privkey: localSigner.privateKey,
|
||||||
});
|
});
|
||||||
|
ark.account = dbAccount;
|
||||||
|
|
||||||
// get final signer with newly created account
|
// get final signer with newly created account
|
||||||
const finalSigner = new NDKNip46Signer(bunker, account, localSigner);
|
const finalSigner = new NDKNip46Signer(bunker, account, localSigner);
|
||||||
@ -156,7 +157,6 @@ export function CreateAccountScreen() {
|
|||||||
|
|
||||||
// update main ndk instance signer
|
// update main ndk instance signer
|
||||||
ark.updateNostrSigner({ signer: finalSigner });
|
ark.updateNostrSigner({ signer: finalSigner });
|
||||||
console.log(ark.ndk.signer);
|
|
||||||
|
|
||||||
// remove default nsecbunker profile and contact list
|
// remove default nsecbunker profile and contact list
|
||||||
await ark.createEvent({ kind: NDKKind.Metadata, content: "", tags: [] });
|
await ark.createEvent({ kind: NDKKind.Metadata, content: "", tags: [] });
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { EyeOffIcon, EyeOnIcon, LoaderIcon } from "@lume/icons";
|
import { EyeOffIcon, EyeOnIcon, LoaderIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
import { useStorage } from "@lume/storage";
|
||||||
import { getPublicKey, nip19 } from "nostr-tools";
|
import { getPublicKey, nip19 } from "nostr-tools";
|
||||||
@ -7,6 +8,7 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export function LoginWithKey() {
|
export function LoginWithKey() {
|
||||||
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
const navigate = useNavigate();
|
const navigate = useNavigate();
|
||||||
|
|
||||||
@ -30,10 +32,11 @@ export function LoginWithKey() {
|
|||||||
const privkey = nip19.decode(data.nsec).data as string;
|
const privkey = nip19.decode(data.nsec).data as string;
|
||||||
const pubkey = getPublicKey(privkey);
|
const pubkey = getPublicKey(privkey);
|
||||||
|
|
||||||
await storage.createAccount({
|
const account = await storage.createAccount({
|
||||||
pubkey: pubkey,
|
pubkey: pubkey,
|
||||||
privkey: privkey,
|
privkey: privkey,
|
||||||
});
|
});
|
||||||
|
ark.account = account;
|
||||||
|
|
||||||
return navigate("/auth/onboarding", { replace: true });
|
return navigate("/auth/onboarding", { replace: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -48,10 +48,11 @@ export function LoginWithNsecbunker() {
|
|||||||
ark.updateNostrSigner({ signer: remoteSigner });
|
ark.updateNostrSigner({ signer: remoteSigner });
|
||||||
|
|
||||||
await storage.createSetting("nsecbunker", "1");
|
await storage.createSetting("nsecbunker", "1");
|
||||||
await storage.createAccount({
|
const account = await storage.createAccount({
|
||||||
pubkey,
|
pubkey: pubkey,
|
||||||
privkey: localSigner.privateKey,
|
privkey: localSigner.privateKey,
|
||||||
});
|
});
|
||||||
|
ark.account = account;
|
||||||
|
|
||||||
return navigate("/auth/onboarding", { replace: true });
|
return navigate("/auth/onboarding", { replace: true });
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
|
@ -109,10 +109,11 @@ export function LoginWithOAuth() {
|
|||||||
ark.updateNostrSigner({ signer: remoteSigner });
|
ark.updateNostrSigner({ signer: remoteSigner });
|
||||||
|
|
||||||
await storage.createSetting("nsecbunker", "1");
|
await storage.createSetting("nsecbunker", "1");
|
||||||
await storage.createAccount({
|
const account = await storage.createAccount({
|
||||||
pubkey,
|
pubkey,
|
||||||
privkey: localSigner.privateKey,
|
privkey: localSigner.privateKey,
|
||||||
});
|
});
|
||||||
|
ark.account = account;
|
||||||
|
|
||||||
return navigate("/auth/onboarding", { replace: true });
|
return navigate("/auth/onboarding", { replace: true });
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ export function OnboardingScreen() {
|
|||||||
|
|
||||||
const toggleLowPower = async () => {
|
const toggleLowPower = async () => {
|
||||||
await storage.createSetting("lowPower", String(+!settings.lowPower));
|
await storage.createSetting("lowPower", String(+!settings.lowPower));
|
||||||
setSettings((state) => ({ ...state, autoupdate: !settings.lowPower }));
|
setSettings((state) => ({ ...state, lowPower: !settings.lowPower }));
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleTranslation = async () => {
|
const toggleTranslation = async () => {
|
||||||
@ -58,7 +58,7 @@ export function OnboardingScreen() {
|
|||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
// get account contacts
|
// get account contacts
|
||||||
await ark.getUserContacts(ark.account.pubkey);
|
await ark.getUserContacts();
|
||||||
|
|
||||||
// refetch newsfeed
|
// refetch newsfeed
|
||||||
await queryClient.prefetchInfiniteQuery({
|
await queryClient.prefetchInfiniteQuery({
|
||||||
@ -154,7 +154,7 @@ export function OnboardingScreen() {
|
|||||||
<h3 className="font-semibold text-lg">Low Power Mode</h3>
|
<h3 className="font-semibold text-lg">Low Power Mode</h3>
|
||||||
<p className="text-neutral-500">
|
<p className="text-neutral-500">
|
||||||
Limited relay connection and hide all media, sustainable for low
|
Limited relay connection and hide all media, sustainable for low
|
||||||
network environment
|
network environment.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@ -171,7 +171,8 @@ export function OnboardingScreen() {
|
|||||||
Translation (nostr.wine)
|
Translation (nostr.wine)
|
||||||
</h3>
|
</h3>
|
||||||
<p className="text-neutral-500">
|
<p className="text-neutral-500">
|
||||||
Translate text to your preferred language, powered by Nostr Wine
|
Translate text to your preferred language, powered by Nostr
|
||||||
|
Wine.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -87,7 +87,7 @@ export function DepotMembers() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/20 backdrop-blur-sm dark:bg-black/20" />
|
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/10 backdrop-blur-sm dark:bg-black/10" />
|
||||||
<Dialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
<Dialog.Content className="fixed inset-0 z-50 flex min-h-full items-center justify-center">
|
||||||
<div className="relative h-min w-full max-w-xl overflow-hidden rounded-xl bg-white dark:bg-black">
|
<div className="relative h-min w-full max-w-xl overflow-hidden rounded-xl bg-white dark:bg-black">
|
||||||
<div className="inline-flex h-14 w-full shrink-0 items-center justify-between border-b border-neutral-100 px-5 dark:border-neutral-900">
|
<div className="inline-flex h-14 w-full shrink-0 items-center justify-between border-b border-neutral-100 px-5 dark:border-neutral-900">
|
||||||
|
@ -13,14 +13,14 @@ export function AdvancedSettingScreen() {
|
|||||||
<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-24 shrink-0 text-end text-sm font-semibold">
|
||||||
Caches
|
Cache
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Use for boost up NDK</div>
|
<div className="text-sm">Use for boost up nostr connection</div>
|
||||||
</div>
|
</div>
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
onClick={() => clearCache()}
|
onClick={() => clearCache()}
|
||||||
className="h-8 w-max rounded-lg bg-blue-500 px-3 text-sm font-medium text-white hover:bg-blue-600"
|
className="h-8 w-max rounded-lg px-3 text-sm font-semibold text-blue-500 bg-blue-100 hover:bg-blue-200"
|
||||||
>
|
>
|
||||||
Clear
|
Clear
|
||||||
</button>
|
</button>
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { LoaderIcon } from "@lume/icons";
|
import { LoaderIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { compactNumber } from "@lume/utils";
|
import { compactNumber } from "@lume/utils";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export function PostCard() {
|
export function PostCard() {
|
||||||
const storage = useStorage();
|
const ark = useArk();
|
||||||
const { status, data } = useQuery({
|
const { status, data } = useQuery({
|
||||||
queryKey: ["user-stats", ark.account.pubkey],
|
queryKey: ["user-stats", ark.account.pubkey],
|
||||||
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
import { useProfile } from "@lume/ark";
|
import { useArk, useProfile } from "@lume/ark";
|
||||||
import { EditIcon, LoaderIcon } from "@lume/icons";
|
import { EditIcon, LoaderIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { displayNpub } from "@lume/utils";
|
import { displayNpub } from "@lume/utils";
|
||||||
import * as Avatar from "@radix-ui/react-avatar";
|
import * as Avatar from "@radix-ui/react-avatar";
|
||||||
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
import { writeText } from "@tauri-apps/plugin-clipboard-manager";
|
||||||
@ -9,7 +8,7 @@ import { nip19 } from "nostr-tools";
|
|||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export function ProfileCard() {
|
export function ProfileCard() {
|
||||||
const storage = useStorage();
|
const ark = useArk();
|
||||||
const svgURI = `data:image/svg+xml;utf8,${encodeURIComponent(
|
const svgURI = `data:image/svg+xml;utf8,${encodeURIComponent(
|
||||||
minidenticon(ark.account.pubkey, 90, 50),
|
minidenticon(ark.account.pubkey, 90, 50),
|
||||||
)}`;
|
)}`;
|
||||||
|
@ -1,13 +1,11 @@
|
|||||||
import { useArk } from "@lume/ark";
|
import { useArk } from "@lume/ark";
|
||||||
import { EditIcon, LoaderIcon } from "@lume/icons";
|
import { EditIcon, LoaderIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { compactNumber } from "@lume/utils";
|
import { compactNumber } from "@lume/utils";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
|
|
||||||
export function RelayCard() {
|
export function RelayCard() {
|
||||||
const ark = useArk();
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
|
||||||
|
|
||||||
const { status, data } = useQuery({
|
const { status, data } = useQuery({
|
||||||
queryKey: ["relays", ark.account.pubkey],
|
queryKey: ["relays", ark.account.pubkey],
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { LoaderIcon } from "@lume/icons";
|
import { LoaderIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { compactNumber } from "@lume/utils";
|
import { compactNumber } from "@lume/utils";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
|
|
||||||
export function ZapCard() {
|
export function ZapCard() {
|
||||||
const storage = useStorage();
|
const ark = useArk();
|
||||||
const { status, data } = useQuery({
|
const { status, data } = useQuery({
|
||||||
queryKey: ["user-stats", ark.account.pubkey],
|
queryKey: ["user-stats", ark.account.pubkey],
|
||||||
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
||||||
|
@ -15,6 +15,7 @@ export function GeneralSettingScreen() {
|
|||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
|
|
||||||
const [settings, setSettings] = useState({
|
const [settings, setSettings] = useState({
|
||||||
|
lowPower: false,
|
||||||
autoupdate: false,
|
autoupdate: false,
|
||||||
autolaunch: false,
|
autolaunch: false,
|
||||||
outbox: false,
|
outbox: false,
|
||||||
@ -30,6 +31,11 @@ export function GeneralSettingScreen() {
|
|||||||
setSettings((prev) => ({ ...prev, appearance: theme }));
|
setSettings((prev) => ({ ...prev, appearance: theme }));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const toggleLowPower = async () => {
|
||||||
|
await storage.createSetting("lowPower", String(+!settings.lowPower));
|
||||||
|
setSettings((state) => ({ ...state, lowPower: !settings.lowPower }));
|
||||||
|
};
|
||||||
|
|
||||||
const toggleAutolaunch = async () => {
|
const toggleAutolaunch = async () => {
|
||||||
if (!settings.autolaunch) {
|
if (!settings.autolaunch) {
|
||||||
await enable();
|
await enable();
|
||||||
@ -42,12 +48,6 @@ export function GeneralSettingScreen() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const toggleOutbox = async () => {
|
|
||||||
await storage.createSetting("outbox", String(+!settings.outbox));
|
|
||||||
// update state
|
|
||||||
setSettings((prev) => ({ ...prev, outbox: !settings.outbox }));
|
|
||||||
};
|
|
||||||
|
|
||||||
const toggleMedia = async () => {
|
const toggleMedia = async () => {
|
||||||
await storage.createSetting("media", String(+!settings.media));
|
await storage.createSetting("media", String(+!settings.media));
|
||||||
storage.settings.media = !settings.media;
|
storage.settings.media = !settings.media;
|
||||||
@ -98,6 +98,12 @@ export function GeneralSettingScreen() {
|
|||||||
autoupdate: !!parseInt(item.value),
|
autoupdate: !!parseInt(item.value),
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
if (item.key === "lowPower")
|
||||||
|
setSettings((prev) => ({
|
||||||
|
...prev,
|
||||||
|
lowPower: !!parseInt(item.value),
|
||||||
|
}));
|
||||||
|
|
||||||
if (item.key === "outbox")
|
if (item.key === "outbox")
|
||||||
setSettings((prev) => ({
|
setSettings((prev) => ({
|
||||||
...prev,
|
...prev,
|
||||||
@ -127,9 +133,9 @@ export function GeneralSettingScreen() {
|
|||||||
<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-24 shrink-0 text-end text-sm font-semibold">
|
||||||
Updater
|
Update
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Auto download new update at Login</div>
|
<div className="text-sm">Automatically download new update</div>
|
||||||
</div>
|
</div>
|
||||||
<Switch.Root
|
<Switch.Root
|
||||||
checked={settings.autoupdate}
|
checked={settings.autoupdate}
|
||||||
@ -139,6 +145,23 @@ export function GeneralSettingScreen() {
|
|||||||
<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]" />
|
<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]" />
|
||||||
</Switch.Root>
|
</Switch.Root>
|
||||||
</div>
|
</div>
|
||||||
|
<div className="flex w-full items-center justify-between">
|
||||||
|
<div className="flex items-center gap-8">
|
||||||
|
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
||||||
|
Low Power
|
||||||
|
</div>
|
||||||
|
<div className="text-sm">
|
||||||
|
Sustainable for low network environment.
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<Switch.Root
|
||||||
|
checked={settings.lowPower}
|
||||||
|
onClick={() => toggleLowPower()}
|
||||||
|
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"
|
||||||
|
>
|
||||||
|
<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]" />
|
||||||
|
</Switch.Root>
|
||||||
|
</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-24 shrink-0 text-end text-sm font-semibold">
|
||||||
@ -154,21 +177,6 @@ export function GeneralSettingScreen() {
|
|||||||
<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]" />
|
<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]" />
|
||||||
</Switch.Root>
|
</Switch.Root>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full items-center justify-between">
|
|
||||||
<div className="flex items-center gap-8">
|
|
||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
|
||||||
Gossip
|
|
||||||
</div>
|
|
||||||
<div className="text-sm">Use Outbox model</div>
|
|
||||||
</div>
|
|
||||||
<Switch.Root
|
|
||||||
checked={settings.outbox}
|
|
||||||
onClick={() => toggleOutbox()}
|
|
||||||
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"
|
|
||||||
>
|
|
||||||
<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]" />
|
|
||||||
</Switch.Root>
|
|
||||||
</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-24 shrink-0 text-end text-sm font-semibold">
|
||||||
@ -189,7 +197,7 @@ export function GeneralSettingScreen() {
|
|||||||
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
<div className="w-24 shrink-0 text-end text-sm font-semibold">
|
||||||
Hashtag
|
Hashtag
|
||||||
</div>
|
</div>
|
||||||
<div className="text-sm">Hide all hashtags in content</div>
|
<div className="text-sm">Show all hashtags in content</div>
|
||||||
</div>
|
</div>
|
||||||
<Switch.Root
|
<Switch.Root
|
||||||
checked={settings.hashtag}
|
checked={settings.hashtag}
|
||||||
|
@ -114,7 +114,7 @@ export function NoteZap() {
|
|||||||
</button>
|
</button>
|
||||||
</Dialog.Trigger>
|
</Dialog.Trigger>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/20 backdrop-blur-xl dark:bg-white/20" />
|
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/10 backdrop-blur-sm dark:bg-white/10" />
|
||||||
<Dialog.Content className="fixed inset-0 z-50 flex items-center justify-center min-h-full">
|
<Dialog.Content className="fixed inset-0 z-50 flex items-center justify-center min-h-full">
|
||||||
<div className="relative w-full max-w-xl bg-white h-min rounded-xl dark:bg-black">
|
<div className="relative w-full max-w-xl bg-white h-min rounded-xl dark:bg-black">
|
||||||
<div className="inline-flex items-center justify-between w-full px-5 py-3 shrink-0">
|
<div className="inline-flex items-center justify-between w-full px-5 py-3 shrink-0">
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
NOSTR_EVENTS,
|
NOSTR_EVENTS,
|
||||||
NOSTR_MENTIONS,
|
NOSTR_MENTIONS,
|
||||||
VIDEOS,
|
VIDEOS,
|
||||||
|
canPreview,
|
||||||
cn,
|
cn,
|
||||||
regionNames,
|
regionNames,
|
||||||
} from "@lume/utils";
|
} from "@lume/utils";
|
||||||
@ -27,9 +28,11 @@ import { useNoteContext } from "./provider";
|
|||||||
|
|
||||||
export function NoteContent({
|
export function NoteContent({
|
||||||
className,
|
className,
|
||||||
|
mini = false,
|
||||||
isTranslatable = false,
|
isTranslatable = false,
|
||||||
}: {
|
}: {
|
||||||
className?: string;
|
className?: string;
|
||||||
|
mini?: boolean;
|
||||||
isTranslatable?: boolean;
|
isTranslatable?: boolean;
|
||||||
}) {
|
}) {
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
@ -52,7 +55,7 @@ export function NoteContent({
|
|||||||
const words = text.split(/( |\n)/);
|
const words = text.split(/( |\n)/);
|
||||||
const urls = [...getUrls(text)];
|
const urls = [...getUrls(text)];
|
||||||
|
|
||||||
if (storage.settings.media && !storage.settings.lowPower) {
|
if (storage.settings.media && !storage.settings.lowPower && !mini) {
|
||||||
images = urls.filter((word) =>
|
images = urls.filter((word) =>
|
||||||
IMAGES.some((el) => {
|
IMAGES.some((el) => {
|
||||||
const url = new URL(word);
|
const url = new URL(word);
|
||||||
@ -79,9 +82,11 @@ export function NoteContent({
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
events = words.filter((word) =>
|
if (!mini) {
|
||||||
NOSTR_EVENTS.some((el) => word.startsWith(el)),
|
events = words.filter((word) =>
|
||||||
);
|
NOSTR_EVENTS.some((el) => word.startsWith(el)),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
const hashtags = words.filter((word) => word.startsWith("#"));
|
const hashtags = words.filter((word) => word.startsWith("#"));
|
||||||
const mentions = words.filter((word) =>
|
const mentions = words.filter((word) =>
|
||||||
@ -198,7 +203,7 @@ export function NoteContent({
|
|||||||
(match, i) => {
|
(match, i) => {
|
||||||
const url = new URL(match);
|
const url = new URL(match);
|
||||||
|
|
||||||
if (!linkPreview) {
|
if (!linkPreview && canPreview(match)) {
|
||||||
linkPreview = match;
|
linkPreview = match;
|
||||||
return <LinkPreview key={match + i} url={url.toString()} />;
|
return <LinkPreview key={match + i} url={url.toString()} />;
|
||||||
}
|
}
|
||||||
@ -217,9 +222,11 @@ export function NoteContent({
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
parsedContent = reactStringReplace(parsedContent, "\n", () => {
|
if (!mini) {
|
||||||
return <div key={nanoid()} className="h-3" />;
|
parsedContent = reactStringReplace(parsedContent, "\n", () => {
|
||||||
});
|
return <div key={nanoid()} className="h-3" />;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof parsedContent[0] === "string") {
|
if (typeof parsedContent[0] === "string") {
|
||||||
parsedContent[0] = parsedContent[0].trimStart();
|
parsedContent[0] = parsedContent[0].trimStart();
|
||||||
@ -259,7 +266,12 @@ export function NoteContent({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn(className)}>
|
<div className={cn(className)}>
|
||||||
<div className="break-p select-text whitespace-pre-line text-balance leading-normal">
|
<div
|
||||||
|
className={cn(
|
||||||
|
"break-p select-text text-balance leading-normal",
|
||||||
|
!mini ? "whitespace-pre-line" : "",
|
||||||
|
)}
|
||||||
|
>
|
||||||
{richContent}
|
{richContent}
|
||||||
</div>
|
</div>
|
||||||
{isTranslatable && storage.settings.translation ? (
|
{isTranslatable && storage.settings.translation ? (
|
||||||
|
@ -1,13 +1,17 @@
|
|||||||
|
import { PinIcon } from "@lume/icons";
|
||||||
|
import { COL_TYPES } from "@lume/utils";
|
||||||
import { memo } from "react";
|
import { memo } from "react";
|
||||||
import { Link } from "react-router-dom";
|
import { Link } from "react-router-dom";
|
||||||
import { Note } from "../";
|
import { Note } from "../";
|
||||||
import { useEvent } from "../../../hooks/useEvent";
|
import { useEvent } from "../../../hooks/useEvent";
|
||||||
|
import { useColumnContext } from "../../column/provider";
|
||||||
import { User } from "../../user";
|
import { User } from "../../user";
|
||||||
|
|
||||||
export const MentionNote = memo(function MentionNote({
|
export const MentionNote = memo(function MentionNote({
|
||||||
eventId,
|
eventId,
|
||||||
openable = true,
|
openable = true,
|
||||||
}: { eventId: string; openable?: boolean }) {
|
}: { eventId: string; openable?: boolean }) {
|
||||||
|
const { addColumn } = useColumnContext();
|
||||||
const { isLoading, isError, data } = useEvent(eventId);
|
const { isLoading, isError, data } = useEvent(eventId);
|
||||||
|
|
||||||
if (isLoading) {
|
if (isLoading) {
|
||||||
@ -34,11 +38,11 @@ export const MentionNote = memo(function MentionNote({
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Note.Provider event={data}>
|
<Note.Provider event={data}>
|
||||||
<Note.Root className="flex flex-col w-full gap-1 my-1 rounded-lg cursor-default bg-neutral-100 dark:bg-neutral-900 border border-neutral-200 dark:border-neutral-800">
|
<Note.Root className="flex flex-col w-full my-1 rounded-lg cursor-default bg-neutral-100 dark:bg-neutral-900 border border-neutral-100 dark:border-neutral-900">
|
||||||
<User.Provider pubkey={data.pubkey}>
|
<User.Provider pubkey={data.pubkey}>
|
||||||
<User.Root className="px-3 mt-3 flex h-6 items-center gap-2">
|
<User.Root className="flex h-10 px-3 items-center gap-2">
|
||||||
<User.Avatar className="size-6 shrink-0 rounded-md object-cover" />
|
<User.Avatar className="size-6 shrink-0 rounded-md object-cover" />
|
||||||
<div className="flex flex-1 items-baseline gap-2">
|
<div className="flex-1 inline-flex gap-2">
|
||||||
<User.Name className="font-semibold text-neutral-900 dark:text-neutral-100" />
|
<User.Name className="font-semibold text-neutral-900 dark:text-neutral-100" />
|
||||||
<span className="text-neutral-600 dark:text-neutral-400">·</span>
|
<span className="text-neutral-600 dark:text-neutral-400">·</span>
|
||||||
<User.Time
|
<User.Time
|
||||||
@ -48,17 +52,30 @@ export const MentionNote = memo(function MentionNote({
|
|||||||
</div>
|
</div>
|
||||||
</User.Root>
|
</User.Root>
|
||||||
</User.Provider>
|
</User.Provider>
|
||||||
<div className="px-3 pb-3 mt-1">
|
<Note.Content mini className="px-3" />
|
||||||
<Note.Content />
|
{openable ? (
|
||||||
{openable ? (
|
<div className="mt-2 px-3 flex items-center justify-between">
|
||||||
<Link
|
<Link
|
||||||
to={`/events/${data.id}`}
|
to={`/events/${data.id}`}
|
||||||
className="mt-2 text-blue-500 hover:text-blue-600"
|
className="text-sm font-medium text-blue-500 hover:text-blue-600"
|
||||||
>
|
>
|
||||||
Show more
|
Show more
|
||||||
</Link>
|
</Link>
|
||||||
) : null}
|
<button
|
||||||
</div>
|
type="button"
|
||||||
|
onClick={async () =>
|
||||||
|
await addColumn({
|
||||||
|
kind: COL_TYPES.thread,
|
||||||
|
title: "Thread",
|
||||||
|
content: data.id,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
className="inline-flex items-center justify-center rounded-md text-neutral-600 dark:text-neutral-400 size-6 bg-neutral-200 dark:bg-neutral-800 hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
||||||
|
>
|
||||||
|
<PinIcon className="size-4" />
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
) : null}
|
||||||
</Note.Root>
|
</Note.Root>
|
||||||
</Note.Provider>
|
</Note.Provider>
|
||||||
);
|
);
|
||||||
|
@ -12,7 +12,7 @@ export function NoteUser({
|
|||||||
return (
|
return (
|
||||||
<User.Provider pubkey={event.pubkey}>
|
<User.Provider pubkey={event.pubkey}>
|
||||||
<User.Root className={cn("flex items-center gap-3", className)}>
|
<User.Root className={cn("flex items-center gap-3", className)}>
|
||||||
<User.Avatar className="size-9 shrink-0 rounded-lg bg-white object-cover ring-1 ring-neutral-200/50 dark:ring-neutral-800/50" />
|
<User.Avatar className="size-9 shrink-0 rounded-lg object-cover ring-1 ring-neutral-200/50 dark:ring-neutral-800/50" />
|
||||||
<div className="flex h-6 flex-1 items-start justify-between gap-2">
|
<div className="flex h-6 flex-1 items-start justify-between gap-2">
|
||||||
<User.Name className="font-semibold text-neutral-950 dark:text-neutral-50" />
|
<User.Name className="font-semibold text-neutral-950 dark:text-neutral-50" />
|
||||||
<User.Time
|
<User.Time
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useStorage } from "@lume/storage";
|
||||||
import { cn } from "@lume/utils";
|
import { cn } from "@lume/utils";
|
||||||
import * as Avatar from "@radix-ui/react-avatar";
|
import * as Avatar from "@radix-ui/react-avatar";
|
||||||
import { minidenticon } from "minidenticons";
|
import { minidenticon } from "minidenticons";
|
||||||
@ -7,6 +8,8 @@ import { useUserContext } from "./provider";
|
|||||||
|
|
||||||
export function UserAvatar({ className }: { className?: string }) {
|
export function UserAvatar({ className }: { className?: string }) {
|
||||||
const user = useUserContext();
|
const user = useUserContext();
|
||||||
|
const storage = useStorage();
|
||||||
|
|
||||||
const fallbackAvatar = useMemo(
|
const fallbackAvatar = useMemo(
|
||||||
() =>
|
() =>
|
||||||
`data:image/svg+xml;utf8,${encodeURIComponent(
|
`data:image/svg+xml;utf8,${encodeURIComponent(
|
||||||
@ -20,7 +23,7 @@ export function UserAvatar({ className }: { className?: string }) {
|
|||||||
<div className="shrink-0">
|
<div className="shrink-0">
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"bg-black/20 dark:bg-white/20 animate-pulse",
|
"bg-black/20 dark:bg-white/20 rounded animate-pulse",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -30,13 +33,23 @@ export function UserAvatar({ className }: { className?: string }) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Avatar.Root className="shrink-0">
|
<Avatar.Root className="shrink-0">
|
||||||
<Avatar.Image
|
{storage.settings.lowPower ? (
|
||||||
src={user.image}
|
<Avatar.Image
|
||||||
alt={user.pubkey}
|
src={fallbackAvatar}
|
||||||
loading="eager"
|
alt={user.pubkey}
|
||||||
decoding="async"
|
loading="eager"
|
||||||
className={className}
|
decoding="async"
|
||||||
/>
|
className={cn("bg-black dark:bg-white", className)}
|
||||||
|
/>
|
||||||
|
) : (
|
||||||
|
<Avatar.Image
|
||||||
|
src={user.image}
|
||||||
|
alt={user.pubkey}
|
||||||
|
loading="eager"
|
||||||
|
decoding="async"
|
||||||
|
className={className}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
<Avatar.Fallback delayMs={120}>
|
<Avatar.Fallback delayMs={120}>
|
||||||
<img
|
<img
|
||||||
src={fallbackAvatar}
|
src={fallbackAvatar}
|
||||||
|
@ -8,7 +8,7 @@ export function UserName({ className }: { className?: string }) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-4 w-20 bg-black/20 dark:bg-white/20 animate-pulse",
|
"h-4 w-20 bg-black/20 dark:bg-white/20 rounded animate-pulse",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
@ -16,7 +16,7 @@ export function UserName({ className }: { className?: string }) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={cn("w-full max-w-[15rem] truncate", className)}>
|
<div className={cn("truncate", className)}>
|
||||||
{user.displayName || user.name || "Anon"}
|
{user.displayName || user.name || "Anon"}
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
@ -29,7 +29,7 @@ export function UserNip05({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
className={cn(
|
className={cn(
|
||||||
"h-4 w-20 bg-black/20 dark:bg-white/20 animate-pulse",
|
"h-4 w-20 bg-black/20 dark:bg-white/20 rounded animate-pulse",
|
||||||
className,
|
className,
|
||||||
)}
|
)}
|
||||||
/>
|
/>
|
||||||
|
@ -9,6 +9,7 @@ import NDK, {
|
|||||||
NDKPrivateKeySigner,
|
NDKPrivateKeySigner,
|
||||||
NDKRelay,
|
NDKRelay,
|
||||||
NDKRelayAuthPolicies,
|
NDKRelayAuthPolicies,
|
||||||
|
NDKUser,
|
||||||
} from "@nostr-dev-kit/ndk";
|
} from "@nostr-dev-kit/ndk";
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
import { fetch } from "@tauri-apps/plugin-http";
|
||||||
import Linkify from "linkify-react";
|
import Linkify from "linkify-react";
|
||||||
@ -19,7 +20,9 @@ import { LumeContext } from "./context";
|
|||||||
|
|
||||||
export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
const [context, setContext] = useState<Ark>(undefined);
|
|
||||||
|
const [ark, setArk] = useState<Ark>(undefined);
|
||||||
|
const [ndk, setNDK] = useState<NDK>(undefined);
|
||||||
|
|
||||||
async function initNostrSigner({
|
async function initNostrSigner({
|
||||||
nsecbunker,
|
nsecbunker,
|
||||||
@ -67,7 +70,7 @@ export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async function init() {
|
async function initNDK() {
|
||||||
const explicitRelayUrls = normalizeRelayUrlSet([
|
const explicitRelayUrls = normalizeRelayUrlSet([
|
||||||
"wss://bostr.nokotaro.com/",
|
"wss://bostr.nokotaro.com/",
|
||||||
"wss://nostr.mutinywallet.com/",
|
"wss://nostr.mutinywallet.com/",
|
||||||
@ -77,14 +80,12 @@ export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
|||||||
const outboxRelayUrls = normalizeRelayUrlSet(["wss://purplepag.es/"]);
|
const outboxRelayUrls = normalizeRelayUrlSet(["wss://purplepag.es/"]);
|
||||||
|
|
||||||
// #TODO: user should config blacklist relays
|
// #TODO: user should config blacklist relays
|
||||||
// No need to connect depot tunnel url
|
// Skip connect depot tunnel url
|
||||||
const blacklistRelayUrls = storage.settings.tunnelUrl.length
|
const blacklistRelayUrls = normalizeRelayUrlSet(
|
||||||
? [
|
storage.settings.tunnelUrl.length
|
||||||
storage.settings.tunnelUrl,
|
? [storage.settings.tunnelUrl, "wss://brb.io/"]
|
||||||
`${storage.settings.tunnelUrl}/`,
|
: ["wss://brb.io/"],
|
||||||
"wss://brb.io/",
|
);
|
||||||
]
|
|
||||||
: ["wss://brb.io/"];
|
|
||||||
|
|
||||||
const cacheAdapter = new NDKCacheAdapterTauri(storage);
|
const cacheAdapter = new NDKCacheAdapterTauri(storage);
|
||||||
const ndk = new NDK({
|
const ndk = new NDK({
|
||||||
@ -115,29 +116,37 @@ export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
|||||||
// auth
|
// auth
|
||||||
ndk.relayAuthDefaultPolicy = async (relay: NDKRelay, challenge: string) => {
|
ndk.relayAuthDefaultPolicy = async (relay: NDKRelay, challenge: string) => {
|
||||||
const signIn = NDKRelayAuthPolicies.signIn({ ndk });
|
const signIn = NDKRelayAuthPolicies.signIn({ ndk });
|
||||||
const event = await signIn(relay, challenge).catch((e) => console.log(e));
|
const event = await signIn(relay, challenge).catch((e) =>
|
||||||
|
console.error(e),
|
||||||
|
);
|
||||||
if (event) {
|
if (event) {
|
||||||
sendNativeNotification(
|
await sendNativeNotification(
|
||||||
`You've sign in sucessfully to relay: ${relay.url}`,
|
`You've sign in sucessfully to relay: ${relay.url}`,
|
||||||
);
|
);
|
||||||
return event;
|
return event;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// update account's metadata
|
setNDK(ndk);
|
||||||
if (signer) {
|
}
|
||||||
const user = ndk.getUser({ pubkey: storage.currentUser.pubkey });
|
|
||||||
|
async function initArk() {
|
||||||
|
// ark utils
|
||||||
|
const ark = new Ark({ ndk, account: storage.currentUser });
|
||||||
|
|
||||||
|
if (ndk && storage.currentUser) {
|
||||||
|
const user = new NDKUser({ pubkey: storage.currentUser.pubkey });
|
||||||
ndk.activeUser = user;
|
ndk.activeUser = user;
|
||||||
|
|
||||||
const contacts = await user.follows();
|
// update contacts
|
||||||
storage.currentUser.contacts = [...contacts].map((user) => user.pubkey);
|
await ark.getUserContacts();
|
||||||
|
|
||||||
// subscribe for new activity
|
// subscribe for new activity
|
||||||
const sub = ndk.subscribe(
|
const sub = ndk.subscribe(
|
||||||
{
|
{
|
||||||
kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Zap],
|
kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Zap],
|
||||||
since: Math.floor(Date.now() / 1000),
|
since: Math.floor(Date.now() / 1000),
|
||||||
"#p": [storage.currentUser.pubkey],
|
"#p": [ark.account.pubkey],
|
||||||
},
|
},
|
||||||
{ closeOnEose: false, groupable: false },
|
{ closeOnEose: false, groupable: false },
|
||||||
);
|
);
|
||||||
@ -169,18 +178,18 @@ export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// ark utils
|
setArk(ark);
|
||||||
const ark = new Ark({ ndk, account: storage.currentUser });
|
|
||||||
|
|
||||||
// update context
|
|
||||||
setContext(ark);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!context) init();
|
if (ndk) initArk();
|
||||||
|
}, [ndk]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!ark && !ndk) initNDK();
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
if (!context) {
|
if (!ark) {
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
data-tauri-drag-region
|
data-tauri-drag-region
|
||||||
@ -207,7 +216,5 @@ export const LumeProvider = ({ children }: PropsWithChildren<object>) => {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return <LumeContext.Provider value={ark}>{children}</LumeContext.Provider>;
|
||||||
<LumeContext.Provider value={context}>{children}</LumeContext.Provider>
|
|
||||||
);
|
|
||||||
};
|
};
|
||||||
|
@ -279,9 +279,6 @@ export class LumeStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const account = await this.getActiveAccount();
|
const account = await this.getActiveAccount();
|
||||||
this.currentUser = account;
|
|
||||||
this.currentUser.contacts = [];
|
|
||||||
|
|
||||||
return account;
|
return account;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,33 +0,0 @@
|
|||||||
import { activityAtom } from "@lume/utils";
|
|
||||||
import { AnimatePresence, motion } from "framer-motion";
|
|
||||||
import { useAtomValue } from "jotai";
|
|
||||||
import { ActivityContent } from "./content";
|
|
||||||
|
|
||||||
export function Activity() {
|
|
||||||
const isActivityOpen = useAtomValue(activityAtom);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<AnimatePresence initial={false} mode="wait">
|
|
||||||
{isActivityOpen ? (
|
|
||||||
<motion.div
|
|
||||||
key={isActivityOpen ? "activity-open" : "activity-close"}
|
|
||||||
layout
|
|
||||||
initial={{ scale: 0.9, opacity: 0, translateX: -20 }}
|
|
||||||
animate={{
|
|
||||||
scale: [0.95, 1],
|
|
||||||
opacity: [0.5, 1],
|
|
||||||
translateX: [-10, 0],
|
|
||||||
}}
|
|
||||||
exit={{
|
|
||||||
scale: [0.95, 0.9],
|
|
||||||
opacity: [0.5, 0],
|
|
||||||
translateX: [-10, -20],
|
|
||||||
}}
|
|
||||||
className="h-full w-[350px] px-1 pb-1 shrink-0"
|
|
||||||
>
|
|
||||||
<ActivityContent />
|
|
||||||
</motion.div>
|
|
||||||
) : null}
|
|
||||||
</AnimatePresence>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,100 +0,0 @@
|
|||||||
import { useArk } from "@lume/ark";
|
|
||||||
import { LoaderIcon } from "@lume/icons";
|
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
|
|
||||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
||||||
import { useCallback, useMemo } from "react";
|
|
||||||
import { ReplyActivity } from "./reply";
|
|
||||||
import { RepostActivity } from "./repost";
|
|
||||||
import { ZapActivity } from "./zap";
|
|
||||||
|
|
||||||
export function ActivityContent() {
|
|
||||||
const ark = useArk();
|
|
||||||
const storage = useStorage();
|
|
||||||
|
|
||||||
const { isLoading, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
|
|
||||||
useInfiniteQuery({
|
|
||||||
queryKey: ["activity"],
|
|
||||||
initialPageParam: 0,
|
|
||||||
queryFn: async ({
|
|
||||||
signal,
|
|
||||||
pageParam,
|
|
||||||
}: {
|
|
||||||
signal: AbortSignal;
|
|
||||||
pageParam: number;
|
|
||||||
}) => {
|
|
||||||
const events = await ark.getInfiniteEvents({
|
|
||||||
filter: {
|
|
||||||
kinds: [NDKKind.Zap],
|
|
||||||
"#p": [ark.account.pubkey],
|
|
||||||
},
|
|
||||||
limit: 100,
|
|
||||||
pageParam,
|
|
||||||
signal,
|
|
||||||
});
|
|
||||||
|
|
||||||
return events;
|
|
||||||
},
|
|
||||||
getNextPageParam: (lastPage) => {
|
|
||||||
const lastEvent = lastPage.at(-1);
|
|
||||||
if (!lastEvent) return;
|
|
||||||
return lastEvent.created_at - 1;
|
|
||||||
},
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const allEvents = useMemo(
|
|
||||||
() => (data ? data.pages.flatMap((page) => page) : []),
|
|
||||||
[data],
|
|
||||||
);
|
|
||||||
|
|
||||||
const renderEvent = useCallback((event: NDKEvent) => {
|
|
||||||
if (event.pubkey === ark.account.pubkey) return null;
|
|
||||||
|
|
||||||
switch (event.kind) {
|
|
||||||
case NDKKind.Text:
|
|
||||||
return <ReplyActivity key={event.id} event={event} />;
|
|
||||||
case NDKKind.Repost:
|
|
||||||
return <RepostActivity key={event.id} event={event} />;
|
|
||||||
case NDKKind.Zap:
|
|
||||||
return <ZapActivity key={event.id} event={event} />;
|
|
||||||
default:
|
|
||||||
return <ReplyActivity key={event.id} event={event} />;
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="w-full h-full flex flex-col justify-between rounded-xl overflow-hidden bg-white shadow-[rgba(50,_50,_105,_0.15)_0px_2px_5px_0px,_rgba(0,_0,_0,_0.05)_0px_1px_1px_0px] dark:bg-black dark:shadow-none dark:ring-1 dark:ring-white/10">
|
|
||||||
<div className="h-full w-full min-h-0">
|
|
||||||
{isLoading ? (
|
|
||||||
<div className="w-[350px] h-full flex items-center justify-center">
|
|
||||||
<LoaderIcon className="size-5 animate-spin" />
|
|
||||||
</div>
|
|
||||||
) : allEvents.length < 1 ? (
|
|
||||||
<div className="w-full h-full flex flex-col items-center justify-center">
|
|
||||||
<p className="mb-2 text-2xl">🎉</p>
|
|
||||||
<p className="text-center font-medium">Yo! Nothing new yet.</p>
|
|
||||||
</div>
|
|
||||||
) : (
|
|
||||||
renderEvent(allEvents[0])
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="h-16 shrink-0 px-3 flex items-center gap-3 bg-neutral-100 dark:bg-neutral-900">
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="h-11 flex-1 inline-flex items-center justify-center rounded-xl font-medium bg-neutral-200 dark:bg-neutral-800 hover:bg-neutral-300 dark:hover:bg-neutral-700"
|
|
||||||
>
|
|
||||||
Previous
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
className="h-11 flex-1 inline-flex items-center justify-center rounded-xl font-medium bg-blue-500 text-white hover:bg-blue-600"
|
|
||||||
>
|
|
||||||
Next
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,51 +0,0 @@
|
|||||||
import { Note, useArk } from "@lume/ark";
|
|
||||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
|
||||||
import { ActivityRootNote } from "./rootNote";
|
|
||||||
|
|
||||||
export function ReplyActivity({ event }: { event: NDKEvent }) {
|
|
||||||
const ark = useArk();
|
|
||||||
const thread = ark.getEventThread({
|
|
||||||
content: event.content,
|
|
||||||
tags: event.tags,
|
|
||||||
});
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="h-full pb-3 flex flex-col justify-between">
|
|
||||||
<div className="h-14 border-b border-neutral-100 dark:border-neutral-900 flex flex-col items-center justify-center px-3">
|
|
||||||
<h3 className="text-center font-semibold leading-tight">
|
|
||||||
Conversation
|
|
||||||
</h3>
|
|
||||||
<p className="text-sm text-blue-500 font-medium leading-tight">
|
|
||||||
@ Someone has replied to your note
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="px-3">
|
|
||||||
{thread ? (
|
|
||||||
<div className="flex flex-col gap-3 mb-1">
|
|
||||||
<ActivityRootNote eventId={thread.rootEventId} />
|
|
||||||
<ActivityRootNote eventId={thread.replyEventId} />
|
|
||||||
</div>
|
|
||||||
) : null}
|
|
||||||
<div className="mt-3 flex flex-col gap-3">
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<p className="text-teal-500 font-medium">New reply</p>
|
|
||||||
<div className="flex-1 h-px bg-teal-300" />
|
|
||||||
<div className="w-4 shrink-0 h-px bg-teal-300" />
|
|
||||||
</div>
|
|
||||||
<Note.Provider event={event}>
|
|
||||||
<Note.Root>
|
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
|
||||||
<Note.User className="flex-1 pr-1" />
|
|
||||||
</div>
|
|
||||||
<Note.Content className="min-w-0 px-3" />
|
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
|
||||||
<Note.Pin />
|
|
||||||
<div className="inline-flex items-center gap-10" />
|
|
||||||
</div>
|
|
||||||
</Note.Root>
|
|
||||||
</Note.Provider>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,33 +0,0 @@
|
|||||||
import { formatCreatedAt } from "@lume/utils";
|
|
||||||
import { NDKEvent } from "@nostr-dev-kit/ndk";
|
|
||||||
import { User } from "../user";
|
|
||||||
import { ActivityRootNote } from "./rootNote";
|
|
||||||
|
|
||||||
export function RepostActivity({ event }: { event: NDKEvent }) {
|
|
||||||
const repostId = event.tags.find((el) => el[0] === "e")[1];
|
|
||||||
const createdAt = formatCreatedAt(event.created_at);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="h-full pb-3 flex flex-col justify-between">
|
|
||||||
<div className="h-14 border-b border-neutral-100 dark:border-neutral-900 flex flex-col items-center justify-center px-3">
|
|
||||||
<h3 className="text-center font-semibold leading-tight">Boost</h3>
|
|
||||||
<p className="text-sm text-blue-500 font-medium leading-tight">
|
|
||||||
@ Someone has reposted to your note
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="px-3">
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<User pubkey={event.pubkey} variant="notify2" />
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<p className="text-teal-500 font-medium">Reposted</p>
|
|
||||||
<div className="flex-1 h-px bg-teal-300" />
|
|
||||||
<div className="w-4 shrink-0 h-px bg-teal-300" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-3 flex flex-col gap-3">
|
|
||||||
<ActivityRootNote eventId={repostId} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,40 +0,0 @@
|
|||||||
import { Note, useEvent } from "@lume/ark";
|
|
||||||
|
|
||||||
export function ActivityRootNote({ eventId }: { eventId: string }) {
|
|
||||||
const { isLoading, isError, data } = useEvent(eventId);
|
|
||||||
|
|
||||||
if (isLoading) {
|
|
||||||
return (
|
|
||||||
<div className="relative flex gap-3">
|
|
||||||
<div className="relative flex-1 rounded-md bg-neutral-200 px-2 py-2 dark:bg-neutral-800">
|
|
||||||
<div className="h-4 w-full animate-pulse bg-neutral-300 dark:bg-neutral-700" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isError) {
|
|
||||||
return (
|
|
||||||
<div className="relative flex gap-3">
|
|
||||||
<div className="relative flex-1 rounded-md bg-neutral-200 px-2 py-2 dark:bg-neutral-800">
|
|
||||||
Failed to fetch event
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Note.Provider event={data}>
|
|
||||||
<Note.Root>
|
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
|
||||||
<Note.User className="flex-1 pr-1" />
|
|
||||||
</div>
|
|
||||||
<Note.Content className="min-w-0 px-3" />
|
|
||||||
<div className="flex items-center justify-between px-3 h-14">
|
|
||||||
<Note.Pin />
|
|
||||||
<div className="inline-flex items-center gap-10" />
|
|
||||||
</div>
|
|
||||||
</Note.Root>
|
|
||||||
</Note.Provider>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
import { compactNumber, formatCreatedAt } from "@lume/utils";
|
|
||||||
import { NDKEvent, zapInvoiceFromEvent } from "@nostr-dev-kit/ndk";
|
|
||||||
import { User } from "../user";
|
|
||||||
import { ActivityRootNote } from "./rootNote";
|
|
||||||
|
|
||||||
export function ZapActivity({ event }: { event: NDKEvent }) {
|
|
||||||
const zapEventId = event.tags.find((tag) => tag[0] === "e")[1];
|
|
||||||
const invoice = zapInvoiceFromEvent(event);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="h-full pb-3 flex flex-col justify-between">
|
|
||||||
<div className="h-14 border-b border-neutral-100 dark:border-neutral-900 flex flex-col items-center justify-center px-3">
|
|
||||||
<h3 className="text-center font-semibold leading-tight">Zap</h3>
|
|
||||||
<p className="text-sm text-blue-500 font-medium leading-tight">
|
|
||||||
@ Someone love your note
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div className="px-3">
|
|
||||||
<div className="flex flex-col gap-3">
|
|
||||||
<User
|
|
||||||
pubkey={event.pubkey}
|
|
||||||
variant="notify2"
|
|
||||||
subtext={`${compactNumber.format(invoice.amount)} sats`}
|
|
||||||
/>
|
|
||||||
<div className="flex items-center gap-3">
|
|
||||||
<p className="text-teal-500 font-medium">Zapped</p>
|
|
||||||
<div className="flex-1 h-px bg-teal-300" />
|
|
||||||
<div className="w-4 shrink-0 h-px bg-teal-300" />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="mt-3 flex flex-col gap-3">
|
|
||||||
<ActivityRootNote eventId={zapEventId} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -20,7 +20,7 @@ export function SettingsLayout() {
|
|||||||
twMerge(
|
twMerge(
|
||||||
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
||||||
isActive
|
isActive
|
||||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-900"
|
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||||
: "",
|
: "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -34,7 +34,7 @@ export function SettingsLayout() {
|
|||||||
twMerge(
|
twMerge(
|
||||||
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
||||||
isActive
|
isActive
|
||||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-900"
|
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||||
: "",
|
: "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -48,7 +48,7 @@ export function SettingsLayout() {
|
|||||||
twMerge(
|
twMerge(
|
||||||
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
||||||
isActive
|
isActive
|
||||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-900"
|
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||||
: "",
|
: "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -62,7 +62,7 @@ export function SettingsLayout() {
|
|||||||
twMerge(
|
twMerge(
|
||||||
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
||||||
isActive
|
isActive
|
||||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-900"
|
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||||
: "",
|
: "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -76,7 +76,7 @@ export function SettingsLayout() {
|
|||||||
twMerge(
|
twMerge(
|
||||||
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
"flex w-20 shrink-0 flex-col items-center justify-center rounded-lg px-2 py-2 text-neutral-700 hover:bg-neutral-100 dark:text-neutral-300 dark:hover:bg-neutral-900",
|
||||||
isActive
|
isActive
|
||||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-900 dark:hover:bg-neutral-900"
|
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||||
: "",
|
: "",
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,7 @@ export function OnboardingModal() {
|
|||||||
return (
|
return (
|
||||||
<Dialog.Root open={onboarding}>
|
<Dialog.Root open={onboarding}>
|
||||||
<Dialog.Portal>
|
<Dialog.Portal>
|
||||||
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/20 backdrop-blur-xl dark:bg-white/20" />
|
<Dialog.Overlay className="fixed inset-0 z-50 bg-black/10 backdrop-blur-sm dark:bg-white/10" />
|
||||||
<Dialog.Content className="fixed inset-0 z-50 flex items-center justify-center min-h-full">
|
<Dialog.Content className="fixed inset-0 z-50 flex items-center justify-center min-h-full">
|
||||||
<div className="relative w-full max-w-lg bg-white h-[500px] rounded-xl dark:bg-black overflow-hidden">
|
<div className="relative w-full max-w-lg bg-white h-[500px] rounded-xl dark:bg-black overflow-hidden">
|
||||||
<OnboardingRouter />
|
<OnboardingRouter />
|
||||||
|
@ -2,6 +2,7 @@ import dayjs from "dayjs";
|
|||||||
import relativeTime from "dayjs/plugin/relativeTime";
|
import relativeTime from "dayjs/plugin/relativeTime";
|
||||||
import updateLocale from "dayjs/plugin/updateLocale";
|
import updateLocale from "dayjs/plugin/updateLocale";
|
||||||
import { nip19 } from "nostr-tools";
|
import { nip19 } from "nostr-tools";
|
||||||
|
import { AUDIOS, IMAGES, VIDEOS } from "./constants";
|
||||||
|
|
||||||
dayjs.extend(relativeTime);
|
dayjs.extend(relativeTime);
|
||||||
dayjs.extend(updateLocale);
|
dayjs.extend(updateLocale);
|
||||||
@ -68,3 +69,23 @@ export const compactNumber = Intl.NumberFormat("en", { notation: "compact" });
|
|||||||
|
|
||||||
// country name
|
// country name
|
||||||
export const regionNames = new Intl.DisplayNames(["en"], { type: "language" });
|
export const regionNames = new Intl.DisplayNames(["en"], { type: "language" });
|
||||||
|
|
||||||
|
// verify link can be preview
|
||||||
|
export function canPreview(text: string) {
|
||||||
|
const url = new URL(text);
|
||||||
|
const ext = url.pathname.split(".").pop();
|
||||||
|
const hostname = url.hostname;
|
||||||
|
|
||||||
|
if (VIDEOS.includes(ext)) return false;
|
||||||
|
if (IMAGES.includes(ext)) return false;
|
||||||
|
if (AUDIOS.includes(ext)) return false;
|
||||||
|
|
||||||
|
if (hostname === "youtube.com") return false;
|
||||||
|
if (hostname === "youtu.be") return false;
|
||||||
|
if (hostname === "x.com") return false;
|
||||||
|
if (hostname === "twitter.com") return false;
|
||||||
|
if (hostname === "facebook.com") return false;
|
||||||
|
if (hostname === "vimeo.com") return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
480
pnpm-lock.yaml
480
pnpm-lock.yaml
@ -270,25 +270,25 @@ importers:
|
|||||||
version: 0.15.0(@nostr-dev-kit/ndk@2.3.2)(nostr-fetch@0.15.0)
|
version: 0.15.0(@nostr-dev-kit/ndk@2.3.2)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.4(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.3(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.5(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 2.0.6(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
version: 1.0.7(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
'@tanstack/react-query':
|
'@tanstack/react-query':
|
||||||
specifier: ^5.17.9
|
specifier: ^5.17.9
|
||||||
version: 5.17.9(react@18.2.0)
|
version: 5.17.9(react@18.2.0)
|
||||||
@ -1927,6 +1927,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.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
resolution: {integrity: sha512-kVK2K7ZD3wwj3qhle0ElXhOjbezIgyl2hVvgwfIdexL3rN6zJmy5AqqIf+D31lxVppdzV8CjAfZ6PklkmInZLw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1951,6 +1971,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
resolution: {integrity: sha512-UBmVDkmR6IvDsloHVN+3rtx4Mi5TFvylYXpluuv0f37dtaz3H99bp8No0LGXRigVpl3UAT4l9j6bIchh42S/Gg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -1979,6 +2022,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
resolution: {integrity: sha512-3SzW+0PW7yBBoQlT8wNcGtaxaD0XSu0uLUFgrtHY08Acx05TaHaOmVLR73c0j/cqpDy53KBMO7s0dx2wmOIDIA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2003,6 +2073,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0):
|
/@radix-ui/react-compose-refs@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
resolution: {integrity: sha512-fDSBgd44FKHa1FRMU59qBMPFcl2PZE+2nmqunj+BWFyYYjnhIDWL2ItDs3rrbJDQOtzt5nIebLCQc4QRfz6LJw==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2065,6 +2158,39 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-dialog@1.0.5(@types/react@18.2.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-direction@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
/@radix-ui/react-direction@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
|
resolution: {integrity: sha512-RXcvnXgyvYvBEOhCBuddKecVkoMiI10Jcm5cTI7abJRAHYfFxeu+FBQs/DvdxSYucxR5mna0dNsL6QFlds5TMA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2104,6 +2230,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-escape-keydown': 1.0.3(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(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:
|
||||||
@ -2131,6 +2281,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-menu': 2.0.6(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0):
|
/@radix-ui/react-focus-guards@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
resolution: {integrity: sha512-Rect2dWbQ8waGzhMavsIbmSVCgYxkXLxxR3ZvCX79JOglzdEy4JXMb98lq4hPxUbLr77nP0UOGf4rcMU+s1pUA==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2168,6 +2344,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==}
|
resolution: {integrity: sha512-OcUN2FU0YpmajD/qkph3XzMcK/NmSk9hGWnjV68p6QiZMgILugusgQwnLSDs3oFSJYGKf3Y49zgFedhGh04k9A==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2197,6 +2395,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0):
|
/@radix-ui/react-id@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
resolution: {integrity: sha512-tI7sT/kqYp8p96yGWY1OAnLHrqDgzHefRBKQ2YAkBS5ja7QLcZ9Z/uY7bEjPUatf8RomoXM8/1sMj1IJaE5UzQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2250,6 +2476,43 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-menu@2.0.6(@types/react@18.2.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-roving-focus': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-popover@1.0.7(@types/react-dom@18.2.18)(@types/react@18.2.47)(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.47)(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:
|
||||||
@ -2285,6 +2548,40 @@ packages:
|
|||||||
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
react-remove-scroll: 2.5.5(@types/react@18.2.47)(react@18.2.0)
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
/@radix-ui/react-popover@1.0.7(@types/react@18.2.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-guards': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-focus-scope': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0)
|
||||||
|
dev: false
|
||||||
|
|
||||||
/@radix-ui/react-popper@1.1.3(@types/react-dom@18.2.18)(@types/react@18.2.47)(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.47)(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:
|
||||||
@ -2315,6 +2612,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.47)(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.5(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-arrow': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-rect': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-size': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/rect': 1.0.1
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(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:
|
||||||
@ -2336,6 +2662,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.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
resolution: {integrity: sha512-UXLW4UAbIY5ZjcvzjfRFo5gxva8QirC9hF7wRE4U5gz+TP0DbRk+//qyuAQ1McDxBt1xNMBTaciFGvEmJvAZCg==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2358,6 +2704,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-layout-effect': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(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:
|
||||||
@ -2379,6 +2746,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(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:
|
||||||
@ -2408,6 +2795,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.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-compose-refs': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-direction': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-callback-ref': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(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.47)(react-dom@18.2.0)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==}
|
resolution: {integrity: sha512-RH5b7af4oHtkcHS7pG6Sgv5rk5Wxa7XI8W5gvB1N/yiuDGZxko1ynvOiVhFM7Cis2A8zxF9bTOUVbRDzPepe6w==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2523,6 +2938,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.47)(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.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-context': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-dismissable-layer': 1.0.5(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-id': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-popper': 1.1.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-portal': 1.0.4(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-presence': 1.0.1(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-primitive': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@radix-ui/react-slot': 1.0.2(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-use-controllable-state': 1.0.1(@types/react@18.2.47)(react@18.2.0)
|
||||||
|
'@radix-ui/react-visually-hidden': 1.0.3(@types/react@18.2.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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.47)(react@18.2.0):
|
/@radix-ui/react-use-callback-ref@1.0.1(@types/react@18.2.47)(react@18.2.0):
|
||||||
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
|
resolution: {integrity: sha512-D94LjX4Sp0xJFVaoQOd3OO9k7tpBYNOXdVhkltUbGv2Qb9OXdrg/CpsjlZv7ia14Sylv398LswWBVVu5nqKzAQ==}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
@ -2646,6 +3092,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.47)(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.47)(react-dom@18.2.0)(react@18.2.0)
|
||||||
|
'@types/react': 18.2.47
|
||||||
|
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:
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use std::process::Command;
|
|
||||||
use keyring::Entry;
|
use keyring::Entry;
|
||||||
|
use std::process::Command;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use webpage::{Webpage, WebpageOptions};
|
use webpage::{Webpage, WebpageOptions};
|
||||||
|
|
||||||
@ -117,14 +117,14 @@ pub async fn opengraph(url: String) -> OpenGraphResponse {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn secure_save(key: String, value: String) -> Result<(), ()> {
|
pub fn secure_save(key: String, value: String) -> Result<(), ()> {
|
||||||
let entry = Entry::new("lume", &key).expect("Failed to create entry");
|
let entry = Entry::new("Lume", &key).expect("Failed to create entry");
|
||||||
let _ = entry.set_password(&value);
|
let _ = entry.set_password(&value);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn secure_load(key: String) -> Result<String, String> {
|
pub fn secure_load(key: String) -> Result<String, String> {
|
||||||
let entry = Entry::new("lume", &key).expect("Failed to create entry");
|
let entry = Entry::new("Lume", &key).expect("Failed to create entry");
|
||||||
if let Ok(password) = entry.get_password() {
|
if let Ok(password) = entry.get_password() {
|
||||||
Ok(password)
|
Ok(password)
|
||||||
} else {
|
} else {
|
||||||
@ -134,7 +134,7 @@ pub fn secure_load(key: String) -> Result<String, String> {
|
|||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn secure_remove(key: String) -> Result<(), ()> {
|
pub fn secure_remove(key: String) -> Result<(), ()> {
|
||||||
let entry = Entry::new("lume", &key).expect("Failed to create entry");
|
let entry = Entry::new("Lume", &key).expect("Failed to create entry");
|
||||||
let _ = entry.delete_password();
|
let _ = entry.delete_password();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user