233 lines
6.2 KiB
TypeScript
233 lines
6.2 KiB
TypeScript
|
import { Image, StyleSheet, Button, ActivityIndicator, TextInput, Modal, Pressable, View } 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 GroupData {
|
|||
|
groupName: string;
|
|||
|
users: string[];
|
|||
|
messages: Message[];
|
|||
|
}
|
|||
|
|
|||
|
export default function GroupsScreen() {
|
|||
|
const [groups, setGroups] = useState<GroupData[]>([]);
|
|||
|
const [isSyncing, setIsSyncing] = useState<boolean>(false);
|
|||
|
const [isModalVisible, setIsModalVisible] = useState<boolean>(false);
|
|||
|
const [newGroupName, setNewGroupName] = useState<string>("");
|
|||
|
|
|||
|
const fetchGroups = async () => {
|
|||
|
try {
|
|||
|
setIsSyncing(true);
|
|||
|
const response = await fetch("http://127.0.0.1:8099/getAllGroups");
|
|||
|
const data: GroupData[] = await response.json();
|
|||
|
setGroups(data);
|
|||
|
} catch (error) {
|
|||
|
console.log('Fetch error:', error);
|
|||
|
} finally {
|
|||
|
setIsSyncing(false);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
const createGroup = async () => {
|
|||
|
if (!newGroupName.trim()) return;
|
|||
|
|
|||
|
try {
|
|||
|
const response = await fetch(`http://127.0.0.1:8099/create_group?group_name=` + newGroupName + `&username=` + "moxitech", {
|
|||
|
method: "GET",
|
|||
|
headers: {
|
|||
|
'Content-Type': 'application/json',
|
|||
|
},
|
|||
|
});
|
|||
|
|
|||
|
if (response.ok) {
|
|||
|
await fetchGroups(); // Обновляем список групп после создания новой
|
|||
|
setIsModalVisible(false); // Закрываем модальное окно
|
|||
|
setNewGroupName(""); // Сбрасываем имя новой группы
|
|||
|
}
|
|||
|
} catch (error) {
|
|||
|
console.log('Create group error:', error);
|
|||
|
}
|
|||
|
};
|
|||
|
|
|||
|
useEffect(() => {
|
|||
|
const syncWithServer = async () => {
|
|||
|
await fetchGroups();
|
|||
|
};
|
|||
|
|
|||
|
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.buttonContainer}>
|
|||
|
<Button
|
|||
|
title="Создать группу"
|
|||
|
color="green"
|
|||
|
onPress={() => setIsModalVisible(true)}
|
|||
|
/>
|
|||
|
</ThemedView>
|
|||
|
|
|||
|
{/* {isSyncing ? (
|
|||
|
<ActivityIndicator size="large" color="#00ff00" />
|
|||
|
) : (
|
|||
|
<Text>None</Text>
|
|||
|
// groups.map( (group, groupIndex) => (
|
|||
|
// <ThemedView key={groupIndex} style={styles.groupContainer}>
|
|||
|
// <ThemedText type="title">{group.groupName}</ThemedText>
|
|||
|
|
|||
|
// <ThemedView style={styles.titleContainer}>
|
|||
|
// <ThemedText type="subtitle">Пользователи</ThemedText>
|
|||
|
// {group.users.map((user, userIndex) => (
|
|||
|
// <ThemedText key={userIndex}>{user}</ThemedText>
|
|||
|
// ))}
|
|||
|
// </ThemedView>
|
|||
|
|
|||
|
// <ThemedView>
|
|||
|
// {group.messages.map((message, messageIndex) => (
|
|||
|
// <ThemedView key={messageIndex} style={styles.Message}>
|
|||
|
// <ThemedText>{message.title}</ThemedText>
|
|||
|
// {message.type === "text" ?
|
|||
|
// <ThemedText>{message.additionally.payload}</ThemedText> :
|
|||
|
// <ThemedText>!!! Please Update Program !!!</ThemedText>
|
|||
|
// }
|
|||
|
// </ThemedView>
|
|||
|
// ))}
|
|||
|
// </ThemedView>
|
|||
|
// </ThemedView>
|
|||
|
// ))
|
|||
|
)
|
|||
|
} */}
|
|||
|
|
|||
|
<Modal
|
|||
|
animationType="slide"
|
|||
|
transparent={true}
|
|||
|
visible={isModalVisible}
|
|||
|
onRequestClose={() => setIsModalVisible(false)}
|
|||
|
>
|
|||
|
<View style={styles.centeredView}>
|
|||
|
<View style={styles.modalView}>
|
|||
|
<ThemedText type="title">Создать новую группу</ThemedText>
|
|||
|
<TextInput
|
|||
|
style={styles.input}
|
|||
|
placeholder="Введите имя группы"
|
|||
|
value={newGroupName}
|
|||
|
onChangeText={setNewGroupName}
|
|||
|
/>
|
|||
|
<Pressable
|
|||
|
style={[styles.button, styles.buttonClose]}
|
|||
|
onPress={createGroup}
|
|||
|
>
|
|||
|
<ThemedText style={styles.textStyle}>Создать</ThemedText>
|
|||
|
</Pressable>
|
|||
|
<Pressable
|
|||
|
style={[styles.button, styles.buttonClose]}
|
|||
|
onPress={() => setIsModalVisible(false)}
|
|||
|
>
|
|||
|
<ThemedText style={styles.textStyle}>Отмена</ThemedText>
|
|||
|
</Pressable>
|
|||
|
</View>
|
|||
|
</View>
|
|||
|
</Modal>
|
|||
|
</ParallaxScrollView>
|
|||
|
);
|
|||
|
}
|
|||
|
|
|||
|
const styles = StyleSheet.create({
|
|||
|
groupContainer: {
|
|||
|
marginBottom: 20,
|
|||
|
},
|
|||
|
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,
|
|||
|
},
|
|||
|
buttonContainer: {
|
|||
|
margin: 10,
|
|||
|
alignItems: 'center',
|
|||
|
},
|
|||
|
centeredView: {
|
|||
|
flex: 1,
|
|||
|
justifyContent: 'center',
|
|||
|
alignItems: 'center',
|
|||
|
marginTop: 22,
|
|||
|
},
|
|||
|
modalView: {
|
|||
|
margin: 20,
|
|||
|
backgroundColor: 'white',
|
|||
|
borderRadius: 20,
|
|||
|
padding: 35,
|
|||
|
alignItems: 'center',
|
|||
|
shadowColor: '#000',
|
|||
|
shadowOffset: {
|
|||
|
width: 0,
|
|||
|
height: 2,
|
|||
|
},
|
|||
|
shadowOpacity: 0.25,
|
|||
|
shadowRadius: 4,
|
|||
|
elevation: 5,
|
|||
|
},
|
|||
|
button: {
|
|||
|
borderRadius: 20,
|
|||
|
padding: 10,
|
|||
|
elevation: 2,
|
|||
|
},
|
|||
|
buttonClose: {
|
|||
|
backgroundColor: '#2196F3',
|
|||
|
marginTop: 10,
|
|||
|
},
|
|||
|
input: {
|
|||
|
height: 40,
|
|||
|
margin: 12,
|
|||
|
borderWidth: 1,
|
|||
|
padding: 10,
|
|||
|
width: 200,
|
|||
|
},
|
|||
|
textStyle: {
|
|||
|
color: 'white',
|
|||
|
fontWeight: 'bold',
|
|||
|
textAlign: 'center',
|
|||
|
},
|
|||
|
});
|