Moxitech-Websocket-Do/frontend/app/(tabs)/index.tsx
2024-09-01 19:43:58 +07:00

193 lines
4.8 KiB
TypeScript
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { Image, StyleSheet, Button, ActivityIndicator, TextInput, Alert } from 'react-native';
import ParallaxScrollView from '@/components/ParallaxScrollView';
import { ThemedText } from '@/components/ThemedText';
import { ThemedView } from '@/components/ThemedView';
import { useEffect, useState } from 'react';
import NetInfo from '@react-native-community/netinfo';
interface Message {
title: string;
type: string;
additionally: {
payload: string;
};
}
interface Data {
users: string[];
messages: Message[];
}
export default function HomeScreen() {
const [groupData, setGroupData] = useState<Data | null>(null);
const [newMessageTitle, setNewMessageTitle] = useState<string>('');
const [newMessagePayload, setNewMessagePayload] = useState<string>('');
const [isSyncing, setIsSyncing] = useState<boolean>(false);
const fetchData = async () => {
try {
const response = await fetch("http://127.0.0.1:8099/grouphash:1/reloadDataFromServer");
const data: Data = await response.json();
setGroupData(data);
} catch (error) {
console.log('Fetch error:', error);
}
};
const addNewMessage = async () => {
if (!newMessageTitle || !newMessagePayload) {
Alert.alert("Error", "Please fill in both the title and the content of the message.");
return;
}
const newMessage: Message = {
title: newMessageTitle,
type: "text",
additionally: {
payload: newMessagePayload,
}
};
// Мгновенное обновление локального состояния
setGroupData(prevData => {
if (prevData) {
return {
...prevData,
messages: [...prevData.messages, newMessage],
};
}
return null;
});
setNewMessageTitle('');
setNewMessagePayload('');
// Отправка новой заметки на сервер
try {
await fetch("http://127.0.0.1:8099/grouphash:1/addMessage", {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(newMessage),
});
} catch (error) {
console.log('Error syncing new message:', error);
}
};
useEffect(() => {
const syncWithServer = async () => {
setIsSyncing(true);
await fetchData();
setIsSyncing(false);
};
const unsubscribe = NetInfo.addEventListener(state => {
if (state.isConnected) {
syncWithServer();
}
});
// Первоначальная загрузка данных
syncWithServer();
return () => {
unsubscribe();
};
}, []);
return (
<ParallaxScrollView
headerBackgroundColor={{ light: '#A1CEDC', dark: '#1D3D47' }}
headerImage={
<Image
source={require('@/assets/images/partial-react-logo.png')}
style={styles.reactLogo}
/>
}>
<ThemedView style={styles.titleContainer}>
<ThemedText type="title">Пользователи</ThemedText>
{groupData?.users.map((user, index) => (
<ThemedText key={index}>{user}</ThemedText>
))}
</ThemedView>
<ThemedView>
{isSyncing ?
<ActivityIndicator size="large" color="#00ff00" /> :
groupData?.messages.map((message, index) => (
<ThemedView key={index} style={styles.Message}>
<ThemedText>{message.title}</ThemedText>
{ message.type === "text" ?
<ThemedText>{message.additionally.payload}</ThemedText> :
<ThemedText>!!! Please Update Program !!!</ThemedText>
}
</ThemedView>
))
}
</ThemedView>
<ThemedView style={styles.inputContainer}>
<TextInput
style={styles.input}
placeholder="Title"
value={newMessageTitle}
onChangeText={setNewMessageTitle}
/>
<TextInput
style={styles.input}
placeholder="Content"
value={newMessagePayload}
onChangeText={setNewMessagePayload}
/>
</ThemedView>
<ThemedView style={styles.buttonAddStyle}>
<Button
onPress={addNewMessage}
title="+"
color="green"
accessibilityLabel="Add new block"
/>
</ThemedView>
</ParallaxScrollView>
);
}
const styles = StyleSheet.create({
titleContainer: {
flexDirection: 'row',
alignItems: 'center',
gap: 8,
},
reactLogo: {
height: 178,
width: 290,
bottom: 0,
left: 0,
position: 'absolute',
},
Message: {
backgroundColor: 'grey',
padding: 10,
marginBottom: 10,
borderRadius: 10,
},
buttonAddStyle: {
width: 50,
height: 60,
},
inputContainer: {
padding: 10,
},
input: {
height: 40,
borderColor: 'gray',
borderWidth: 1,
marginBottom: 10,
paddingHorizontal: 10,
},
});