From 5ae6694da365c3c22b7dc00a999182e0310f6c38 Mon Sep 17 00:00:00 2001 From: MohamedBassem Date: Fri, 19 Apr 2024 12:29:19 +0100 Subject: feature(mobile): Add support for nested listed on mobile --- apps/mobile/app/dashboard/(tabs)/lists.tsx | 107 ++++++++++++++++++++++++----- 1 file changed, 89 insertions(+), 18 deletions(-) diff --git a/apps/mobile/app/dashboard/(tabs)/lists.tsx b/apps/mobile/app/dashboard/(tabs)/lists.tsx index 53817bf2..ed085f3d 100644 --- a/apps/mobile/app/dashboard/(tabs)/lists.tsx +++ b/apps/mobile/app/dashboard/(tabs)/lists.tsx @@ -4,11 +4,53 @@ import { Link } from "expo-router"; import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; import PageTitle from "@/components/ui/PageTitle"; import { api } from "@/lib/trpc"; -import { ChevronRight } from "lucide-react-native"; +import { ChevronRight, Triangle } from "lucide-react-native"; + +import { useBookmarkLists } from "@hoarder/shared-react/hooks/lists"; +import { ZBookmarkListTreeNode } from "@hoarder/shared/utils/listUtils"; + +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 } = api.lists.list.useQuery(); + const { data: lists, isPending } = useBookmarkLists(); + const [showChildrenOf, setShowChildrenOf] = useState>( + {}, + ); const apiUtils = api.useUtils(); useEffect(() => { @@ -24,46 +66,75 @@ export default function Lists() { apiUtils.lists.list.invalidate(); }; - const links = [ + 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, }, ]; - links.push( - ...lists.lists.map((l) => ({ - id: l.id, - logo: l.icon, - name: l.name, - href: `/dashboard/lists/${l.id}`, - })), + Object.values(lists.root).forEach((list) => + traverseTree(list, links, showChildrenOf), ); return ( } contentContainerStyle={{ gap: 5, }} renderItem={(l) => ( - - - - {l.item.logo} {l.item.name} - - - - + + {l.item.numChildren > 0 && ( + { + setShowChildrenOf((prev) => ({ + ...prev, + [l.item.id]: !prev[l.item.id], + })); + }} + > + + + )} + + + + + {l.item.logo} {l.item.name} + + + + + )} data={links} refreshing={refreshing} -- cgit v1.2.3-70-g09d2