Sync profile page & Update mobile device names

DO NOT TRY ANDROID. IT IS BROKEN AND PANICKING ON CORE WHEN COMPILED.
This commit is contained in:
Arnab Chakraborty
2024-10-14 21:18:28 -04:00
parent 122b4b2b23
commit c7e87f0862
4 changed files with 127 additions and 5 deletions

View File

@@ -25,6 +25,7 @@ import {
LibraryContextProvider,
P2PContextProvider,
RspcProvider,
useBridgeMutation,
useBridgeQuery,
useBridgeSubscription,
useClientContext,
@@ -132,16 +133,37 @@ function AppContainer() {
useInvalidateQuery();
const { id } = useSnapshot(currentLibraryStore);
const userResponse = useBridgeMutation('cloud.userResponse');
useBridgeSubscription(['cloud.listenCloudServicesNotifications'], {
onData: (d) => {
console.log('Received cloud service notification', d);
switch (d.kind) {
case 'ReceivedJoinSyncGroupRequest':
// TODO: Show modal to accept or reject
// WARNING: This is a debug solution to accept the device into the sync group. THIS SHOULD NOT MAKE IT TO PRODUCTION
userResponse.mutate({
kind: 'AcceptDeviceInSyncGroup',
data: {
ticket: d.data.ticket,
accepted: {
id: d.data.sync_group.library.pub_id,
name: d.data.sync_group.library.name,
description: null
}
}
});
// TODO: Move the code above into the dialog below (@Rocky43007)
// dialogManager.create((dp) => (
// <RequestAddDialog
// device_model={'MacBookPro'}
// device_name={"Arnab's Macbook"}
// library_name={"Arnab's Library"}
// {...dp}
// />
// ));
break;
default:
// TODO: Show notification/toast for other kinds
toast.info(`Cloud Service Notification -> ${d.kind}`);
toast.info(`Cloud Service Notification: ${d.kind}`);
break;
}
}

View File

@@ -1,13 +1,15 @@
import { useNavigation } from '@react-navigation/native';
import { Envelope } from 'phosphor-react-native';
import { useEffect, useState } from 'react';
import { Text, View } from 'react-native';
import { useBridgeMutation, useBridgeQuery, useLibraryMutation } from '@sd/client';
import Card from '~/components/layout/Card';
import ScreenContainer from '~/components/layout/ScreenContainer';
import { Button } from '~/components/primitive/Button';
import { tw } from '~/lib/tailwind';
import { SettingsStackScreenProps } from '~/navigation/tabs/SettingsStack';
import { getUserStore, useUserStore } from '~/stores/userStore';
import { AUTH_SERVER_URL } from '~/utils';
import { AUTH_SERVER_URL, getTokens } from '~/utils';
const AccountProfile = () => {
const userInfo = useUserStore().userInfo;
@@ -16,6 +18,28 @@ const AccountProfile = () => {
const capitalizedEmailName = (emailName?.charAt(0).toUpperCase() ?? '') + emailName?.slice(1);
const navigator = useNavigation<SettingsStackScreenProps<'AccountLogin'>['navigation']>();
const cloudBootstrap = useBridgeMutation('cloud.bootstrap');
const devices = useBridgeQuery(['cloud.devices.list']);
const addLibraryToCloud = useLibraryMutation('cloud.libraries.create');
const listLibraries = useBridgeQuery(['cloud.libraries.list', true]);
const createSyncGroup = useLibraryMutation('cloud.syncGroups.create');
const listSyncGroups = useBridgeQuery(['cloud.syncGroups.list']);
const requestJoinSyncGroup = useBridgeMutation('cloud.syncGroups.request_join');
const currentDevice = useBridgeQuery(['cloud.devices.get_current_device']);
const [{ accessToken, refreshToken }, setTokens] = useState<{
accessToken: string;
refreshToken: string;
}>({
accessToken: '',
refreshToken: ''
});
useEffect(() => {
(async () => {
const { accessToken, refreshToken } = await getTokens();
setTokens({ accessToken, refreshToken });
})();
}, []);
async function signOut() {
await fetch(`${AUTH_SERVER_URL}/api/auth/signout`, {
method: 'POST'
@@ -49,6 +73,59 @@ const AccountProfile = () => {
</Button>
</View>
</Card>
{/* Debug buttons */}
<Card style={tw`flex gap-2 text-white`}>
<Button
variant="gray"
onPress={async () => {
cloudBootstrap.mutate([accessToken.trim(), refreshToken.trim()]);
}}
>
<Text style={tw`text-white`}>Start Cloud Bootstrap</Text>
</Button>
<Button
variant="gray"
onPress={async () => {
addLibraryToCloud.mutate(null);
}}
>
<Text style={tw`text-white`}>Add Library to Cloud</Text>
</Button>
<Button
variant="gray"
onPress={async () => {
createSyncGroup.mutate(null);
}}
>
<Text style={tw`text-white`}>Create Sync Group</Text>
</Button>
</Card>
<View style={tw`mt-5 flex flex-col gap-3 text-white`}>
<Text style={tw`text-md font-semibold`}>Library Sync Groups</Text>
{listSyncGroups.data?.map((group) => (
<Card key={group.pub_id} style="w-full p-4">
<Text style={tw`text-sm font-semibold text-white`}>{group.library.name}</Text>
<Button
style={tw`mt-2`}
onPress={async () => {
if (!currentDevice.data) await currentDevice.refetch();
if (currentDevice.data && devices.data) {
requestJoinSyncGroup.mutate({
asking_device: currentDevice.data,
sync_group: {
devices: devices.data,
...group
}
});
}
}}
>
<Text style={tw`text-white`}>Join Sync Group</Text>
</Button>
</Card>
)) || <Text style={tw`text-white`}>No sync groups found.</Text>}
</View>
</View>
</ScreenContainer>
);

View File

@@ -197,7 +197,15 @@ impl ManagedVersion<NodeConfigVersion> for NodeConfig {
type MigrationError = NodeConfigError;
fn from_latest_version() -> Option<Self> {
#[cfg(not(any(target_os = "ios", target_os = "android")))]
let mut name = whoami::devicename();
#[cfg(target_os = "ios")]
let mut name = "iOS Device".to_string();
#[cfg(target_os = "android")]
let mut name = "Android Device".to_string();
name.truncate(255);
let os = DeviceOS::from_env();
@@ -328,12 +336,28 @@ impl NodeConfig {
);
config.remove("name");
#[cfg(not(any(target_os = "ios", target_os = "android")))]
config.insert(
String::from("name"),
serde_json::to_value(whoami::devicename())
.map_err(VersionManagerError::SerdeJson)?,
);
#[cfg(target_os = "ios")]
config.insert(
String::from("name"),
serde_json::to_value("iOS Device")
.map_err(VersionManagerError::SerdeJson)?,
);
#[cfg(target_os = "android")]
config.insert(
String::from("name"),
serde_json::to_value("Android Device")
.map_err(VersionManagerError::SerdeJson)?,
);
config.insert(
String::from("os"),
serde_json::to_value(std::env::consts::OS)

View File

@@ -28,7 +28,6 @@ const Profile = ({
const { accessToken, refreshToken } = getTokens();
const cloudBootstrap = useBridgeMutation('cloud.bootstrap');
const cloudDeleteDevice = useBridgeMutation('cloud.devices.delete');
const devices = useBridgeQuery(['cloud.devices.list']);
const addLibraryToCloud = useLibraryMutation('cloud.libraries.create');
const listLibraries = useBridgeQuery(['cloud.libraries.list', true]);