Edit Readme & Clean up anything left over from the already outdated template I made

This commit is contained in:
2025-06-19 13:48:13 -05:00
parent 301a9acec0
commit 4a9c1a7fec
9 changed files with 285 additions and 113 deletions

View File

@ -50,15 +50,6 @@ export const StatusList = ({ initialStatuses = [] }: ListProps) => {
});
});
//const { connectionStatus, connect: reconnect } = useStatusSubscription({
//enabled: isAuthenticated,
//onStatusUpdate: () => {
//refetch().catch((error) => {
//console.error('Error refetching statuses:', error);
//});
//},
//});
const handleUpdateStatus = () => {
if (!isAuthenticated) {
setUpdateStatusMessage(
@ -306,7 +297,7 @@ export const StatusList = ({ initialStatuses = [] }: ListProps) => {
)}
{!tvMode && (
<Card className='p-6 mt-6'>
<Card className='p-6 mt-4 w-full'>
<div className='flex flex-col gap-4'>
<h3 className='text-lg font-semibold'>Update Status</h3>
<div className='flex flex-col gap-4'>

View File

@ -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<ConnectionStatus>(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,

View File

@ -37,7 +37,7 @@ export const useStatusData = ({
}
},
enabled,
refetchInterval: 30000,
refetchInterval: 30000, // 30 seconds
refetchOnWindowFocus: true,
refetchOnMount: true,
initialData,