diff --git a/src/views/mod-queue/mod-queue.tsx b/src/views/mod-queue/mod-queue.tsx index 5fd480ed..8d91a433 100644 --- a/src/views/mod-queue/mod-queue.tsx +++ b/src/views/mod-queue/mod-queue.tsx @@ -251,8 +251,106 @@ interface ModQueueButtonProps { isMobile?: boolean; } -export const ModQueueButton = ({ boardIdentifier, isMobile }: ModQueueButtonProps) => { +// Counter item that uses useEditedComment to get real-time moderation status +// and reports its status via callback +interface ModQueueCountItemProps { + comment: Comment; + alertThresholdHours: number; + onStatusChange: (cid: string, status: { awaiting: boolean; urgent: boolean }) => void; +} + +const ModQueueCountItem = ({ comment, alertThresholdHours, onStatusChange }: ModQueueCountItemProps) => { + const { editedComment } = useEditedComment({ comment }); + const displayComment = editedComment || comment; + + const { cid, approved, removed, timestamp } = displayComment; + const isAwaiting = approved !== true && removed !== true; + const timeWaiting = Date.now() / 1000 - timestamp; + const isUrgent = isAwaiting && timeWaiting > alertThresholdHours * 3600; + + // Report status changes to parent - useEffect is appropriate here for syncing with parent state + useEffect(() => { + onStatusChange(cid, { awaiting: isAwaiting, urgent: isUrgent }); + }, [cid, isAwaiting, isUrgent, onStatusChange]); + + return null; +}; + +// Inner component that handles counting with useEditedComment for each item +interface ModQueueButtonContentProps { + feed: Comment[]; + alertThresholdHours: number; + boardIdentifier?: string; + isMobile?: boolean; +} + +const ModQueueButtonContent = ({ feed, alertThresholdHours, boardIdentifier, isMobile }: ModQueueButtonContentProps) => { const { t } = useTranslation(); + const [statusMap, setStatusMap] = useState>(new Map()); + + const handleStatusChange = React.useCallback((cid: string, status: { awaiting: boolean; urgent: boolean }) => { + setStatusMap((prev) => { + const next = new Map(prev); + next.set(cid, status); + return next; + }); + }, []); + + // Calculate counts from status map + const { normalCount, urgentCount } = useMemo(() => { + let normal = 0; + let urgent = 0; + for (const { awaiting, urgent: isUrgent } of statusMap.values()) { + if (awaiting) { + if (isUrgent) urgent++; + else normal++; + } + } + return { normalCount: normal, urgentCount: urgent }; + }, [statusMap]); + + const totalCount = normalCount + urgentCount; + const to = boardIdentifier ? `/${boardIdentifier}/queue` : '/mod/queue'; + + const buttonContent = ( + + ); + + return ( + <> + {/* Render counter items to track real-time moderation status */} + {feed.map((item) => ( + + ))} + {isMobile ? buttonContent : <>[{buttonContent}]} + + ); +}; + +export const ModQueueButton = ({ boardIdentifier, isMobile }: ModQueueButtonProps) => { const { alertThresholdHours } = useModQueueStore(); const { accountSubplebbits } = useAccountSubplebbits(); const accountSubplebbitAddresses = useMemo(() => Object.keys(accountSubplebbits || {}), [accountSubplebbits]); @@ -289,69 +387,7 @@ export const ModQueueButton = ({ boardIdentifier, isMobile }: ModQueueButtonProp return null; } - // Separate comments into normal and urgent based on threshold - // Only count items awaiting approval (not approved or rejected) for blinking counter - // Match ModQueueRow logic: use > (strictly greater) to be consistent - const { normalCount, urgentCount } = useMemo(() => { - const thresholdSeconds = alertThresholdHours * 3600; - const now = Date.now() / 1000; - - let normal = 0; - let urgent = 0; - - for (const item of feed) { - // Only count items that are awaiting approval (not approved or rejected) - const isAwaitingApproval = item.approved !== true && item.removed !== true; - - if (!isAwaitingApproval) { - // Skip items that are already approved or rejected - continue; - } - - const timeWaiting = now - item.timestamp; - if (timeWaiting > thresholdSeconds) { - urgent++; - } else { - normal++; - } - } - - return { normalCount: normal, urgentCount: urgent }; - }, [feed, alertThresholdHours]); - - const totalCount = normalCount + urgentCount; - - // Use boardIdentifier for the route, but resolvedAddress for mod check - const to = boardIdentifier ? `/${boardIdentifier}/queue` : '/mod/queue'; - - const buttonContent = ( - - ); - - return isMobile ? buttonContent : <>[{buttonContent}]; + return ; }; export const ModQueueView = ({ boardIdentifier: propBoardIdentifier }: ModQueueViewProps) => {