diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fc3a725cf..4d92f093c 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -92,25 +92,25 @@ importers: version: 4.9.2(prop-types@15.8.1)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) applesauce-channel: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-content: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-core: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-lists: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-net: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-react: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) applesauce-signer: specifier: next - version: 0.0.0-next-20241119142128(typescript@5.6.3) + version: 0.0.0-next-20241119173145(typescript@5.6.3) bech32: specifier: ^2.0.0 version: 2.0.0 @@ -1869,26 +1869,26 @@ packages: resolution: {integrity: sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==} engines: {node: '>=8'} - applesauce-channel@0.0.0-next-20241119142128: - resolution: {integrity: sha512-AynaT+pM9fNBValeuj3ad1/KNEcLyGo2oupnXYvvY1G0cgVSW6L3YAO+p5VA/XCrWGsecnGQksJYVAvLAGqDHQ==} + applesauce-channel@0.0.0-next-20241119173145: + resolution: {integrity: sha512-+2bysV0gNdC2AKrylO+xP8ETp2eGbPbw7lz1kHI2p+fA5OIFn0j+6Ge8wEGv4E9n9eLIxa6welZKqWolCR0xDg==} - applesauce-content@0.0.0-next-20241119142128: - resolution: {integrity: sha512-e6oPmu6fDRFzfra9WpxffytgFE4o5Ot5LgCE8uZNTUZYY3/f05xW4qPJAIuIddP3RK19AvsXsXHDHotQ+KV07g==} + applesauce-content@0.0.0-next-20241119173145: + resolution: {integrity: sha512-JSjnM2rRCEhsDH0PzsfN4iFetOoE1UVY13ug2dsYLYM7K/ZZDgCj1W7wtIFZQKQANrqUs0Cx4zdhTTnSnbdDmQ==} - applesauce-core@0.0.0-next-20241119142128: - resolution: {integrity: sha512-mftudp86ZKQYH+eFThOUj7yt+gFgMlFdLBW7VEHJAnVlXj1FLPQohvf6C0kpFtMNxnAPMlRCPGLUQn5z32VBfA==} + applesauce-core@0.0.0-next-20241119173145: + resolution: {integrity: sha512-Y0w+uc+ByojiyrFgQInY2Klg51sYnTWPXvWRdT7RP1rw4WkOTvLvek1y6VoUmrcZG7Ss0f/eKiQiqhWamNIxDQ==} - applesauce-lists@0.0.0-next-20241119142128: - resolution: {integrity: sha512-QUrorAGEcj7b0jIarVhUWs32VlRc2ovpE6GOxa9rxHln8aRsJ2VEtKKTxc+dpMhnG5hB1v4MT9LXnvSnulw3mA==} + applesauce-lists@0.0.0-next-20241119173145: + resolution: {integrity: sha512-XzJtS5ZNnIE3YUh3eppilyGIpfnE1RqV4VuQqoNGhGYwbbn2b3o8Z0+dKe7+VyGu50HGcCAlhvdTjgV6VgMiXw==} - applesauce-net@0.0.0-next-20241119142128: - resolution: {integrity: sha512-/vsNdP+icA/K4So8ilqh5YMu77bXQ5F4kuV0WZai5BAeIW+sbvPju+7jWUTs/AFSNFDLLL8jzx7FzXe2Ui4tuA==} + applesauce-net@0.0.0-next-20241119173145: + resolution: {integrity: sha512-TUdIY+2Ida1gMg4KTcPoByRdw9uLd3bl8ztyS51adfeKow0Qs7bAhuBLuzLav0sUwG8QzWVGqBHgVOf/KX7uTw==} - applesauce-react@0.0.0-next-20241119142128: - resolution: {integrity: sha512-FJzgri22ZLDHp8imsnvGDKu3k0LhXewolElyCyJZnNP20tlsjHjwGrnScaNTYFtnsbDwRx3UhF9NiYsiWwZS1g==} + applesauce-react@0.0.0-next-20241119173145: + resolution: {integrity: sha512-uMyAPFJVxT8/jPatxw/X/HmVSSXCyXyDg7vXpexr+aejryidIXIUDI2aZnaHgNbknx8QsqeeXP2d5AgvCrDnZA==} - applesauce-signer@0.0.0-next-20241119142128: - resolution: {integrity: sha512-/hL/rSzNR4Y6UQ58/d8MOzOXccwHbR1DIkHOvn+Dir3ZYs5qDXFsSwhC4zNmmHab7Vo7aVgmCpE6TKzY026u6w==} + applesauce-signer@0.0.0-next-20241119173145: + resolution: {integrity: sha512-uLqsdLinVtwaNp1YfNMdK8ohPO/GxLK2F+srWYFUeKFErY08bXp8cbQubuaD9FYVaUOOWERFrqwoGv+FEb5Msw==} argparse@1.0.10: resolution: {integrity: sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==} @@ -3124,8 +3124,8 @@ packages: micromark-util-sanitize-uri@2.0.1: resolution: {integrity: sha512-9N9IomZ/YuGGZZmQec1MbgxtlgougxTodVwDzzEouPKo3qFWvymFHWcnDi2vzV1ff6kas9ucW+o3yzJK9YB1AQ==} - micromark-util-subtokenize@2.0.2: - resolution: {integrity: sha512-xKxhkB62vwHUuuxHe9Xqty3UaAsizV2YKq5OV344u3hFBbf8zIYrhYOWhAQb94MtMPkjTOzzjJ/hid9/dR5vFA==} + micromark-util-subtokenize@2.0.3: + resolution: {integrity: sha512-VXJJuNxYWSoYL6AJ6OQECCFGhIU2GGHMw8tahogePBrjkG8aCCas3ibkp7RnVOSTClg2is05/R7maAhF1XyQMg==} micromark-util-symbol@2.0.1: resolution: {integrity: sha512-vs5t8Apaud9N28kgCrRUdEed4UJ+wWNvicHLPxCa9ENlYuAY31M0ETy5y1vA33YoNPDFTghEbnh6efaE8h4x0Q==} @@ -6158,22 +6158,22 @@ snapshots: dependencies: color-convert: 2.0.1 - applesauce-channel@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-channel@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) nostr-tools: 2.10.3(typescript@5.6.3) rxjs: 7.8.1 transitivePeerDependencies: - supports-color - typescript - applesauce-content@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-content@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: '@cashu/cashu-ts': 2.0.0-rc1 '@types/hast': 3.0.4 '@types/mdast': 4.0.4 '@types/unist': 3.0.3 - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) mdast-util-find-and-replace: 3.0.1 nostr-tools: 2.10.3(typescript@5.6.3) remark: 15.0.1 @@ -6184,7 +6184,7 @@ snapshots: - supports-color - typescript - applesauce-core@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-core@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: debug: 4.3.7 json-stringify-deterministic: 1.0.12 @@ -6196,13 +6196,13 @@ snapshots: - supports-color - typescript - applesauce-lists@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-lists@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: '@noble/hashes': 1.5.0 '@noble/secp256k1': 1.7.1 '@scure/base': 1.1.9 '@types/dom-serial': 1.0.6 - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) debug: 4.3.7 nostr-tools: 2.10.3(typescript@5.6.3) rxjs: 7.8.1 @@ -6210,9 +6210,9 @@ snapshots: - supports-color - typescript - applesauce-net@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-net@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) nanoid: 5.0.8 nostr-tools: 2.10.3(typescript@5.6.3) rxjs: 7.8.1 @@ -6221,10 +6221,10 @@ snapshots: - supports-color - typescript - applesauce-react@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-react@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: - applesauce-content: 0.0.0-next-20241119142128(typescript@5.6.3) - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-content: 0.0.0-next-20241119173145(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) nostr-tools: 2.10.3(typescript@5.6.3) react: 18.3.1 rxjs: 7.8.1 @@ -6232,14 +6232,14 @@ snapshots: - supports-color - typescript - applesauce-signer@0.0.0-next-20241119142128(typescript@5.6.3): + applesauce-signer@0.0.0-next-20241119173145(typescript@5.6.3): dependencies: '@noble/hashes': 1.5.0 '@noble/secp256k1': 1.7.1 '@scure/base': 1.1.9 '@types/dom-serial': 1.0.6 - applesauce-core: 0.0.0-next-20241119142128(typescript@5.6.3) - applesauce-net: 0.0.0-next-20241119142128(typescript@5.6.3) + applesauce-core: 0.0.0-next-20241119173145(typescript@5.6.3) + applesauce-net: 0.0.0-next-20241119173145(typescript@5.6.3) debug: 4.3.7 nanoid: 5.0.8 nostr-tools: 2.10.3(typescript@5.6.3) @@ -7641,7 +7641,7 @@ snapshots: micromark-util-html-tag-name: 2.0.1 micromark-util-normalize-identifier: 2.0.1 micromark-util-resolve-all: 2.0.1 - micromark-util-subtokenize: 2.0.2 + micromark-util-subtokenize: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.1 @@ -7788,7 +7788,7 @@ snapshots: micromark-util-encode: 2.0.1 micromark-util-symbol: 2.0.1 - micromark-util-subtokenize@2.0.2: + micromark-util-subtokenize@2.0.3: dependencies: devlop: 1.1.0 micromark-util-chunked: 2.0.1 @@ -7815,7 +7815,7 @@ snapshots: micromark-util-normalize-identifier: 2.0.1 micromark-util-resolve-all: 2.0.1 micromark-util-sanitize-uri: 2.0.1 - micromark-util-subtokenize: 2.0.2 + micromark-util-subtokenize: 2.0.3 micromark-util-symbol: 2.0.1 micromark-util-types: 2.0.1 transitivePeerDependencies: diff --git a/src/app.tsx b/src/app.tsx index 23f91721e..a0e75f747 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -104,6 +104,7 @@ import PostSettings from "./views/settings/post"; import AccountSettings from "./views/settings/accounts"; import ArticlesHomeView from "./views/articles"; import ArticleView from "./views/articles/article"; +import WalletView from "./views/wallet"; const TracksView = lazy(() => import("./views/tracks")); const UserTracksTab = lazy(() => import("./views/user/tracks")); const UserVideosTab = lazy(() => import("./views/user/videos")); @@ -336,6 +337,19 @@ const router = createHashRouter([ { path: "", element: }, ], }, + { + path: "wallet", + children: [ + { + path: "", + element: ( + + + + ), + }, + ], + }, { path: "videos", children: [ diff --git a/src/components/copy-icon-button.tsx b/src/components/copy-icon-button.tsx index 0481e0166..46d78e0d8 100644 --- a/src/components/copy-icon-button.tsx +++ b/src/components/copy-icon-button.tsx @@ -1,5 +1,5 @@ import { useState } from "react"; -import { IconButton, IconButtonProps, useToast } from "@chakra-ui/react"; +import { Button, ButtonProps, IconButton, IconButtonProps, useToast } from "@chakra-ui/react"; import { CheckIcon, CopyToClipboardIcon } from "./icons"; @@ -8,7 +8,7 @@ type CopyIconButtonProps = Omit & { icon?: IconButtonProps["icon"]; }; -export const CopyIconButton = ({ value, icon, ...props }: CopyIconButtonProps) => { +export function CopyIconButton({ value, icon, ...props }: CopyIconButtonProps) { const toast = useToast(); const [copied, setCopied] = useState(false); @@ -27,4 +27,31 @@ export const CopyIconButton = ({ value, icon, ...props }: CopyIconButtonProps) = {...props} /> ); +} + +type CopyButtonProps = Omit & { + value: string | undefined | (() => string); + icon?: IconButtonProps["icon"]; }; +export function CopyButton({ value, icon, children, ...props }: CopyButtonProps) { + const toast = useToast(); + const [copied, setCopied] = useState(false); + + return ( + + ); +} diff --git a/src/components/debug-modal/event-debug-modal.tsx b/src/components/debug-modal/event-debug-modal.tsx index 35c5f4099..5052345bd 100644 --- a/src/components/debug-modal/event-debug-modal.tsx +++ b/src/components/debug-modal/event-debug-modal.tsx @@ -1,173 +1,102 @@ -import { PropsWithChildren, ReactNode, useCallback, useMemo, useState } from "react"; +import { ComponentType, useState } from "react"; import { Modal, ModalOverlay, ModalContent, ModalBody, ModalCloseButton, - Heading, - AccordionItem, - Accordion, - AccordionPanel, - AccordionIcon, - AccordionButton, - Box, ModalHeader, - Code, - AccordionPanelProps, Button, Text, + ComponentWithAs, + IconProps, + IconButton, + Flex, } from "@chakra-ui/react"; import { nip19 } from "nostr-tools"; -import { Link as RouterLink } from "react-router-dom"; import { ModalProps } from "@chakra-ui/react"; -import { getSeenRelays } from "applesauce-core/helpers"; -import { TextNoteContentSymbol } from "applesauce-content/text"; -import { Root } from "applesauce-content/nast"; -import { getContentPointers, getContentTagRefs, getThreadReferences } from "../../helpers/nostr/event"; import { NostrEvent } from "../../types/nostr-event"; import RawValue from "./raw-value"; -import { CopyIconButton } from "../copy-icon-button"; -import DebugEventTags from "./event-tags"; import { getSharableEventAddress } from "../../services/event-relay-hint"; -import { usePublishEvent } from "../../providers/global/publish-provider"; -import { EditIcon } from "../icons"; -import { RelayFavicon } from "../relay-favicon"; -import { ErrorBoundary } from "../error-boundary"; +import { CodeIcon, RelayIcon, ThreadIcon } from "../icons"; +import RawJsonPage from "./pages/raw"; +import PenTool01 from "../icons/pen-tool-01"; +import DebugContentPage from "./pages/content"; +import DebugThreadingPage from "./pages/threading"; +import Tag01 from "../icons/tag-01"; +import DebugTagsPage from "./pages/tags"; +import DebugEventRelaysPage from "./pages/relays"; +import Database01 from "../icons/database-01"; +import DebugEventCachePage from "./pages/cache"; -function Section({ - label, - children, - actions, - ...props -}: PropsWithChildren<{ label: string; actions?: ReactNode }> & Omit) { - return ( - -

- - - {label} - - {actions &&
e.stopPropagation()}>{actions}
} - -
-

- - {children} - -
- ); -} +type DebugTool = { + id: string; + name: string; + icon: ComponentWithAs<"svg", IconProps>; + component: ComponentType<{ event: NostrEvent }>; +}; -function JsonCode({ data }: { data: any }) { +const tools: DebugTool[] = [ + { id: "content", name: "Content", icon: PenTool01, component: DebugContentPage }, + { id: "json", name: "JSON", icon: CodeIcon, component: RawJsonPage }, + { id: "threading", name: "Threading", icon: ThreadIcon, component: DebugThreadingPage }, + { id: "tags", name: "Tags", icon: Tag01, component: DebugTagsPage }, + { id: "relays", name: "Relays", icon: RelayIcon, component: DebugEventRelaysPage }, + { id: "cache", name: "Cache", icon: Database01, component: DebugEventCachePage }, +]; + +function DefaultPage({ event, setSelected }: { setSelected: (id: string) => void; event: NostrEvent }) { return ( - - {JSON.stringify(data, null, 2)} - + <> + + + + + {tools.map(({ icon: Icon, name, id }) => ( + + ))} + + ); } export default function EventDebugModal({ event, ...props }: { event: NostrEvent } & Omit) { - const contentRefs = useMemo(() => getContentPointers(event.content), [event]); - const publish = usePublishEvent(); - const [loading, setLoading] = useState(false); - const broadcast = useCallback(async () => { - setLoading(true); - await publish("Broadcast", event); - setLoading(false); - }, []); + const [selected, setSelected] = useState(""); - const nast = Reflect.get(event, TextNoteContentSymbol) as Root; + const tool = tools.find((t) => t.id === selected); + const Page = tool?.component; + const IconComponent = tool?.icon; return ( - {event.id} + + {tool && IconComponent && ( + } aria-label="Select Tool" onClick={() => setSelected("")} /> + )} + {tool?.name || event.id} + - - -
- - - -
- -
} - > - - {event.content} - + + {Page ? : } - {contentRefs.length > 0 && ( - <> - - embeds - - {contentRefs.map((pointer, i) => ( - <> - - {pointer.type + "\n"} - {JSON.stringify(pointer.data, null, 2)} - - - ))} - - )} -
-
- - - - } - > - -
-
- -
-
- - - - Tags referenced in content - -
-
- Seen on: - {Array.from(getSeenRelays(event) ?? []).map((url) => ( - - {url} - - ))} - -
- {nast && ( -
- -
- )} -
+ {tool && ( + + )}
diff --git a/src/components/debug-modal/pages/cache.tsx b/src/components/debug-modal/pages/cache.tsx new file mode 100644 index 000000000..9c4bc8113 --- /dev/null +++ b/src/components/debug-modal/pages/cache.tsx @@ -0,0 +1,33 @@ +import { CloseButton, Code, Flex, Text } from "@chakra-ui/react"; +import { NostrEvent } from "nostr-tools"; + +import useEventUpdate from "../../../hooks/use-event-update"; +import { eventStore } from "../../../services/event-store"; + +export default function DebugEventCachePage({ event }: { event: NostrEvent }) { + useEventUpdate(event.id); + const fields = Object.getOwnPropertySymbols(event); + const update = () => eventStore.update(event); + + return ( + + {fields.map((field) => ( + + + {field.description} + + + {JSON.stringify(Reflect.get(event, field))} + + { + Reflect.deleteProperty(event, field); + update(); + }} + /> + + ))} + + ); +} diff --git a/src/components/debug-modal/pages/content.tsx b/src/components/debug-modal/pages/content.tsx new file mode 100644 index 000000000..1ba53766e --- /dev/null +++ b/src/components/debug-modal/pages/content.tsx @@ -0,0 +1,24 @@ +import { Code, Flex } from "@chakra-ui/react"; +import { NostrEvent } from "nostr-tools"; +import { TextNoteContentSymbol } from "applesauce-content/text"; +import { Root } from "applesauce-content/nast"; + +import { CopyButton } from "../../copy-icon-button"; +import RawJson from "../raw-json"; + +export default function DebugContentPage({ event }: { event: NostrEvent }) { + const nast = Reflect.get(event, TextNoteContentSymbol) as Root; + + return ( + + + Copy content + + + {event.content} + + + {nast && } + + ); +} diff --git a/src/components/debug-modal/pages/raw.tsx b/src/components/debug-modal/pages/raw.tsx new file mode 100644 index 000000000..8fca76b1f --- /dev/null +++ b/src/components/debug-modal/pages/raw.tsx @@ -0,0 +1,29 @@ +import { Button, ButtonGroup, Code } from "@chakra-ui/react"; +import { NostrEvent } from "nostr-tools"; +import { Link as RouterLink } from "react-router-dom"; + +import { EditIcon } from "../../icons"; +import { CopyButton } from "../../copy-icon-button"; + +export default function RawJsonPage({ event }: { event: NostrEvent }) { + return ( + <> + + Copy + + + + + {JSON.stringify(event, null, 2)} + + + ); +} diff --git a/src/components/debug-modal/pages/relays.tsx b/src/components/debug-modal/pages/relays.tsx new file mode 100644 index 000000000..3d91bdfa3 --- /dev/null +++ b/src/components/debug-modal/pages/relays.tsx @@ -0,0 +1,31 @@ +import { useCallback, useState } from "react"; +import { NostrEvent } from "nostr-tools"; +import { Button, Text } from "@chakra-ui/react"; +import { getSeenRelays } from "applesauce-core/helpers"; + +import { usePublishEvent } from "../../../providers/global/publish-provider"; +import { RelayFavicon } from "../../relay-favicon"; + +export default function DebugEventRelaysPage({ event }: { event: NostrEvent }) { + const publish = usePublishEvent(); + const [loading, setLoading] = useState(false); + const broadcast = useCallback(async () => { + setLoading(true); + await publish("Broadcast", event); + setLoading(false); + }, []); + + return ( + <> + Seen on: + {Array.from(getSeenRelays(event) ?? []).map((url) => ( + + {url} + + ))} + + + ); +} diff --git a/src/components/debug-modal/pages/tags.tsx b/src/components/debug-modal/pages/tags.tsx new file mode 100644 index 000000000..f7da07cd8 --- /dev/null +++ b/src/components/debug-modal/pages/tags.tsx @@ -0,0 +1,18 @@ +import { Flex } from "@chakra-ui/react"; +import { NostrEvent } from "nostr-tools"; + +import { ErrorBoundary } from "../../error-boundary"; +import DebugEventTags from "../event-tags"; +import RawJson from "../raw-json"; +import { getContentTagRefs } from "../../../helpers/nostr/event"; + +export default function DebugTagsPage({ event }: { event: NostrEvent }) { + return ( + + + + + + + ); +} diff --git a/src/components/debug-modal/pages/threading.tsx b/src/components/debug-modal/pages/threading.tsx new file mode 100644 index 000000000..b65dd62af --- /dev/null +++ b/src/components/debug-modal/pages/threading.tsx @@ -0,0 +1,14 @@ +import { NostrEvent } from "nostr-tools"; +import { getNip10References } from "applesauce-core/helpers"; + +import { getThreadReferences } from "../../../helpers/nostr/event"; +import RawJson from "../raw-json"; + +export default function DebugThreadingPage({ event }: { event: NostrEvent }) { + return ( + <> + + + + ); +} diff --git a/src/components/debug-modal/raw-json.tsx b/src/components/debug-modal/raw-json.tsx index 3e818b1a0..842d54a56 100644 --- a/src/components/debug-modal/raw-json.tsx +++ b/src/components/debug-modal/raw-json.tsx @@ -2,15 +2,13 @@ import { Box, Code, Flex, Heading } from "@chakra-ui/react"; export default function RawJson({ json, heading }: { heading: string; json: any }) { return ( - + {heading} - - - {JSON.stringify(json, null, 2)} - - + + {JSON.stringify(json, null, 2)} + ); } diff --git a/src/components/debug-modal/raw-value.tsx b/src/components/debug-modal/raw-value.tsx index 725071429..35ee34acd 100644 --- a/src/components/debug-modal/raw-value.tsx +++ b/src/components/debug-modal/raw-value.tsx @@ -1,4 +1,4 @@ -import { Box, Code, Flex, Heading } from "@chakra-ui/react"; +import { Box, Code, Heading } from "@chakra-ui/react"; import { CopyIconButton } from "../copy-icon-button"; export default function RawValue({ value, heading }: { heading: string; value?: string | null }) { @@ -7,12 +7,10 @@ export default function RawValue({ value, heading }: { heading: string; value?: {heading} - - - {value} - - - + + + {value} + ); } diff --git a/src/components/layout/nav-items.tsx b/src/components/layout/nav-items.tsx index f891e1aad..9d057c746 100644 --- a/src/components/layout/nav-items.tsx +++ b/src/components/layout/nav-items.tsx @@ -1,3 +1,4 @@ +import { useMemo } from "react"; import { Box, Button, ButtonProps, Icon, Link, Text, others, useDisclosure } from "@chakra-ui/react"; import { Link as RouterLink, useLocation } from "react-router-dom"; import { nip19 } from "nostr-tools"; @@ -26,7 +27,7 @@ import KeyboardShortcut from "../keyboard-shortcut"; import useRecentIds from "../../hooks/use-recent-ids"; import { internalApps, internalTools } from "../../views/other-stuff/apps"; import { App, AppIcon } from "../../views/other-stuff/component/app-card"; -import { useMemo } from "react"; +import Wallet02 from "../icons/wallet-02"; export default function NavItems() { const location = useLocation(); @@ -49,6 +50,7 @@ export default function NavItems() { else if (location.pathname.startsWith("/notifications")) active = "notifications"; else if (location.pathname.startsWith("/launchpad")) active = "launchpad"; else if (location.pathname.startsWith("/discovery")) active = "discovery"; + else if (location.pathname.startsWith("/wallet")) active = "wallet"; else if (location.pathname.startsWith("/dm")) active = "dm"; else if (location.pathname.startsWith("/streams")) active = "streams"; else if (location.pathname.startsWith("/relays")) active = "relays"; @@ -149,6 +151,15 @@ export default function NavItems() { Messages {showShortcuts && } + {/* */} )} + )} + + + ); +} + +export default function WalletView() { + const account = useCurrentAccount()!; + + const readRelays = useReadRelays(); + const { timeline } = useTimelineLoader("wallets", readRelays, { kinds: [37375], authors: [account.pubkey] }); + + return ( + + {timeline.map((wallet) => ( + + ))} + + ); +}