diff --git a/apps/badges/app/layout.tsx b/apps/badges/app/layout.tsx
index df7c484..6fb63aa 100644
--- a/apps/badges/app/layout.tsx
+++ b/apps/badges/app/layout.tsx
@@ -1,5 +1,5 @@
export const metadata = {
- metadataBase: new URL("https://badges.page"),
+ metadataBase: new URL('https://badges.page'),
title: "Badges",
description: "Create, collect and award badges",
};
diff --git a/apps/emojis/app/utils.ts b/apps/emojis/app/utils.ts
new file mode 100644
index 0000000..d9bd79e
--- /dev/null
+++ b/apps/emojis/app/utils.ts
@@ -0,0 +1,33 @@
+import { Relay, Tag } from "@ngine/core";
+
+export function encodeRelayURL(url: string): string {
+ url = url.trim();
+ if (url.startsWith("wss://")) {
+ url = url.slice(6);
+ }
+ return encodeURIComponent(url);
+}
+
+export function relayToTag(r: Relay): Tag {
+ if (r.read && !r.write) {
+ return ["r", r.url, "read"];
+ }
+ if (r.write && !r.read) {
+ return ["r", r.url, "write"];
+ }
+ return ["r", r.url];
+}
+
+export function tagToRelay(t: Tag): Relay {
+ const url = t[1].replace(/\/$/, "");
+
+ if (t[2] === "read") {
+ return { url, read: true, write: false };
+ }
+
+ if (t[2] === "write") {
+ return { url, read: false, write: true };
+ }
+
+ return { url, read: true, write: true };
+}
diff --git a/apps/emojis/ui/layout.tsx b/apps/emojis/ui/layout.tsx
index 8a1d803..ca81129 100644
--- a/apps/emojis/ui/layout.tsx
+++ b/apps/emojis/ui/layout.tsx
@@ -15,11 +15,7 @@ import { theme } from "./theme";
const cacheAdapter = new NDKCacheAdapterDexie({ dbName: "emojis" });
const ndk = new NDK({
- explicitRelayUrls: [
- "wss://nos.lol",
- "wss://relay.nostr.band",
- "wss://frens.nostr1.com",
- ],
+ explicitRelayUrls: ["wss://nos.lol", "wss://relay.nostr.band", "wss://frens.nostr1.com"],
outboxRelayUrls: ["wss://purplepag.es"],
enableOutboxModel: true,
cacheAdapter,
diff --git a/apps/relays/app/components/footer.tsx b/apps/relays/app/components/footer.tsx
index 383a2f0..914e989 100644
--- a/apps/relays/app/components/footer.tsx
+++ b/apps/relays/app/components/footer.tsx
@@ -13,9 +13,9 @@ export default function Footer(props: StackProps) {
{...props}
>
- Relay data provided by
-
- nostr.watch
+ Made with ❤️ by{" "}
+
+ verbiricha
diff --git a/apps/relays/app/components/relay-link.tsx b/apps/relays/app/components/relay-link.tsx
index e21e88b..fd2186b 100644
--- a/apps/relays/app/components/relay-link.tsx
+++ b/apps/relays/app/components/relay-link.tsx
@@ -5,7 +5,7 @@ import { useRelays } from "@ngine/core";
import Link from "./link";
import RelayFavicon from "./relay-favicon";
-import { humanize, encode } from "@lib/urls";
+import { encodeRelayURL } from "../utils";
interface RelayLinkProps {
url: string;
@@ -13,12 +13,11 @@ interface RelayLinkProps {
export default function RelayLink({ url }: RelayLinkProps) {
const relays = useRelays();
- const isInMyRelays = useMemo(
- () => relays.map(humanize).includes(humanize(url)),
- [relays, url],
- );
- const encoded = useMemo(() => `/relay/${encode(url)}`, [url]);
- const domain = useMemo(() => humanize(url), [url]);
+ const isInMyRelays = useMemo(() => relays.includes(url), [relays, url]);
+ const encoded = useMemo(() => `/relay/${encodeRelayURL(url)}`, [url]);
+ const domain = useMemo(() => {
+ return url.replace("ws://", "").replace("wss://", "");
+ }, [url]);
return (
diff --git a/apps/relays/app/components/relay-metadata.tsx b/apps/relays/app/components/relay-metadata.tsx
index d9eae7f..3d6f122 100644
--- a/apps/relays/app/components/relay-metadata.tsx
+++ b/apps/relays/app/components/relay-metadata.tsx
@@ -7,7 +7,6 @@ import RelayFavicon from "./relay-favicon";
import RelaySummary from "./relay-summary";
import ToggleRelay from "./toggle-relay";
import { RelayMetadata } from "../hooks/useRelayMetadata";
-import { humanize } from "@lib/urls";
export default function Metadata({
url,
@@ -16,7 +15,9 @@ export default function Metadata({
url: string;
metadata: RelayMetadata;
}) {
- const domain = useMemo(() => humanize(url), [url]);
+ const domain = useMemo(() => {
+ return url.replace("ws://", "").replace("wss://", "");
+ }, [url]);
return (
diff --git a/apps/relays/app/components/relays.tsx b/apps/relays/app/components/relays.tsx
index b959a75..06b3363 100644
--- a/apps/relays/app/components/relays.tsx
+++ b/apps/relays/app/components/relays.tsx
@@ -3,73 +3,58 @@
import { useRouter } from "next/navigation";
import { useState, useMemo } from "react";
import {
+ Alert,
+ AlertIcon,
Stack,
Button,
+ Text,
Icon,
Input,
InputGroup,
InputLeftElement,
InputRightElement,
- Stat,
- StatLabel,
- StatNumber,
- StatGroup,
} from "@chakra-ui/react";
+import { useQuery } from "@tanstack/react-query";
import { useIntl, FormattedMessage } from "react-intl";
import { useRelays } from "@ngine/core";
import RelayLink from "./relay-link";
import RelayIcon from "./relay-icon";
-import { humanize, encode } from "@lib/urls";
-import useRelayStatus from "@hooks/useRelayStatus";
+import { encodeRelayURL } from "../utils";
export default function Relays() {
const { formatMessage } = useIntl();
const router = useRouter();
const [relay, setRelay] = useState("");
- const { events, online, offline } = useRelayStatus();
const myRelays = useRelays();
- const relaySet = useMemo(() => new Set(myRelays.map(humanize)), [myRelays]);
+ const { data, isFetched, isError } = useQuery({
+ queryKey: ["relays"],
+ queryFn: () =>
+ fetch(`https://api.nostr.watch/v1/online`).then((r) => r.json()),
+ });
function relayScore(url: string) {
- if (relaySet.has(humanize(url))) {
- return 42;
+ if (myRelays.includes(url)) {
+ return 1;
}
return 0;
}
const relays = useMemo(() => {
- const raw = [...online].sort((a, b) => relayScore(b) - relayScore(a));
+ const raw = data
+ ? [...data].sort((a, b) => relayScore(b) - relayScore(a))
+ : [];
return raw
.filter((url) => url.toLowerCase().includes(relay.toLowerCase()))
.slice(0, 21);
- }, [online, relay]);
+ }, [relay, data, myRelays]);
function goToRelay(url: string) {
- router.push(`/relay/${encode(url)}`);
+ router.push(`/relay/${encodeRelayURL(url)}`);
}
return (
-
- {/* @ts-ignore */}
-
- {events.length}
- Relays
-
-
- {/* @ts-ignore */}
-
- {online.length}
- Online
-
-
- {/* @ts-ignore */}
-
- {offline.length}
- Offline
-
-
- {relays.map((url) => (
-
- ))}
+ {isError && (
+
+
+
+
+ )}
+ {isFetched &&
+ relays.map((url: string) => )}
+ {isFetched && relays.length === 0 && (
+
+
+
+ )}
);
diff --git a/apps/relays/app/utils.ts b/apps/relays/app/utils.ts
index 676fb91..d9bd79e 100644
--- a/apps/relays/app/utils.ts
+++ b/apps/relays/app/utils.ts
@@ -19,7 +19,7 @@ export function relayToTag(r: Relay): Tag {
}
export function tagToRelay(t: Tag): Relay {
- const url = t[1];
+ const url = t[1].replace(/\/$/, "");
if (t[2] === "read") {
return { url, read: true, write: false };
diff --git a/apps/relays/hooks/useRelayStatus.ts b/apps/relays/hooks/useRelayStatus.ts
deleted file mode 100644
index 50f52c8..0000000
--- a/apps/relays/hooks/useRelayStatus.ts
+++ /dev/null
@@ -1,41 +0,0 @@
-import { NDKKind, NDKSubscriptionCacheUsage } from "@nostr-dev-kit/ndk";
-import { useEvent, useEvents } from "@ngine/core";
-
-export function useStatus(url: string) {
- const event = useEvent(
- {
- kinds: [30_066 as NDKKind],
- "#d": [url],
- authors: [
- "151c17c9d234320cf0f189af7b761f63419fd6c38c6041587a008b7682e4640f",
- ],
- },
- {
- cacheUsage: NDKSubscriptionCacheUsage.CACHE_FIRST,
- },
- );
- return event;
-}
-
-export default function useRelayStatus() {
- const { events } = useEvents(
- {
- kinds: [30_066 as NDKKind],
- authors: [
- "151c17c9d234320cf0f189af7b761f63419fd6c38c6041587a008b7682e4640f",
- ],
- },
- {
- cacheUsage: NDKSubscriptionCacheUsage.PARALLEL,
- },
- );
- const online = events
- .filter((e) => e.tagValue("s") === "online")
- .map((e) => e.tagValue("d"))
- .filter((s) => s) as string[];
- const offline = events
- .filter((e) => e.tagValue("s") !== "online")
- .map((e) => e.tagValue("d"))
- .filter((s) => s) as string[];
- return { events, online, offline };
-}
diff --git a/apps/relays/lib/urls.ts b/apps/relays/lib/urls.ts
deleted file mode 100644
index f6a224e..0000000
--- a/apps/relays/lib/urls.ts
+++ /dev/null
@@ -1,8 +0,0 @@
-export function encode(url: string): string {
- url = url.trim();
- return encodeURIComponent(humanize(url));
-}
-
-export function humanize(url: string) {
- return url.replace("ws://", "").replace("wss://", "").replace(/\/$/, "");
-}
diff --git a/apps/relays/tsconfig.json b/apps/relays/tsconfig.json
index 38ebcf9..1cd8a4d 100644
--- a/apps/relays/tsconfig.json
+++ b/apps/relays/tsconfig.json
@@ -16,8 +16,6 @@
"baseUrl": "./",
"paths": {
"@ui/*": ["ui/*"],
- "@hooks/*": ["hooks/*"],
- "@lib/*": ["lib/*"],
}
},
"include": [
diff --git a/packages/core/src/state.ts b/packages/core/src/state.ts
index 7752898..2876604 100644
--- a/packages/core/src/state.ts
+++ b/packages/core/src/state.ts
@@ -18,7 +18,7 @@ export const relaysAtom = atom((get) => {
relayList?.tags
.filter((t) => t[0] === "r")
.map((t) => {
- const url = t[1];
+ const url = t[1].replace(/\/$/, "");
const read = t.length === 2 || t[2] === "read";
const write = t.length === 2 || t[2] === "write";
return { url, read, write };