Refactor: Implement debouncing and anti-flashing fixes

This commit is contained in:
gpt-engineer-app[bot]
2025-10-09 15:47:09 +00:00
parent f01c58a056
commit 039fe46e55
2 changed files with 68 additions and 38 deletions

View File

@@ -34,6 +34,7 @@ export const useModerationStats = (options: UseModerationStatsOptions = {}) => {
const [isInitialLoad, setIsInitialLoad] = useState(true);
const [lastUpdated, setLastUpdated] = useState<Date | null>(null);
const onStatsChangeRef = useRef(onStatsChange);
const statsDebounceRef = useRef<NodeJS.Timeout | null>(null);
// Update ref when callback changes
useEffect(() => {
@@ -93,27 +94,35 @@ export const useModerationStats = (options: UseModerationStatsOptions = {}) => {
}
}, [enabled, fetchStats]);
// Debounced stats fetch to prevent rapid-fire updates
const debouncedFetchStats = useCallback(() => {
if (statsDebounceRef.current) {
clearTimeout(statsDebounceRef.current);
}
statsDebounceRef.current = setTimeout(() => {
fetchStats(true); // Silent refresh
}, 500); // 500ms debounce
}, [fetchStats]);
// Realtime subscription for instant stat updates
useEffect(() => {
if (!enabled || !realtimeEnabled) return;
const channel = supabase
.channel('moderation-stats-realtime')
.on('postgres_changes', { event: '*', schema: 'public', table: 'content_submissions' }, () => {
fetchStats(true); // Silent refresh
})
.on('postgres_changes', { event: '*', schema: 'public', table: 'reports' }, () => {
fetchStats(true);
})
.on('postgres_changes', { event: '*', schema: 'public', table: 'reviews' }, () => {
fetchStats(true);
})
.on('postgres_changes', { event: '*', schema: 'public', table: 'content_submissions' }, debouncedFetchStats)
.on('postgres_changes', { event: '*', schema: 'public', table: 'reports' }, debouncedFetchStats)
.on('postgres_changes', { event: '*', schema: 'public', table: 'reviews' }, debouncedFetchStats)
.subscribe();
return () => {
supabase.removeChannel(channel);
if (statsDebounceRef.current) {
clearTimeout(statsDebounceRef.current);
}
};
}, [enabled, realtimeEnabled, fetchStats]);
}, [enabled, realtimeEnabled, debouncedFetchStats]);
// Polling (fallback when realtime is disabled)
useEffect(() => {