import { useEffect, useState } from "react"; import { FlatList, Pressable, View } from "react-native"; import * as Haptics from "expo-haptics"; import { Link, router } from "expo-router"; import FullPageError from "@/components/FullPageError"; import ChevronRight from "@/components/ui/ChevronRight"; import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; import FullPageSpinner from "@/components/ui/FullPageSpinner"; import PageTitle from "@/components/ui/PageTitle"; import { Text } from "@/components/ui/Text"; import { api } from "@/lib/trpc"; import { useColorScheme } from "@/lib/useColorScheme"; import { condProps } from "@/lib/utils"; import { Plus } from "lucide-react-native"; import { useBookmarkLists } from "@karakeep/shared-react/hooks/lists"; import { ZBookmarkListTreeNode } from "@karakeep/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 { colors } = useColorScheme(); const [refreshing, setRefreshing] = useState(false); const { data: lists, isPending, error, refetch } = useBookmarkLists(); const [showChildrenOf, setShowChildrenOf] = useState>( {}, ); const apiUtils = api.useUtils(); 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 ( router.push("/dashboard/lists/new")} /> } contentContainerStyle={{ gap: 5, }} renderItem={(l) => ( 0, props: { marginLeft: l.item.level * 20 }, })} > {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} /> ); }