diff --git a/apps/mobile/app.json b/apps/mobile/app.json
index b205b80d..baf2ca6e 100644
--- a/apps/mobile/app.json
+++ b/apps/mobile/app.json
@@ -30,7 +30,7 @@
"NSAllowsLocalNetworking": true
}
},
- "buildNumber": "7"
+ "buildNumber": "8"
},
"android": {
"adaptiveIcon": {
@@ -48,7 +48,7 @@
}
},
"package": "app.hoarder.hoardermobile",
- "versionCode": 7
+ "versionCode": 8
},
"plugins": [
"expo-router",
diff --git a/apps/mobile/app/dashboard/(tabs)/lists.tsx b/apps/mobile/app/dashboard/(tabs)/lists.tsx
index 9e4b0929..c7e3a874 100644
--- a/apps/mobile/app/dashboard/(tabs)/lists.tsx
+++ b/apps/mobile/app/dashboard/(tabs)/lists.tsx
@@ -1,15 +1,32 @@
-import { useEffect, useState } from "react";
+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 NewListModal from "@/components/lists/NewListModal";
import { TailwindResolver } from "@/components/TailwindResolver";
import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView";
import PageTitle from "@/components/ui/PageTitle";
import { api } from "@/lib/trpc";
-import { ChevronRight } from "lucide-react-native";
+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;
@@ -53,6 +70,7 @@ export default function Lists() {
{},
);
const apiUtils = api.useUtils();
+ const newListModal = useRef(null);
useEffect(() => {
setRefreshing(isPending);
@@ -94,9 +112,17 @@ export default function Lists() {
return (
+
}
+ ListHeaderComponent={
+
+
+ newListModal.current?.present()}
+ />
+
+ }
contentContainerStyle={{
gap: 5,
}}
diff --git a/apps/mobile/components/lists/NewListModal.tsx b/apps/mobile/components/lists/NewListModal.tsx
new file mode 100644
index 00000000..d31ac362
--- /dev/null
+++ b/apps/mobile/components/lists/NewListModal.tsx
@@ -0,0 +1,80 @@
+import React, { useState } from "react";
+import { Text, View } from "react-native";
+import {
+ BottomSheetBackdrop,
+ BottomSheetModal,
+ BottomSheetModalProps,
+ BottomSheetView,
+ useBottomSheetModal,
+} from "@gorhom/bottom-sheet";
+
+import { useCreateBookmarkList } from "@hoarder/shared-react/hooks/lists";
+
+import { Button } from "../ui/Button";
+import { Input } from "../ui/Input";
+import PageTitle from "../ui/PageTitle";
+import { useToast } from "../ui/Toast";
+
+const NewListModal = React.forwardRef<
+ BottomSheetModal,
+ Omit
+>(({ ...props }, ref) => {
+ const { dismiss } = useBottomSheetModal();
+ const { toast } = useToast();
+ const [text, setText] = useState("");
+
+ const { mutate, isPending } = useCreateBookmarkList({
+ onSuccess: () => {
+ dismiss();
+ },
+ onError: () => {
+ toast({
+ message: "Something went wrong",
+ variant: "destructive",
+ });
+ },
+ });
+
+ const onSubmit = () => {
+ mutate({
+ name: text,
+ icon: "🚀",
+ });
+ };
+
+ return (
+
+ setText("")}
+ backdropComponent={(props) => (
+
+ )}
+ {...props}
+ >
+
+
+
+ 🚀
+
+
+
+
+
+
+ );
+});
+
+NewListModal.displayName = "NewListModal";
+
+export default NewListModal;