Moxitech-Websocket-Do/frontend/app/(tabs)/index.tsx

193 lines
4.8 KiB
TypeScript
Raw Normal View History

import { Image, StyleSheet, Button, ActivityIndicator, TextInput, Alert } from 'react-native';
2024-09-01 02:36:40 +07:00
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';
2024-09-01 02:36:40 +07:00
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);
2024-09-01 02:36:40 +07:00
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),
2024-09-01 02:36:40 +07:00
});
} 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();
};
2024-09-01 02:36:40 +07:00
}, []);
2024-09-01 02:36:40 +07:00
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 ?
2024-09-01 02:36:40 +07:00
<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>
2024-09-01 02:36:40 +07:00
<ThemedView style={styles.buttonAddStyle}>
<Button
onPress={addNewMessage}
2024-09-01 02:36:40 +07:00
title="+"
color="green"
accessibilityLabel="Add new block"
/>
</ThemedView>
</ParallaxScrollView>
);
}
2024-09-01 02:36:40 +07:00
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,
},
2024-09-01 02:36:40 +07:00
});