Fix moderation queue tab switch reload

This commit is contained in:
gpt-engineer-app[bot]
2025-10-11 17:20:35 +00:00
parent f9e12596c7
commit 10950a4034
3 changed files with 42 additions and 8 deletions

View File

@@ -157,13 +157,15 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
getAdminPanelPollInterval,
getAutoRefreshStrategy,
getPreserveInteractionState,
getUseRealtimeQueue
getUseRealtimeQueue,
getRefreshOnTabVisible
} = useAdminSettings();
const refreshMode = getAdminPanelRefreshMode();
const pollInterval = getAdminPanelPollInterval();
const refreshStrategy = getAutoRefreshStrategy();
const preserveInteraction = getPreserveInteractionState();
const useRealtimeQueue = getUseRealtimeQueue();
const refreshOnTabVisible = getRefreshOnTabVisible();
// Track recently removed items to prevent realtime override of optimistic updates
const recentlyRemovedRef = useRef<Set<string>>(new Set());
@@ -172,6 +174,8 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
// Store admin settings and stable refs to avoid triggering fetchItems recreation
const refreshStrategyRef = useRef(refreshStrategy);
const preserveInteractionRef = useRef(preserveInteraction);
const refreshOnTabVisibleRef = useRef(refreshOnTabVisible);
const activeTabRef = useRef<QueueTab>(activeTab);
const userRef = useRef(user);
const toastRef = useRef(toast);
const isAdminRef = useRef(isAdmin);
@@ -180,11 +184,17 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
useEffect(() => {
refreshStrategyRef.current = refreshStrategy;
preserveInteractionRef.current = preserveInteraction;
refreshOnTabVisibleRef.current = refreshOnTabVisible;
userRef.current = user;
toastRef.current = toast;
isAdminRef.current = isAdmin;
isSuperuserRef.current = isSuperuser;
}, [refreshStrategy, preserveInteraction, user, toast, isAdmin, isSuperuser]);
}, [refreshStrategy, preserveInteraction, refreshOnTabVisible, user, toast, isAdmin, isSuperuser]);
// Sync activeTab with ref
useEffect(() => {
activeTabRef.current = activeTab;
}, [activeTab]);
// Persist sort configuration
useEffect(() => {
@@ -1165,7 +1175,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
};
}, [user, useRealtimeQueue, debouncedRealtimeUpdate]);
// Visibility change handler - pause queue updates when tab is hidden
// Visibility change handler - smart tab switching behavior
useEffect(() => {
const handleVisibilityChange = () => {
if (document.hidden) {
@@ -1174,17 +1184,23 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
} else {
console.log('📱 Tab visible - resuming queue updates');
pauseFetchingRef.current = false;
// Optional: trigger single refresh when tab becomes visible
if (initialFetchCompleteRef.current && !isMountingRef.current) {
console.log('🔄 Tab became visible - triggering refresh');
fetchItems(filtersRef.current.entityFilter, filtersRef.current.statusFilter, true, activeTab);
// Check admin setting for auto-refresh behavior
const shouldRefresh = refreshOnTabVisibleRef.current;
if (shouldRefresh && initialFetchCompleteRef.current && !isMountingRef.current) {
console.log('🔄 Tab became visible - triggering refresh (admin setting enabled)');
fetchItems(filtersRef.current.entityFilter, filtersRef.current.statusFilter, true, activeTabRef.current);
} else {
console.log('✅ Tab became visible - resuming without refresh');
// Realtime subscriptions will handle updates naturally
}
}
};
document.addEventListener('visibilitychange', handleVisibilityChange);
return () => document.removeEventListener('visibilitychange', handleVisibilityChange);
}, [fetchItems, activeTab]);
}, []); // Empty deps - all values come from refs
const handleResetToPending = async (item: ModerationItem) => {
setActionLoading(item.id);

View File

@@ -157,6 +157,12 @@ export function useAdminSettings() {
return cleanValue === 'true' || cleanValue === true;
};
const getRefreshOnTabVisible = (): boolean => {
const value = getSettingValue('system.refresh_on_tab_visible', 'false');
const cleanValue = typeof value === 'string' ? value.replace(/"/g, '') : value;
return cleanValue === 'true' || cleanValue === true;
};
return {
settings,
isLoading,
@@ -180,5 +186,6 @@ export function useAdminSettings() {
getAutoRefreshStrategy,
getPreserveInteractionState,
getUseRealtimeQueue,
getRefreshOnTabVisible,
};
}

View File

@@ -0,0 +1,11 @@
-- Add admin setting to control auto-refresh on tab visibility change
INSERT INTO admin_settings (setting_key, setting_value, category, description, created_at, updated_at)
VALUES (
'system.refresh_on_tab_visible',
'false',
'system',
'Auto-refresh moderation queue when returning to tab (default: false, realtime handles updates)',
now(),
now()
)
ON CONFLICT (setting_key) DO NOTHING;