import React, {useState, useEffect, useCallback} from 'react';
import {
TouchableOpacity,
Text,
View,
FlatList,
Alert,
ActivityIndicator,
} from 'react-native';
import {useUser} from '../../context/UserContext';
import ApiManager from '../../services/ApiManager';
import SceneSceenStyle from '../../styles/SceneSceenStyle';
import {useMqtt} from '../../context/MqttContext';
import {useFocusEffect} from '@react-navigation/native';
import {COLORS} from '../../styles/colors';
import uiStyle from '../../styles/uiStyle';
import SceneSkeleton from '../../services/SceneSkeleton';
const SceneScreen = ({navigation}) => {
const [items, setItems] = useState([]);
const [isFetching, setIsFetching] = useState(false);
const {userDetails} = useUser();
const {connectionState, subscribe, unsubscribe, publish} = useMqtt();
// --- MQTT Topics ---
const MQTT_SUBSCRIBE_TOPIC =
'advaint/cus_' + userDetails.customer_id + '/scene/feedback';
const MQTT_PUBLISH_TOPIC =
'advaint/cus_' + userDetails.customer_id + '/scene';
useEffect(() => {
if (userDetails?.customer_id) {
getSceneDetails();
} else {
setItems([]);
}
}, [userDetails?.customer_id]);
useFocusEffect(
useCallback(() => {
console.log(
'HomeScreen focused, subscribing to MQTT topic:',
MQTT_SUBSCRIBE_TOPIC,
);
const callback = (data, topic) => {
// Handle incoming messages
console.log(`Received MQTT message on topic: ${topic}, data: ${data}`);
try {
const payload = JSON.parse(data);
console.log('Parsed MQTT Payload:', payload);
if (payload && payload.scene_id && payload.scene_status) {
setItems(prevItems => {
return prevItems.map(item => {
if (item.scene_id === payload.scene_id) {
return {...item, scene_status: payload.scene_status};
}
return item;
});
});
}
} catch (e) {
console.warn('MQTT message data is not JSON:', data);
}
};
subscribe(MQTT_SUBSCRIBE_TOPIC, callback);
return () => {
console.log(
'HomeScreen blurred, unsubscribing from MQTT topic:',
MQTT_SUBSCRIBE_TOPIC,
);
unsubscribe(MQTT_SUBSCRIBE_TOPIC, callback);
};
}, [subscribe, unsubscribe, userDetails?.flat]),
);
const getSceneDetails = async (isManualRefresh = false) => {
if (!userDetails?.customer_id) {
console.log('User details not available yet or missing customer_id.');
setIsFetching(false);
return;
}
console.log(`Fetching list... Manual Refresh: ${isManualRefresh}`);
setIsFetching(true);
const customer_id = userDetails.customer_id;
try {
const listResponse = await ApiManager.getScene(customer_id);
console.log('zone received listResponse:', listResponse.Data);
if (listResponse) {
setItems(listResponse.Data);
} else {
console.error(
'API did not return expected data structure:',
listResponse,
);
setItems([]);
if (isManualRefresh) {
Alert.alert(
'Error',
'Failed to fetch items. Invalid data format received.',
);
}
}
} catch (error) {
console.error('Fetch List Error in CommunityScreen:', error);
if (isManualRefresh) {
Alert.alert(
'Fetch Failed',
error.message || 'An unexpected error occurred while fetching items.',
);
}
setItems([]);
} finally {
setIsFetching(false);
}
};
const handleRefresh = () => {
getSceneDetails(true);
};
const changeScene = item => {
console.log('item', item);
const scenJson = {
scene_id: item.scene_id,
parameter: item.scene_status === 'ON' ? 0 : 1,
mode: 'MOBILE',
contact_id: userDetails.flat_contact_id,
};
console.log('Publishing MQTT message:', scenJson);
publish(MQTT_PUBLISH_TOPIC, scenJson);
};
const renderItem = ({item}) => (
<TouchableOpacity
style={[
SceneSceenStyle.zoneListView,
{
backgroundColor:
item.scene_status === 'ON' ? uiStyle.blue_color : COLORS.white_color,
},
]}
onPress={() => {
changeScene(item);
}}>
<Text
style={[
SceneSceenStyle.itemTypeText,
{color: item.scene_status === 'ON' ? COLORS.white_color : null},
]}>
{item.scene_name}
</Text>
</TouchableOpacity>
);
const renderContent = () => {
if (isFetching && items.length === 0) {
return <SceneSkeleton />;
}
if (!isFetching && items.length === 0) {
return (
<View style={SceneSceenStyle.centeredMessageContainer}>
<Text style={SceneSceenStyle.messageText}>No scene items found.</Text>
</View>
);
}
return (
<FlatList
data={items}
renderItem={renderItem}
keyExtractor={item => item.scene_id.toString()}
contentContainerStyle={SceneSceenStyle.listContentContainer}
onRefresh={handleRefresh}
refreshing={isFetching}
/>
);
};
return <View style={SceneSceenStyle.safeArea}>{renderContent()}</View>;
};
export default SceneScreen;
i have used SceneSkeleton when data is loading on refresh also I want to fech SceneSkeleton untill data reloads
make chnages and provide code with src folder