Files
ppc_amnet/amnet-native/app/ServerAddModal.tsx
T
2024-08-21 21:00:18 +01:00

111 lines
4.0 KiB
TypeScript

import {Card, Paragraph, useTheme} from "react-native-paper";
import {TextInput, TouchableOpacity, View} from "react-native";
import {useCallback, useEffect, useLayoutEffect, useState} from "react";
import {useModalStyles} from "../utils/ModalStyles";
import RealmContext from "../models/RealmContext";
import {AMServer} from "../models/AMServer";
const {useRealm} = RealmContext;
export default function ServerAddModal({route, navigation}) {
const realm = useRealm();
const theme = useTheme();
const modalStyles = useModalStyles();
const [serverAddress, setServerAddress] = useState('');
// add option to add server address when loading a share link
useEffect(() => {
handleDeepLink(realm, navigation, route, setServerAddress);
}, [route]);
useLayoutEffect(() => {
navigation.setOptions({
headerLeft: () => <TouchableOpacity onPress={() => navigation.goBack()}>
<Paragraph style={modalStyles.headerText}>Cancel</Paragraph>
</TouchableOpacity>,
});
}, [navigation, modalStyles]);
useLayoutEffect(() => {
let urlValid = false;
try {
new URL(serverAddress);
urlValid = true;
} catch {
// do nothing
}
const themeOptions = urlValid ? modalStyles.headerText : {color: theme.colors.outline};
navigation.setOptions({
headerRight: () => <TouchableOpacity disabled={!urlValid} onPress={() => saveServer()}>
<Paragraph style={{...themeOptions, fontWeight: "600"}}>Save</Paragraph>
</TouchableOpacity>
})
}, [navigation, modalStyles, serverAddress]);
const saveServer = useCallback(() => {
let serverObject = realm.objects<AMServer>("server").find(x => x.serverAddress == serverAddress);
if (!serverObject) {
realm.write(() => {
serverObject = realm.create<AMServer>("server", AMServer.generate(serverAddress));
});
}
navigation.goBack();
setTimeout(() => navigation.navigate('server', {
serverId: serverObject._id.toHexString()
}), 500);
}, [serverAddress, realm]);
return (<View style={{display: "flex", gap: 10, justifyContent: "center", paddingHorizontal: 15, paddingTop: 25}}>
<Card mode="contained">
<Card.Content>
<View style={{...modalStyles.formItemRow, gap: 10}}>
<Paragraph style={{...modalStyles.formItemName, minWidth: 0}}>
Address
</Paragraph>
<TextInput style={modalStyles.formItemInput}
autoFocus
numberOfLines={1}
keyboardType="url"
autoComplete="off"
textContentType="URL"
autoCapitalize="none"
value={serverAddress}
onChangeText={setServerAddress}
placeholder="http://192.168.1.2:6070"
placeholderTextColor={theme.colors.outline}/>
</View>
</Card.Content>
</Card>
<Paragraph style={modalStyles.formFootnote}>
If you're using HTTPS, ensure a trusted certificate has been configured via HTTP.SYS
</Paragraph>
</View>)
}
function handleDeepLink(realm, navigation, route, setAddress: (address: string) => void) {
if (!route.params?.serverAddress) {
return;
}
const serverUrl = decodeURIComponent(route.params.serverAddress);
const item = realm.objects(AMServer).filtered("serverAddress = $0", serverUrl);
if (item.length) {
navigation.goBack();
navigation.navigate('server', {
serverId: item._id.toHexString()
});
} else {
setAddress(serverUrl);
}
// clear param from route
navigation.setParams({serverAddress: null});
}