import Button from '@app/components/Button' import GradientScrollView from '@app/components/GradientScrollView' import { Server } from '@app/models/settings' import { selectSettings } from '@app/state/settings' import { useStore } from '@app/state/store' import colors from '@app/styles/colors' import font from '@app/styles/font' import { useNavigation } from '@react-navigation/native' import md5 from 'md5' import React, { useCallback, useState } from 'react' import { StyleSheet, Text, TextInput, ToastAndroid, View } from 'react-native' import { v4 as uuidv4 } from 'uuid' const ServerView: React.FC<{ id?: string }> = ({ id }) => { const navigation = useNavigation() const activeServer = useStore(selectSettings.activeServer) const servers = useStore(selectSettings.servers) const addServer = useStore(selectSettings.addServer) const updateServer = useStore(selectSettings.updateServer) const removeServer = useStore(selectSettings.removeServer) const server = id ? servers.find(s => s.id === id) : undefined const pingServer = useStore(selectSettings.pingServer) const [address, setAddress] = useState(server?.address || '') const [username, setUsername] = useState(server?.username || '') const [password, setPassword] = useState(server?.token ? 'password' : '') const [testing, setTesting] = useState(false) const [removing, setRemoving] = useState(false) const [saving, setSaving] = useState(false) const validate = useCallback(() => { return !!address && !!username && !!password }, [address, username, password]) const canRemove = useCallback(() => { return id && servers.length > 1 && activeServer?.id !== id }, [id, servers, activeServer]) const exit = useCallback(() => { if (navigation.canGoBack()) { navigation.goBack() } else { navigation.navigate('main') } }, [navigation]) const createServer = useCallback<() => Server>(() => { const salt = server?.salt || uuidv4() let token: string if (password === 'password' && server?.token) { token = server.token } else { token = md5(password + salt) } return { id: server?.id || uuidv4(), address, username, salt, token, } }, [address, password, server?.id, server?.salt, server?.token, username]) const save = useCallback(() => { if (!validate()) { return } setSaving(true) const update = createServer() const waitForSave = async () => { try { if (id) { updateServer(update) } else { await addServer(update) } exit() } catch (err) { console.error(err) setSaving(false) } } waitForSave() }, [addServer, createServer, exit, id, updateServer, validate]) const remove = useCallback(() => { if (!canRemove()) { return } setRemoving(true) const waitForRemove = async () => { try { await removeServer(id as string) exit() } catch (err) { console.error(err) setRemoving(false) } } waitForRemove() }, [canRemove, exit, id, removeServer]) const test = useCallback(() => { setTesting(true) const potential = createServer() const ping = async () => { const res = await pingServer(potential) if (res) { ToastAndroid.show(`Connection to ${potential.address} OK!`, ToastAndroid.SHORT) } else { ToastAndroid.show(`Connection to ${potential.address} failed, check settings or server`, ToastAndroid.SHORT) } setTesting(false) } ping() }, [createServer, pingServer, setTesting]) const disableControls = useCallback(() => { return !validate() || testing || removing || saving }, [validate, testing, removing, saving]) return ( Address Username Password