From dc43d3b20ca5ea8207ff90678a1e2a9925bdd72b Mon Sep 17 00:00:00 2001 From: gibbyb Date: Mon, 17 Mar 2025 12:58:04 -0500 Subject: [PATCH] Fixed the automatic updating of all statuses. --- components/status/StatusList.tsx | 128 +++++++++++++++++++++++++++---- 1 file changed, 113 insertions(+), 15 deletions(-) diff --git a/components/status/StatusList.tsx b/components/status/StatusList.tsx index 0e8e6ac..478267a 100644 --- a/components/status/StatusList.tsx +++ b/components/status/StatusList.tsx @@ -304,12 +304,8 @@ const StatusList = ({headerImage, headerTitle}: StatusListProps) => { }; }, [fetchStatuses, isFocused, lastFetchTime]); - // Set up realtime subscription const setupRealtimeSubscription = useCallback(() => { - // Get only statuses from the last week to reduce payload - const oneWeekAgo = new Date(); - oneWeekAgo.setDate(oneWeekAgo.getDate() - 7); - + console.log('Setting up realtime subscription'); const subscription = supabase .channel('status_changes') .on('postgres_changes', @@ -317,33 +313,135 @@ const StatusList = ({headerImage, headerTitle}: StatusListProps) => { event: 'INSERT', schema: 'public', table: 'statuses', - filter: `created_at>gt.${oneWeekAgo.toISOString()}` }, (payload) => { console.log('New status received:', payload); - handleNewStatus(payload.new.id); + // Get the complete data immediately instead of just the ID + const newStatus = payload.new; + // Fetch the complete status with profile data + fetchStatusWithProfile(newStatus.id); } ) .subscribe((status) => { console.log('Realtime subscription status:', status); }); - subscriptionRef.current = subscription; return subscription; - }, [handleNewStatus]); + }, []); + + // Add this new function to fetch a single status with profile data + const fetchStatusWithProfile = async (statusId: string) => { + try { + console.log('Fetching status with profile:', statusId); + const { data, error } = await supabase + .from('statuses') + .select(` + id, + user_id, + status, + created_at, + profiles:profiles(full_name, avatar_url) + `) + .eq('id', statusId) + .single(); + + if (error) throw error; + if (data) { + // Transform the data + const transformedStatus = { + ...data, + profiles: Array.isArray(data.profiles) ? data.profiles[0] : data.profiles + }; + + console.log('Received transformed status:', transformedStatus); + + // Update statuses immediately without debouncing + setStatuses(prevStatuses => { + const newStatuses = [...prevStatuses]; + const existingIndex = newStatuses.findIndex(s => s.user_id === transformedStatus.user_id); + + if (existingIndex !== -1) { + // If the new status is more recent, replace the existing one + if (new Date(transformedStatus.created_at) > new Date(newStatuses[existingIndex].created_at)) { + newStatuses[existingIndex] = transformedStatus; + + // Mark as recently updated + setRecentlyUpdatedIds(prev => { + const newSet = new Set(prev); + newSet.add(transformedStatus.id); + return newSet; + }); + + // Schedule removal of highlight + setTimeout(() => { + setRecentlyUpdatedIds(current => { + const updatedSet = new Set(current); + updatedSet.delete(transformedStatus.id); + return updatedSet; + }); + }, 3000); + } + } else { + // If this is a new user, add to the array + newStatuses.push(transformedStatus); + + // Mark as recently updated + setRecentlyUpdatedIds(prev => { + const newSet = new Set(prev); + newSet.add(transformedStatus.id); + return newSet; + }); + + // Schedule removal of highlight + setTimeout(() => { + setRecentlyUpdatedIds(current => { + const updatedSet = new Set(current); + updatedSet.delete(transformedStatus.id); + return updatedSet; + }); + }, 3000); + } + + // Sort by most recent + newStatuses.sort((a, b) => + new Date(b.created_at).getTime() - new Date(a.created_at).getTime() + ); + + return newStatuses; + }); + + // Animate the fade-in + Animated.sequence([ + Animated.timing(fadeAnimation, { + toValue: 1, + duration: 300, + useNativeDriver: true, + }), + Animated.timing(fadeAnimation, { + toValue: 0, + duration: 300, + delay: 2000, + useNativeDriver: true, + }), + ]).start(); + } + } catch (error) { + console.error('Error fetching status with profile:', error); + } + }; // Set up real-time subscription when component is focused useEffect(() => { + let subscription: RealtimeChannel | null = null; if (isFocused && isConnected) { - // Initial fetch fetchStatuses(); - - // Set up real-time subscription - const subscription = setupRealtimeSubscription(); + subscription = setupRealtimeSubscription(); + console.log('Subscription established: ', subscription); // Clean up subscription when component unmounts or loses focus return () => { if (subscription) { + console.log('Removing subscription channel: ', subscription); supabase.removeChannel(subscription); subscriptionRef.current = null; } @@ -540,14 +638,14 @@ const styles = StyleSheet.create({ flexDirection: 'row', padding: 16, borderRadius: 12, - marginHorizontal: 16, + marginHorizontal: 8, marginVertical: 8, shadowColor: '#000', shadowOffset: { width: 0, height: 1 }, shadowOpacity: 0.1, shadowRadius: 2, elevation: 2, - height: 104, // Fixed height for getItemLayout optimization + height: 120, // Fixed height for getItemLayout optimization }, recentlyUpdated: { backgroundColor: 'rgba(100, 200, 255, 0.1)',