mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-29 16:30:55 +00:00
chore: clean up
This commit is contained in:
parent
ed6423e4aa
commit
16efd495a0
@ -43,7 +43,7 @@
|
|||||||
"react-currency-input-field": "^3.6.14",
|
"react-currency-input-field": "^3.6.14",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.49.3",
|
"react-hook-form": "^7.49.3",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"smol-toml": "^1.1.3",
|
"smol-toml": "^1.1.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
@ -52,11 +52,11 @@
|
|||||||
"@lume/tailwindcss": "workspace:^",
|
"@lume/tailwindcss": "workspace:^",
|
||||||
"@lume/tsconfig": "workspace:^",
|
"@lume/tsconfig": "workspace:^",
|
||||||
"@lume/types": "workspace:^",
|
"@lume/types": "workspace:^",
|
||||||
"@types/node": "^20.11.4",
|
"@types/node": "^20.11.5",
|
||||||
"@types/react": "^18.2.48",
|
"@types/react": "^18.2.48",
|
||||||
"@types/react-dom": "^18.2.18",
|
"@types/react-dom": "^18.2.18",
|
||||||
"@vitejs/plugin-react-swc": "^3.5.0",
|
"@vitejs/plugin-react-swc": "^3.5.0",
|
||||||
"autoprefixer": "^10.4.16",
|
"autoprefixer": "^10.4.17",
|
||||||
"cross-env": "^7.0.3",
|
"cross-env": "^7.0.3",
|
||||||
"encoding": "^0.1.13",
|
"encoding": "^0.1.13",
|
||||||
"postcss": "^8.4.33",
|
"postcss": "^8.4.33",
|
||||||
|
@ -32,7 +32,7 @@ export function DepotContactCard() {
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setStatus(false);
|
setStatus(false);
|
||||||
toast.error(e);
|
toast.error(String(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ export function DepotOnboardingScreen() {
|
|||||||
navigate("/depot/");
|
navigate("/depot/");
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(e);
|
toast.error(String(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { useStorage } from "@lume/storage";
|
import { useStorage } from "@lume/storage";
|
||||||
import { downloadDir } from "@tauri-apps/api/path";
|
import { downloadDir } from "@tauri-apps/api/path";
|
||||||
import { message, save } from "@tauri-apps/plugin-dialog";
|
import { message, save } from "@tauri-apps/plugin-dialog";
|
||||||
@ -11,6 +12,7 @@ interface RouteError {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function ErrorScreen() {
|
export function ErrorScreen() {
|
||||||
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
const error = useRouteError() as RouteError;
|
const error = useRouteError() as RouteError;
|
||||||
|
|
||||||
|
@ -1,153 +0,0 @@
|
|||||||
import { useArk, useProfile } from "@lume/ark";
|
|
||||||
import { useStorage } from "@lume/storage";
|
|
||||||
import { NIP05 } from "@lume/ui";
|
|
||||||
import { displayNpub } from "@lume/utils";
|
|
||||||
import * as Avatar from "@radix-ui/react-avatar";
|
|
||||||
import { minidenticon } from "minidenticons";
|
|
||||||
import { useEffect, useState } from "react";
|
|
||||||
import { Link, useNavigate } from "react-router-dom";
|
|
||||||
import { toast } from "sonner";
|
|
||||||
import { UserStats } from "./stats";
|
|
||||||
|
|
||||||
export function UserProfile({ pubkey }: { pubkey: string }) {
|
|
||||||
const ark = useArk();
|
|
||||||
const storage = useStorage();
|
|
||||||
|
|
||||||
const { user } = useProfile(pubkey);
|
|
||||||
|
|
||||||
const [followed, setFollowed] = useState(false);
|
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const svgURI = `data:image/svg+xml;utf8,${encodeURIComponent(
|
|
||||||
minidenticon(pubkey, 90, 50),
|
|
||||||
)}`;
|
|
||||||
|
|
||||||
const follow = async () => {
|
|
||||||
try {
|
|
||||||
if (!ark.ndk.signer) return navigate("/new/privkey");
|
|
||||||
setFollowed(true);
|
|
||||||
|
|
||||||
const add = await ark.createContact({ pubkey });
|
|
||||||
|
|
||||||
if (!add) {
|
|
||||||
toast.success("You already follow this user");
|
|
||||||
setFollowed(false);
|
|
||||||
}
|
|
||||||
} catch (e) {
|
|
||||||
toast.error(e);
|
|
||||||
setFollowed(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const unfollow = async () => {
|
|
||||||
try {
|
|
||||||
if (!ark.ndk.signer) return navigate("/new/privkey");
|
|
||||||
setFollowed(false);
|
|
||||||
|
|
||||||
await ark.deleteContact({ pubkey });
|
|
||||||
} catch (e) {
|
|
||||||
toast.error(e);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
if (ark.account.contacts.includes(pubkey)) {
|
|
||||||
setFollowed(true);
|
|
||||||
}
|
|
||||||
}, []);
|
|
||||||
|
|
||||||
if (!user) return <p>Loading...</p>;
|
|
||||||
|
|
||||||
return (
|
|
||||||
<>
|
|
||||||
<div className="h-56 w-full overflow-hidden rounded-tl-lg">
|
|
||||||
{user?.banner ? (
|
|
||||||
<img
|
|
||||||
src={user?.banner}
|
|
||||||
alt="user banner"
|
|
||||||
className="h-full w-full rounded-tl-lg object-cover"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<div className="h-full w-full rounded-tl-lg bg-neutral-100 dark:bg-neutral-900" />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="-mt-7 flex w-full flex-col items-center px-5">
|
|
||||||
<Avatar.Root className="shrink-0">
|
|
||||||
<Avatar.Image
|
|
||||||
src={user?.picture || user?.image}
|
|
||||||
alt={pubkey}
|
|
||||||
loading="lazy"
|
|
||||||
decoding="async"
|
|
||||||
style={{ contentVisibility: "auto" }}
|
|
||||||
className="h-14 w-14 rounded-lg bg-white object-cover ring-2 ring-neutral-100 dark:ring-neutral-900"
|
|
||||||
/>
|
|
||||||
<Avatar.Fallback delayMs={300}>
|
|
||||||
<img
|
|
||||||
src={svgURI}
|
|
||||||
alt={pubkey}
|
|
||||||
className="h-14 w-14 rounded-lg bg-black dark:bg-white"
|
|
||||||
/>
|
|
||||||
</Avatar.Fallback>
|
|
||||||
</Avatar.Root>
|
|
||||||
<div className="mt-2 flex flex-1 flex-col gap-6">
|
|
||||||
<div className="flex flex-col items-center gap-1">
|
|
||||||
<div className="inline-flex flex-col items-center">
|
|
||||||
<h5 className="text-center text-xl font-semibold text-neutral-900 dark:text-neutral-100">
|
|
||||||
{user?.name ||
|
|
||||||
user?.display_name ||
|
|
||||||
user?.displayName ||
|
|
||||||
"No name"}
|
|
||||||
</h5>
|
|
||||||
{user?.nip05 ? (
|
|
||||||
<NIP05
|
|
||||||
pubkey={pubkey}
|
|
||||||
nip05={user.nip05}
|
|
||||||
className="text-neutral-600 dark:text-neutral-400"
|
|
||||||
/>
|
|
||||||
) : (
|
|
||||||
<span className="max-w-[15rem] truncate text-sm text-neutral-500 dark:text-neutral-400">
|
|
||||||
{displayNpub(pubkey, 16)}
|
|
||||||
</span>
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<div className="flex flex-col gap-6">
|
|
||||||
{user?.about || user?.bio ? (
|
|
||||||
<p className="mt-2 max-w-[500px] select-text break-words text-center text-neutral-900 dark:text-neutral-100">
|
|
||||||
{user.about || user.bio}
|
|
||||||
</p>
|
|
||||||
) : (
|
|
||||||
<div />
|
|
||||||
)}
|
|
||||||
<UserStats pubkey={pubkey} />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div className="inline-flex items-center justify-center gap-2">
|
|
||||||
{followed ? (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={unfollow}
|
|
||||||
className="inline-flex h-10 w-36 items-center justify-center rounded-md bg-neutral-200 text-sm font-medium text-neutral-900 backdrop-blur-xl hover:bg-blue-500 hover:text-neutral-100 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-blue-600 dark:hover:text-neutral-100"
|
|
||||||
>
|
|
||||||
Unfollow
|
|
||||||
</button>
|
|
||||||
) : (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={follow}
|
|
||||||
className="inline-flex h-10 w-36 items-center justify-center rounded-md bg-neutral-200 text-sm font-medium text-neutral-900 backdrop-blur-xl hover:bg-blue-500 hover:text-neutral-100 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-blue-600 dark:hover:text-neutral-100"
|
|
||||||
>
|
|
||||||
Follow
|
|
||||||
</button>
|
|
||||||
)}
|
|
||||||
<Link
|
|
||||||
to={`/chats/${pubkey}`}
|
|
||||||
className="inline-flex h-10 w-36 items-center justify-center rounded-md bg-neutral-200 text-sm font-medium text-neutral-900 backdrop-blur-xl hover:bg-blue-500 hover:text-neutral-100 dark:bg-neutral-800 dark:text-neutral-100 dark:hover:bg-blue-600 dark:hover:text-neutral-100"
|
|
||||||
>
|
|
||||||
Message
|
|
||||||
</Link>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,84 +0,0 @@
|
|||||||
import { LoaderIcon } from "@lume/icons";
|
|
||||||
import { compactNumber } from "@lume/utils";
|
|
||||||
import { useQuery } from "@tanstack/react-query";
|
|
||||||
import { fetch } from "@tauri-apps/plugin-http";
|
|
||||||
|
|
||||||
export function UserStats({ pubkey }: { pubkey: string }) {
|
|
||||||
const { status, data } = useQuery({
|
|
||||||
queryKey: ["user-stats", pubkey],
|
|
||||||
queryFn: async ({ signal }: { signal: AbortSignal }) => {
|
|
||||||
const res = await fetch(
|
|
||||||
`https://api.nostr.band/v0/stats/profile/${pubkey}`,
|
|
||||||
{
|
|
||||||
signal,
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if (!res.ok) {
|
|
||||||
throw new Error("Error");
|
|
||||||
}
|
|
||||||
|
|
||||||
return await res.json();
|
|
||||||
},
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
refetchOnMount: false,
|
|
||||||
refetchOnReconnect: false,
|
|
||||||
staleTime: Infinity,
|
|
||||||
});
|
|
||||||
|
|
||||||
if (status === "pending") {
|
|
||||||
return (
|
|
||||||
<div className="flex w-full items-center justify-center">
|
|
||||||
<LoaderIcon className="h-5 w-5 animate-spin text-neutral-900 dark:text-neutral-100" />
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (status === "error") {
|
|
||||||
return <div className="flex w-full items-center justify-center" />;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="flex w-full items-center justify-center gap-10">
|
|
||||||
<div className="inline-flex flex-col items-center gap-1">
|
|
||||||
<span className="font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
|
||||||
{compactNumber.format(data?.stats[pubkey]?.followers_pubkey_count) ??
|
|
||||||
0}
|
|
||||||
</span>
|
|
||||||
<span className="text-sm leading-none text-neutral-500 dark:text-neutral-400">
|
|
||||||
Followers
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="inline-flex flex-col items-center gap-1">
|
|
||||||
<span className="font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
|
||||||
{compactNumber.format(
|
|
||||||
data?.stats[pubkey]?.pub_following_pubkey_count,
|
|
||||||
) ?? 0}
|
|
||||||
</span>
|
|
||||||
<span className="text-sm leading-none text-neutral-500 dark:text-neutral-400">
|
|
||||||
Following
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="inline-flex flex-col items-center gap-1">
|
|
||||||
<span className="font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
|
||||||
{compactNumber.format(
|
|
||||||
data?.stats[pubkey]?.zaps_received?.msats / 1000 ?? 0,
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span className="text-sm leading-none text-neutral-500 dark:text-neutral-400">
|
|
||||||
Zaps received
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div className="inline-flex flex-col items-center gap-1">
|
|
||||||
<span className="font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
|
||||||
{compactNumber.format(
|
|
||||||
data?.stats[pubkey]?.zaps_sent?.msats / 1000 ?? 0,
|
|
||||||
)}
|
|
||||||
</span>
|
|
||||||
<span className="text-sm leading-none text-neutral-500 dark:text-neutral-400">
|
|
||||||
Zaps sent
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,97 +0,0 @@
|
|||||||
import { NoteSkeleton, RepostNote, TextNote, useArk } from "@lume/ark";
|
|
||||||
import { ArrowRightCircleIcon, LoaderIcon } from "@lume/icons";
|
|
||||||
import { FETCH_LIMIT } from "@lume/utils";
|
|
||||||
import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
|
|
||||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
|
||||||
import { useMemo } from "react";
|
|
||||||
import { useParams } from "react-router-dom";
|
|
||||||
import { UserProfile } from "./components/profile";
|
|
||||||
|
|
||||||
export function UserScreen() {
|
|
||||||
const { pubkey } = useParams();
|
|
||||||
const ark = useArk();
|
|
||||||
const { status, data, hasNextPage, isFetchingNextPage, fetchNextPage } =
|
|
||||||
useInfiniteQuery({
|
|
||||||
queryKey: ["user-posts", pubkey],
|
|
||||||
initialPageParam: 0,
|
|
||||||
queryFn: async ({
|
|
||||||
signal,
|
|
||||||
pageParam,
|
|
||||||
}: {
|
|
||||||
signal: AbortSignal;
|
|
||||||
pageParam: number;
|
|
||||||
}) => {
|
|
||||||
const events = await ark.getInfiniteEvents({
|
|
||||||
filter: {
|
|
||||||
kinds: [NDKKind.Text, NDKKind.Repost],
|
|
||||||
authors: [pubkey],
|
|
||||||
},
|
|
||||||
limit: FETCH_LIMIT,
|
|
||||||
pageParam,
|
|
||||||
signal,
|
|
||||||
});
|
|
||||||
|
|
||||||
return events;
|
|
||||||
},
|
|
||||||
getNextPageParam: (lastPage) => {
|
|
||||||
const lastEvent = lastPage.at(-1);
|
|
||||||
if (!lastEvent) return;
|
|
||||||
return lastEvent.created_at - 1;
|
|
||||||
},
|
|
||||||
refetchOnWindowFocus: false,
|
|
||||||
});
|
|
||||||
|
|
||||||
const allEvents = useMemo(
|
|
||||||
() => (data ? data.pages.flatMap((page) => page) : []),
|
|
||||||
[data],
|
|
||||||
);
|
|
||||||
|
|
||||||
// render event match event kind
|
|
||||||
const renderItem = (event: NDKEvent) => {
|
|
||||||
switch (event.kind) {
|
|
||||||
case NDKKind.Text:
|
|
||||||
return <TextNote key={event.id} event={event} />;
|
|
||||||
case NDKKind.Repost:
|
|
||||||
return <RepostNote key={event.id} event={event} />;
|
|
||||||
default:
|
|
||||||
return <TextNote key={event.id} event={event} />;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
return (
|
|
||||||
<div className="relative h-full w-full overflow-y-auto">
|
|
||||||
<UserProfile pubkey={pubkey} />
|
|
||||||
<div className="mt-6 h-full w-full border-t border-neutral-100 px-1.5 dark:border-neutral-900">
|
|
||||||
<h3 className="mb-2 pt-4 text-center text-lg font-semibold leading-none text-neutral-900 dark:text-neutral-100">
|
|
||||||
Latest posts
|
|
||||||
</h3>
|
|
||||||
<div className="mx-auto flex h-full max-w-[500px] flex-col justify-between gap-1.5 pb-4 pt-1.5">
|
|
||||||
{status === "pending" ? (
|
|
||||||
<NoteSkeleton />
|
|
||||||
) : (
|
|
||||||
allEvents.map((item) => renderItem(item))
|
|
||||||
)}
|
|
||||||
<div className="flex h-16 items-center justify-center px-3 pb-3">
|
|
||||||
{hasNextPage ? (
|
|
||||||
<button
|
|
||||||
type="button"
|
|
||||||
onClick={() => fetchNextPage()}
|
|
||||||
disabled={!hasNextPage || isFetchingNextPage}
|
|
||||||
className="inline-flex items-center justify-center w-full h-12 gap-2 font-medium bg-neutral-100 hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800 rounded-xl focus:outline-none"
|
|
||||||
>
|
|
||||||
{isFetchingNextPage ? (
|
|
||||||
<LoaderIcon className="size-5 animate-spin" />
|
|
||||||
) : (
|
|
||||||
<>
|
|
||||||
<ArrowRightCircleIcon className="size-5" />
|
|
||||||
Load more
|
|
||||||
</>
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
) : null}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -9,7 +9,7 @@
|
|||||||
},
|
},
|
||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@biomejs/biome": "^1.5.2",
|
"@biomejs/biome": "^1.5.2",
|
||||||
"@tauri-apps/cli": "^2.0.0-alpha.21",
|
"@tauri-apps/cli": "2.0.0-alpha.21",
|
||||||
"turbo": "^1.11.3"
|
"turbo": "^1.11.3"
|
||||||
},
|
},
|
||||||
"packageManager": "pnpm@8.9.0",
|
"packageManager": "pnpm@8.9.0",
|
||||||
|
@ -23,7 +23,7 @@
|
|||||||
"jotai": "^2.6.2",
|
"jotai": "^2.6.2",
|
||||||
"linkify-react": "^4.1.3",
|
"linkify-react": "^4.1.3",
|
||||||
"linkifyjs": "^4.1.3",
|
"linkifyjs": "^4.1.3",
|
||||||
"media-chrome": "^2.0.1",
|
"media-chrome": "^2.1.0",
|
||||||
"minidenticons": "^4.2.0",
|
"minidenticons": "^4.2.0",
|
||||||
"nanoid": "^5.0.4",
|
"nanoid": "^5.0.4",
|
||||||
"nostr-fetch": "^0.15.0",
|
"nostr-fetch": "^0.15.0",
|
||||||
@ -32,7 +32,7 @@
|
|||||||
"re-resizable": "^6.9.11",
|
"re-resizable": "^6.9.11",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-currency-input-field": "^3.6.14",
|
"react-currency-input-field": "^3.6.14",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"react-string-replace": "^1.1.1",
|
"react-string-replace": "^1.1.1",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"tippy.js": "^6.3.7",
|
"tippy.js": "^6.3.7",
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { UnverifiedIcon, VerifiedIcon } from "@lume/icons";
|
import { UnverifiedIcon, VerifiedIcon } from "@lume/icons";
|
||||||
import { cn } from "@lume/utils";
|
import { cn, displayNpub } from "@lume/utils";
|
||||||
import { useQuery } from "@tanstack/react-query";
|
import { useQuery } from "@tanstack/react-query";
|
||||||
import { useArk } from "../../hooks/useArk";
|
import { useArk } from "../../hooks/useArk";
|
||||||
import { useUserContext } from "./provider";
|
import { useUserContext } from "./provider";
|
||||||
@ -39,9 +39,9 @@ export function UserNip05({
|
|||||||
return (
|
return (
|
||||||
<div className="inline-flex items-center gap-1">
|
<div className="inline-flex items-center gap-1">
|
||||||
<p className={cn("text-sm font-medium", className)}>
|
<p className={cn("text-sm font-medium", className)}>
|
||||||
{user.nip05.startsWith("_@")
|
{user?.nip05?.startsWith("_@")
|
||||||
? user.nip05.replace("_@", "")
|
? user?.nip05?.replace("_@", "")
|
||||||
: user.nip05}
|
: displayNpub(pubkey, 16)}
|
||||||
</p>
|
</p>
|
||||||
{!isLoading && verified ? (
|
{!isLoading && verified ? (
|
||||||
<VerifiedIcon className="size-4 text-teal-500" />
|
<VerifiedIcon className="size-4 text-teal-500" />
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -11,7 +11,7 @@
|
|||||||
"@nostr-dev-kit/ndk": "^2.3.3",
|
"@nostr-dev-kit/ndk": "^2.3.3",
|
||||||
"@tanstack/react-query": "^5.17.15",
|
"@tanstack/react-query": "^5.17.15",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
"virtua": "^0.20.5"
|
"virtua": "^0.20.5"
|
||||||
},
|
},
|
||||||
|
@ -65,8 +65,6 @@ export class LumeStorage {
|
|||||||
|
|
||||||
const account = await this.getActiveAccount();
|
const account = await this.getActiveAccount();
|
||||||
if (account) this.currentUser = account;
|
if (account) this.currentUser = account;
|
||||||
|
|
||||||
this.nwc = await this.loadPrivkey("Nostr Wallet Connect");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async #keyring_save(key: string, value: string) {
|
async #keyring_save(key: string, value: string) {
|
||||||
@ -427,10 +425,14 @@ export class LumeStorage {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public async logout() {
|
public async logout() {
|
||||||
this.currentUser = null;
|
const res = await this.#db.execute(
|
||||||
return await this.#db.execute(
|
|
||||||
"UPDATE accounts SET is_active = '0' WHERE id = $1;",
|
"UPDATE accounts SET is_active = '0' WHERE id = $1;",
|
||||||
[this.currentUser.id],
|
[this.currentUser.id],
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (res) {
|
||||||
|
this.currentUser = null;
|
||||||
|
this.nwc = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.49.3",
|
"react-hook-form": "^7.49.3",
|
||||||
"react-hotkeys-hook": "^4.4.4",
|
"react-hotkeys-hook": "^4.4.4",
|
||||||
"react-router-dom": "^6.21.2",
|
"react-router-dom": "^6.21.3",
|
||||||
"slate": "^0.101.5",
|
"slate": "^0.101.5",
|
||||||
"slate-react": "^0.101.5",
|
"slate-react": "^0.101.5",
|
||||||
"sonner": "^1.3.1",
|
"sonner": "^1.3.1",
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
|
import { useArk } from "@lume/ark";
|
||||||
import { LogoutIcon } from "@lume/icons";
|
import { LogoutIcon } from "@lume/icons";
|
||||||
import { useStorage } from "@lume/storage";
|
import { useStorage } from "@lume/storage";
|
||||||
import * as AlertDialog from "@radix-ui/react-alert-dialog";
|
import * as AlertDialog from "@radix-ui/react-alert-dialog";
|
||||||
@ -6,10 +7,10 @@ import { useNavigate } from "react-router-dom";
|
|||||||
import { toast } from "sonner";
|
import { toast } from "sonner";
|
||||||
|
|
||||||
export function Logout() {
|
export function Logout() {
|
||||||
|
const ark = useArk();
|
||||||
const storage = useStorage();
|
const storage = useStorage();
|
||||||
|
|
||||||
const navigate = useNavigate();
|
|
||||||
const queryClient = useQueryClient();
|
const queryClient = useQueryClient();
|
||||||
|
const navigate = useNavigate();
|
||||||
|
|
||||||
const logout = async () => {
|
const logout = async () => {
|
||||||
try {
|
try {
|
||||||
@ -18,11 +19,14 @@ export function Logout() {
|
|||||||
|
|
||||||
// clear cache
|
// clear cache
|
||||||
queryClient.clear();
|
queryClient.clear();
|
||||||
|
ark.account = null;
|
||||||
|
ark.ndk.signer = null;
|
||||||
|
ark.ndk.activeUser = null;
|
||||||
|
|
||||||
// redirect to welcome screen
|
// redirect to welcome screen
|
||||||
navigate("/auth/welcome");
|
navigate("/auth/");
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
toast.error(e);
|
toast.error(String(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -23,7 +23,7 @@ export function AvatarUploadButton({
|
|||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
toast.error(e);
|
toast.error(String(e));
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
664
pnpm-lock.yaml
664
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue
Block a user