mirror of
https://github.com/hzrd149/nostrudel.git
synced 2025-04-09 20:29:17 +02:00
cleanup route parsing
This commit is contained in:
parent
e40c2e160d
commit
621b3ac510
@ -187,16 +187,18 @@ export function pointerToATag(pointer: AddressPointer): ATag {
|
||||
return relay ? ["a", coordinate, relay] : ["a", coordinate];
|
||||
}
|
||||
|
||||
export type CustomEventPointer = Omit<AddressPointer, "identifier"> & {
|
||||
export type CustomAddressPointer = Omit<AddressPointer, "identifier"> & {
|
||||
identifier?: string;
|
||||
};
|
||||
|
||||
export function parseCoordinate(a: string): CustomEventPointer | null;
|
||||
export function parseCoordinate(a: string, requireD: false): CustomEventPointer | null;
|
||||
export function parseCoordinate(a: string): CustomAddressPointer | null;
|
||||
export function parseCoordinate(a: string, requireD: false): CustomAddressPointer | null;
|
||||
export function parseCoordinate(a: string, requireD: true): AddressPointer | null;
|
||||
export function parseCoordinate(a: string, requireD: false, silent: false): CustomEventPointer;
|
||||
export function parseCoordinate(a: string, requireD: false, silent: false): CustomAddressPointer;
|
||||
export function parseCoordinate(a: string, requireD: true, silent: false): AddressPointer;
|
||||
export function parseCoordinate(a: string, requireD = false, silent = true): CustomEventPointer | null {
|
||||
export function parseCoordinate(a: string, requireD: true, silent: true): AddressPointer | null;
|
||||
export function parseCoordinate(a: string, requireD: false, silent: true): CustomAddressPointer | null;
|
||||
export function parseCoordinate(a: string, requireD = false, silent = true): CustomAddressPointer | null {
|
||||
const parts = a.split(":") as (string | undefined)[];
|
||||
const kind = parts[0] && parseInt(parts[0]);
|
||||
const pubkey = parts[1];
|
||||
|
33
src/hooks/use-params-address-pointer.ts
Normal file
33
src/hooks/use-params-address-pointer.ts
Normal file
@ -0,0 +1,33 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import type { AddressPointer } from "nostr-tools/lib/types/nip19";
|
||||
|
||||
import { CustomAddressPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
|
||||
export default function useParamsAddressPointer(key: string): AddressPointer;
|
||||
export default function useParamsAddressPointer(key: string, requireD: true): AddressPointer;
|
||||
export default function useParamsAddressPointer(key: string, requireD: false): CustomAddressPointer;
|
||||
export default function useParamsAddressPointer(key: string, requireD: boolean = true): AddressPointer {
|
||||
const params = useParams();
|
||||
const value = params[key] as string;
|
||||
if (!value) throw new Error(`Missing ${key} in route`);
|
||||
|
||||
if (value.includes(":")) {
|
||||
if (requireD) {
|
||||
return parseCoordinate(value, true, false);
|
||||
} else {
|
||||
// @ts-ignore
|
||||
return parseCoordinate(value, false, false);
|
||||
}
|
||||
}
|
||||
|
||||
// its not a coordinate, try to parse the nip19
|
||||
const pointer = nip19.decode(value as string);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "naddr":
|
||||
return pointer.data;
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
23
src/hooks/use-params-event-pointer.ts
Normal file
23
src/hooks/use-params-event-pointer.ts
Normal file
@ -0,0 +1,23 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import type { EventPointer } from "nostr-tools/lib/types/nip19";
|
||||
|
||||
import { isHexKey } from "../helpers/nip19";
|
||||
|
||||
export default function useParamsEventPointer(key: string): EventPointer {
|
||||
const params = useParams();
|
||||
const value = params[key] as string;
|
||||
if (!value) throw new Error(`Missing ${key} in route`);
|
||||
|
||||
if (isHexKey(value)) return { id: value, relays: [] };
|
||||
const pointer = nip19.decode(value as string);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "note":
|
||||
return { id: pointer.data as string, relays: [] };
|
||||
case "nevent":
|
||||
return pointer.data;
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
22
src/hooks/use-params-pubkey-pointer.ts
Normal file
22
src/hooks/use-params-pubkey-pointer.ts
Normal file
@ -0,0 +1,22 @@
|
||||
import { useParams } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import type { ProfilePointer } from "nostr-tools/lib/types/nip19";
|
||||
import { isHexKey } from "../helpers/nip19";
|
||||
|
||||
export default function useParamsProfilePointer(key: string = "pubkey"): ProfilePointer {
|
||||
const params = useParams();
|
||||
const value = params[key] as string;
|
||||
if (!value) throw new Error(`Missing ${key} in route`);
|
||||
|
||||
if (isHexKey(value)) return { pubkey: value, relays: [] };
|
||||
const pointer = nip19.decode(value);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "npub":
|
||||
return { pubkey: pointer.data as string, relays: [] };
|
||||
case "nprofile":
|
||||
return pointer.data;
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
@ -2,11 +2,11 @@ import { useMemo } from "react";
|
||||
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import replaceableEventLoaderService, { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { CustomEventPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import { CustomAddressPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import useSubject from "./use-subject";
|
||||
|
||||
export default function useReplaceableEvent(
|
||||
cord: string | CustomEventPointer | undefined,
|
||||
cord: string | CustomAddressPointer | undefined,
|
||||
additionalRelays: string[] = [],
|
||||
opts: RequestOptions = {},
|
||||
) {
|
||||
|
@ -2,13 +2,13 @@ import { useMemo } from "react";
|
||||
|
||||
import { useReadRelayUrls } from "./use-client-relays";
|
||||
import replaceableEventLoaderService, { RequestOptions } from "../services/replaceable-event-requester";
|
||||
import { CustomEventPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import { CustomAddressPointer, parseCoordinate } from "../helpers/nostr/events";
|
||||
import Subject from "../classes/subject";
|
||||
import { NostrEvent } from "../types/nostr-event";
|
||||
import useSubjects from "./use-subjects";
|
||||
|
||||
export default function useReplaceableEvents(
|
||||
coordinates: string[] | CustomEventPointer[] | undefined,
|
||||
coordinates: string[] | CustomAddressPointer[] | undefined,
|
||||
additionalRelays: string[] = [],
|
||||
opts: RequestOptions = {},
|
||||
) {
|
||||
|
@ -1,5 +1,5 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { Kind, nip19 } from "nostr-tools";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Kind } from "nostr-tools";
|
||||
import {
|
||||
Button,
|
||||
Flex,
|
||||
@ -35,6 +35,7 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import BadgeAwardCard from "./components/badge-award-card";
|
||||
import TimelineLoader from "../../classes/timeline-loader";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
|
||||
|
||||
function BadgeActivityTab({ timeline }: { timeline: TimelineLoader }) {
|
||||
const awards = useSubject(timeline.timeline);
|
||||
@ -154,15 +155,8 @@ function BadgeDetailsPage({ badge }: { badge: NostrEvent }) {
|
||||
);
|
||||
}
|
||||
|
||||
function useBadgeCoordinate() {
|
||||
const { naddr } = useParams() as { naddr: string };
|
||||
const parsed = nip19.decode(naddr);
|
||||
if (parsed.type !== "naddr") throw new Error(`Unknown type ${parsed.type}`);
|
||||
return parsed.data;
|
||||
}
|
||||
|
||||
export default function BadgeDetailsView() {
|
||||
const pointer = useBadgeCoordinate();
|
||||
const pointer = useParamsAddressPointer("naddr");
|
||||
const badge = useReplaceableEvent(pointer);
|
||||
|
||||
if (!badge) return <Spinner />;
|
||||
|
@ -1,9 +1,8 @@
|
||||
import { memo, useCallback, useMemo } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, Flex, Heading, Spacer, Spinner, useDisclosure } from "@chakra-ui/react";
|
||||
import { Kind } from "nostr-tools";
|
||||
|
||||
import { safeDecode } from "../../helpers/nip19";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
@ -25,6 +24,7 @@ import { groupMessages } from "../../helpers/nostr/dms";
|
||||
import ChannelMessageBlock from "./components/channel-message-block";
|
||||
import TimelineActionAndStatus from "../../components/timeline-page/timeline-action-and-status";
|
||||
import ChannelMessageForm from "./components/send-message-form";
|
||||
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
|
||||
|
||||
const ChannelChatLog = memo(({ timeline, channel }: { timeline: TimelineLoader; channel: NostrEvent }) => {
|
||||
const messages = useSubject(timeline.timeline);
|
||||
@ -109,14 +109,8 @@ function ChannelPage({ channel }: { channel: NostrEvent }) {
|
||||
}
|
||||
|
||||
export default function ChannelView() {
|
||||
const { id } = useParams() as { id: string };
|
||||
const parsed = useMemo(() => {
|
||||
const result = safeDecode(id);
|
||||
if (!result) return;
|
||||
if (result.type === "note") return { id: result.data };
|
||||
if (result.type === "nevent") return result.data;
|
||||
}, [id]);
|
||||
const channel = useSingleEvent(parsed?.id, parsed?.relays ?? []);
|
||||
const pointer = useParamsEventPointer("id");
|
||||
const channel = useSingleEvent(pointer?.id, pointer?.relays);
|
||||
|
||||
if (!channel) return <Spinner />;
|
||||
|
||||
|
@ -24,6 +24,7 @@ import ThreadsProvider from "../../providers/thread-provider";
|
||||
import { useRouterMarker } from "../../providers/drawer-sub-view-provider";
|
||||
import TimelineLoader from "../../classes/timeline-loader";
|
||||
import DirectMessageBlock from "./components/direct-message-block";
|
||||
import useParamsProfilePointer from "../../hooks/use-params-pubkey-pointer";
|
||||
|
||||
/** This is broken out from DirectMessageChatPage for performance reasons. Don't use outside of file */
|
||||
const ChatLog = memo(({ timeline }: { timeline: TimelineLoader }) => {
|
||||
@ -142,25 +143,8 @@ function DirectMessageChatPage({ pubkey }: { pubkey: string }) {
|
||||
);
|
||||
}
|
||||
|
||||
function useUserPointer() {
|
||||
const { pubkey } = useParams() as { pubkey: string };
|
||||
|
||||
if (isHexKey(pubkey)) return { pubkey, relays: [] };
|
||||
const pointer = nip19.decode(pubkey);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "npub":
|
||||
return { pubkey: pointer.data as string, relays: [] };
|
||||
case "nprofile":
|
||||
const d = pointer.data as nip19.ProfilePointer;
|
||||
return { pubkey: d.pubkey, relays: d.relays ?? [] };
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default function DirectMessageChatView() {
|
||||
const { pubkey } = useUserPointer();
|
||||
const { pubkey } = useParamsProfilePointer();
|
||||
|
||||
return (
|
||||
<RequireCurrentAccount>
|
||||
|
@ -13,8 +13,8 @@ import {
|
||||
useToast,
|
||||
} from "@chakra-ui/react";
|
||||
import { ChevronLeftIcon } from "@chakra-ui/icons";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import dayjs from "dayjs";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
|
||||
import {
|
||||
DMV_CONTENT_DISCOVERY_JOB_KIND,
|
||||
@ -32,7 +32,6 @@ import useSubject from "../../hooks/use-subject";
|
||||
import useTimelineLoader from "../../hooks/use-timeline-loader";
|
||||
import { useReadRelayUrls } from "../../hooks/use-client-relays";
|
||||
import { useUserRelays } from "../../hooks/use-user-relays";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useSigningContext } from "../../providers/signing-provider";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import RequireCurrentAccount from "../../providers/require-current-account";
|
||||
@ -40,8 +39,8 @@ import { CodeIcon } from "../../components/icons";
|
||||
import { unique } from "../../helpers/array";
|
||||
import DebugChains from "./components/debug-chains";
|
||||
import Feed from "./components/feed";
|
||||
import { parseCoordinate } from "../../helpers/nostr/events";
|
||||
import { AddressPointer } from "nostr-tools/lib/types/nip19";
|
||||
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
|
||||
|
||||
function DVMFeedPage({ pointer }: { pointer: AddressPointer }) {
|
||||
const [since] = useState(() => dayjs().subtract(1, "hour").unix());
|
||||
@ -124,20 +123,8 @@ function DVMFeedPage({ pointer }: { pointer: AddressPointer }) {
|
||||
);
|
||||
}
|
||||
|
||||
function useDVMCoordinate() {
|
||||
const { addr } = useParams() as { addr: string };
|
||||
if (addr.includes(":")) {
|
||||
const parsed = parseCoordinate(addr, true);
|
||||
if (!parsed) throw new Error("Bad coordinate");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const parsed = nip19.decode(addr);
|
||||
if (parsed.type !== "naddr") throw new Error(`Unknown type ${parsed.type}`);
|
||||
return parsed.data;
|
||||
}
|
||||
export default function DVMFeedView() {
|
||||
const pointer = useDVMCoordinate();
|
||||
const pointer = useParamsAddressPointer("addr");
|
||||
|
||||
return (
|
||||
<RequireCurrentAccount>
|
||||
|
@ -1,6 +1,5 @@
|
||||
import { useState } from "react";
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { useForm } from "react-hook-form";
|
||||
import { useThrottle } from "react-use";
|
||||
import dayjs from "dayjs";
|
||||
@ -8,7 +7,6 @@ import dayjs from "dayjs";
|
||||
import {
|
||||
Button,
|
||||
ButtonGroup,
|
||||
Divider,
|
||||
Flex,
|
||||
Heading,
|
||||
Image,
|
||||
@ -39,6 +37,7 @@ import UserAvatarLink from "../../components/user-avatar-link";
|
||||
import NoteZapButton from "../../components/note/note-zap-button";
|
||||
import { QuoteRepostButton } from "../../components/note/components/quote-repost-button";
|
||||
import Timestamp from "../../components/timestamp";
|
||||
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
|
||||
|
||||
function AddEmojiForm({ onAdd }: { onAdd: (values: { name: string; url: string }) => void }) {
|
||||
const { register, handleSubmit, watch, getValues, reset } = useForm({
|
||||
@ -220,15 +219,8 @@ function EmojiPackPage({ pack }: { pack: NostrEvent }) {
|
||||
);
|
||||
}
|
||||
|
||||
function useListCoordinate() {
|
||||
const { addr } = useParams() as { addr: string };
|
||||
const parsed = nip19.decode(addr);
|
||||
if (parsed.type !== "naddr") throw new Error(`Unknown type ${parsed.type}`);
|
||||
return parsed.data;
|
||||
}
|
||||
|
||||
export default function EmojiPackView() {
|
||||
const coordinate = useListCoordinate();
|
||||
const coordinate = useParamsAddressPointer("addr");
|
||||
const pack = useReplaceableEvent(coordinate);
|
||||
|
||||
if (!pack) {
|
||||
|
@ -1,5 +1,4 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { nip19 } from "nostr-tools";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Button, ButtonGroup, Divider, Flex, Heading, Spacer, Spinner } from "@chakra-ui/react";
|
||||
|
||||
import { ChevronLeftIcon } from "../../components/icons";
|
||||
@ -7,8 +6,6 @@ import GoalMenu from "./components/goal-menu";
|
||||
import { getGoalAmount, getGoalName } from "../../helpers/nostr/goal";
|
||||
import GoalProgress from "./components/goal-progress";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import { isHexKey } from "../../helpers/nip19";
|
||||
import { EventPointer } from "nostr-tools/lib/types/nip19";
|
||||
import UserAvatar from "../../components/user-avatar";
|
||||
import UserLink from "../../components/user-link";
|
||||
import GoalContents from "./components/goal-contents";
|
||||
@ -16,19 +13,11 @@ import GoalZapList from "./components/goal-zap-list";
|
||||
import { readablizeSats } from "../../helpers/bolt11";
|
||||
import GoalZapButton from "./components/goal-zap-button";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
|
||||
function useGoalPointerFromParams(): EventPointer {
|
||||
const { id } = useParams() as { id: string };
|
||||
if (isHexKey(id)) return { id };
|
||||
const parsed = nip19.decode(id);
|
||||
if (parsed.type === "nevent") return parsed.data;
|
||||
if (parsed.type === "note") return { id: parsed.data };
|
||||
throw new Error("bad goal id");
|
||||
}
|
||||
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
|
||||
|
||||
export default function GoalDetailsView() {
|
||||
const navigate = useNavigate();
|
||||
const pointer = useGoalPointerFromParams();
|
||||
const pointer = useParamsEventPointer("id");
|
||||
|
||||
const goal = useSingleEvent(pointer.id, pointer.relays);
|
||||
if (!goal) return <Spinner />;
|
||||
|
@ -1,12 +1,12 @@
|
||||
import { useNavigate, useParams } from "react-router-dom";
|
||||
import { useNavigate } from "react-router-dom";
|
||||
import { Kind, nip19 } from "nostr-tools";
|
||||
import type { DecodeResult } from "nostr-tools/lib/types/nip19";
|
||||
import { Box, Button, Flex, Heading, SimpleGrid, Spacer, Text } from "@chakra-ui/react";
|
||||
|
||||
import UserLink from "../../components/user-link";
|
||||
import { Box, Button, Flex, Heading, SimpleGrid, Spacer, Text } from "@chakra-ui/react";
|
||||
import { ChevronLeftIcon } from "../../components/icons";
|
||||
import useCurrentAccount from "../../hooks/use-current-account";
|
||||
import { useDeleteEventContext } from "../../providers/delete-event-provider";
|
||||
import { parseCoordinate } from "../../helpers/nostr/events";
|
||||
import {
|
||||
getEventsFromList,
|
||||
getListDescription,
|
||||
@ -27,23 +27,9 @@ import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { COMMUNITY_DEFINITION_KIND } from "../../helpers/nostr/communities";
|
||||
import { EmbedEvent, EmbedEventPointer } from "../../components/embed-event";
|
||||
import { encodePointer } from "../../helpers/nip19";
|
||||
import { DecodeResult } from "nostr-tools/lib/types/nip19";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import UserAvatarLink from "../../components/user-avatar-link";
|
||||
|
||||
function useListCoordinate() {
|
||||
const { addr } = useParams() as { addr: string };
|
||||
|
||||
if (addr.includes(":")) {
|
||||
const parsed = parseCoordinate(addr);
|
||||
if (!parsed) throw new Error("Bad coordinate");
|
||||
return parsed;
|
||||
}
|
||||
|
||||
const parsed = nip19.decode(addr);
|
||||
if (parsed.type !== "naddr") throw new Error(`Unknown type ${parsed.type}`);
|
||||
return parsed.data;
|
||||
}
|
||||
import useParamsAddressPointer from "../../hooks/use-params-address-pointer";
|
||||
|
||||
function BookmarkedEvent({ id, relays }: { id: string; relays?: string[] }) {
|
||||
const event = useSingleEvent(id, relays);
|
||||
@ -53,16 +39,16 @@ function BookmarkedEvent({ id, relays }: { id: string; relays?: string[] }) {
|
||||
|
||||
export default function ListDetailsView() {
|
||||
const navigate = useNavigate();
|
||||
const coordinate = useListCoordinate();
|
||||
const pointer = useParamsAddressPointer("addr");
|
||||
const { deleteEvent } = useDeleteEventContext();
|
||||
const account = useCurrentAccount();
|
||||
|
||||
const list = useReplaceableEvent(coordinate, [], { alwaysRequest: true });
|
||||
const list = useReplaceableEvent(pointer, [], { alwaysRequest: true });
|
||||
|
||||
if (!list)
|
||||
return (
|
||||
<>
|
||||
Looking for list "{coordinate.identifier}" created by <UserLink pubkey={coordinate.pubkey} />
|
||||
Looking for list "{pointer.identifier}" created by <UserLink pubkey={pointer.pubkey} />
|
||||
</>
|
||||
);
|
||||
|
||||
|
5
src/views/note-transform/index.tsx
Normal file
5
src/views/note-transform/index.tsx
Normal file
@ -0,0 +1,5 @@
|
||||
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
|
||||
|
||||
export default function NoteTransformView() {
|
||||
const pointer = useParamsEventPointer("id");
|
||||
}
|
@ -42,8 +42,6 @@ import StreamSatsPerMinute from "../components/stream-sats-per-minute";
|
||||
import { UserEmojiProvider } from "../../../providers/emoji-provider";
|
||||
import StreamStatusBadge from "../components/status-badge";
|
||||
import ChatMessageForm from "./stream-chat/stream-chat-form";
|
||||
import useStreamChatTimeline from "./stream-chat/use-stream-chat-timeline";
|
||||
import UserSearchDirectoryProvider from "../../../providers/user-directory-provider";
|
||||
import StreamChatLog from "./stream-chat/chat-log";
|
||||
import TopZappers from "../components/top-zappers";
|
||||
import StreamHashtags from "../components/stream-hashtags";
|
||||
|
@ -13,6 +13,7 @@ import IntersectionObserverProvider from "../../providers/intersection-observer"
|
||||
import { useTimelineCurserIntersectionCallback } from "../../hooks/use-timeline-cursor-intersection-callback";
|
||||
import useThreadTimelineLoader from "../../hooks/use-thread-timeline-loader";
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
|
||||
|
||||
function ThreadPage({ thread, rootId, focusId }: { thread: Map<string, ThreadItem>; rootId: string; focusId: string }) {
|
||||
const isRoot = rootId === focusId;
|
||||
@ -61,23 +62,8 @@ function ThreadPage({ thread, rootId, focusId }: { thread: Map<string, ThreadIte
|
||||
);
|
||||
}
|
||||
|
||||
function useNotePointer() {
|
||||
const { id } = useParams() as { id: string };
|
||||
if (isHexKey(id)) return { id, relays: [] };
|
||||
const pointer = nip19.decode(id);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "note":
|
||||
return { id: pointer.data as string, relays: [] };
|
||||
case "nevent":
|
||||
return { id: pointer.data.id, relays: pointer.data.relays ?? [] };
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
export default function ThreadView() {
|
||||
const pointer = useNotePointer();
|
||||
const pointer = useParamsEventPointer("id");
|
||||
const readRelays = useReadRelayUrls(pointer.relays);
|
||||
|
||||
const focusedEvent = useSingleEvent(pointer.id, pointer.relays);
|
||||
|
@ -13,16 +13,13 @@ import {
|
||||
Tbody,
|
||||
Td,
|
||||
Text,
|
||||
Textarea,
|
||||
Th,
|
||||
Thead,
|
||||
Tr,
|
||||
useDisclosure,
|
||||
} from "@chakra-ui/react";
|
||||
import { useParams } from "react-router-dom";
|
||||
|
||||
import useSingleEvent from "../../hooks/use-single-event";
|
||||
import { safeDecode } from "../../helpers/nip19";
|
||||
import VerticalPageLayout from "../../components/vertical-page-layout";
|
||||
import { NostrEvent } from "../../types/nostr-event";
|
||||
import { ErrorBoundary } from "../../components/error-boundary";
|
||||
@ -46,6 +43,7 @@ import TorrentComments from "./components/torrents-comments";
|
||||
import ReplyForm from "../thread/components/reply-form";
|
||||
import { getReferences } from "../../helpers/nostr/events";
|
||||
import MessageTextCircle01 from "../../components/icons/message-text-circle-01";
|
||||
import useParamsEventPointer from "../../hooks/use-params-event-pointer";
|
||||
|
||||
function TorrentDetailsPage({ torrent }: { torrent: NostrEvent }) {
|
||||
const files = getTorrentFiles(torrent);
|
||||
@ -141,14 +139,8 @@ function TorrentDetailsPage({ torrent }: { torrent: NostrEvent }) {
|
||||
}
|
||||
|
||||
export default function TorrentDetailsView() {
|
||||
const { id } = useParams() as { id: string };
|
||||
const parsed = useMemo(() => {
|
||||
const result = safeDecode(id);
|
||||
if (!result) return;
|
||||
if (result.type === "note") return { id: result.data };
|
||||
if (result.type === "nevent") return result.data;
|
||||
}, [id]);
|
||||
const torrent = useSingleEvent(parsed?.id, parsed?.relays ?? []);
|
||||
const pointer = useParamsEventPointer("id");
|
||||
const torrent = useSingleEvent(pointer?.id, pointer?.relays ?? []);
|
||||
|
||||
if (!torrent) return <Spinner />;
|
||||
|
||||
|
@ -46,6 +46,7 @@ import { STEMSTR_TRACK_KIND } from "../../helpers/nostr/stemstr";
|
||||
import { STREAM_KIND } from "../../helpers/nostr/stream";
|
||||
import { TORRENT_KIND } from "../../helpers/nostr/torrents";
|
||||
import { GOAL_KIND } from "../../helpers/nostr/goal";
|
||||
import useParamsProfilePointer from "../../hooks/use-params-pubkey-pointer";
|
||||
|
||||
const tabs = [
|
||||
{ label: "About", path: "about" },
|
||||
@ -66,22 +67,6 @@ const tabs = [
|
||||
{ label: "Muted by", path: "muted-by" },
|
||||
];
|
||||
|
||||
function useUserPointer() {
|
||||
const { pubkey } = useParams() as { pubkey: string };
|
||||
if (isHexKey(pubkey)) return { pubkey, relays: [] };
|
||||
const pointer = nip19.decode(pubkey);
|
||||
|
||||
switch (pointer.type) {
|
||||
case "npub":
|
||||
return { pubkey: pointer.data as string, relays: [] };
|
||||
case "nprofile":
|
||||
const d = pointer.data as nip19.ProfilePointer;
|
||||
return { pubkey: d.pubkey, relays: d.relays ?? [] };
|
||||
default:
|
||||
throw new Error(`Unknown type ${pointer.type}`);
|
||||
}
|
||||
}
|
||||
|
||||
function useUserTopRelays(pubkey: string, count: number = 4) {
|
||||
const readRelays = useReadRelayUrls();
|
||||
// get user relays
|
||||
@ -96,7 +81,7 @@ function useUserTopRelays(pubkey: string, count: number = 4) {
|
||||
}
|
||||
|
||||
const UserView = () => {
|
||||
const { pubkey, relays: pointerRelays } = useUserPointer();
|
||||
const { pubkey, relays: pointerRelays = [] } = useParamsProfilePointer();
|
||||
const navigate = useNavigate();
|
||||
const [relayCount, setRelayCount] = useState(4);
|
||||
const userTopRelays = useUserTopRelays(pubkey, relayCount);
|
||||
|
Loading…
x
Reference in New Issue
Block a user