diff --git a/amnet-native/app/ServerAddModal.tsx b/amnet-native/app/ServerAddModal.tsx new file mode 100644 index 0000000..dd720ef --- /dev/null +++ b/amnet-native/app/ServerAddModal.tsx @@ -0,0 +1,84 @@ +import {useCallback, useEffect, useState} from "react"; +import {Card, Paragraph, useTheme} from "react-native-paper"; +import {TextInput, TouchableOpacity, View} from "react-native"; +import {useModalStyles} from "../utils/ModalStyles"; + +import RealmContext from "../models/RealmContext"; +import {AMServer} from "../models/AMServer"; + +const {useRealm} = RealmContext; + +export default function ServerAddModal({navigation}) { + const realm = useRealm(); + const theme = useTheme(); + const modalStyles = useModalStyles(); + + const [serverAddress, setServerAddress] = useState(''); + + useEffect(() => { + navigation.setOptions({ + headerLeft: () => navigation.goBack()}> + Cancel + , + }); + }, [navigation, modalStyles]); + + useEffect(() => { + let urlValid = false; + + try { + new URL(serverAddress); + urlValid = true; + } catch { + // do nothing + } + + const themeOptions = urlValid ? modalStyles.headerText : {color: theme.colors.outline}; + + navigation.setOptions({ + headerRight: () => saveServer()}> + Save + + }) + }, [navigation, modalStyles, serverAddress]); + + const saveServer = useCallback(() => { + let serverObject = realm.objects("server").find(x => x.serverAddress == serverAddress); + if (!serverObject) { + realm.write(() => { + serverObject = realm.create("server", AMServer.generate(serverAddress)); + }); + } + + navigation.goBack(); + setTimeout(() => navigation.navigate('server-card-in', { + serverId: serverObject._id.toHexString() + }), 500); + }, [serverAddress, realm]); + + return ( + + + + + Address + + + + + + + + If you're using HTTPS, ensure a trusted certificate has been configured via HTTP.SYS + + ) +} diff --git a/amnet-native/app/ServerCardIn.tsx b/amnet-native/app/ServerCardIn.tsx new file mode 100644 index 0000000..d9bcacd --- /dev/null +++ b/amnet-native/app/ServerCardIn.tsx @@ -0,0 +1,9 @@ +import {ScrollView} from "react-native"; + +export default function ServerCardIn({navigation}) { + return ( + + + + ) +} \ No newline at end of file diff --git a/amnet-native/app/ServerManager.tsx b/amnet-native/app/ServerManager.tsx index e0cdc39..656f79b 100644 --- a/amnet-native/app/ServerManager.tsx +++ b/amnet-native/app/ServerManager.tsx @@ -1,9 +1,61 @@ -import {Text, View} from "react-native"; +import {Paragraph} from "react-native-paper"; +import React, {useCallback, useMemo} from "react"; +import {FlatList, Text, View} from "react-native"; +import {Globe, History, ServerOff} from "lucide-react-native"; +import {EmptyStatePlaceholder} from "../components/EmptyStatePlaceholder"; +import {AMUICard, AMUICardDetail} from "../components/AMUICard"; +import TimeAgo from "../components/TimeAgo"; + +import RealmContext from "../models/RealmContext"; +import {AMServer} from "../models/AMServer"; + +const {useQuery} = RealmContext; + +function ServerCard(props: { server: AMServer, navigation: any }) { + const pageCallback = useCallback(() => { + props.navigation.navigate('server-card-in', { + serverId: props.server._id.toHexString() + }); + }, [props.navigation, props.server]); -export default function ServerManager() { return ( - - Server Manager - - ); + + + + + {props.server.serverAddress} + + + + + {props.server.lastUsed + ? () + : (never)} + + + ) +} + +export default function ServerManager({navigation}) { + const query = useQuery(AMServer); + const servers = useMemo(() => query.sorted("lastUsed"), [query]); + + if (!servers.length) { + return ( + + }/> + + ); + } + + + return ( + i._id.toString()} + contentContainerStyle={{paddingBottom: 40}} + ItemSeparatorComponent={() => } + renderItem={i => }/> + ) } \ No newline at end of file diff --git a/amnet-native/app/ServerManagerStack.tsx b/amnet-native/app/ServerManagerStack.tsx new file mode 100644 index 0000000..037bd44 --- /dev/null +++ b/amnet-native/app/ServerManagerStack.tsx @@ -0,0 +1,42 @@ +import {Plus} from "lucide-react-native"; +import {TouchableOpacity} from "react-native"; +import {useTheme} from "@react-navigation/native"; +import {createNativeStackNavigator} from "@react-navigation/native-stack"; + +import ServerCardIn from "./ServerCardIn"; +import ServerManager from "./ServerManager"; +import ServerAddModal from "./ServerAddModal"; + +const Stack = createNativeStackNavigator(); + +export default function ServerManagerStack({navigation}) { + const theme = useTheme(); + + return ( + + + navigation.navigate('add-server')}> + + + }}/> + + + + + + + + + ); +} \ No newline at end of file