feat: redesign relay screen

This commit is contained in:
reya
2024-01-14 18:05:36 +07:00
parent f908c46a19
commit dae4b1d52b
18 changed files with 495 additions and 270 deletions
@@ -49,18 +49,18 @@ export function RelayEventList({ relayUrl }: { relayUrl: string }) {
(event: NDKEvent) => {
switch (event.kind) {
case NDKKind.Text:
return <TextNote key={event.id} event={event} />;
return <TextNote key={event.id} event={event} className="mt-3" />;
case NDKKind.Repost:
return <RepostNote key={event.id} event={event} />;
return <RepostNote key={event.id} event={event} className="mt-3" />;
default:
return <TextNote key={event.id} event={event} />;
return <TextNote key={event.id} event={event} className="mt-3" />;
}
},
[data],
);
return (
<VList className="mx-auto h-full w-full max-w-[500px] pt-10 scrollbar-none">
<VList className="mx-auto h-full w-full max-w-[500px] px-3 scrollbar-none">
{status === "pending" ? (
<NoteSkeleton />
) : (
@@ -1,4 +1,4 @@
import { useRelay } from "@lume/ark";
import { useRelaylist } from "@lume/ark";
import { PlusIcon } from "@lume/icons";
import { NDKRelayUrl } from "@nostr-dev-kit/ndk";
import { normalizeRelayUrl } from "nostr-fetch";
@@ -8,7 +8,8 @@ import { toast } from "sonner";
const domainRegex = /^([a-z0-9]+(-[a-z0-9]+)*\.)+[a-z]{2,}$/;
export function RelayForm() {
const { connectRelay } = useRelay();
const { connectRelay } = useRelaylist();
const [relay, setRelay] = useState<{
url: NDKRelayUrl;
purpose: "read" | "write" | undefined;
@@ -35,28 +36,24 @@ export function RelayForm() {
};
return (
<div className="flex flex-col gap-1">
<div className="flex gap-2">
<input
className="h-11 flex-1 rounded-lg border-transparent bg-neutral-100 px-3 placeholder:text-neutral-500 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:bg-neutral-900 dark:placeholder:text-neutral-400 dark:focus:ring-blue-800"
placeholder="wss://"
spellCheck={false}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
value={relay.url}
onChange={(e) =>
setRelay((prev) => ({ ...prev, url: e.target.value }))
}
/>
<button
type="button"
onClick={() => create()}
className="inline-flex h-11 w-11 shrink-0 items-center justify-center rounded-lg bg-blue-500 text-white hover:bg-blue-600"
>
<PlusIcon className="h-5 w-5" />
</button>
</div>
<div className="flex gap-2">
<input
className="h-11 w-full rounded-lg border-transparent px-3 placeholder:text-neutral-500 focus:border-blue-500 focus:ring focus:ring-blue-200 bg-white/50 dark:bg-black/50 dark:placeholder:text-neutral-400 dark:focus:ring-blue-800"
placeholder="wss://"
spellCheck={false}
autoComplete="off"
autoCorrect="off"
autoCapitalize="off"
value={relay.url}
onChange={(e) => setRelay((prev) => ({ ...prev, url: e.target.value }))}
/>
<button
type="button"
onClick={() => create()}
className="inline-flex size-11 shrink-0 items-center justify-center rounded-lg bg-blue-500 text-white hover:bg-blue-600"
>
<PlusIcon className="size-5" />
</button>
</div>
);
}
@@ -0,0 +1,38 @@
import { useRelaylist } from "@lume/ark";
import { PlusIcon, ShareIcon } from "@lume/icons";
import { normalizeRelayUrl } from "nostr-fetch";
import { Link } from "react-router-dom";
export function RelayItem({ url }: { url: string }) {
const domain = new URL(url).hostname;
const { connectRelay } = useRelaylist();
return (
<div className="flex h-14 w-full items-center justify-between border-b border-neutral-100 px-5 dark:border-neutral-950">
<div className="inline-flex items-center gap-2">
<span className="text-sm font-semibold text-neutral-500 dark:text-neutral-400">
Relay:{" "}
</span>
<span className="max-w-[200px] truncate text-sm font-medium text-neutral-900 dark:text-neutral-100">
{url}
</span>
</div>
<div className="inline-flex items-center gap-2">
<Link
to={`/relays/${domain}/`}
className="inline-flex h-6 items-center justify-center gap-1 rounded bg-neutral-100 px-1.5 text-sm font-medium hover:bg-neutral-200 dark:bg-neutral-900 dark:hover:bg-neutral-800"
>
<ShareIcon className="h-3 w-3" />
Inspect
</Link>
<button
type="button"
onClick={() => connectRelay.mutate(normalizeRelayUrl(url))}
className="inline-flex h-6 w-6 items-center justify-center rounded bg-blue-100 text-blue-500 hover:bg-blue-200 dark:bg-blue-900 hover:dark:bg-blue-800"
>
<PlusIcon className="size-4" />
</button>
</div>
</div>
);
}
@@ -27,7 +27,7 @@ export function RelayList() {
};
return (
<div className="col-span-2 border-r border-neutral-100 dark:border-neutral-900">
<div className="col-span-2 bg-white">
{status === "pending" ? (
<div className="flex h-full w-full items-center justify-center pb-10">
<div className="inline-flex flex-col items-center justify-center gap-2">
@@ -1,16 +1,15 @@
import { useArk } from "@lume/ark";
import { CancelIcon, RefreshIcon } from "@lume/icons";
import { useStorage } from "@lume/storage";
import { cn } from "@lume/utils";
import { NDKKind } from "@nostr-dev-kit/ndk";
import { useQuery } from "@tanstack/react-query";
import { RelayForm } from "./relayForm";
export function UserRelayList() {
export function RelaySidebar({ className }: { className?: string }) {
const ark = useArk();
const storage = useStorage();
const { status, data, refetch } = useQuery({
queryKey: ["relays", ark.account.pubkey],
queryKey: ["relay-personal"],
queryFn: async () => {
const event = await ark.getEventByFilter({
filter: {
@@ -20,7 +19,7 @@ export function UserRelayList() {
});
if (!event) return [];
return event.tags;
return event.tags.filter((tag) => tag[0] === "r");
},
refetchOnWindowFocus: false,
});
@@ -30,8 +29,13 @@ export function UserRelayList() {
);
return (
<div className="col-span-1">
<div className="inline-flex items-center justify-between w-full h-16 px-3 border-b border-neutral-100 dark:border-neutral-900">
<div
className={cn(
"rounded-l-xl bg-white/50 backdrop-blur-xl dark:bg-black/50",
className,
)}
>
<div className="inline-flex items-center justify-between w-full h-14 px-3 border-b border-black/10 dark:border-white/10">
<h3 className="font-semibold">Connected relays</h3>
<button
type="button"
@@ -54,7 +58,7 @@ export function UserRelayList() {
data.map((item) => (
<div
key={item[1]}
className="flex items-center justify-between px-3 rounded-lg group h-11 bg-neutral-100 dark:bg-neutral-900"
className="flex items-center justify-between px-3 rounded-lg group h-11 bg-white/50 dark:bg-black/50"
>
<div className="inline-flex items-baseline gap-2">
{currentRelays.has(item[1]) ? (
@@ -69,7 +73,7 @@ export function UserRelayList() {
</span>
)}
<p className="max-w-[20rem] truncate text-sm font-medium text-neutral-900 dark:text-neutral-100">
{item[1]}
{item[1].replace("wss://", "").replace("ws://", "")}
</p>
</div>
<div className="inline-flex items-center gap-2">