import { siteConfig } from '@/lib/config' import { useGlobal } from '@/lib/global' import { useRouter } from 'next/router' import { useEffect, useState } from 'react' import CONFIG from '../config' import BlogPostCard from './BlogPostCard' import NavPostItem from './NavPostItem' /** * 部落格列表滾動分頁 * @param posts 所有文章 * @param tags 所有標籤 * @returns {JSX.Element} * @constructor */ const NavPostList = props => { const { filteredNavPages } = props const { locale, currentSearch } = useGlobal() const router = useRouter() // 依分類將文章歸成資料夾 const categoryFolders = groupArticles(filteredNavPages) // 存放被展開的群組 const [expandedGroups, setExpandedGroups] = useState([]) // 是否採用排他折疊,一次只展開一個資料夾 const GITBOOK_EXCLUSIVE_COLLAPSE = siteConfig( 'GITBOOK_EXCLUSIVE_COLLAPSE', null, CONFIG ) useEffect(() => { // 展開資料夾 setTimeout(() => { const currentPath = decodeURIComponent(router.asPath.split('?')[0]) const defaultOpenIndex = getDefaultOpenIndexByPath( categoryFolders, currentPath ) setExpandedGroups([defaultOpenIndex]) }, 500) // eslint-disable-next-line react-hooks/exhaustive-deps }, [router, filteredNavPages]) // 切換折疊項目,當陣列狀態改變時觸發 const toggleItem = index => { let newExpandedGroups = [...expandedGroups] // 建立新的展開群組陣列 // 若 expandedGroups 中不存在則加入,存在則移除 if (expandedGroups.includes(index)) { // 若 expandedGroups 中包含 index,則移除 newExpandedGroups = newExpandedGroups.filter( expandedIndex => expandedIndex !== index ) } else { // 若 expandedGroups 中不含 index,則加入 newExpandedGroups.push(index) } // 是否排他 if (GITBOOK_EXCLUSIVE_COLLAPSE) { // 若折疊選單為排他模式,僅保留目前群組其餘關閉 newExpandedGroups = newExpandedGroups.filter( expandedIndex => expandedIndex === index ) } // 更新展開群組陣列 setExpandedGroups(newExpandedGroups) } // 無資料時 if (!categoryFolders || categoryFolders.length === 0) { // 空白內容 return (

{locale.COMMON.NO_RESULTS_FOUND}{' '} {currentSearch &&

{currentSearch}
}

) } // 文章首頁對應路徑 const href = siteConfig('GITBOOK_INDEX_PAGE') + '' const homePost = { id: '-1', title: siteConfig('DESCRIPTION'), href: href.indexOf('/') !== 0 ? '/' + href : href } return (
{/* 當前文章 */} {/* 文章列表 */} {categoryFolders?.map((group, index) => ( toggleItem(index)} // 將切換函式傳給子元件 /> ))}
) } // 依分類將文章歸成資料夾 function groupArticles(filteredNavPages) { if (!filteredNavPages) { return [] } const groups = [] const AUTO_SORT = siteConfig('GITBOOK_AUTO_SORT', true, CONFIG) for (let i = 0; i < filteredNavPages.length; i++) { const item = filteredNavPages[i] const categoryName = item?.category ? item?.category : '' // 將 category 轉成字串 let existingGroup = null // 啟用自動分組排序;會把相同分類歸到同一個資料夾,忽略 Notion 中的排序 if (AUTO_SORT) { existingGroup = groups.find(group => group.category === categoryName) // 尋找同名的最後一個群組 } else { existingGroup = groups[groups.length - 1] // 取得最後一個群組 } // 新增資料 if (existingGroup && existingGroup.category === categoryName) { existingGroup.items.push(item) } else { groups.push({ category: categoryName, items: [item] }) } } return groups } /** * 查看當前路徑需要展開的選單索引 * 若皆不符合則回傳 0,即預設展開第一個 * @param {*} categoryFolders * @param {*} path * @returns {number} 需展開的選單索引 */ function getDefaultOpenIndexByPath(categoryFolders, path) { // 找出符合條件的第一個索引 const index = categoryFolders.findIndex(group => { return group.items.some(post => path === post.href) }) // 若找到符合條件的索引則回傳 if (index !== -1) { return index } return 0 } export default NavPostList