diff --git a/.changeset/chilly-tomatoes-rest.md b/.changeset/chilly-tomatoes-rest.md new file mode 100644 index 000000000..a76517069 --- /dev/null +++ b/.changeset/chilly-tomatoes-rest.md @@ -0,0 +1,5 @@ +--- +"nostrudel": minor +--- + +Remove "open in drawer" for notes diff --git a/src/app.tsx b/src/app.tsx index f77a53036..06d27a774 100644 --- a/src/app.tsx +++ b/src/app.tsx @@ -6,7 +6,6 @@ import GlobalStyles from "./styles"; import { ErrorBoundary } from "./components/error-boundary"; import AppLayout from "./components/layout"; -import DrawerSubViewProvider from "./providers/drawer-sub-view-provider"; import { RouteProviders } from "./providers/route"; import useSetColorMode from "./hooks/use-set-color-mode"; @@ -138,11 +137,9 @@ export const App = () => ( - - }> - - - + }> + + ); diff --git a/src/components/embed-event/event-types/embedded-note.tsx b/src/components/embed-event/event-types/embedded-note.tsx index c31f882d6..c88bce19d 100644 --- a/src/components/embed-event/event-types/embedded-note.tsx +++ b/src/components/embed-event/event-types/embedded-note.tsx @@ -1,7 +1,6 @@ import { MouseEventHandler, useCallback } from "react"; import { Card, CardProps, Flex, LinkBox, Spacer } from "@chakra-ui/react"; import { Link as RouterLink, useNavigate } from "react-router"; -import { useObservable } from "applesauce-react/hooks"; import { NostrEvent } from "../../../types/nostr-event"; import UserAvatarLink from "../../user/user-avatar-link"; @@ -11,16 +10,13 @@ import { TrustProvider } from "../../../providers/local/trust-provider"; import { NoteLink } from "../../note/note-link"; import Timestamp from "../../timestamp"; import { CompactNoteContent } from "../../compact-note-content"; -import { useNavigateInDrawer } from "../../../providers/drawer-sub-view-provider"; import HoverLinkOverlay from "../../hover-link-overlay"; import { getSharableEventAddress } from "../../../services/relay-hints"; -import localSettings from "../../../services/local-settings"; import useAppSettings from "../../../hooks/use-user-app-settings"; export default function EmbeddedNote({ event, ...props }: Omit & { event: NostrEvent }) { const { showSignatureVerification } = useAppSettings(); - const enableDrawer = useObservable(localSettings.enableNoteThreadDrawer); - const navigate = enableDrawer ? useNavigateInDrawer() : useNavigate(); + const navigate = useNavigate(); const to = `/n/${getSharableEventAddress(event)}`; const handleClick = useCallback( diff --git a/src/components/embed-event/event-types/embedded-torrent-comment.tsx b/src/components/embed-event/event-types/embedded-torrent-comment.tsx index 9d6d3b269..3f5a23255 100644 --- a/src/components/embed-event/event-types/embedded-torrent-comment.tsx +++ b/src/components/embed-event/event-types/embedded-torrent-comment.tsx @@ -1,5 +1,6 @@ import { Card, CardProps, Flex, LinkBox, Spacer, Text } from "@chakra-ui/react"; -import { Link as RouterLink } from "react-router"; +import { Link as RouterLink, useNavigate } from "react-router"; +import { nip19 } from "nostr-tools"; import { NostrEvent } from "../../../types/nostr-event"; import UserAvatarLink from "../../user/user-avatar-link"; @@ -12,16 +13,14 @@ import HoverLinkOverlay from "../../hover-link-overlay"; import { getThreadReferences } from "../../../helpers/nostr/event"; import useSingleEvent from "../../../hooks/use-single-event"; import { getTorrentTitle } from "../../../helpers/nostr/torrents"; -import { useNavigateInDrawer } from "../../../providers/drawer-sub-view-provider"; import { MouseEventHandler, useCallback } from "react"; -import { nip19 } from "nostr-tools"; import useAppSettings from "../../../hooks/use-user-app-settings"; export default function EmbeddedTorrentComment({ comment, ...props }: Omit & { comment: NostrEvent }) { - const navigate = useNavigateInDrawer(); + const navigate = useNavigate(); const { showSignatureVerification } = useAppSettings(); const refs = getThreadReferences(comment); const torrent = useSingleEvent(refs.root?.e?.id, refs.root?.e?.relays); diff --git a/src/components/embed-event/event-types/embedded-torrent.tsx b/src/components/embed-event/event-types/embedded-torrent.tsx index ba8bea41a..7293352c5 100644 --- a/src/components/embed-event/event-types/embedded-torrent.tsx +++ b/src/components/embed-event/event-types/embedded-torrent.tsx @@ -24,14 +24,12 @@ import Timestamp from "../../timestamp"; import Magnet from "../../icons/magnet"; import { getTorrentMagnetLink, getTorrentSize, getTorrentTitle } from "../../../helpers/nostr/torrents"; import { formatBytes } from "../../../helpers/number"; -import { useNavigateInDrawer } from "../../../providers/drawer-sub-view-provider"; import HoverLinkOverlay from "../../hover-link-overlay"; import { getSharableEventAddress } from "../../../services/relay-hints"; import localSettings from "../../../services/local-settings"; export default function EmbeddedTorrent({ torrent, ...props }: Omit & { torrent: NostrEvent }) { - const enableDrawer = useObservable(localSettings.enableNoteThreadDrawer); - const navigate = enableDrawer ? useNavigateInDrawer() : useNavigate(); + const navigate = useNavigate(); const link = `/torrents/${getSharableEventAddress(torrent)}`; const handleClick = useCallback( diff --git a/src/components/layout/mobile/drawer-nav.tsx b/src/components/layout/mobile/drawer-nav.tsx deleted file mode 100644 index 59415e15a..000000000 --- a/src/components/layout/mobile/drawer-nav.tsx +++ /dev/null @@ -1,91 +0,0 @@ -import { - Box, - Button, - Center, - Drawer, - DrawerBody, - DrawerContent, - DrawerHeader, - DrawerOverlay, - Flex, - ModalProps, - Spacer, - Text, -} from "@chakra-ui/react"; -import { Link as RouterLink } from "react-router"; -import { IconButton } from "@chakra-ui/react"; -import { useObservable } from "applesauce-react/hooks"; - -import { UserAvatar } from "../../user/user-avatar"; -import useCurrentAccount from "../../../hooks/use-current-account"; -import UserName from "../../user/user-name"; -import UserDnsIdentity from "../../user/user-dns-identity"; -import { DirectMessagesIcon, RelayIcon, SearchIcon, SettingsIcon } from "../../icons"; -import { bakery$ } from "../../../services/bakery"; - -export default function DrawerNav({ isOpen, onClose, ...props }: Omit) { - const account = useCurrentAccount(); - const bakery = useObservable(bakery$); - - return ( - - - - - {account ? ( - <> - - - - - - - - } - to="/settings" - /> - {/* */} - - ) : ( - - )} - - - -
- -
- Search -
- -
- -
- Messages -
- -
- -
- My Network -
- - {bakery && ( - - )} -
-
-
- ); -} diff --git a/src/components/note/open-in-drawer-button.tsx b/src/components/note/open-in-drawer-button.tsx deleted file mode 100644 index 4aae7c32c..000000000 --- a/src/components/note/open-in-drawer-button.tsx +++ /dev/null @@ -1,32 +0,0 @@ -import { MouseEventHandler, useCallback } from "react"; -import { IconButton, IconButtonProps } from "@chakra-ui/react"; -import { To } from "react-router"; - -import { DrawerIcon } from "../icons"; -import { useNavigateInDrawer } from "../../providers/drawer-sub-view-provider"; - -export default function OpenInDrawerButton({ - to, - onClick, - ...props -}: Omit & { to: To }) { - const navigate = useNavigateInDrawer(); - - const handleClick = useCallback>( - (e) => { - navigate(to); - if (onClick) onClick(e); - }, - [navigate, onClick], - ); - - return ( - } - aria-label="Open in drawer" - title="Open in drawer" - onClick={handleClick} - {...props} - /> - ); -} diff --git a/src/components/note/timeline-note/index.tsx b/src/components/note/timeline-note/index.tsx index 3a126a398..d9a969f64 100644 --- a/src/components/note/timeline-note/index.tsx +++ b/src/components/note/timeline-note/index.tsx @@ -34,7 +34,6 @@ import NoteReactions from "./components/note-reactions"; import ReplyForm from "../../../views/thread/components/reply-form"; import { getThreadReferences } from "../../../helpers/nostr/event"; import Timestamp from "../../timestamp"; -import OpenInDrawerButton from "../open-in-drawer-button"; import { useBreakpointValue } from "../../../providers/global/breakpoint-provider"; import HoverLinkOverlay from "../../hover-link-overlay"; import NoteCommunityMetadata from "./note-community-metadata"; @@ -100,9 +99,6 @@ export function TimelineNote({ {showSignatureVerification && } - {!hideDrawerButton && ( - - )} {showReplyLine && } diff --git a/src/providers/drawer-sub-view-provider.tsx b/src/providers/drawer-sub-view-provider.tsx deleted file mode 100644 index 211d0406f..000000000 --- a/src/providers/drawer-sub-view-provider.tsx +++ /dev/null @@ -1,222 +0,0 @@ -import { - PropsWithChildren, - Suspense, - createContext, - lazy, - useCallback, - useContext, - useEffect, - useMemo, - useRef, - useState, -} from "react"; -import { - ButtonGroup, - Drawer, - DrawerBody, - DrawerCloseButton, - DrawerContent, - DrawerHeader, - DrawerOverlay, - DrawerProps, - Heading, - IconButton, - Spinner, -} from "@chakra-ui/react"; -import { Location, RouteObject, RouterProvider, To, createMemoryRouter, useNavigate } from "react-router"; - -import { ErrorBoundary } from "../components/error-boundary"; -import ThreadView from "../views/thread"; -import { ChevronLeftIcon, ChevronRightIcon, ExternalLinkIcon } from "../components/icons"; -import { logger } from "../helpers/debug"; -import { RouteProviders } from "./route"; -import useRouterMarker from "../hooks/use-router-marker"; - -const TorrentDetailsView = lazy(() => import("../views/torrents/torrent")); - -type Router = ReturnType; - -const IsInDrawerContext = createContext(false); -const DrawerSubViewContext = createContext<{ openDrawer: (route: To) => void; closeDrawer: () => void }>({ - openDrawer() {}, - closeDrawer() {}, -}); - -function DrawerSubView({ - router, - openInParent, - ...props -}: Omit & { router: Router; openInParent: (to: To) => void }) { - const [title, setTitle] = useState(""); - - return ( - - - - - - - } aria-label="Back" onClick={() => router.navigate(-1)} /> - } aria-label="Forward" onClick={() => router.navigate(+1)} /> - } - aria-label="Open" - onClick={() => openInParent(router.state.location)} - /> - - {title} - - - - - - Loading page - - } - > - - - - - - - - ); -} - -const routes: RouteObject[] = [ - { - path: "/n/:id", - element: ( - - - - ), - }, - { - path: "/torrents/:id", - element: ( - - - - ), - }, -]; - -export function useDrawerSubView() { - return useContext(DrawerSubViewContext); -} - -export function useNavigateInDrawer() { - const navigate = useNavigate(); - const isInDrawer = useContext(IsInDrawerContext); - const { openDrawer } = useDrawerSubView(); - - return isInDrawer ? navigate : openDrawer; -} - -const log = logger.extend("DrawerRouter"); - -export default function DrawerSubViewProvider({ - children, - parentRouter, -}: PropsWithChildren & { parentRouter: Router }) { - const [router, setRouter] = useState(null); - - const openInParent = useCallback((to: To) => parentRouter.navigate(to), [parentRouter]); - - const direction = useRef<"up" | "down">(); - const marker = useRouterMarker(parentRouter); - - useEffect(() => { - return parentRouter.subscribe((event) => { - const location = event.location as Location<{ subRouterPath?: To | null } | null>; - const subRoute = location.state?.subRouterPath; - - if (subRoute) { - if (router) { - if (router.state.location.pathname !== subRoute && direction.current !== "up") { - log("Updating router from parent state"); - direction.current = "down"; - router.navigate(subRoute); - direction.current = undefined; - } - } else { - log("Create Router"); - - const newRouter = createMemoryRouter(routes, { initialEntries: [subRoute] }); - newRouter.subscribe((e) => { - if ( - e.errors && - e.errors["__shim-error-route__"].status === 404 && - e.errors["__shim-error-route__"].internal - ) { - openInParent(e.location); - } else if (direction.current !== "down") { - log("Updating parent state from Router"); - direction.current = "up"; - parentRouter.navigate(parentRouter.state.location, { - preventScrollReset: true, - state: { ...parentRouter.state.location.state, subRouterPath: e.location.pathname }, - }); - } - direction.current = undefined; - }); - - // use the parent routers createHref method so that users can open links in new tabs - newRouter.createHref = parentRouter.createHref; - - setRouter(newRouter); - } - } else if (router) { - log("Destroy Router"); - setRouter(null); - } - }); - }, [parentRouter, router, setRouter]); - - const openDrawer = useCallback( - (to: To) => { - marker.set(); - parentRouter.navigate(parentRouter.state.location, { - preventScrollReset: true, - state: { ...parentRouter.state.location.state, subRouterPath: to }, - }); - }, - [parentRouter], - ); - - const closeDrawer = useCallback(() => { - const i = marker.index.current; - if (i !== null && i > 0) { - log(`Navigating back ${i} entries to the point the drawer was opened`); - parentRouter.navigate(-i); - } else { - log(`Failed to navigate back, clearing state`); - parentRouter.navigate(parentRouter.state.location, { - preventScrollReset: true, - state: { ...parentRouter.state.location.state, subRouterPath: undefined }, - }); - } - - // reset marker - marker.reset(); - }, [parentRouter]); - - const context = useMemo( - () => ({ - openDrawer, - closeDrawer, - }), - [openDrawer, closeDrawer], - ); - - return ( - - {children} - {router && } - - ); -} diff --git a/src/services/local-settings.ts b/src/services/local-settings.ts index e108fd70d..3a219e37a 100644 --- a/src/services/local-settings.ts +++ b/src/services/local-settings.ts @@ -14,14 +14,6 @@ import { nanoid } from "nanoid"; const idbMaxEvents = new NumberLocalStorageEntry("nostr-idb-max-events", 10_000); const wasmPersistForDays = new NullableNumberLocalStorageEntry("wasm-relay-oldest-event", 365); -// note behavior -const enableNoteThreadDrawer = new LocalStorageEntry( - "enable-note-thread-drawer", - false, - (raw) => raw === "true", - (v) => String(v), -); - const hideZapBubbles = new BooleanLocalStorageEntry("hide-zap-bubbles", false); // webrtc relay @@ -72,7 +64,6 @@ const bakeryURL = new LocalStorageEntry("bakery-url", ""); const localSettings = { idbMaxEvents, wasmPersistForDays, - enableNoteThreadDrawer, hideZapBubbles, webRtcLocalIdentity, webRtcSignalingRelays, diff --git a/src/views/notifications/threads.tsx b/src/views/notifications/threads.tsx index 58dc2efb7..713a93312 100644 --- a/src/views/notifications/threads.tsx +++ b/src/views/notifications/threads.tsx @@ -1,4 +1,5 @@ import { MouseEventHandler, useCallback, useMemo } from "react"; +import { AvatarGroup, Box, Button, ButtonGroup, Flex, LinkBox, Text, useDisclosure } from "@chakra-ui/react"; import { kinds, NostrEvent } from "nostr-tools"; import { useObservable } from "applesauce-react/hooks"; import { Link as RouterLink, useNavigate } from "react-router"; @@ -12,7 +13,6 @@ import { useNotifications } from "../../providers/global/notifications-provider" import { TORRENT_COMMENT_KIND } from "../../helpers/nostr/torrents"; import { groupByRoot } from "../../helpers/notification"; import { ChevronLeftIcon } from "../../components/icons"; -import { AvatarGroup, Box, Button, ButtonGroup, Flex, LinkBox, Text, useDisclosure } from "@chakra-ui/react"; import UserAvatarLink from "../../components/user/user-avatar-link"; import useSingleEvent from "../../hooks/use-single-event"; import UserLink from "../../components/user/user-link"; @@ -21,7 +21,6 @@ import Timestamp from "../../components/timestamp"; import HoverLinkOverlay from "../../components/hover-link-overlay"; import PeopleListSelection from "../../components/people-list-selection/people-list-selection"; import IntersectionObserverProvider from "../../providers/local/intersection-observer"; -import { useNavigateInDrawer } from "../../providers/drawer-sub-view-provider"; import useEventIntersectionRef from "../../hooks/use-event-intersection-ref"; import useShareableEventAddress from "../../hooks/use-shareable-event-address"; import localSettings from "../../services/local-settings"; @@ -30,8 +29,7 @@ import GitBranch01 from "../../components/icons/git-branch-01"; const THREAD_KINDS = [kinds.ShortTextNote, TORRENT_COMMENT_KIND]; function ReplyEntry({ event }: { event: NostrEvent }) { - const enableDrawer = useObservable(localSettings.enableNoteThreadDrawer); - const navigate = enableDrawer ? useNavigateInDrawer() : useNavigate(); + const navigate = useNavigate(); const address = useShareableEventAddress(event); const onClick = useCallback( (e) => { diff --git a/src/views/settings/display/index.tsx b/src/views/settings/display/index.tsx index b04248db1..bfdb2bdd7 100644 --- a/src/views/settings/display/index.tsx +++ b/src/views/settings/display/index.tsx @@ -21,7 +21,6 @@ export default function DisplaySettings() { const { register, submit, formState } = useSettingsForm(); const hideZapBubbles = useObservable(localSettings.hideZapBubbles); - const enableNoteDrawer = useObservable(localSettings.enableNoteThreadDrawer); return ( Enabled: shows a warning for notes with NIP-36 Content Warning - - - - Open embedded notes in side drawer - - localSettings.enableNoteThreadDrawer.next(!localSettings.enableNoteThreadDrawer.value)} - /> - - - Enabled: Clicking on an embedded note will open it in a side drawer - - Muted words