mirror of
https://github.com/pacnpal/thrilltrack-explorer.git
synced 2025-12-21 15:11:12 -05:00
Refactor: Stabilize admin panel auto-refresh
This commit is contained in:
@@ -80,6 +80,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
const [interactingWith, setInteractingWith] = useState<Set<string>>(new Set());
|
||||
const [newItemsCount, setNewItemsCount] = useState(0);
|
||||
const [isRefreshing, setIsRefreshing] = useState(false);
|
||||
const [profileCache, setProfileCache] = useState<Map<string, any>>(new Map());
|
||||
const { toast } = useToast();
|
||||
const { isAdmin, isSuperuser } = useUserRole();
|
||||
const { user } = useAuth();
|
||||
@@ -109,8 +110,8 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
return;
|
||||
}
|
||||
|
||||
// Prevent duplicate requests
|
||||
if (isRefreshing && silent) {
|
||||
// Prevent ANY refresh if one is in progress
|
||||
if (isRefreshing) {
|
||||
console.log('⏭️ Skipping refresh - already in progress');
|
||||
return;
|
||||
}
|
||||
@@ -377,7 +378,20 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
.select('user_id, username, display_name, avatar_url')
|
||||
.in('user_id', userIds);
|
||||
|
||||
const profileMap = new Map(profiles?.map(p => [p.user_id, p]) || []);
|
||||
// Update profile cache with stable references
|
||||
setProfileCache(prevCache => {
|
||||
const newCache = new Map(prevCache);
|
||||
profiles?.forEach(p => {
|
||||
const existing = newCache.get(p.user_id);
|
||||
// Only update if data actually changed
|
||||
if (!existing || JSON.stringify(existing) !== JSON.stringify(p)) {
|
||||
newCache.set(p.user_id, p);
|
||||
}
|
||||
});
|
||||
return newCache;
|
||||
});
|
||||
|
||||
const profileMap = profileCache;
|
||||
|
||||
// Combine and format items
|
||||
const formattedItems: ModerationItem[] = [
|
||||
@@ -448,7 +462,7 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
addToTop: true,
|
||||
});
|
||||
|
||||
// If there are changes
|
||||
// Only update state if there are actual changes
|
||||
if (mergeResult.hasChanges) {
|
||||
const actuallyNewItems = mergeResult.changes.added.length;
|
||||
|
||||
@@ -458,30 +472,31 @@ export const ModerationQueue = forwardRef<ModerationQueueRef>((props, ref) => {
|
||||
updated: mergeResult.changes.updated.length,
|
||||
removed: mergeResult.changes.removed.length,
|
||||
totalItems: mergeResult.items.length,
|
||||
protectedIds: Array.from(preserveInteraction ? interactingWith : new Set<string>()),
|
||||
strategy: refreshStrategy,
|
||||
preserveInteraction
|
||||
});
|
||||
|
||||
// Filter out items user is interacting with
|
||||
const protectedIds = preserveInteraction ? interactingWith : new Set<string>();
|
||||
const mergedWithProtection = mergeResult.items.map(item => {
|
||||
if (protectedIds.has(item.id)) {
|
||||
// Find and preserve the current version of this item
|
||||
// Only apply protection map if needed
|
||||
let finalItems = mergeResult.items;
|
||||
if (preserveInteraction && interactingWith.size > 0) {
|
||||
finalItems = mergeResult.items.map(item => {
|
||||
if (interactingWith.has(item.id)) {
|
||||
const currentItem = items.find(i => i.id === item.id);
|
||||
return currentItem || item;
|
||||
}
|
||||
return item;
|
||||
});
|
||||
}
|
||||
|
||||
setItems(mergedWithProtection);
|
||||
// Only call setItems if reference has actually changed
|
||||
if (finalItems !== items) {
|
||||
setItems(finalItems);
|
||||
}
|
||||
|
||||
// Only set new items count if there are genuinely new items
|
||||
if (actuallyNewItems > 0) {
|
||||
setNewItemsCount(actuallyNewItems);
|
||||
}
|
||||
} else {
|
||||
// No changes detected - keep current state completely unchanged
|
||||
// No changes detected - skip all state updates
|
||||
console.log('✅ No changes detected, keeping current state');
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user