From f186c2a514e853dec101c7c96788d8d5db333185 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruce=20R=C3=B6ttgers?= Date: Mon, 20 Oct 2025 19:33:15 +0200 Subject: [PATCH 1/4] fullscreen mode as own screen, still some bugs --- .../explore/page/[pageId]/_layout-base.tsx | 35 ++++++ .../main/explore/page/[pageId]/_main-base.tsx | 38 ++++++ .../explore/page/[pageId]/_page-root-view.tsx | 14 +-- .../explore/page/[pageId]/_section-base.tsx | 114 ++++++++++++++++++ .../page/[pageId]/fullscreen/_layout.tsx | 4 + .../page/[pageId]/fullscreen/index.tsx | 2 + .../[pageId]/fullscreen/section/[title].tsx | 3 + app/app/main/explore/page/[pageId]/index.tsx | 30 ----- .../page/[pageId]/{ => map}/_layout.tsx | 34 +----- .../main/explore/page/[pageId]/map/index.tsx | 3 + .../page/[pageId]/map/section/[title].tsx | 3 + .../explore/page/[pageId]/section/[title].tsx | 114 ------------------ app/components/place-card.tsx | 4 +- app/hooks/use-is-fullscreen.tsx | 19 --- app/hooks/use-move-to.ts | 1 - 15 files changed, 215 insertions(+), 203 deletions(-) create mode 100644 app/app/main/explore/page/[pageId]/_layout-base.tsx create mode 100644 app/app/main/explore/page/[pageId]/_main-base.tsx create mode 100644 app/app/main/explore/page/[pageId]/_section-base.tsx create mode 100644 app/app/main/explore/page/[pageId]/fullscreen/_layout.tsx create mode 100644 app/app/main/explore/page/[pageId]/fullscreen/index.tsx create mode 100644 app/app/main/explore/page/[pageId]/fullscreen/section/[title].tsx delete mode 100644 app/app/main/explore/page/[pageId]/index.tsx rename app/app/main/explore/page/[pageId]/{ => map}/_layout.tsx (88%) create mode 100644 app/app/main/explore/page/[pageId]/map/index.tsx create mode 100644 app/app/main/explore/page/[pageId]/map/section/[title].tsx delete mode 100644 app/app/main/explore/page/[pageId]/section/[title].tsx delete mode 100644 app/hooks/use-is-fullscreen.tsx diff --git a/app/app/main/explore/page/[pageId]/_layout-base.tsx b/app/app/main/explore/page/[pageId]/_layout-base.tsx new file mode 100644 index 0000000..72d49fd --- /dev/null +++ b/app/app/main/explore/page/[pageId]/_layout-base.tsx @@ -0,0 +1,35 @@ +import { ScrollRefProvider } from "@/hooks/use-scroll-ref"; +import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons"; +import { Link, Stack } from "expo-router"; +import { ComponentType, ReactNode } from "react"; + +export function withFullscreenLayout( + LayoutComp: ComponentType<{ children: ReactNode }>, + isFullscreen: boolean, +) { + function RootLayout() { + const stack = ( + ( + + + + ), + }} + /> + ); + + return ( + + {stack} + + ); + } + + return RootLayout; +} diff --git a/app/app/main/explore/page/[pageId]/_main-base.tsx b/app/app/main/explore/page/[pageId]/_main-base.tsx new file mode 100644 index 0000000..6788a13 --- /dev/null +++ b/app/app/main/explore/page/[pageId]/_main-base.tsx @@ -0,0 +1,38 @@ +import useMoveTo from "@/hooks/use-move-to"; +import useWikiQuery from "@/hooks/use-wiki-query"; +import { useLocalSearchParams } from "expo-router"; +import { useEffect } from "react"; +import PageRootView from "./_page-root-view"; +import { usePushCityVisit } from "@/hooks/visited-cities"; + +export function generatePage(isFullscreen: boolean) { + return function Page() { + let { pageId } = useLocalSearchParams(); + pageId = typeof pageId === "string" ? pageId : pageId[0]; + const pageQuery = useWikiQuery(pageId); + const moveTo = useMoveTo(); + + useEffect(() => { + if (pageQuery.data) { + moveTo( + // @ts-ignore NEEDS FIXING WHEN GEO REVISED + parseFloat(pageQuery.data.properties.geo["2"]), + // @ts-ignore NEEDS FIXING WHEN GEO REVISED + parseFloat(pageQuery.data.properties.geo["1"]), + // @ts-ignore NEEDS FIXING WHEN GEO REVISED + parseFloat(pageQuery.data.properties.geo?.zoom ?? "13"), + ); + } + }, [pageQuery.data, moveTo]); + + usePushCityVisit({ id: pageId, title: pageQuery.data?.properties.title }); + + return ( + + ); + }; +} diff --git a/app/app/main/explore/page/[pageId]/_page-root-view.tsx b/app/app/main/explore/page/[pageId]/_page-root-view.tsx index ae5b057..3cb0129 100644 --- a/app/app/main/explore/page/[pageId]/_page-root-view.tsx +++ b/app/app/main/explore/page/[pageId]/_page-root-view.tsx @@ -1,4 +1,3 @@ -import { useIsFullscreen } from "@/hooks/use-is-fullscreen"; import { getCityAtom } from "@/utils/bookmarks"; import { MapMarker, MarkerType, useMapStore } from "@/utils/store"; import { NodeType, RootNode } from "@bcye/structured-wikivoyage-types"; @@ -15,7 +14,7 @@ function PageContent({ pageQuery, id, }: { - pageQuery: UseQueryResult; + pageQuery: UseQdefaultueryResult; id: string; }) { const bookmarks = useAtomValue(getCityAtom(id)); @@ -30,7 +29,8 @@ function PageContent({ const marker: MapMarker = { id: bId, // somehow broken else - link: `/main/explore/page/${id}/section/${bookmark.section}` as Route, + // if this is fullscreen, the markers are not gonna be available anywhere so it is safe to hardcode this to map view. + link: `/main/explore/page/${id}/map/section/${bookmark.section}` as Route, lat, long, type: MarkerType.Bookmark, @@ -71,12 +71,12 @@ function PageContent({ export default function PageRootView({ pageQuery, id, + isFullscreen, }: { pageQuery: UseQueryResult; id: string | null; + isFullscreen: boolean; }) { - const isFullscreen = useIsFullscreen(); - return ( diff --git a/app/app/main/explore/page/[pageId]/_section-base.tsx b/app/app/main/explore/page/[pageId]/_section-base.tsx new file mode 100644 index 0000000..0b17e26 --- /dev/null +++ b/app/app/main/explore/page/[pageId]/_section-base.tsx @@ -0,0 +1,114 @@ +import WikiContent from "@/components/render-node"; +import { useScrollRef } from "@/hooks/use-scroll-ref"; +import useWikiQuery from "@/hooks/use-wiki-query"; +import { citiesAtom, getCityAtom } from "@/utils/bookmarks"; +import { NodeType, SectionNode } from "@bcye/structured-wikivoyage-types"; +import { BottomSheetScrollView } from "@gorhom/bottom-sheet"; +import { Stack, useLocalSearchParams } from "expo-router"; +import { useAtom } from "jotai/react"; +import { append, assoc, dissoc } from "ramda"; +import { useCallback } from "react"; +import { ScrollView } from "react-native"; +import { SkeletonView, View } from "react-native-ui-lib"; +import { toast } from "sonner-native"; + +export function generateSection(isFullscreen: boolean) { + /** + * Renders a specific section of a Wikipedia page in Markdown format. + * + * The component retrieves the page title and ID from local search parameters, fetches the page's wikitext + * via a TRPC query, and then extracts and converts the designated section—identified by the title—to Markdown. + * It slices off the section header from the converted Markdown and displays a skeleton view while the content loads. + */ + return function Section() { + const { title, pageId } = useLocalSearchParams(); + const wikiQuery = useWikiQuery(pageId as string); + const section = wikiQuery.data?.children.find( + (c) => c.type === NodeType.Section && c.properties.title === title, + ) as SectionNode | undefined; + const ref = useScrollRef(); + const [bookmarks, setBookmarks] = useAtom(getCityAtom(pageId as string)); + const [cities, setCities] = useAtom(citiesAtom); + const pageTitle = wikiQuery.data?.properties.title; + + const isBookmarked = useCallback( + function isBookmarked(id: string) { + return !!bookmarks[id]; + }, + [bookmarks], + ); + + const toggleBookmarked = useCallback( + function toggleBookmarked(id: string) { + if (id == ",") { + toast.error( + "This listing doesn't have a location and can't be bookmarked. Add one on en.wikivoyage.org", + ); + return; + } + + if (isBookmarked(id)) { + setBookmarks(dissoc(id, bookmarks)); + } else { + if (!cities.find((c) => c.qid === pageId)) { + setCities( + append({ qid: pageId as string, name: pageTitle! }, cities), + ); + } + // no valid lat-lng + setBookmarks( + assoc( + id, + { section: title, properties: section!.properties }, + bookmarks, + ), + ); + } + }, + [ + bookmarks, + setBookmarks, + section, + isBookmarked, + pageTitle, + cities, + setCities, + pageId, + title, + ], + ); + + if (!section) return null; + + return ( + + + + !isFullscreen ? ( + + + + ) : ( + + + + ) + } + /> + + ); + }; +} diff --git a/app/app/main/explore/page/[pageId]/fullscreen/_layout.tsx b/app/app/main/explore/page/[pageId]/fullscreen/_layout.tsx new file mode 100644 index 0000000..27304f9 --- /dev/null +++ b/app/app/main/explore/page/[pageId]/fullscreen/_layout.tsx @@ -0,0 +1,4 @@ +import { Fragment } from "react"; +import { withFullscreenLayout } from "../_layout-base"; + +export default withFullscreenLayout(Fragment, true); diff --git a/app/app/main/explore/page/[pageId]/fullscreen/index.tsx b/app/app/main/explore/page/[pageId]/fullscreen/index.tsx new file mode 100644 index 0000000..bdb3aeb --- /dev/null +++ b/app/app/main/explore/page/[pageId]/fullscreen/index.tsx @@ -0,0 +1,2 @@ +import { generatePage } from "../_main-base"; +export default generatePage(true); diff --git a/app/app/main/explore/page/[pageId]/fullscreen/section/[title].tsx b/app/app/main/explore/page/[pageId]/fullscreen/section/[title].tsx new file mode 100644 index 0000000..91621de --- /dev/null +++ b/app/app/main/explore/page/[pageId]/fullscreen/section/[title].tsx @@ -0,0 +1,3 @@ +import { generateSection } from "../../_section-base"; + +export default generateSection(true); diff --git a/app/app/main/explore/page/[pageId]/index.tsx b/app/app/main/explore/page/[pageId]/index.tsx deleted file mode 100644 index af87250..0000000 --- a/app/app/main/explore/page/[pageId]/index.tsx +++ /dev/null @@ -1,30 +0,0 @@ -import useMoveTo from "@/hooks/use-move-to"; -import useWikiQuery from "@/hooks/use-wiki-query"; -import { useLocalSearchParams } from "expo-router"; -import { useEffect } from "react"; -import PageRootView from "./_page-root-view"; -import { usePushCityVisit } from "@/hooks/visited-cities"; - -export default function Page() { - let { pageId } = useLocalSearchParams(); - pageId = typeof pageId === "string" ? pageId : pageId[0]; - const pageQuery = useWikiQuery(pageId); - const moveTo = useMoveTo(); - - useEffect(() => { - if (pageQuery.data) { - moveTo( - // @ts-ignore NEEDS FIXING WHEN GEO REVISED - parseFloat(pageQuery.data.properties.geo["2"]), - // @ts-ignore NEEDS FIXING WHEN GEO REVISED - parseFloat(pageQuery.data.properties.geo["1"]), - // @ts-ignore NEEDS FIXING WHEN GEO REVISED - parseFloat(pageQuery.data.properties.geo?.zoom ?? "13"), - ); - } - }, [pageQuery.data, moveTo]); - - usePushCityVisit({ id: pageId, title: pageQuery.data?.properties.title }); - - return ; -} diff --git a/app/app/main/explore/page/[pageId]/_layout.tsx b/app/app/main/explore/page/[pageId]/map/_layout.tsx similarity index 88% rename from app/app/main/explore/page/[pageId]/_layout.tsx rename to app/app/main/explore/page/[pageId]/map/_layout.tsx index eb5258e..9546cc3 100644 --- a/app/app/main/explore/page/[pageId]/_layout.tsx +++ b/app/app/main/explore/page/[pageId]/map/_layout.tsx @@ -1,6 +1,5 @@ -import { FullScreenProvider } from "@/hooks/use-is-fullscreen"; import useMoveTo, { CameraRefContext } from "@/hooks/use-move-to"; -import { ScrollRefProvider, useBottomSheetRef } from "@/hooks/use-scroll-ref"; +import { useBottomSheetRef } from "@/hooks/use-scroll-ref"; import { IconName } from "@/utils/icon.types"; import { Region, useMapStore } from "@/utils/store"; import { PRIMARY_COLOR } from "@/utils/theme"; @@ -21,44 +20,19 @@ import { LocationAccuracy, requestForegroundPermissionsAsync, } from "expo-location"; -import { Stack, useRouter } from "expo-router"; +import { useRouter } from "expo-router"; import { MutableRefObject, useRef, useState } from "react"; import { Dimensions, StyleSheet, Text } from "react-native"; import { GestureHandlerRootView } from "react-native-gesture-handler"; import { Card, TouchableOpacity } from "react-native-ui-lib"; +import { withFullscreenLayout } from "../_layout-base"; /** * Root layout component that wraps the application with data providers and renders the main interface. * * This component provides the TRPC and QueryClient contexts for state and data management, and embeds a MapLayout that displays the map along with a bottom sheet containing the navigation stack. */ -export default function RootLayout() { - const [fullscreen, setFullscreen] = useState(false); - - const stack = ( - ( - setFullscreen(!fullscreen)}> - - - ), - }} - /> - ); - - return ( - - - {!fullscreen ? {stack} : stack} - - - ); -} +export default withFullscreenLayout(MapLayout); const snapPoints = ["20%", "40%", "50%"]; const initialSnapIndex = 1; diff --git a/app/app/main/explore/page/[pageId]/map/index.tsx b/app/app/main/explore/page/[pageId]/map/index.tsx new file mode 100644 index 0000000..052707c --- /dev/null +++ b/app/app/main/explore/page/[pageId]/map/index.tsx @@ -0,0 +1,3 @@ +import { generatePage } from "../_main-base"; + +export default generatePage(false); diff --git a/app/app/main/explore/page/[pageId]/map/section/[title].tsx b/app/app/main/explore/page/[pageId]/map/section/[title].tsx new file mode 100644 index 0000000..00950c6 --- /dev/null +++ b/app/app/main/explore/page/[pageId]/map/section/[title].tsx @@ -0,0 +1,3 @@ +import { generateSection } from "../../_section-base"; + +export default generateSection(false); diff --git a/app/app/main/explore/page/[pageId]/section/[title].tsx b/app/app/main/explore/page/[pageId]/section/[title].tsx deleted file mode 100644 index 7605b90..0000000 --- a/app/app/main/explore/page/[pageId]/section/[title].tsx +++ /dev/null @@ -1,114 +0,0 @@ -import WikiContent from "@/components/render-node"; -import { useIsFullscreen } from "@/hooks/use-is-fullscreen"; -import { useScrollRef } from "@/hooks/use-scroll-ref"; -import useWikiQuery from "@/hooks/use-wiki-query"; -import { citiesAtom, getCityAtom } from "@/utils/bookmarks"; -import { NodeType, SectionNode } from "@bcye/structured-wikivoyage-types"; -import { BottomSheetScrollView } from "@gorhom/bottom-sheet"; -import { Stack, useLocalSearchParams } from "expo-router"; -import { useAtom } from "jotai/react"; -import { append, assoc, dissoc } from "ramda"; -import { useCallback } from "react"; -import { ScrollView } from "react-native"; -import { SkeletonView, View } from "react-native-ui-lib"; -import { toast } from "sonner-native"; - -/** - * Renders a specific section of a Wikipedia page in Markdown format. - * - * The component retrieves the page title and ID from local search parameters, fetches the page's wikitext - * via a TRPC query, and then extracts and converts the designated section—identified by the title—to Markdown. - * It slices off the section header from the converted Markdown and displays a skeleton view while the content loads. - */ -export default function Section() { - const { title, pageId } = useLocalSearchParams(); - const wikiQuery = useWikiQuery(pageId as string); - const section = wikiQuery.data?.children.find( - (c) => c.type === NodeType.Section && c.properties.title === title, - ) as SectionNode | undefined; - const ref = useScrollRef(); - const isFullscreen = useIsFullscreen(); - const [bookmarks, setBookmarks] = useAtom(getCityAtom(pageId as string)); - const [cities, setCities] = useAtom(citiesAtom); - const pageTitle = wikiQuery.data?.properties.title; - - const isBookmarked = useCallback( - function isBookmarked(id: string) { - return !!bookmarks[id]; - }, - [bookmarks], - ); - - const toggleBookmarked = useCallback( - function toggleBookmarked(id: string) { - if (id == ",") { - toast.error( - "This listing doesn't have a location and can't be bookmarked. Add one on en.wikivoyage.org", - ); - return; - } - - if (isBookmarked(id)) { - setBookmarks(dissoc(id, bookmarks)); - } else { - if (!cities.find((c) => c.qid === pageId)) { - setCities( - append({ qid: pageId as string, name: pageTitle! }, cities), - ); - } - // no valid lat-lng - setBookmarks( - assoc( - id, - { section: title, properties: section!.properties }, - bookmarks, - ), - ); - } - }, - [ - bookmarks, - setBookmarks, - section, - isBookmarked, - pageTitle, - cities, - setCities, - pageId, - title, - ], - ); - - if (!section) return null; - - return ( - - - - !isFullscreen ? ( - - - - ) : ( - - - - ) - } - /> - - ); -} diff --git a/app/components/place-card.tsx b/app/components/place-card.tsx index 284cad7..1ff669e 100644 --- a/app/components/place-card.tsx +++ b/app/components/place-card.tsx @@ -12,11 +12,11 @@ export default function PlaceCard({ item }: { item: Place }) { const router = useRouter(); function openPlace() { - router.navigate(`/main/explore/page/${item.id}`); + router.navigate(`/main/explore/page/${item.id}/map`); } return ( - + {item.title} diff --git a/app/hooks/use-is-fullscreen.tsx b/app/hooks/use-is-fullscreen.tsx deleted file mode 100644 index 27e90d8..0000000 --- a/app/hooks/use-is-fullscreen.tsx +++ /dev/null @@ -1,19 +0,0 @@ -import { createContext, ReactNode, useContext } from "react"; - -const FullScreenContext = createContext(false); - -export function FullScreenProvider({ - fullscreen, - children, -}: { - fullscreen: boolean; - children: ReactNode; -}) { - return ( - - {children} - - ); -} - -export const useIsFullscreen = () => useContext(FullScreenContext); diff --git a/app/hooks/use-move-to.ts b/app/hooks/use-move-to.ts index 38a6383..8aaa3f2 100644 --- a/app/hooks/use-move-to.ts +++ b/app/hooks/use-move-to.ts @@ -4,7 +4,6 @@ export const CameraRefContext = createContext< (lng: number, lat: number, zoom: number) => void >(() => { // noop - console.log("noop, inside defaultValue"); }); export default function useMoveTo() { From f015b8cef0bfbd1f444a4768b87aac8cf5ff3ed8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruce=20R=C3=B6ttgers?= Date: Mon, 20 Oct 2025 22:31:53 +0200 Subject: [PATCH 2/4] fix up navigation --- app/app/main/explore/page/[pageId]/_page-root-view.tsx | 10 ++++++++-- app/components/place-card.tsx | 2 +- app/package.json | 1 + 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/app/app/main/explore/page/[pageId]/_page-root-view.tsx b/app/app/main/explore/page/[pageId]/_page-root-view.tsx index 3cb0129..66ff27c 100644 --- a/app/app/main/explore/page/[pageId]/_page-root-view.tsx +++ b/app/app/main/explore/page/[pageId]/_page-root-view.tsx @@ -3,7 +3,7 @@ import { MapMarker, MarkerType, useMapStore } from "@/utils/store"; import { NodeType, RootNode } from "@bcye/structured-wikivoyage-types"; import { BottomSheetScrollView } from "@gorhom/bottom-sheet"; import { UseQueryResult } from "@tanstack/react-query"; -import { Link, Route, Stack } from "expo-router"; +import { Link, Route, Stack, usePathname } from "expo-router"; import { useAtomValue } from "jotai/react"; import { filter, map, split, splitEvery } from "ramda"; import { useEffect } from "react"; @@ -118,11 +118,17 @@ export default function PageRootView({ * @param pageId - The identifier for the page, used to construct the dynamic navigation route. */ function Infocard({ title, pageId }: { title: string; pageId: string }) { + const pathname = usePathname(); return ( 404 + // @ts-ignore cannot be inferred + pathname: pathname.includes("section") + ? pathname + : pathname + "/section/[title]", params: { title }, }} > diff --git a/app/components/place-card.tsx b/app/components/place-card.tsx index 1ff669e..22a3af7 100644 --- a/app/components/place-card.tsx +++ b/app/components/place-card.tsx @@ -16,7 +16,7 @@ export default function PlaceCard({ item }: { item: Place }) { } return ( - + {item.title} diff --git a/app/package.json b/app/package.json index cb97b6d..a63e446 100644 --- a/app/package.json +++ b/app/package.json @@ -11,6 +11,7 @@ }, "scripts": { "start": "expo start", + "start:ng": "expo start --tunnel", "reset-project": "node ./scripts/reset-project.js", "android": "DARK_MODE=media expo run:android", "android:reconnect": "adb reverse tcp:8081 tcp:8081", From 75ca327daa32ae96966089f9ee5fd95082ce45da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruce=20R=C3=B6ttgers?= Date: Mon, 20 Oct 2025 22:35:56 +0200 Subject: [PATCH 3/4] fix types --- app/app/main/explore/page/[pageId]/_page-root-view.tsx | 2 +- app/app/main/explore/page/[pageId]/map/_layout.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/app/app/main/explore/page/[pageId]/_page-root-view.tsx b/app/app/main/explore/page/[pageId]/_page-root-view.tsx index 66ff27c..e6fa3ca 100644 --- a/app/app/main/explore/page/[pageId]/_page-root-view.tsx +++ b/app/app/main/explore/page/[pageId]/_page-root-view.tsx @@ -14,7 +14,7 @@ function PageContent({ pageQuery, id, }: { - pageQuery: UseQdefaultueryResult; + pageQuery: UseQueryResult; id: string; }) { const bookmarks = useAtomValue(getCityAtom(id)); diff --git a/app/app/main/explore/page/[pageId]/map/_layout.tsx b/app/app/main/explore/page/[pageId]/map/_layout.tsx index 9546cc3..51d9f59 100644 --- a/app/app/main/explore/page/[pageId]/map/_layout.tsx +++ b/app/app/main/explore/page/[pageId]/map/_layout.tsx @@ -32,7 +32,7 @@ import { withFullscreenLayout } from "../_layout-base"; * * This component provides the TRPC and QueryClient contexts for state and data management, and embeds a MapLayout that displays the map along with a bottom sheet containing the navigation stack. */ -export default withFullscreenLayout(MapLayout); +export default withFullscreenLayout(MapLayout, false); const snapPoints = ["20%", "40%", "50%"]; const initialSnapIndex = 1; From ef5391f73c0fdcd725e5881ef851fab33fd6cefe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bruce=20R=C3=B6ttgers?= Date: Wed, 22 Oct 2025 11:19:36 +0200 Subject: [PATCH 4/4] last state - probably not right approach to do this fullscreen, get a functioning map lib instead --- .../explore/page/[pageId]/_layout-base.tsx | 10 ++++++-- .../explore/page/[pageId]/_page-root-view.tsx | 18 +++++++++++--- app/components/render-node.tsx | 5 ++++ app/utils/store.ts | 24 +++++++++++++------ 4 files changed, 45 insertions(+), 12 deletions(-) diff --git a/app/app/main/explore/page/[pageId]/_layout-base.tsx b/app/app/main/explore/page/[pageId]/_layout-base.tsx index 72d49fd..c0c2033 100644 --- a/app/app/main/explore/page/[pageId]/_layout-base.tsx +++ b/app/app/main/explore/page/[pageId]/_layout-base.tsx @@ -1,6 +1,6 @@ import { ScrollRefProvider } from "@/hooks/use-scroll-ref"; import MaterialCommunityIcons from "@expo/vector-icons/MaterialCommunityIcons"; -import { Link, Stack } from "expo-router"; +import { Link, Stack, usePathname } from "expo-router"; import { ComponentType, ReactNode } from "react"; export function withFullscreenLayout( @@ -8,11 +8,17 @@ export function withFullscreenLayout( isFullscreen: boolean, ) { function RootLayout() { + const pathname = usePathname(); + const navigationName = isFullscreen + ? pathname.replace("fullscreen", "map") + : pathname.replace("map", "fullscreen"); + const stack = ( ( - + // @ts-ignore Can't be dynamically inferred + ; id: string; + isFullscreen: boolean; }) { const bookmarks = useAtomValue(getCityAtom(id)); const registerMarker = useMapStore((s) => s.registerMarker); @@ -23,6 +25,8 @@ function PageContent({ useEffect( function registerBookmarks() { + if (isFullscreen) return; + const markers: MapMarker[] = []; for (const [bId, bookmark] of Object.entries(bookmarks)) { const [lat, long] = map(parseFloat, split(",", bId)); @@ -45,7 +49,7 @@ function PageContent({ } }; }, - [bookmarks, id, registerMarker, deregisterMarker], + [bookmarks, id, registerMarker, deregisterMarker, isFullscreen], ); return map( @@ -94,11 +98,19 @@ export default function PageRootView({ ) : pageQuery.data && id ? ( !isFullscreen ? ( - + ) : ( - + ) ) : null diff --git a/app/components/render-node.tsx b/app/components/render-node.tsx index bc2bd73..b5143b1 100644 --- a/app/components/render-node.tsx +++ b/app/components/render-node.tsx @@ -194,6 +194,8 @@ function Listing({ ); } +let count = 0; + function useRegisterOnMap( lat: string, long: string, @@ -212,6 +214,7 @@ function useRegisterOnMap( const { scrollTo } = useLocalSearchParams(); useEffect(() => { + if (path.includes("fullscreen")) return; // bookmarked items are registered elsewhere if (isBookmarked(coordsId)) return; @@ -223,9 +226,11 @@ function useRegisterOnMap( type: MarkerType.Normal, }; registerCard(marker); + console.log("registered marker", ++count); return () => { deregisterCard(marker); + console.log("deregistered marker"); }; }, [coordsId, isBookmarked, deregisterCard, lat, long, path, registerCard]); diff --git a/app/utils/store.ts b/app/utils/store.ts index 80a10db..7f3be00 100644 --- a/app/utils/store.ts +++ b/app/utils/store.ts @@ -36,12 +36,22 @@ export const useMapStore = create((set) => ({ })); }, deregisterMarker(marker) { - set((s) => ({ - ...s, - markers: s.markers.toSpliced( - s.markers.findIndex((m) => m.id == marker.id), - 1, - ), - })); + set((s) => { + const prevL = s.markers.length; + const newM = { + ...s, + markers: s.markers.toSpliced( + s.markers.findIndex((m) => m.id == marker.id), + 1, + ), + }; + const newL = newM.markers.length; + if (prevL == newL) { + console.warn( + `Tried to deregister marker ${marker.id} but it was not found in store.`, + ); + } + return newM; + }); }, }));