diff --git a/README.md b/README.md index 8fa1df20e..d7a06109d 100644 --- a/README.md +++ b/README.md @@ -1,12 +1,21 @@ -# TODO +# TODO Features -- Adding loading state to `useUserMetadata` so views can show loading state -- Add a debounce to user metadata services so it dose not spam the relay when updating subscription -- user metadata service: remove author from subscription once metadata is returned -- create a stats page showing state of local db and info about app -- create user timeline service that caching events and supports loading older events on request - -## Ideas +## MVP - come up with a clever name +- cache user timelines for performance +- add "Load more" button for user timelines +- build event/thread view +- build relays tab under user +- connect to browser extension for signing +- add simple post form +- add stats page for debugging and cool stats + +## Stage 1 + - build support for DMs +- linkify posts +- detect LN invoices +- detect LNURL +- add user tip button +- create mobile layout diff --git a/index.html b/index.html index bee3e4187..347a9fed8 100644 --- a/index.html +++ b/index.html @@ -3,7 +3,11 @@ - + + personal-nostr-client diff --git a/src/components/icons/global.svg b/src/components/icons/global.svg new file mode 100644 index 000000000..d4af44a75 --- /dev/null +++ b/src/components/icons/global.svg @@ -0,0 +1 @@ + diff --git a/src/components/icons/home.svg b/src/components/icons/home.svg new file mode 100644 index 000000000..f5742ceee --- /dev/null +++ b/src/components/icons/home.svg @@ -0,0 +1 @@ + diff --git a/src/components/icons/settings.svg b/src/components/icons/settings.svg new file mode 100644 index 000000000..542b57478 --- /dev/null +++ b/src/components/icons/settings.svg @@ -0,0 +1 @@ + diff --git a/src/components/page.tsx b/src/components/page.tsx index a041346e2..109e6f73c 100644 --- a/src/components/page.tsx +++ b/src/components/page.tsx @@ -1,28 +1,85 @@ import React from "react"; -import { Box, Button, Container, HStack, VStack } from "@chakra-ui/react"; +import { + Box, + Button, + Container, + Flex, + IconButton, + VStack, +} from "@chakra-ui/react"; import { useNavigate } from "react-router-dom"; import { ErrorBoundary } from "./error-boundary"; import { ConnectedRelays } from "./connected-relays"; -export const Page = ({ children }: { children: React.ReactNode }) => { +import homeIcon from "./icons/home.svg"; +import globalIcon from "./icons/global.svg"; +import settingsIcon from "./icons/settings.svg"; +import { useIsMobile } from "../hooks/use-is-mobile"; + +const MobileLayout = ({ children }: { children: React.ReactNode }) => { const navigate = useNavigate(); return ( - - - - - - - - - - {children} - - - - - + + + {children} + + + } + aria-label="Home" + onClick={() => navigate("/")} + flexGrow="1" + size="lg" + /> + } + aria-label="Global Feed" + onClick={() => navigate("/global")} + flexGrow="1" + size="lg" + /> + } + aria-label="Settings" + onClick={() => navigate("/settings")} + flexGrow="1" + size="lg" + /> + + + ); +}; +const DesktopLayout = ({ children }: { children: React.ReactNode }) => { + const navigate = useNavigate(); + + return ( + + + + + + + + + {children} + + + + ); }; + +export const Page = ({ children }: { children: React.ReactNode }) => { + const isMobile = useIsMobile(); + const Layout = isMobile ? MobileLayout : DesktopLayout; + + return {children}; +}; diff --git a/src/components/post.tsx b/src/components/post.tsx index 495bec17c..4cfa78f60 100644 --- a/src/components/post.tsx +++ b/src/components/post.tsx @@ -5,7 +5,6 @@ import { Card, CardBody, CardHeader, - Code, Flex, Heading, HStack, @@ -35,7 +34,7 @@ export const Post = React.memo(({ event }: PostProps) => { : event.pubkey; return ( - + @@ -50,7 +49,7 @@ export const Post = React.memo(({ event }: PostProps) => { - + @@ -65,7 +64,6 @@ export const Post = React.memo(({ event }: PostProps) => { )} - {event.id} diff --git a/src/hooks/use-is-mobile.ts b/src/hooks/use-is-mobile.ts new file mode 100644 index 000000000..6b30a0712 --- /dev/null +++ b/src/hooks/use-is-mobile.ts @@ -0,0 +1,7 @@ +import { useMediaQuery } from "@chakra-ui/react"; + +export function useIsMobile() { + const [isMobile] = useMediaQuery("(max-width: 1000px)"); + + return isMobile; +} diff --git a/src/services/db/index.ts b/src/services/db/index.ts index 68aebfe90..7d8ca3de0 100644 --- a/src/services/db/index.ts +++ b/src/services/db/index.ts @@ -25,7 +25,15 @@ const MIGRATIONS: MigrationFunction[] = [ // setup data const settings = db.createObjectStore("settings"); - settings.put(["wss://nostr.rdfriedl.com"], "relays"); + settings.put( + [ + "wss://nostr.rdfriedl.com", + "wss://relay.damus.io", + "wss://relay.nostr.info", + "wss://nostr.zebedee.cloud", + ], + "relays" + ); }, ]; diff --git a/src/styles.css b/src/styles.css new file mode 100644 index 000000000..073831cb8 --- /dev/null +++ b/src/styles.css @@ -0,0 +1,8 @@ +html, +body, +#root { + margin: 0; + height: 100%; + width: 100%; + overflow: hidden; +} diff --git a/src/views/global/index.tsx b/src/views/global/index.tsx index da95af1a4..a8a0529e8 100644 --- a/src/views/global/index.tsx +++ b/src/views/global/index.tsx @@ -41,7 +41,7 @@ export const GlobalView = () => { if (timeline.length > 20) timeline.length = 20; return ( - + {timeline.map((event) => ( ))} diff --git a/src/views/user/index.tsx b/src/views/user/index.tsx index 9276706ef..6e0484b8a 100644 --- a/src/views/user/index.tsx +++ b/src/views/user/index.tsx @@ -8,15 +8,16 @@ import { TabPanels, Tabs, Text, - VStack, } from "@chakra-ui/react"; import { useParams } from "react-router-dom"; import { UserPostsTab } from "./posts"; import { useUserMetadata } from "../../hooks/use-user-metadata"; import { UserAvatar } from "../../components/user-avatar"; import { getUserFullName } from "../../helpers/user-metadata"; +import { useIsMobile } from "../../hooks/use-is-mobile"; export const UserView = () => { + const isMobile = useIsMobile(); const { pubkey } = useParams(); if (!pubkey) { // TODO: better 404 @@ -27,24 +28,34 @@ export const UserView = () => { const label = metadata ? getUserFullName(metadata) || pubkey : pubkey; return ( - - {" "} - - - - {label} + + + + + {label} {loadingMetadata ? : {metadata?.about}} - + Posts Other Relays - - + + @@ -55,6 +66,6 @@ export const UserView = () => { - + ); }; diff --git a/src/views/user/posts.tsx b/src/views/user/posts.tsx index 4a1d11283..4a8f6e034 100644 --- a/src/views/user/posts.tsx +++ b/src/views/user/posts.tsx @@ -43,7 +43,7 @@ export const UserPostsTab = ({ pubkey }: { pubkey: string }) => { if (timeline.length > 20) timeline.length = 20; return ( - + {timeline.map((event) => ( ))}