diff options
Diffstat (limited to 'apps/mobile')
| -rw-r--r-- | apps/mobile/app/dashboard/(tabs)/index.tsx | 18 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/_layout.tsx | 7 | ||||
| -rw-r--r-- | apps/mobile/app/dashboard/add-note.tsx | 114 | ||||
| -rw-r--r-- | apps/mobile/components/bookmarks/BookmarkCard.tsx | 11 | ||||
| -rw-r--r-- | apps/mobile/components/bookmarks/NewBookmarkModal.tsx | 129 |
5 files changed, 154 insertions, 125 deletions
diff --git a/apps/mobile/app/dashboard/(tabs)/index.tsx b/apps/mobile/app/dashboard/(tabs)/index.tsx index 5dccc845..994ebb45 100644 --- a/apps/mobile/app/dashboard/(tabs)/index.tsx +++ b/apps/mobile/app/dashboard/(tabs)/index.tsx @@ -1,17 +1,24 @@ +import { useRef } from "react"; import { Platform, View } from "react-native"; import * as Haptics from "expo-haptics"; import * as ImagePicker from "expo-image-picker"; import { useRouter } from "expo-router"; +import NoteEditorModal from "@/components/bookmarks/NewBookmarkModal"; import UpdatingBookmarkList from "@/components/bookmarks/UpdatingBookmarkList"; import CustomSafeAreaView from "@/components/ui/CustomSafeAreaView"; import PageTitle from "@/components/ui/PageTitle"; import { useToast } from "@/components/ui/Toast"; import useAppSettings from "@/lib/settings"; import { useUploadAsset } from "@/lib/upload"; +import { BottomSheetModal } from "@gorhom/bottom-sheet"; import { MenuView } from "@react-native-menu/menu"; import { SquarePen } from "lucide-react-native"; -function HeaderRight() { +function HeaderRight({ + openNewBookmarkModal, +}: { + openNewBookmarkModal: () => void; +}) { const { toast } = useToast(); const router = useRouter(); const { settings } = useAppSettings(); @@ -25,7 +32,7 @@ function HeaderRight() { onPressAction={async ({ nativeEvent }) => { Haptics.selectionAsync(); if (nativeEvent.event === "note") { - router.navigate("dashboard/add-note"); + openNewBookmarkModal(); } else if (nativeEvent.event === "link") { router.navigate("dashboard/add-link"); } else if (nativeEvent.event === "library") { @@ -79,14 +86,19 @@ function HeaderRight() { } export default function Home() { + const newBookmarkModal = useRef<BottomSheetModal>(null); + return ( <CustomSafeAreaView> + <NoteEditorModal ref={newBookmarkModal} snapPoints={["90%", "60%"]} /> <UpdatingBookmarkList query={{ archived: false }} header={ <View className="flex flex-row justify-between"> <PageTitle title="Home" /> - <HeaderRight /> + <HeaderRight + openNewBookmarkModal={() => newBookmarkModal.current?.present()} + /> </View> } /> diff --git a/apps/mobile/app/dashboard/_layout.tsx b/apps/mobile/app/dashboard/_layout.tsx index 7548a6db..e8733fe0 100644 --- a/apps/mobile/app/dashboard/_layout.tsx +++ b/apps/mobile/app/dashboard/_layout.tsx @@ -61,13 +61,6 @@ export default function Dashboard() { presentation: "modal", }} /> - <Stack.Screen - name="add-note" - options={{ - title: "New Note", - presentation: "modal", - }} - /> </StyledStack> ); } diff --git a/apps/mobile/app/dashboard/add-note.tsx b/apps/mobile/app/dashboard/add-note.tsx deleted file mode 100644 index 8aa31936..00000000 --- a/apps/mobile/app/dashboard/add-note.tsx +++ /dev/null @@ -1,114 +0,0 @@ -import { useEffect, useState } from "react"; -import { Text, View } from "react-native"; -import { Stack, useLocalSearchParams, useRouter } from "expo-router"; -import { Button } from "@/components/ui/Button"; -import { Input } from "@/components/ui/Input"; -import { api } from "@/lib/trpc"; - -import { - useCreateBookmark, - useUpdateBookmarkText, -} from "@hoarder/shared-react/hooks/bookmarks"; -import { BookmarkTypes } from "@hoarder/shared/types/bookmarks"; - -export default function AddNote() { - const { bookmarkId } = useLocalSearchParams(); - if (bookmarkId && typeof bookmarkId !== "string") { - throw new Error("Unexpected param type"); - } - - const isEditing = !!bookmarkId; - - const [text, setText] = useState(""); - const [error, setError] = useState<string | undefined>(); - const router = useRouter(); - - const { data: bookmark } = api.bookmarks.getBookmark.useQuery( - { bookmarkId: bookmarkId! }, - { - enabled: !!bookmarkId, - }, - ); - - useEffect(() => { - if (bookmark) { - if (bookmark.content.type !== BookmarkTypes.TEXT) { - throw new Error("Wrong content type rendered"); - } - setText(bookmark.content.text); - } - }, [bookmark]); - - const onSuccess = () => { - if (router.canGoBack()) { - router.replace("./"); - } else { - router.replace("dashboard"); - } - }; - - const { mutate: createBookmark } = useCreateBookmark({ - onSuccess, - onError: (e) => { - let message; - if (e.data?.zodError) { - const zodError = e.data.zodError; - message = JSON.stringify(zodError); - } else { - message = `Something went wrong: ${e.message}`; - } - setError(message); - }, - }); - - const { mutate: updateBookmark } = useUpdateBookmarkText({ - onSuccess, - onError: (e) => { - let message; - if (e.data?.zodError) { - const zodError = e.data.zodError; - message = JSON.stringify(zodError); - } else { - message = `Something went wrong: ${e.message}`; - } - setError(message); - }, - }); - - const mutate = (text: string) => { - if (isEditing) { - updateBookmark({ - bookmarkId, - text, - }); - } else { - createBookmark({ type: BookmarkTypes.TEXT, text }); - } - }; - - return ( - <View className="flex gap-2 p-4"> - <Stack.Screen - options={{ - title: isEditing ? "Edit Note" : "Add Note", - }} - /> - {error && ( - <Text className="w-full text-center text-red-500">{error}</Text> - )} - <Input - value={text} - onChangeText={setText} - multiline - numberOfLines={8} - placeholder="What's on your mind?" - autoFocus - textAlignVertical="top" - /> - <Button - onPress={() => mutate(text)} - label={isEditing ? "Save" : "Add Note"} - /> - </View> - ); -} diff --git a/apps/mobile/components/bookmarks/BookmarkCard.tsx b/apps/mobile/components/bookmarks/BookmarkCard.tsx index ed6a3b2c..8c582d59 100644 --- a/apps/mobile/components/bookmarks/BookmarkCard.tsx +++ b/apps/mobile/components/bookmarks/BookmarkCard.tsx @@ -35,6 +35,7 @@ import { useToast } from "../ui/Toast"; import BookmarkAssetImage from "./BookmarkAssetImage"; import BookmarkTextMarkdown from "./BookmarkTextMarkdown"; import ListPickerModal from "./ListPickerModal"; +import NoteEditorModal from "./NewBookmarkModal"; function ActionBar({ bookmark }: { bookmark: ZBookmark }) { const { toast } = useToast(); @@ -74,6 +75,7 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { }); const manageListsSheetRef = useRef<BottomSheetModal>(null); + const editBookmarkModal = useRef<BottomSheetModal>(null); return ( <View className="flex flex-row gap-4"> @@ -99,6 +101,13 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { snapPoints={["50%", "90%"]} bookmarkId={bookmark.id} /> + {bookmark.content.type === BookmarkTypes.TEXT && ( + <NoteEditorModal + ref={editBookmarkModal} + bookmark={bookmark} + snapPoints={["90%", "60%"]} + /> + )} <MenuView onPressAction={({ nativeEvent }) => { @@ -115,7 +124,7 @@ function ActionBar({ bookmark }: { bookmark: ZBookmark }) { } else if (nativeEvent.event === "manage_list") { manageListsSheetRef?.current?.present(); } else if (nativeEvent.event === "edit") { - router.push(`/dashboard/add-note?bookmarkId=${bookmark.id}`); + editBookmarkModal.current?.present(); } }} actions={[ diff --git a/apps/mobile/components/bookmarks/NewBookmarkModal.tsx b/apps/mobile/components/bookmarks/NewBookmarkModal.tsx new file mode 100644 index 00000000..8ac8bb39 --- /dev/null +++ b/apps/mobile/components/bookmarks/NewBookmarkModal.tsx @@ -0,0 +1,129 @@ +import React, { useEffect, useState } from "react"; +import { Text, View } from "react-native"; +import { + BottomSheetBackdrop, + BottomSheetModal, + BottomSheetModalProps, + BottomSheetTextInput, + BottomSheetView, + useBottomSheetModal, +} from "@gorhom/bottom-sheet"; + +import { + useCreateBookmark, + useUpdateBookmarkText, +} from "@hoarder/shared-react/hooks/bookmarks"; +import { BookmarkTypes, ZBookmark } from "@hoarder/shared/types/bookmarks"; + +import { Button } from "../ui/Button"; +import PageTitle from "../ui/PageTitle"; + +const NoteEditorModal = React.forwardRef< + BottomSheetModal, + Omit< + BottomSheetModalProps, + "children" | "backdropComponent" | "onDismiss" + > & { + bookmark?: ZBookmark; + } +>(({ bookmark, ...props }, ref) => { + const { dismiss } = useBottomSheetModal(); + const isEditing = !!bookmark; + + const [text, setText] = useState(""); + const [error, setError] = useState<string | undefined>(); + + const resetText = () => { + if (bookmark) { + if (bookmark.content.type !== BookmarkTypes.TEXT) { + throw new Error("Wrong content type rendered"); + } + setText(bookmark.content.text); + } + }; + + useEffect(resetText, []); + + const onSuccess = () => { + resetText(); + dismiss(); + }; + + const { mutate: createBookmark } = useCreateBookmark({ + onSuccess, + onError: (e) => { + let message; + if (e.data?.zodError) { + const zodError = e.data.zodError; + message = JSON.stringify(zodError); + } else { + message = `Something went wrong: ${e.message}`; + } + setError(message); + }, + }); + + const { mutate: updateBookmark } = useUpdateBookmarkText({ + onSuccess, + onError: (e) => { + let message; + if (e.data?.zodError) { + const zodError = e.data.zodError; + message = JSON.stringify(zodError); + } else { + message = `Something went wrong: ${e.message}`; + } + setError(message); + }, + }); + + const mutate = (text: string) => { + if (isEditing) { + updateBookmark({ + bookmarkId: bookmark.id, + text, + }); + } else { + createBookmark({ type: BookmarkTypes.TEXT, text }); + } + }; + + return ( + <View> + <BottomSheetModal + ref={ref} + backdropComponent={(props) => ( + <BottomSheetBackdrop + appearsOnIndex={0} + disappearsOnIndex={-1} + {...props} + /> + )} + {...props} + > + <PageTitle title={isEditing ? "Edit Note" : "New Note"} /> + <BottomSheetView className="p-4"> + {error && ( + <Text className="w-full text-center text-red-500">{error}</Text> + )} + <BottomSheetTextInput + value={text} + onChangeText={setText} + multiline + numberOfLines={8} + placeholder="What's on your mind?" + autoFocus + textAlignVertical="top" + /> + <Button + onPress={() => mutate(text)} + label={isEditing ? "Save" : "Add Note"} + /> + </BottomSheetView> + </BottomSheetModal> + </View> + ); +}); +NoteEditorModal.displayName = "NewBookmarkModal"; + +export default NoteEditorModal; |
