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] ? (
) : (