import { useEffect, useRef, useState } from "react"; import { FlatList, Pressable, Text, View } from "react-native"; import * as Haptics from "expo-haptics"; import { Link } from "expo-router"; import FullPageError from "@/components/FullPageError"; import NewListModal from "@/components/lists/NewListModal"; import { TailwindResolver } from "@/components/TailwindResolver"; import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; import FullPageSpinner from "@/components/ui/FullPageSpinner"; import PageTitle from "@/components/ui/PageTitle"; import { api } from "@/lib/trpc"; import { BottomSheetModal } from "@gorhom/bottom-sheet"; import { ChevronRight, Plus } from "lucide-react-native"; import { useBookmarkLists } from "@hoarder/shared-react/hooks/lists"; import { ZBookmarkListTreeNode } from "@hoarder/shared/utils/listUtils"; function HeaderRight({ openNewListModal }: { openNewListModal: () => void }) { return ( { Haptics.selectionAsync(); openNewListModal(); }} > ); } interface ListLink { id: string; logo: string; name: string; href: string; level: number; parent?: string; numChildren: number; collapsed: boolean; } function traverseTree( node: ZBookmarkListTreeNode, links: ListLink[], showChildrenOf: Record, parent?: string, level = 0, ) { links.push({ id: node.item.id, logo: node.item.icon, name: node.item.name, href: `/dashboard/lists/${node.item.id}`, level, parent, numChildren: node.children?.length ?? 0, collapsed: !showChildrenOf[node.item.id], }); if (node.children && showChildrenOf[node.item.id]) { node.children.forEach((child) => traverseTree(child, links, showChildrenOf, node.item.id, level + 1), ); } } export default function Lists() { const [refreshing, setRefreshing] = useState(false); const { data: lists, isPending, error, refetch } = useBookmarkLists(); const [showChildrenOf, setShowChildrenOf] = useState>( {}, ); const apiUtils = api.useUtils(); const newListModal = useRef(null); useEffect(() => { setRefreshing(isPending); }, [isPending]); if (error) { return refetch()} />; } if (!lists) { return ; } const onRefresh = () => { apiUtils.lists.list.invalidate(); }; const links: ListLink[] = [ { id: "fav", logo: "⭐️", name: "Favourites", href: "/dashboard/favourites", level: 0, numChildren: 0, collapsed: false, }, { id: "arch", logo: "🗄️", name: "Archive", href: "/dashboard/archive", level: 0, numChildren: 0, collapsed: false, }, ]; Object.values(lists.root).forEach((list) => traverseTree(list, links, showChildrenOf), ); return ( newListModal.current?.present()} /> } contentContainerStyle={{ gap: 5, }} renderItem={(l) => ( {l.item.numChildren > 0 && ( { setShowChildrenOf((prev) => ({ ...prev, [l.item.id]: !prev[l.item.id], })); }} > ( )} /> )} {l.item.logo} {l.item.name} )} data={links} refreshing={refreshing} onRefresh={onRefresh} /> ); }