Add GitBook theme structure with Traditional Chinese docs
This commit is contained in:
223
gitbook/layouts/BaseLayout.jsx
Normal file
223
gitbook/layouts/BaseLayout.jsx
Normal file
@@ -0,0 +1,223 @@
|
||||
'use client'
|
||||
|
||||
import { AdSlot } from '@/components/GoogleAdsense'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import LoadingCover from '@/components/LoadingCover'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { createContext, useContext, useEffect, useRef, useState } from 'react'
|
||||
import { siteConfig } from '@/lib/config'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
import { useRouter } from 'next/router'
|
||||
import { getShortId } from '@/lib/utils/pageId'
|
||||
import Announcement from '../components/Announcement'
|
||||
import ArticleInfo from '../components/ArticleInfo'
|
||||
import BottomMenuBar from '../components/BottomMenuBar'
|
||||
import Catalog from '../components/Catalog'
|
||||
import Footer from '../components/Footer'
|
||||
import Header from '../components/Header'
|
||||
import InfoCard from '../components/InfoCard'
|
||||
import JumpToTopButton from '../components/JumpToTopButton'
|
||||
import NavPostList from '../components/NavPostList'
|
||||
import PageNavDrawer from '../components/PageNavDrawer'
|
||||
import RevolverMaps from '../components/RevolverMaps'
|
||||
import CONFIG from '../config'
|
||||
import { Style } from '../style'
|
||||
|
||||
const AlgoliaSearchModal = dynamic(
|
||||
() => import('@/components/AlgoliaSearchModal'),
|
||||
{ ssr: false }
|
||||
)
|
||||
const WWAds = dynamic(() => import('@/components/WWAds'), { ssr: false })
|
||||
|
||||
// 主題全域變數
|
||||
const ThemeGlobalGitbook = createContext()
|
||||
const useGitBookGlobal = () => useContext(ThemeGlobalGitbook)
|
||||
|
||||
/**
|
||||
* 為最新文章加入紅點標記
|
||||
*/
|
||||
function getNavPagesWithLatest(allNavPages, latestPosts, post) {
|
||||
// localStorage 儲存 id 與上次閱讀時間戳: posts_read_time = {"${post.id}":"Date()"}
|
||||
const postReadTime = JSON.parse(
|
||||
localStorage.getItem('post_read_time') || '{}'
|
||||
)
|
||||
if (post) {
|
||||
postReadTime[getShortId(post.id)] = new Date().getTime()
|
||||
}
|
||||
// 更新記錄
|
||||
localStorage.setItem('post_read_time', JSON.stringify(postReadTime))
|
||||
|
||||
return allNavPages?.map(item => {
|
||||
const res = {
|
||||
short_id: item.short_id,
|
||||
title: item.title || '',
|
||||
pageCoverThumbnail: item.pageCoverThumbnail || '',
|
||||
category: item.category || null,
|
||||
tags: item.tags || null,
|
||||
summary: item.summary || null,
|
||||
slug: item.slug,
|
||||
href: item.href,
|
||||
pageIcon: item.pageIcon || '',
|
||||
lastEditedDate: item.lastEditedDate
|
||||
}
|
||||
// 屬於最新的文章通常 6 篇 &&(無閱讀紀錄 || 最近更新時間大於上次閱讀時間)
|
||||
if (
|
||||
latestPosts.some(post => post?.id.indexOf(item?.short_id) === 14) &&
|
||||
(!postReadTime[item.short_id] ||
|
||||
postReadTime[item.short_id] < new Date(item.lastEditedDate).getTime())
|
||||
) {
|
||||
return { ...res, isLatest: true }
|
||||
} else {
|
||||
return res
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/**
|
||||
* 基礎佈局
|
||||
* 左右雙欄,手機版改為頂部導覽列
|
||||
*/
|
||||
const LayoutBase = props => {
|
||||
const {
|
||||
children,
|
||||
post,
|
||||
allNavPages,
|
||||
latestPosts,
|
||||
slotLeft,
|
||||
slotRight,
|
||||
slotTop
|
||||
} = props
|
||||
const { fullWidth } = useGlobal()
|
||||
const router = useRouter()
|
||||
const [tocVisible, changeTocVisible] = useState(false)
|
||||
const [pageNavVisible, changePageNavVisible] = useState(false)
|
||||
const [filteredNavPages, setFilteredNavPages] = useState(allNavPages)
|
||||
|
||||
const searchModal = useRef(null)
|
||||
|
||||
useEffect(() => {
|
||||
setFilteredNavPages(getNavPagesWithLatest(allNavPages, latestPosts, post))
|
||||
}, [router])
|
||||
|
||||
const GITBOOK_LOADING_COVER = siteConfig(
|
||||
'GITBOOK_LOADING_COVER',
|
||||
true,
|
||||
CONFIG
|
||||
)
|
||||
return (
|
||||
<ThemeGlobalGitbook.Provider
|
||||
value={{
|
||||
searchModal,
|
||||
tocVisible,
|
||||
changeTocVisible,
|
||||
filteredNavPages,
|
||||
setFilteredNavPages,
|
||||
allNavPages,
|
||||
pageNavVisible,
|
||||
changePageNavVisible
|
||||
}}>
|
||||
<Style />
|
||||
|
||||
<div
|
||||
id='theme-gitbook'
|
||||
className={`${siteConfig('FONT_STYLE')} pb-16 md:pb-0 scroll-smooth bg-white dark:bg-black w-full h-full min-h-screen justify-center dark:text-gray-300`}>
|
||||
<AlgoliaSearchModal cRef={searchModal} {...props} />
|
||||
|
||||
{/* 頂部導覽列 */}
|
||||
<Header {...props} />
|
||||
|
||||
<main
|
||||
id='wrapper'
|
||||
className={`${siteConfig('LAYOUT_SIDEBAR_REVERSE') ? 'flex-row-reverse' : ''} relative flex justify-between w-full gap-x-6 h-full mx-auto max-w-screen-4xl`}>
|
||||
{/* 左側抽屜 */}
|
||||
{fullWidth ? null : (
|
||||
<div className={'hidden md:block relative z-10 '}>
|
||||
<div className='w-80 pt-14 pb-4 sticky top-0 h-screen flex justify-between flex-col'>
|
||||
{/* 導覽清單 */}
|
||||
<div className='overflow-y-scroll scroll-hidden pt-10 pl-5'>
|
||||
{/* 嵌入區塊 */}
|
||||
{slotLeft}
|
||||
|
||||
{/* 文章列表 */}
|
||||
<NavPostList filteredNavPages={filteredNavPages} {...props} />
|
||||
</div>
|
||||
{/* 頁尾 */}
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{/* 內容區域 */}
|
||||
<div
|
||||
id='center-wrapper'
|
||||
className='flex flex-col justify-between w-full relative z-10 pt-14 min-h-screen'>
|
||||
<div
|
||||
id='container-inner'
|
||||
className={`w-full ${fullWidth ? 'px-5' : 'max-w-3xl px-3 lg:px-0'} justify-center mx-auto`}>
|
||||
{slotTop}
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
|
||||
{children}
|
||||
|
||||
{/* Google 廣告 */}
|
||||
<AdSlot type='in-article' />
|
||||
<WWAds className='w-full' orientation='horizontal' />
|
||||
</div>
|
||||
|
||||
{/* 手機版頁尾 */}
|
||||
<div className='md:hidden'>
|
||||
<Footer {...props} />
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* 右側資訊欄 */}
|
||||
{fullWidth ? null : (
|
||||
<div
|
||||
className={
|
||||
'w-72 hidden 2xl:block dark:border-transparent flex-shrink-0 relative z-10 '
|
||||
}>
|
||||
<div className='py-14 sticky top-0'>
|
||||
<ArticleInfo post={props?.post ? props?.post : props.notice} />
|
||||
|
||||
<div>
|
||||
{/* 桌面版目錄 */}
|
||||
<Catalog {...props} />
|
||||
{slotRight}
|
||||
{router.route === '/' && (
|
||||
<>
|
||||
<InfoCard {...props} />
|
||||
{siteConfig(
|
||||
'GITBOOK_WIDGET_REVOLVER_MAPS',
|
||||
null,
|
||||
CONFIG
|
||||
) === 'true' && <RevolverMaps />}
|
||||
<Live2D />
|
||||
</>
|
||||
)}
|
||||
{/* 主題首頁僅顯示公告 */}
|
||||
<Announcement {...props} />
|
||||
</div>
|
||||
|
||||
<AdSlot type='in-article' />
|
||||
<Live2D />
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</main>
|
||||
|
||||
{GITBOOK_LOADING_COVER && <LoadingCover />}
|
||||
|
||||
{/* 回頂按鈕 */}
|
||||
<JumpToTopButton />
|
||||
|
||||
{/* 手機版導覽抽屜 */}
|
||||
<PageNavDrawer {...props} filteredNavPages={filteredNavPages} />
|
||||
|
||||
{/* 手機版底部導覽列 */}
|
||||
<BottomMenuBar {...props} />
|
||||
</div>
|
||||
</ThemeGlobalGitbook.Provider>
|
||||
)
|
||||
}
|
||||
|
||||
export { LayoutBase, useGitBookGlobal }
|
Reference in New Issue
Block a user