diff --git a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx index 15e05ff1d..69995626a 100644 --- a/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx +++ b/apps/mobile/src/components/drawer/DrawerLibraryManager.tsx @@ -1,7 +1,7 @@ import { useDrawerStatus } from '@react-navigation/drawer'; import { useNavigation } from '@react-navigation/native'; import { MotiView } from 'moti'; -import { CaretRight, Gear, Lock, Plus } from 'phosphor-react-native'; +import { CaretRight, CloudArrowDown, Gear, Lock, Plus } from 'phosphor-react-native'; import { useEffect, useRef, useState } from 'react'; import { Alert, Pressable, Text, View } from 'react-native'; import { useClientContext } from '@sd/client'; @@ -12,6 +12,7 @@ import { AnimatedHeight } from '../animation/layout'; import { ModalRef } from '../layout/Modal'; import CreateLibraryModal from '../modal/CreateLibraryModal'; import { Divider } from '../primitive/Divider'; +import ImportModalLibrary from '../modal/ImportLibraryModal'; const DrawerLibraryManager = () => { const [dropdownClosed, setDropdownClosed] = useState(true); @@ -91,6 +92,14 @@ const DrawerLibraryManager = () => { New Library + modalRef.current?.present()} + > + + Import Library + + {/* Manage Library */} { diff --git a/apps/mobile/src/components/modal/ImportLibraryModal.tsx b/apps/mobile/src/components/modal/ImportLibraryModal.tsx new file mode 100644 index 000000000..a73428ad8 --- /dev/null +++ b/apps/mobile/src/components/modal/ImportLibraryModal.tsx @@ -0,0 +1,163 @@ +import { useNavigation } from '@react-navigation/native'; +import { useQueryClient } from '@tanstack/react-query'; +import { forwardRef, useState } from 'react'; +import { Text, View } from 'react-native'; +import { + insertLibrary, + useBridgeMutation, + useBridgeQuery, + useClientContext, + usePlausibleEvent +} from '@sd/client'; +import { Modal, ModalRef } from '~/components/layout/Modal'; +import { Button } from '~/components/primitive/Button'; +import { ModalInput } from '~/components/primitive/Input'; +import useForwardedRef from '~/hooks/useForwardedRef'; +import { tw } from '~/lib/tailwind'; +import { currentLibraryStore } from '~/utils/nav'; + +const ImportModalLibrary = forwardRef((_, ref) => { + const navigation = useNavigation(); + const modalRef = useForwardedRef(ref); + + const queryClient = useQueryClient(); + const { libraries } = useClientContext(); + const [libName, setLibName] = useState(''); + + const submitPlausibleEvent = usePlausibleEvent(); + + const cloudLibraries = useBridgeQuery(['cloud.library.list']); + const joinLibrary = useBridgeMutation(['cloud.library.join']); + + // const { mutate: createLibrary, isLoading: createLibLoading } = useBridgeMutation( + // 'library.create', + // { + // onSuccess: (lib) => { + // // Reset form + // setLibName(''); + + // // We do this instead of invalidating the query because it triggers a full app re-render?? + // insertLibrary(queryClient, lib); + + // // Switch to the new library + // currentLibraryStore.id = lib.uuid; + + // submitPlausibleEvent({ event: { type: 'libraryCreate' } }); + // }, + // onSettled: () => { + // modalRef.current?.dismiss(); + // } + // } + // ); + + if (cloudLibraries.isLoading) + return ( + { + // Resets form onDismiss + setLibName(''); + }} + showCloseButton + // Disable panning gestures + enableHandlePanningGesture={false} + enableContentPanningGesture={false} + > + + Loading... + + + + ); + + return ( + { + // Resets form onDismiss + setLibName(''); + }} + showCloseButton + // Disable panning gestures + enableHandlePanningGesture={false} + enableContentPanningGesture={false} + > + + {cloudLibraries.data + ?.filter( + (cloudLibrary) => !libraries.data?.find((l) => l.uuid === cloudLibrary.uuid) + ) + .map((cloudLibrary) => ( + + {cloudLibrary.name} + + + + + ))} + + + ); +}); + +export default ImportModalLibrary; diff --git a/apps/mobile/src/screens/settings/library/Cloud.tsx b/apps/mobile/src/screens/settings/library/Cloud.tsx index f11362353..6e2b267ab 100644 --- a/apps/mobile/src/screens/settings/library/Cloud.tsx +++ b/apps/mobile/src/screens/settings/library/Cloud.tsx @@ -1,4 +1,5 @@ import { Linking, Text, View } from 'react-native'; +import { useLibraryContext, useLibraryMutation, useLibraryQuery } from '@sd/client'; import ScreenContainer from '~/components/layout/ScreenContainer'; import { Button } from '~/components/primitive/Button'; import { tw } from '~/lib/tailwind'; @@ -24,9 +25,74 @@ const Cloud = ({ navigation }: SettingsStackScreenProps<'Cloud'>) => { }; const Authenticated = () => { + const { library } = useLibraryContext(); + + const cloudLibrary = useLibraryQuery(['cloud.library.get'], { suspense: true, retry: false }); + + const createLibrary = useLibraryMutation(['cloud.library.create']); + const syncLibrary = useLibraryMutation(['cloud.library.sync']); + + const thisInstance = cloudLibrary.data?.instances.find( + (instance) => instance.uuid === library.instance_id + ); + return ( - You are authenticated! + {cloudLibrary.data ? ( + + + Library + Name: {cloudLibrary.data.name} + + + + + {thisInstance && ( + + This Instance + Id: {thisInstance.id} + UUID: {thisInstance.uuid} + Public Key: {thisInstance.identity} + + )} + + Instances + + {cloudLibrary.data.instances + .filter((instance) => instance.uuid !== library.instance_id) + .map((instance) => ( + + Id: {instance.id} + UUID: {instance.uuid} + Public Key: {instance.identity} + + ))} + + + + ) : ( + + + + )} ); }; @@ -43,7 +109,7 @@ const Login = () => { await login(); }} > - {authState.status !== 'loggingIn' ? Login : Logging In} + {authState.status !== 'loggingIn' ? Login : Logging In} {authState.status === 'loggingIn' && ( )} diff --git a/apps/mobile/src/screens/settings/library/SyncSettings.tsx b/apps/mobile/src/screens/settings/library/SyncSettings.tsx index c48af06e6..384e5caf9 100644 --- a/apps/mobile/src/screens/settings/library/SyncSettings.tsx +++ b/apps/mobile/src/screens/settings/library/SyncSettings.tsx @@ -107,7 +107,7 @@ const SyncSettingsScreen = ({ navigation }: SettingsStackScreenProps<'SyncSettin - {data[ACTORS.CloudReceive] ? ( + {data[ACTORS.CloudIngest] ? ( ) : (