mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-06-06 15:10:29 +00:00
NEXT主题,分类标签调整
This commit is contained in:
@@ -25,6 +25,9 @@ const BLOG = {
|
|||||||
POSTS_PER_PAGE: 6, // post counts per page
|
POSTS_PER_PAGE: 6, // post counts per page
|
||||||
POSTS_SORT_BY: 'notion', // 排序方式 'date'按时间,'notion'由notion控制
|
POSTS_SORT_BY: 'notion', // 排序方式 'date'按时间,'notion'由notion控制
|
||||||
|
|
||||||
|
PREVIEW_CATEGORY_COUNT: 16, // 首页最多展示的分类数量,0为不限制
|
||||||
|
PREVIEW_TAG_COUNT: 16, // 首页最多展示的标签数量,0为不限制
|
||||||
|
|
||||||
// 社交链接,不需要可留空白,例如 CONTACT_WEIBO:''
|
// 社交链接,不需要可留空白,例如 CONTACT_WEIBO:''
|
||||||
CONTACT_EMAIL: 'tlyong1992@hotmail.com',
|
CONTACT_EMAIL: 'tlyong1992@hotmail.com',
|
||||||
CONTACT_WEIBO: '',
|
CONTACT_WEIBO: '',
|
||||||
|
|||||||
@@ -3,11 +3,11 @@
|
|||||||
* @param allPosts
|
* @param allPosts
|
||||||
* @returns {Promise<{}|*[]>}
|
* @returns {Promise<{}|*[]>}
|
||||||
*/
|
*/
|
||||||
export async function getAllCategories (allPosts) {
|
export async function getAllCategories ({ allPosts, categoryOptions, sliceCount = 0 }) {
|
||||||
if (!allPosts) {
|
if (!allPosts || !categoryOptions) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
// 计数
|
||||||
let categories = allPosts.map(p => p.category)
|
let categories = allPosts.map(p => p.category)
|
||||||
categories = [...categories.flat()]
|
categories = [...categories.flat()]
|
||||||
const categoryObj = {}
|
const categoryObj = {}
|
||||||
@@ -18,5 +18,19 @@ export async function getAllCategories (allPosts) {
|
|||||||
categoryObj[category] = 1
|
categoryObj[category] = 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return categoryObj
|
const list = []
|
||||||
|
categoryOptions.forEach(c => {
|
||||||
|
const count = categoryObj[c.value]
|
||||||
|
if (count) {
|
||||||
|
list.push({ id: c.id, name: c.value, color: c.color, count })
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
// 按照数量排序
|
||||||
|
// list.sort((a, b) => b.count - a.count)
|
||||||
|
if (sliceCount && sliceCount > 0) {
|
||||||
|
return list.slice(0, sliceCount)
|
||||||
|
} else {
|
||||||
|
return list
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,15 +6,13 @@
|
|||||||
* @param tagOptions tags的下拉选项
|
* @param tagOptions tags的下拉选项
|
||||||
* @returns {Promise<{}|*[]>}
|
* @returns {Promise<{}|*[]>}
|
||||||
*/
|
*/
|
||||||
export async function getAllTags ({ allPosts, sliceCount = 16, tagOptions }) {
|
export async function getAllTags ({ allPosts, sliceCount = 0, tagOptions }) {
|
||||||
if (!allPosts) {
|
if (!allPosts || !tagOptions) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
// 计数
|
||||||
let tags = allPosts.map(p => p.tags)
|
let tags = allPosts.map(p => p.tags)
|
||||||
tags = [...tags.flat()]
|
tags = [...tags.flat()]
|
||||||
|
|
||||||
// 标签计数
|
|
||||||
const tagObj = {}
|
const tagObj = {}
|
||||||
tags.forEach(tag => {
|
tags.forEach(tag => {
|
||||||
if (tag in tagObj) {
|
if (tag in tagObj) {
|
||||||
@@ -23,13 +21,16 @@ export async function getAllTags ({ allPosts, sliceCount = 16, tagOptions }) {
|
|||||||
tagObj[tag] = 1
|
tagObj[tag] = 1
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
const list = []
|
||||||
// 按照标签数量排序
|
tagOptions.forEach(c => {
|
||||||
const list = Object.keys(tagObj).map((tag) => {
|
const count = tagObj[c.value]
|
||||||
const color = tagOptions.find(option => option.value === tag)?.color || 'gray'
|
if (count) {
|
||||||
return { name: tag, count: tagObj[tag], color }
|
list.push({ id: c.id, name: c.value, color: c.color, count })
|
||||||
|
}
|
||||||
})
|
})
|
||||||
list.sort((a, b) => b.count - a.count)
|
|
||||||
|
// 按照数量排序
|
||||||
|
// list.sort((a, b) => b.count - a.count)
|
||||||
if (sliceCount && sliceCount > 0) {
|
if (sliceCount && sliceCount > 0) {
|
||||||
return list.slice(0, sliceCount)
|
return list.slice(0, sliceCount)
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ import { getAllTags } from './getAllTags'
|
|||||||
* @param {*} pageId
|
* @param {*} pageId
|
||||||
* @param {*} from
|
* @param {*} from
|
||||||
* @param latestPostCount 截取最新文章数量
|
* @param latestPostCount 截取最新文章数量
|
||||||
|
* @param categoryCount
|
||||||
* @param tagsCount 截取标签数量
|
* @param tagsCount 截取标签数量
|
||||||
* @param pageType 过滤的文章类型,数组格式 ['Page','Post']
|
* @param pageType 过滤的文章类型,数组格式 ['Page','Post']
|
||||||
* @returns {
|
* @returns {
|
||||||
@@ -27,15 +28,17 @@ export async function getGlobalNotionData ({
|
|||||||
pageId = BLOG.NOTION_PAGE_ID,
|
pageId = BLOG.NOTION_PAGE_ID,
|
||||||
from,
|
from,
|
||||||
latestPostCount = 5,
|
latestPostCount = 5,
|
||||||
tagsCount = 16,
|
categoryCount = BLOG.PREVIEW_CATEGORY_COUNT,
|
||||||
|
tagsCount = BLOG.PREVIEW_TAG_COUNT,
|
||||||
pageType = ['Post']
|
pageType = ['Post']
|
||||||
}) {
|
}) {
|
||||||
const notionPageData = await getNotionPageData({ pageId, from })
|
const notionPageData = await getNotionPageData({ pageId, from })
|
||||||
const tagOptions = notionPageData.tagOptions
|
const tagOptions = notionPageData.tagOptions
|
||||||
|
const categoryOptions = notionPageData.categoryOptions
|
||||||
const allPosts = await getAllPosts({ notionPageData, from, pageType })
|
const allPosts = await getAllPosts({ notionPageData, from, pageType })
|
||||||
const postCount = await getAllPostCount({ notionPageData, from })
|
const postCount = await getAllPostCount({ notionPageData, from })
|
||||||
const customNav = await getCustomNav({ notionPageData })
|
const customNav = await getCustomNav({ notionPageData })
|
||||||
const categories = await getAllCategories(allPosts)
|
const categories = await getAllCategories({ allPosts, categoryOptions, sliceCount: categoryCount })
|
||||||
const tags = await getAllTags({ allPosts, tagOptions, sliceCount: tagsCount })
|
const tags = await getAllTags({ allPosts, tagOptions, sliceCount: tagsCount })
|
||||||
const latestPosts = await getLatestPosts({ notionPageData, from, latestPostCount })
|
const latestPosts = await getLatestPosts({ notionPageData, from, latestPostCount })
|
||||||
return { allPosts, latestPosts, categories, postCount, customNav, tags }
|
return { allPosts, latestPosts, categories, postCount, customNav, tags }
|
||||||
@@ -110,6 +113,11 @@ function getTagOptions (schema) {
|
|||||||
return tagSchema?.options || {}
|
return tagSchema?.options || {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function getCategoryOptions (schema) {
|
||||||
|
const categorySchema = Object.values(schema).find(e => e.name === 'category')
|
||||||
|
return categorySchema?.options || {}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 调用NotionAPI获取Page数据
|
* 调用NotionAPI获取Page数据
|
||||||
* @returns {Promise<JSX.Element|null|*>}
|
* @returns {Promise<JSX.Element|null|*>}
|
||||||
@@ -119,7 +127,6 @@ async function getPageRecordMapByNotionAPI ({ pageId, from }) {
|
|||||||
if (!pageRecordMap) {
|
if (!pageRecordMap) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
|
|
||||||
pageId = idToUuid(pageId)
|
pageId = idToUuid(pageId)
|
||||||
const collection = Object.values(pageRecordMap.collection)[0]?.value
|
const collection = Object.values(pageRecordMap.collection)[0]?.value
|
||||||
const collectionQuery = pageRecordMap.collection_query
|
const collectionQuery = pageRecordMap.collection_query
|
||||||
@@ -127,6 +134,7 @@ async function getPageRecordMapByNotionAPI ({ pageId, from }) {
|
|||||||
const schema = collection?.schema
|
const schema = collection?.schema
|
||||||
const rawMetadata = block[pageId].value
|
const rawMetadata = block[pageId].value
|
||||||
const tagOptions = getTagOptions(schema)
|
const tagOptions = getTagOptions(schema)
|
||||||
|
const categoryOptions = getCategoryOptions(schema)
|
||||||
|
|
||||||
// Check Type Page-Database和Inline-Database
|
// Check Type Page-Database和Inline-Database
|
||||||
if (
|
if (
|
||||||
@@ -143,6 +151,7 @@ async function getPageRecordMapByNotionAPI ({ pageId, from }) {
|
|||||||
block,
|
block,
|
||||||
schema,
|
schema,
|
||||||
tagOptions,
|
tagOptions,
|
||||||
|
categoryOptions,
|
||||||
rawMetadata
|
rawMetadata
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ export default function Category (props) {
|
|||||||
|
|
||||||
export async function getStaticProps () {
|
export async function getStaticProps () {
|
||||||
const from = 'category-index-props'
|
const from = 'category-index-props'
|
||||||
const { allPosts, categories, tags, postCount, latestPosts, customNav } = await getGlobalNotionData({ from })
|
const { allPosts, categories, tags, postCount, latestPosts, customNav } = await getGlobalNotionData({ from, categoryCount: 0 })
|
||||||
|
|
||||||
return {
|
return {
|
||||||
props: {
|
props: {
|
||||||
|
|||||||
@@ -12,16 +12,16 @@ export const LayoutCategoryIndex = (props) => {
|
|||||||
type: 'website'
|
type: 'website'
|
||||||
}
|
}
|
||||||
return <LayoutBase meta={meta} totalPosts={allPosts} {...props}>
|
return <LayoutBase meta={meta} totalPosts={allPosts} {...props}>
|
||||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow h-full'>
|
||||||
<div className='dark:text-gray-200 mb-5'>
|
<div className='dark:text-gray-200 mb-5'>
|
||||||
<i className='mr-4 fas faTh' />{locale.COMMON.CATEGORY}:
|
<i className='mr-4 fas faTh' />{locale.COMMON.CATEGORY}:
|
||||||
</div>
|
</div>
|
||||||
<div id='category-list' className='duration-200 flex flex-wrap'>
|
<div id='category-list' className='duration-200 flex flex-wrap'>
|
||||||
{Object.keys(categories).map(category => {
|
{categories.map(category => {
|
||||||
return <Link key={category} href={`/category/${category}`} passHref>
|
return <Link key={category.name} href={`/category/${category.name}`} passHref>
|
||||||
<div
|
<div
|
||||||
className={'hover:text-black dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600 px-5 cursor-pointer py-2 hover:bg-gray-100'}>
|
className={'hover:text-black dark:hover:text-white dark:text-gray-300 dark:hover:bg-gray-600 px-5 cursor-pointer py-2 hover:bg-gray-100'}>
|
||||||
<i className='mr-4 fas fa-folder' />{category}({categories[category]})
|
<i className='mr-4 fas fa-folder' />{category.name}({category.count})
|
||||||
</div>
|
</div>
|
||||||
</Link>
|
</Link>
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ export const LayoutTagIndex = (props) => {
|
|||||||
type: 'website'
|
type: 'website'
|
||||||
}
|
}
|
||||||
return <LayoutBase meta={meta} {...props}>
|
return <LayoutBase meta={meta} {...props}>
|
||||||
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow'>
|
<div className='bg-white dark:bg-gray-700 px-10 py-10 shadow h-full'>
|
||||||
<div className='dark:text-gray-200 mb-5'><i className='fas fa-tags mr-4'/>{locale.COMMON.TAGS}:</div>
|
<div className='dark:text-gray-200 mb-5'><i className='fas fa-tags mr-4'/>{locale.COMMON.TAGS}:</div>
|
||||||
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
<div id='tags-list' className='duration-200 flex flex-wrap'>
|
||||||
{ tags.map(tag => {
|
{ tags.map(tag => {
|
||||||
|
|||||||
@@ -2,16 +2,17 @@ import Link from 'next/link'
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
|
|
||||||
const CategoryGroup = ({ currentCategory, categories }) => {
|
const CategoryGroup = ({ currentCategory, categories }) => {
|
||||||
|
if (!categories) return <></>
|
||||||
return <>
|
return <>
|
||||||
<div id='category-list' className='dark:border-gray-600 flex flex-wrap'>
|
<div id='category-list' className='dark:border-gray-600 flex flex-wrap'>
|
||||||
{Object.keys(categories).map(category => {
|
{categories.map(category => {
|
||||||
const selected = currentCategory === category
|
const selected = currentCategory === category.name
|
||||||
return <Link key={category} href={`/category/${category}`} passHref>
|
return <Link key={category.name} href={`/category/${category.name}`} passHref>
|
||||||
<a className={(selected
|
<a className={(selected
|
||||||
? 'hover:text-white dark:hover:text-white bg-gray-600 text-white '
|
? 'hover:text-white dark:hover:text-white bg-gray-600 text-white '
|
||||||
: 'dark:text-gray-400 text-gray-500 hover:text-white hover:bg-gray-500 dark:hover:text-white') +
|
: 'dark:text-gray-400 text-gray-500 hover:text-white hover:bg-gray-500 dark:hover:text-white') +
|
||||||
' text-sm w-full items-center duration-300 px-2 cursor-pointer py-1 font-light'}>
|
' text-sm w-full items-center duration-300 px-2 cursor-pointer py-1 font-light'}>
|
||||||
<i className={`${selected ? 'text-white fa-folder-open ' : 'text-gray-400 fa-folder '} mr-2 fas`} />{category}({categories[category]})
|
<i className={`${selected ? 'text-white fa-folder-open ' : 'text-gray-400 fa-folder '} mr-2 fas`} />{category.name}({category.count})
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
})}
|
})}
|
||||||
|
|||||||
@@ -10,10 +10,10 @@ const CategoryList = ({ currentCategory, categories }) => {
|
|||||||
|
|
||||||
return <ul className='flex py-1 space-x-3'>
|
return <ul className='flex py-1 space-x-3'>
|
||||||
<li className='w-16 py-2 dark:text-gray-200 whitespace-nowrap'>{locale.COMMON.CATEGORY}</li>
|
<li className='w-16 py-2 dark:text-gray-200 whitespace-nowrap'>{locale.COMMON.CATEGORY}</li>
|
||||||
{Object.keys(categories).map(category => {
|
{categories.map(category => {
|
||||||
const selected = category === currentCategory
|
const selected = category.name === currentCategory
|
||||||
return (
|
return (
|
||||||
<Link key={category} href={`/category/${category}`} passHref>
|
<Link key={category.name} href={`/category/${category.name}`} passHref>
|
||||||
<li
|
<li
|
||||||
className={`cursor-pointer border rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-light text-sm whitespace-nowrap dark:text-gray-300
|
className={`cursor-pointer border rounded-xl duration-200 mr-1 my-1 px-2 py-1 font-light text-sm whitespace-nowrap dark:text-gray-300
|
||||||
${selected
|
${selected
|
||||||
@@ -23,7 +23,7 @@ const CategoryList = ({ currentCategory, categories }) => {
|
|||||||
>
|
>
|
||||||
<a>
|
<a>
|
||||||
<i className={`${selected ? 'fa-folder-open ' : 'fa-folder '} fas mr-1`}/>
|
<i className={`${selected ? 'fa-folder-open ' : 'fa-folder '} fas mr-1`}/>
|
||||||
{`${category} `}
|
{`${category.name} (${category.count})`}
|
||||||
</a>
|
</a>
|
||||||
</li>
|
</li>
|
||||||
</Link>)
|
</Link>)
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import Card from './Card'
|
|||||||
import CategoryGroup from './CategoryGroup'
|
import CategoryGroup from './CategoryGroup'
|
||||||
import TagGroups from './TagGroups'
|
import TagGroups from './TagGroups'
|
||||||
import CONFIG_NEXT from '../config_next'
|
import CONFIG_NEXT from '../config_next'
|
||||||
|
import { useRouter } from 'next/router'
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 侧边平铺
|
* 侧边平铺
|
||||||
@@ -16,18 +17,13 @@ import CONFIG_NEXT from '../config_next'
|
|||||||
* @returns {JSX.Element}
|
* @returns {JSX.Element}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
const SideAreaRight = ({
|
const SideAreaRight = (props) => {
|
||||||
tags,
|
const { tags, currentTag, slot, categories, currentCategory } = props
|
||||||
currentTag,
|
|
||||||
slot,
|
|
||||||
categories,
|
|
||||||
currentCategory
|
|
||||||
}) => {
|
|
||||||
const { locale } = useGlobal()
|
const { locale } = useGlobal()
|
||||||
if (!CONFIG_NEXT.RIGHT_BAR) {
|
if (!CONFIG_NEXT.RIGHT_BAR) {
|
||||||
return <></>
|
return <></>
|
||||||
}
|
}
|
||||||
|
const router = useRouter()
|
||||||
return (<aside id='right' className='hidden 2xl:block flex-col w-60 ml-4'>
|
return (<aside id='right' className='hidden 2xl:block flex-col w-60 ml-4'>
|
||||||
|
|
||||||
{CONFIG_NEXT.RIGHT_AD && <Card className='mb-2'>
|
{CONFIG_NEXT.RIGHT_AD && <Card className='mb-2'>
|
||||||
@@ -44,15 +40,16 @@ const SideAreaRight = ({
|
|||||||
</Card>}
|
</Card>}
|
||||||
|
|
||||||
<div className="sticky top-4">
|
<div className="sticky top-4">
|
||||||
|
{slot}
|
||||||
|
|
||||||
{/* 分类 */}
|
{/* 分类 */}
|
||||||
{CONFIG_NEXT.RIGHT_CATEGORY_LIST && categories && (
|
{CONFIG_NEXT.RIGHT_CATEGORY_LIST && router.asPath !== '/category' && categories && (
|
||||||
<Card>
|
<Card>
|
||||||
<div className='text-sm px-2 flex flex-nowrap justify-between font-light'>
|
<div className='text-sm px-2 flex flex-nowrap justify-between font-light'>
|
||||||
<div className='pb-1 text-gray-600 dark:text-gray-300'><i icon={faThList} className='mr-2' />{locale.COMMON.CATEGORY}</div>
|
<div className='pb-1 text-gray-600 dark:text-gray-300'><i className='mr-2 fas fa-th-list' />{locale.COMMON.CATEGORY}</div>
|
||||||
<Link href={'/category'} passHref>
|
<Link href={'/category'} passHref>
|
||||||
<a className='text-gray-400 hover:text-black dark:text-gray-400 dark:hover:text-white hover:underline cursor-pointer'>
|
<a className='text-gray-400 hover:text-black dark:text-gray-400 dark:hover:text-white hover:underline cursor-pointer'>
|
||||||
{locale.COMMON.MORE} <i icon={faAngleRight} />
|
{locale.COMMON.MORE} <i className='fas fa-angle-right' />
|
||||||
</a>
|
</a>
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
@@ -60,9 +57,7 @@ const SideAreaRight = ({
|
|||||||
</Card>
|
</Card>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{slot}
|
{CONFIG_NEXT.RIGHT_TAG_LIST && router.asPath !== '/tag' && tags && (
|
||||||
|
|
||||||
{CONFIG_NEXT.RIGHT_TAG_LIST && tags && (
|
|
||||||
<Card>
|
<Card>
|
||||||
<div className="text-sm pb-1 px-2 flex flex-nowrap justify-between font-light dark:text-gray-200">
|
<div className="text-sm pb-1 px-2 flex flex-nowrap justify-between font-light dark:text-gray-200">
|
||||||
<div className="text-gray-600 dark:text-gray-200">
|
<div className="text-gray-600 dark:text-gray-200">
|
||||||
|
|||||||
Reference in New Issue
Block a user