JIT
call handleRefresh on scroll down in schedule screen component
import React, {useState, useEffect, useCallback, useLayoutEffect} from 'react'; import { TouchableOpacity, Text, View, FlatList, Alert, ActivityIndicator, Image, TextInput, } from 'react-native'; import {useUser} from '../../context/UserContext'; import ApiManager from '../../services/ApiManager'; import ScheduleScreenStyle from '../../styles/ScheduleScreenStyle'; import {useMqtt} from '../../context/MqttContext'; import {useFocusEffect} from '@react-navigation/native'; import moment from 'moment'; import {COLORS} from '../../styles/colors'; import {fontSize, fontWeight} from '../../styles/fontstyle'; import {ADD, ARROW, CALENDER, SEARCH, TIME} from '../../assets'; import HomeScreenStyles from '../../styles/HomeScreenStyles'; import AddItemModal from '../../services/AddItemModal'; import uiStyle from '../../styles/uiStyle'; const ScheduleScreen = ({navigation}) => { const [items, setItems] = useState([]); const [filteredItems, setFilteredItems] = useState([]); const [isFetching, setIsFetching] = useState(false); const [search, setSearch] = useState(''); const [scheduleId, setScheduleId] = useState(''); const [scheduleName, setScheduleName] = useState(''); const [deletePoup, setDeletePopup] = useState(false); const {userDetails} = useUser(); const {connectionState, subscribe, unsubscribe, publish} = useMqtt(); const [sceneStatuses, setSceneStatuses] = useState({}); const MQTT_SUBSCRIBE_TOPIC = 'advaint/deletesceneschedule/cus_' + userDetails.customer_id + '/feedback'; const MQTT_PUBLISH_TOPIC = `advaint/deletesceneschedule/cus_${userDetails.customer_id}`; useEffect(() => { if (userDetails?.customer_id) { getScheduleDetails(); } else { setItems([]); } }, [userDetails?.customer_id]); useEffect(() => { const filtered = items.filter(item => `${item.schedule_name} ${item.scene_name}` .toLowerCase() .includes(search.toLowerCase()), ); setFilteredItems(filtered); }, [search, items]); useLayoutEffect(() => { navigation.setOptions({ headerRight: () => ( <TouchableOpacity style={{ backgroundColor: uiStyle.blue_color, borderRadius: 100, marginRight: 20, padding: 5, }} onPress={() => {}}> <Image source={ADD} style={{height: 20, width: 20, tintColor: COLORS.white_color}} /> </TouchableOpacity> ), }); }, [navigation, userDetails]); useFocusEffect( useCallback(() => { const callback = (data, topic) => { try { const payload = JSON.parse(data); console.log('payload', payload); if (payload) { handleRefresh(); } } catch (e) { console.warn('MQTT message data is not JSON:', data); } }; subscribe(MQTT_SUBSCRIBE_TOPIC, callback); return () => { unsubscribe(MQTT_SUBSCRIBE_TOPIC, callback); }; }, [subscribe, unsubscribe, userDetails?.flat]), ); const getScheduleDetails = async (isManualRefresh = false) => { if (!userDetails?.customer_id) { setIsFetching(false); return; } setIsFetching(true); const customer_id = userDetails.customer_id; try { const listResponse = await ApiManager.getScheduleScene(customer_id); if (listResponse?.Data) { setItems(listResponse.Data); } else { setItems([]); if (isManualRefresh) { Alert.alert('Error', 'Invalid data format received.'); } } } catch (error) { if (isManualRefresh) { Alert.alert( 'Fetch Failed', error.message || 'Unexpected error occurred.', ); } setItems([]); } finally { setIsFetching(false); } }; const handleRefresh = () => { getScheduleDetails(true); }; const deleteSchedule = () => { const deleteJson = { customer_id: userDetails?.customer_id, schedule_id: scheduleId, }; console.log('Publishing MQTT message:', deleteJson); publish(MQTT_PUBLISH_TOPIC, deleteJson); }; const renderItem = ({item}) => { const totalDays = item.day_of_week; const selectedDaysList = totalDays.split(',').map(Number); const dayAbbreviations = ['Su', 'M', 'Tu', 'W', 'Th', 'F', 'Sa']; const abbreviatedDays = selectedDaysList.map( dayNumber => dayAbbreviations[dayNumber], ); const abbreviatedDaysText = abbreviatedDays.join(', '); return ( <TouchableOpacity style={ScheduleScreenStyle.ScheduleListView} onPress={() => { setScheduleId(item.schedule_id); setScheduleName(item.schedule_name); setDeletePopup(true); }}> <View> <Text style={ScheduleScreenStyle.schedule_header_style}> {item.schedule_name} </Text> <Text style={{ color: COLORS.label_color, fontSize: fontSize.sub_heading, fontWeight: fontWeight.label_weight, marginBottom: 5, }}> Scene:{' '} <Text style={ScheduleScreenStyle.contenView}> {item.scene_name} </Text> </Text> <View style={ScheduleScreenStyle.date_time_details_View}> <Image source={CALENDER} style={{height: 20, width: 20}} /> <Text style={ScheduleScreenStyle.contenView}> {moment(item.start_date).format('DD-MM-YYYY')} to{' '} {moment(item.end_date).format('DD-MM-YYYY')} {'\n'} ({abbreviatedDaysText}) </Text> </View> <View style={ScheduleScreenStyle.date_time_details_View}> <Image source={TIME} style={{height: 20, width: 20}} /> <Text style={ScheduleScreenStyle.contenView}> {moment(item.start_time, 'HH:mm').format('hh:mm a')} to{' '} {moment(item.end_time, 'HH:mm').format('hh:mm a')} </Text> </View> </View> <Image source={ARROW} style={{height: 20, width: 20}} /> </TouchableOpacity> ); }; const renderContent = () => { if (isFetching && items.length === 0) { return ( <View style={ScheduleScreenStyle.centeredMessageContainer}> <ActivityIndicator size="large" color="#007bff" /> <Text style={ScheduleScreenStyle.messageText}>Loading items...</Text> </View> ); } if (!isFetching && filteredItems.length === 0) { return ( <View style={ScheduleScreenStyle.centeredMessageContainer}> <Text style={ScheduleScreenStyle.messageText}> No items found </Text> </View> ); } return ( <FlatList data={filteredItems} renderItem={renderItem} keyExtractor={item => item.id} contentContainerStyle={ScheduleScreenStyle.listContentContainer} onRefresh={handleRefresh} refreshing={isFetching} /> ); }; return ( <View style={ScheduleScreenStyle.safeArea}> <View style={ScheduleScreenStyle.searchView}> <Image source={SEARCH} style={{height: 20, width: 20, tintColor: COLORS.black_color}} /> <TextInput value={search} placeholder="Search" onChangeText={text => setSearch(text)} style={{flex: 1, marginLeft: 10}} /> </View> {renderContent()} {deletePoup && ( <AddItemModal isVisible={deletePoup} onClose={() => { setDeletePopup(false); }} modalTitle={`Schedule: ${scheduleName}`} fields={[]} type="delete_schedule" onDisableSchedule={() => { deleteSchedule(); setDeletePopup(false); }}> <View style={HomeScreenStyles.modalDisplayContent}></View> </AddItemModal> )} </View> ); }; export default ScheduleScreen; here i want to call handleRefresh even if filteredItems is empty i want to call it when i scroll down on screen
Updated files
v1