Update Status
diff --git a/src/lib/hooks/useSharedStatusSubscription.ts b/src/lib/hooks/useSharedStatusSubscription.ts
index ea83c89..34819cc 100644
--- a/src/lib/hooks/useSharedStatusSubscription.ts
+++ b/src/lib/hooks/useSharedStatusSubscription.ts
@@ -1,5 +1,5 @@
'use client';
-import { useState, useEffect, useCallback } from 'react';
+import { useState, useEffect, useCallback, useRef } from 'react';
import { createClient } from '@/utils/supabase';
import type { RealtimeChannel } from '@supabase/supabase-js';
@@ -14,115 +14,197 @@ let sharedChannel: RealtimeChannel | null = null;
let sharedConnectionStatus: ConnectionStatus = 'disconnected';
const subscribers = new Set<(status: ConnectionStatus) => void>();
const statusUpdateCallbacks = new Set<() => void>();
-//const subscribers: Set<(status: ConnectionStatus) => void> = new Set();
-//const statusUpdateCallbacks: Set<() => void> = new Set();
let reconnectAttempts = 0;
let reconnectTimeout: NodeJS.Timeout | undefined;
const supabase = createClient();
const notifySubscribers = (status: ConnectionStatus) => {
+ console.log('๐ข notifySubscribers: Notifying', subscribers.size, 'subscribers of status change to:', status);
sharedConnectionStatus = status;
- subscribers.forEach(callback => callback(status));
+ subscribers.forEach((callback, index) => {
+ console.log('๐ข notifySubscribers: Calling subscriber', index + 1);
+ callback(status);
+ });
+ console.log('๐ข notifySubscribers: All subscribers notified');
};
const notifyStatusUpdate = () => {
- statusUpdateCallbacks.forEach(callback => callback());
+ console.log('๐ notifyStatusUpdate: Notifying', statusUpdateCallbacks.size, 'status update callbacks');
+ statusUpdateCallbacks.forEach((callback, index) => {
+ console.log('๐ notifyStatusUpdate: Calling callback', index + 1);
+ callback();
+ });
+ console.log('๐ notifyStatusUpdate: All callbacks executed');
};
const cleanup = () => {
+ console.log('๐งน cleanup: Starting cleanup process');
+
if (reconnectTimeout) {
+ console.log('๐งน cleanup: Clearing reconnect timeout');
clearTimeout(reconnectTimeout);
reconnectTimeout = undefined;
}
if (sharedChannel) {
+ console.log('๐งน cleanup: Removing shared channel');
supabase.removeChannel(sharedChannel).catch((error) => {
- console.error('Error removing shared channel:', error);
+ console.error('โ cleanup: Error removing shared channel:', error);
});
sharedChannel = null;
}
+
+ console.log('โ
cleanup: Cleanup completed');
};
const connect = () => {
- if (sharedChannel) return; // Already connected or connecting
+ console.log('๐ connect: Function called');
+ console.log('๐ connect: sharedChannel exists:', !!sharedChannel);
+ console.log('๐ connect: subscribers count:', subscribers.size);
+ if (sharedChannel) {
+ console.log('โ connect: Already connected or connecting, returning early');
+ return;
+ }
+
+ console.log('๐ connect: Starting connection process');
cleanup();
notifySubscribers('connecting');
+ console.log('๐ connect: Creating new channel');
const channel = supabase
.channel('shared_status_updates', {
config: { broadcast: {self: true }}
})
- .on('broadcast', { event: 'status_updated' }, () => {
+ .on('broadcast', { event: 'status_updated' }, (payload) => {
+ console.log('๐ก connect: Broadcast event received:', payload);
notifyStatusUpdate();
})
.subscribe((status) => {
+ console.log('๐ก connect: Subscription status changed to:', status);
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
if (status === 'SUBSCRIBED') {
+ console.log('โ
connect: Successfully subscribed to realtime');
notifySubscribers('connected');
reconnectAttempts = 0;
+ console.log('โ
connect: Reset reconnect attempts to 0');
// eslint-disable-next-line @typescript-eslint/no-unsafe-enum-comparison
} else if (status === 'CHANNEL_ERROR' || status === 'CLOSED') {
+ console.log('โ connect: Channel error or closed, status:', status);
notifySubscribers('disconnected');
if (reconnectAttempts < 5) {
reconnectAttempts++;
const delay = 2000 * reconnectAttempts;
+ console.log('๐ connect: Scheduling reconnection attempt', reconnectAttempts, 'in', delay, 'ms');
reconnectTimeout = setTimeout(() => {
- if (subscribers.size > 0) { // Only reconnect if there are active subscribers
+ console.log('๐ connect: Reconnection timeout executed');
+ if (subscribers.size > 0) {
+ console.log('๐ connect: Calling connect() for reconnection');
connect();
+ } else {
+ console.log('โ connect: No active subscribers, skipping reconnection');
}
}, delay);
+ } else {
+ console.warn('โ ๏ธ connect: Max reconnection attempts (5) reached');
}
}
});
sharedChannel = channel;
+ console.log('๐ connect: Channel stored in sharedChannel variable');
};
const disconnect = () => {
+ console.log('๐ disconnect: Function called');
cleanup();
notifySubscribers('disconnected');
};
export const useSharedStatusSubscription = (onStatusUpdate?: () => void) => {
+ console.log('๐ useSharedStatusSubscription: Hook called');
+
const [connectionStatus, setConnectionStatus] = useState(sharedConnectionStatus);
+ const onStatusUpdateRef = useRef(onStatusUpdate);
+ const hasInitialized = useRef(false);
+
+ // Keep the ref updated
+ onStatusUpdateRef.current = onStatusUpdate;
+
+ // Create a stable callback
+ const stableOnStatusUpdate = useCallback(() => {
+ onStatusUpdateRef.current?.();
+ }, []);
useEffect(() => {
+ console.log('๐ง useSharedStatusSubscription useEffect: Running');
+ console.log('๐ง useSharedStatusSubscription useEffect: hasInitialized:', hasInitialized.current);
+ console.log('๐ง useSharedStatusSubscription useEffect: Current subscribers count:', subscribers.size);
+
+ // Prevent duplicate initialization
+ if (hasInitialized.current) {
+ console.log('๐ง useSharedStatusSubscription useEffect: Already initialized, skipping');
+ return;
+ }
+
+ hasInitialized.current = true;
+
// Subscribe to status changes
subscribers.add(setConnectionStatus);
+ console.log('๐ง useSharedStatusSubscription useEffect: Added setConnectionStatus to subscribers');
// Subscribe to status updates
if (onStatusUpdate) {
- statusUpdateCallbacks.add(onStatusUpdate);
+ statusUpdateCallbacks.add(stableOnStatusUpdate);
+ console.log('๐ง useSharedStatusSubscription useEffect: Added stable onStatusUpdate callback');
}
// Connect if this is the first subscriber
if (subscribers.size === 1) {
- const timeout = setTimeout(connect, 1000);
- return () => clearTimeout(timeout);
+ console.log('๐ง useSharedStatusSubscription useEffect: First subscriber, setting up connection');
+ const timeout = setTimeout(() => {
+ console.log('๐ง useSharedStatusSubscription useEffect: Connection timeout executed, calling connect()');
+ connect();
+ }, 1000);
+
+ return () => {
+ console.log('๐ง useSharedStatusSubscription useEffect: Cleanup - clearing connection timeout');
+ clearTimeout(timeout);
+ hasInitialized.current = false;
+ subscribers.delete(setConnectionStatus);
+ statusUpdateCallbacks.delete(stableOnStatusUpdate);
+
+ if (subscribers.size === 0) {
+ disconnect();
+ }
+ };
}
return () => {
- // Cleanup subscriptions
+ console.log('๐ง useSharedStatusSubscription useEffect: Cleanup function running');
+ hasInitialized.current = false;
subscribers.delete(setConnectionStatus);
- if (onStatusUpdate) {
- statusUpdateCallbacks.delete(onStatusUpdate);
- }
+ statusUpdateCallbacks.delete(stableOnStatusUpdate);
- // Disconnect if no more subscribers
if (subscribers.size === 0) {
+ console.log('๐ง useSharedStatusSubscription useEffect: No more subscribers, calling disconnect()');
disconnect();
}
};
- }, [onStatusUpdate]);
+ }, []); // Empty dependency array!
const reconnect = useCallback(() => {
+ console.log('๐ reconnect: Function called');
reconnectAttempts = 0;
+ console.log('๐ reconnect: Reset reconnectAttempts to 0, calling connect()');
connect();
}, []);
+ console.log('๐ useSharedStatusSubscription: connectionStatus:', connectionStatus);
+
return {
connectionStatus,
connect: reconnect,
diff --git a/src/lib/hooks/useStatusData.ts b/src/lib/hooks/useStatusData.ts
index 4f290de..aeedb00 100644
--- a/src/lib/hooks/useStatusData.ts
+++ b/src/lib/hooks/useStatusData.ts
@@ -37,7 +37,7 @@ export const useStatusData = ({
}
},
enabled,
- refetchInterval: 30000,
+ refetchInterval: 30000, // 30 seconds
refetchOnWindowFocus: true,
refetchOnMount: true,
initialData,