fixed post count
This commit is contained in:
@@ -96,7 +96,48 @@ export default function BoardIndex() {
|
|||||||
nodes.forEach((node) => sortNodes(node.children))
|
nodes.forEach((node) => sortNodes(node.children))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const aggregateNodes = (node) => {
|
||||||
|
if (!node.children?.length) {
|
||||||
|
return {
|
||||||
|
threads: node.threads_count ?? 0,
|
||||||
|
views: node.views_count ?? 0,
|
||||||
|
posts: node.posts_count ?? 0,
|
||||||
|
last: node.last_post_at ? { at: node.last_post_at, node } : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let threads = node.threads_count ?? 0
|
||||||
|
let views = node.views_count ?? 0
|
||||||
|
let posts = node.posts_count ?? 0
|
||||||
|
let last = node.last_post_at ? { at: node.last_post_at, node } : null
|
||||||
|
|
||||||
|
node.children.forEach((child) => {
|
||||||
|
const agg = aggregateNodes(child)
|
||||||
|
threads += agg.threads
|
||||||
|
views += agg.views
|
||||||
|
posts += agg.posts
|
||||||
|
if (agg.last && (!last || agg.last.at > last.at)) {
|
||||||
|
last = agg.last
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
node.threads_count = threads
|
||||||
|
node.views_count = views
|
||||||
|
node.posts_count = posts
|
||||||
|
if (last) {
|
||||||
|
const source = last.node
|
||||||
|
node.last_post_at = source.last_post_at
|
||||||
|
node.last_post_user_id = source.last_post_user_id
|
||||||
|
node.last_post_user_name = source.last_post_user_name
|
||||||
|
node.last_post_user_rank_color = source.last_post_user_rank_color
|
||||||
|
node.last_post_user_group_color = source.last_post_user_group_color
|
||||||
|
}
|
||||||
|
|
||||||
|
return { threads, views, posts, last }
|
||||||
|
}
|
||||||
|
|
||||||
sortNodes(roots)
|
sortNodes(roots)
|
||||||
|
roots.forEach((root) => aggregateNodes(root))
|
||||||
|
|
||||||
return roots
|
return roots
|
||||||
}, [forums])
|
}, [forums])
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Button, Badge, Card, Col, Container, Form, Modal, Row } from 'react-bootstrap'
|
import { Button, Badge, Card, Col, Container, Form, Modal, Row } from 'react-bootstrap'
|
||||||
import { Link, useParams } from 'react-router-dom'
|
import { Link, useParams } from 'react-router-dom'
|
||||||
import { createThread, getForum, listForumsByParent, listThreadsByForum } from '../api/client'
|
import { createThread, getForum, listAllForums, listThreadsByForum } from '../api/client'
|
||||||
import PortalTopicRow from '../components/PortalTopicRow'
|
import PortalTopicRow from '../components/PortalTopicRow'
|
||||||
import { useAuth } from '../context/AuthContext'
|
import { useAuth } from '../context/AuthContext'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
@@ -71,6 +71,77 @@ export default function ForumView() {
|
|||||||
</div>
|
</div>
|
||||||
))
|
))
|
||||||
|
|
||||||
|
const getParentId = (node) => {
|
||||||
|
if (!node.parent) return null
|
||||||
|
if (typeof node.parent === 'string') {
|
||||||
|
return node.parent.split('/').pop()
|
||||||
|
}
|
||||||
|
return node.parent.id ?? null
|
||||||
|
}
|
||||||
|
|
||||||
|
const buildForumTree = (allForums) => {
|
||||||
|
const map = new Map()
|
||||||
|
const roots = []
|
||||||
|
|
||||||
|
allForums.forEach((item) => {
|
||||||
|
map.set(String(item.id), { ...item, children: [] })
|
||||||
|
})
|
||||||
|
|
||||||
|
allForums.forEach((item) => {
|
||||||
|
const parentId = getParentId(item)
|
||||||
|
const node = map.get(String(item.id))
|
||||||
|
if (parentId && map.has(String(parentId))) {
|
||||||
|
map.get(String(parentId)).children.push(node)
|
||||||
|
} else {
|
||||||
|
roots.push(node)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
const aggregateNodes = (node) => {
|
||||||
|
if (!node.children?.length) {
|
||||||
|
return {
|
||||||
|
threads: node.threads_count ?? 0,
|
||||||
|
views: node.views_count ?? 0,
|
||||||
|
posts: node.posts_count ?? 0,
|
||||||
|
last: node.last_post_at ? { at: node.last_post_at, node } : null,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let threads = node.threads_count ?? 0
|
||||||
|
let views = node.views_count ?? 0
|
||||||
|
let posts = node.posts_count ?? 0
|
||||||
|
let last = node.last_post_at ? { at: node.last_post_at, node } : null
|
||||||
|
|
||||||
|
node.children.forEach((child) => {
|
||||||
|
const agg = aggregateNodes(child)
|
||||||
|
threads += agg.threads
|
||||||
|
views += agg.views
|
||||||
|
posts += agg.posts
|
||||||
|
if (agg.last && (!last || agg.last.at > last.at)) {
|
||||||
|
last = agg.last
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
node.threads_count = threads
|
||||||
|
node.views_count = views
|
||||||
|
node.posts_count = posts
|
||||||
|
if (last) {
|
||||||
|
const source = last.node
|
||||||
|
node.last_post_at = source.last_post_at
|
||||||
|
node.last_post_user_id = source.last_post_user_id
|
||||||
|
node.last_post_user_name = source.last_post_user_name
|
||||||
|
node.last_post_user_rank_color = source.last_post_user_rank_color
|
||||||
|
node.last_post_user_group_color = source.last_post_user_group_color
|
||||||
|
}
|
||||||
|
|
||||||
|
return { threads, views, posts, last }
|
||||||
|
}
|
||||||
|
|
||||||
|
roots.forEach((root) => aggregateNodes(root))
|
||||||
|
|
||||||
|
return map
|
||||||
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
let active = true
|
let active = true
|
||||||
|
|
||||||
@@ -81,9 +152,11 @@ export default function ForumView() {
|
|||||||
const forumData = await getForum(id)
|
const forumData = await getForum(id)
|
||||||
if (!active) return
|
if (!active) return
|
||||||
setForum(forumData)
|
setForum(forumData)
|
||||||
const childData = await listForumsByParent(id)
|
const allForums = await listAllForums()
|
||||||
if (!active) return
|
if (!active) return
|
||||||
setChildren(childData)
|
const treeMap = buildForumTree(allForums)
|
||||||
|
const currentNode = treeMap.get(String(forumData.id))
|
||||||
|
setChildren(currentNode?.children ?? [])
|
||||||
if (forumData.type === 'forum') {
|
if (forumData.type === 'forum') {
|
||||||
const threadData = await listThreadsByForum(id)
|
const threadData = await listThreadsByForum(id)
|
||||||
if (!active) return
|
if (!active) return
|
||||||
|
|||||||
Reference in New Issue
Block a user