feat: move nwc to settings
This commit is contained in:
@@ -1,6 +1,8 @@
|
||||
import {
|
||||
AdvancedSettingsIcon,
|
||||
InfoIcon,
|
||||
NwcFilledIcon,
|
||||
NwcIcon,
|
||||
SecureIcon,
|
||||
SettingsIcon,
|
||||
UserIcon,
|
||||
@@ -25,7 +27,7 @@ export function SettingsLayout() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<UserIcon className="h-6 w-6" />
|
||||
<UserIcon className="size-6" />
|
||||
<p className="text-sm font-medium">User</p>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
@@ -39,9 +41,23 @@ export function SettingsLayout() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<SettingsIcon className="h-6 w-6" />
|
||||
<SettingsIcon className="size-6" />
|
||||
<p className="text-sm font-medium">General</p>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to="/settings/nwc"
|
||||
className={({ isActive }) =>
|
||||
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",
|
||||
isActive
|
||||
? "bg-neutral-100 text-blue-500 hover:bg-neutral-100 dark:bg-neutral-950 dark:hover:bg-neutral-900"
|
||||
: "",
|
||||
)
|
||||
}
|
||||
>
|
||||
<NwcIcon className="size-6" />
|
||||
<p className="text-sm font-medium">Wallet</p>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
to="/settings/backup"
|
||||
className={({ isActive }) =>
|
||||
@@ -53,7 +69,7 @@ export function SettingsLayout() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<SecureIcon className="h-6 w-6" />
|
||||
<SecureIcon className="size-6" />
|
||||
<p className="text-sm font-medium">Backup</p>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
@@ -67,7 +83,7 @@ export function SettingsLayout() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<AdvancedSettingsIcon className="h-6 w-6" />
|
||||
<AdvancedSettingsIcon className="size-6" />
|
||||
<p className="text-sm font-medium">Advanced</p>
|
||||
</NavLink>
|
||||
<NavLink
|
||||
@@ -81,7 +97,7 @@ export function SettingsLayout() {
|
||||
)
|
||||
}
|
||||
>
|
||||
<InfoIcon className="h-6 w-6" />
|
||||
<InfoIcon className="size-6" />
|
||||
<p className="text-sm font-medium">About</p>
|
||||
</NavLink>
|
||||
</div>
|
||||
|
||||
@@ -7,9 +7,6 @@ import {
|
||||
DepotIcon,
|
||||
HomeFilledIcon,
|
||||
HomeIcon,
|
||||
NwcIcon,
|
||||
RelayFilledIcon,
|
||||
RelayIcon,
|
||||
SettingsFilledIcon,
|
||||
SettingsIcon,
|
||||
} from "@lume/icons";
|
||||
|
||||
@@ -1,25 +1,22 @@
|
||||
import { RepostNote, TextNote, useArk, useProfile } from "@lume/ark";
|
||||
import { RepostNote, TextNote, User, useArk } from "@lume/ark";
|
||||
import {
|
||||
ArrowLeftIcon,
|
||||
ArrowRightCircleIcon,
|
||||
ArrowRightIcon,
|
||||
LoaderIcon,
|
||||
} from "@lume/icons";
|
||||
import { FETCH_LIMIT, displayNpub } from "@lume/utils";
|
||||
import { FETCH_LIMIT } from "@lume/utils";
|
||||
import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { useEffect, useMemo, useState } from "react";
|
||||
import { Link, useNavigate, useParams } from "react-router-dom";
|
||||
import { toast } from "sonner";
|
||||
import { useMemo } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { WindowVirtualizer } from "virtua";
|
||||
import { NIP05 } from "../nip05";
|
||||
|
||||
export function UserRoute() {
|
||||
const ark = useArk();
|
||||
const navigate = useNavigate();
|
||||
|
||||
const { id } = useParams();
|
||||
const { user } = useProfile(id);
|
||||
const { data, hasNextPage, isLoading, isFetchingNextPage, fetchNextPage } =
|
||||
useInfiniteQuery({
|
||||
queryKey: ["user-posts", id],
|
||||
@@ -51,37 +48,11 @@ export function UserRoute() {
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
const [followed, setFollowed] = useState(false);
|
||||
|
||||
const allEvents = useMemo(
|
||||
() => (data ? data.pages.flatMap((page) => page) : []),
|
||||
[data],
|
||||
);
|
||||
|
||||
const follow = async (pubkey: string) => {
|
||||
try {
|
||||
const add = await ark.createContact({ pubkey });
|
||||
if (add) {
|
||||
setFollowed(true);
|
||||
} else {
|
||||
toast.success("You already follow this user");
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const unfollow = async (pubkey: string) => {
|
||||
try {
|
||||
const remove = await ark.deleteContact({ pubkey });
|
||||
if (remove) {
|
||||
setFollowed(false);
|
||||
}
|
||||
} catch (error) {
|
||||
console.log(error);
|
||||
}
|
||||
};
|
||||
|
||||
const renderItem = (event: NDKEvent) => {
|
||||
switch (event.kind) {
|
||||
case NDKKind.Text:
|
||||
@@ -93,12 +64,6 @@ export function UserRoute() {
|
||||
}
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
if (ark.account.contacts.includes(id)) {
|
||||
setFollowed(true);
|
||||
}
|
||||
}, []);
|
||||
|
||||
return (
|
||||
<div className="pb-5 overflow-y-auto">
|
||||
<WindowVirtualizer>
|
||||
@@ -119,66 +84,27 @@ export function UserRoute() {
|
||||
</button>
|
||||
</div>
|
||||
<div className="px-3">
|
||||
<div className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<img
|
||||
src={user?.picture || user?.image}
|
||||
alt={id}
|
||||
className="h-12 w-12 shrink-0 rounded-lg object-cover"
|
||||
loading="lazy"
|
||||
decoding="async"
|
||||
/>
|
||||
<div className="inline-flex items-center gap-2">
|
||||
{followed ? (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => unfollow(id)}
|
||||
className="inline-flex h-9 w-28 items-center justify-center rounded-lg bg-neutral-200 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-800"
|
||||
>
|
||||
Unfollow
|
||||
</button>
|
||||
) : (
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => follow(id)}
|
||||
className="inline-flex h-9 w-28 items-center justify-center rounded-lg bg-neutral-200 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-800"
|
||||
>
|
||||
Follow
|
||||
</button>
|
||||
)}
|
||||
<Link
|
||||
to={`/chats/${id}`}
|
||||
className="inline-flex h-9 w-28 items-center justify-center rounded-lg bg-neutral-200 text-sm font-medium hover:bg-blue-500 hover:text-white dark:bg-neutral-800"
|
||||
>
|
||||
Message
|
||||
</Link>
|
||||
<User.Provider pubkey={id}>
|
||||
<User.Root className="flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<User.Avatar className="h-12 w-12 shrink-0 rounded-lg object-cover" />
|
||||
<User.Button
|
||||
target={id}
|
||||
className="inline-flex items-center justify-center w-24 text-sm font-semibold border-t rounded-lg border-neutral-900 dark:border-neutral-800 h-9 bg-neutral-950 text-neutral-50 dark:bg-neutral-900 hover:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-1 flex-col gap-1.5">
|
||||
<div className="flex flex-col">
|
||||
<h5 className="text-lg font-semibold">
|
||||
{user?.name ||
|
||||
user?.display_name ||
|
||||
user?.displayName ||
|
||||
"Anon"}
|
||||
</h5>
|
||||
{user?.nip05 ? (
|
||||
<NIP05
|
||||
<div className="flex flex-1 flex-col gap-1.5">
|
||||
<div className="flex flex-col">
|
||||
<User.Name className="text-lg font-semibold" />
|
||||
<User.NIP05
|
||||
pubkey={id}
|
||||
nip05={user?.nip05}
|
||||
className="max-w-[15rem] truncate text-sm text-neutral-600 dark:text-neutral-400"
|
||||
/>
|
||||
) : (
|
||||
<span className="max-w-[15rem] truncate text-sm text-neutral-600 dark:text-neutral-400">
|
||||
{displayNpub(id, 16)}
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<User.About className="text-neutral-900 dark:text-neutral-100" />
|
||||
</div>
|
||||
<div className="max-w-[500px] select-text break-words text-neutral-900 dark:text-neutral-100">
|
||||
{user?.about}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</User.Root>
|
||||
</User.Provider>
|
||||
<div className="pt-2 mt-2 border-t border-neutral-100 dark:border-neutral-900">
|
||||
<h3 className="text-lg font-semibold text-neutral-900 dark:text-neutral-100">
|
||||
Latest posts
|
||||
|
||||
Reference in New Issue
Block a user