mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
Merge branch 'main' of https://github.com/tangly1024/NotionNext
This commit is contained in:
@@ -13,6 +13,7 @@ const BLOG = {
|
||||
APPEARANCE: process.env.NEXT_PUBLIC_APPEARANCE || 'light', // ['light', 'dark', 'auto'], // light 日间模式 , dark夜间模式, auto根据时间和主题自动夜间模式
|
||||
APPEARANCE_DARK_TIME: process.env.NEXT_PUBLIC_APPEARANCE_DARK_TIME || [18, 6], // 夜间模式起至时间,false时关闭根据时间自动切换夜间模式
|
||||
|
||||
TAG_SORT_BY_COUNT: true, // 标签是否按照文章数量倒序排列,文章多的标签排在前。
|
||||
IS_TAG_COLOR_DISTINGUISHED:
|
||||
process.env.NEXT_PUBLIC_IS_TAG_COLOR_DISTINGUISHED === 'true' || true, // 对于名称相同的tag是否区分tag的颜色
|
||||
|
||||
|
||||
@@ -56,6 +56,9 @@ export default function CustomContextMenu(props) {
|
||||
setShow(true)
|
||||
}
|
||||
|
||||
/**
|
||||
* 鼠标点击事件
|
||||
*/
|
||||
const handleClick = event => {
|
||||
if (menuRef.current && !menuRef.current.contains(event.target)) {
|
||||
setShow(false)
|
||||
@@ -140,6 +143,26 @@ export default function CustomContextMenu(props) {
|
||||
htmlElement.classList?.add(newStatus ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
// 一些配置变量
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST'
|
||||
)
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY'
|
||||
)
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG'
|
||||
)
|
||||
const CAN_COPY = siteConfig('CAN_COPY')
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK'
|
||||
)
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE'
|
||||
)
|
||||
const CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH = siteConfig(
|
||||
'CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH'
|
||||
)
|
||||
return (
|
||||
<div
|
||||
ref={menuRef}
|
||||
@@ -167,7 +190,7 @@ export default function CustomContextMenu(props) {
|
||||
|
||||
{/* 跳转导航按钮 */}
|
||||
<div className='w-full px-2'>
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_RANDOM_POST && (
|
||||
<div
|
||||
onClick={handleJumpToRandomPost}
|
||||
title={locale.MENU.WALK_AROUND}
|
||||
@@ -177,7 +200,7 @@ export default function CustomContextMenu(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_CATEGORY && (
|
||||
<Link
|
||||
href='/category'
|
||||
title={locale.MENU.CATEGORY}
|
||||
@@ -187,7 +210,7 @@ export default function CustomContextMenu(props) {
|
||||
</Link>
|
||||
)}
|
||||
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_TAG && (
|
||||
<Link
|
||||
href='/tag'
|
||||
title={locale.MENU.TAGS}
|
||||
@@ -202,7 +225,7 @@ export default function CustomContextMenu(props) {
|
||||
|
||||
{/* 功能按钮 */}
|
||||
<div className='w-full px-2'>
|
||||
{siteConfig('CAN_COPY') && (
|
||||
{CAN_COPY && (
|
||||
<div
|
||||
onClick={handleCopy}
|
||||
title={locale.MENU.COPY}
|
||||
@@ -212,7 +235,7 @@ export default function CustomContextMenu(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_SHARE_LINK && (
|
||||
<div
|
||||
onClick={handleCopyLink}
|
||||
title={locale.MENU.SHARE_URL}
|
||||
@@ -222,7 +245,7 @@ export default function CustomContextMenu(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_DARK_MODE && (
|
||||
<div
|
||||
onClick={handleChangeDarkMode}
|
||||
title={
|
||||
@@ -241,7 +264,7 @@ export default function CustomContextMenu(props) {
|
||||
</div>
|
||||
)}
|
||||
|
||||
{siteConfig('CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH') && (
|
||||
{CUSTOM_RIGHT_CLICK_CONTEXT_MENU_THEME_SWITCH && (
|
||||
<div
|
||||
onClick={handleChangeTheme}
|
||||
title={locale.MENU.THEME_SWITCH}
|
||||
|
||||
@@ -5,7 +5,7 @@ import getAllPageIds from '@/lib/notion/getAllPageIds'
|
||||
import { getAllTags } from '@/lib/notion/getAllTags'
|
||||
import { getConfigMapFromConfigPage } from '@/lib/notion/getNotionConfig'
|
||||
import getPageProperties, {
|
||||
adjustPageProperties
|
||||
adjustPageProperties
|
||||
} from '@/lib/notion/getPageProperties'
|
||||
import { fetchInBatches, getPage } from '@/lib/notion/getPostBlocks'
|
||||
import { compressImage, mapImgUrl } from '@/lib/notion/mapImage'
|
||||
@@ -77,15 +77,17 @@ export async function getNotionPageData({ pageId, from }) {
|
||||
}
|
||||
|
||||
// 返回给前端的数据做处理
|
||||
return compressData(deepClone(data))
|
||||
return handleDataBeforeReturn(deepClone(data))
|
||||
}
|
||||
|
||||
/**
|
||||
* 减少返回给前端的数据
|
||||
* 并脱敏
|
||||
* 返回给浏览器前端的数据处理
|
||||
* 适当脱敏
|
||||
* 减少体积
|
||||
* 其它处理
|
||||
* @param {*} db
|
||||
*/
|
||||
function compressData(db) {
|
||||
function handleDataBeforeReturn(db) {
|
||||
// 清理多余数据
|
||||
delete db.block
|
||||
delete db.schema
|
||||
@@ -545,11 +547,17 @@ async function getDataBaseInfoByNotionAPI({ pageId, from }) {
|
||||
)
|
||||
})?.[0]
|
||||
)
|
||||
// 所有分类
|
||||
const categoryOptions = getAllCategories({
|
||||
allPages,
|
||||
categoryOptions: getCategoryOptions(schema)
|
||||
})
|
||||
const tagOptions = getAllTags({ allPages, tagOptions: getTagOptions(schema) })
|
||||
// 所有标签
|
||||
const tagOptions = getAllTags({
|
||||
allPages,
|
||||
tagOptions: getTagOptions(schema),
|
||||
NOTION_CONFIG
|
||||
})
|
||||
// 旧的菜单
|
||||
const customNav = getCustomNav({
|
||||
allPages: collectionData.filter(
|
||||
|
||||
@@ -4,7 +4,7 @@ import { isIterable } from '../utils'
|
||||
* 获取所有文章的标签
|
||||
* @param allPosts
|
||||
* @param sliceCount 默认截取数量为12,若为0则返回全部
|
||||
* @param tagOptions tags的下拉选项
|
||||
* @param categoryOptions categories的下拉选项
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
|
||||
@@ -13,8 +13,14 @@ import { isIterable } from '../utils'
|
||||
* @param allPosts
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export function getAllCategories({ allPages, categoryOptions, sliceCount = 0 }) {
|
||||
const allPosts = allPages?.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
export function getAllCategories({
|
||||
allPages,
|
||||
categoryOptions,
|
||||
sliceCount = 0
|
||||
}) {
|
||||
const allPosts = allPages?.filter(
|
||||
page => page.type === 'Post' && page.status === 'Published'
|
||||
)
|
||||
if (!allPosts || !categoryOptions) {
|
||||
return []
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { siteConfig } from '../config'
|
||||
import { isIterable } from '../utils'
|
||||
import BLOG from '@/blog.config'
|
||||
|
||||
/**
|
||||
* 获取所有文章的标签
|
||||
@@ -8,8 +8,15 @@ import BLOG from '@/blog.config'
|
||||
* @param tagOptions tags的下拉选项
|
||||
* @returns {Promise<{}|*[]>}
|
||||
*/
|
||||
export function getAllTags({ allPages, sliceCount = 0, tagOptions }) {
|
||||
const allPosts = allPages?.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
export function getAllTags({
|
||||
allPages,
|
||||
sliceCount = 0,
|
||||
tagOptions,
|
||||
NOTION_CONFIG
|
||||
}) {
|
||||
const allPosts = allPages?.filter(
|
||||
page => page.type === 'Post' && page.status === 'Published'
|
||||
)
|
||||
|
||||
if (!allPosts || !tagOptions) {
|
||||
return []
|
||||
@@ -27,7 +34,12 @@ export function getAllTags({ allPages, sliceCount = 0, tagOptions }) {
|
||||
})
|
||||
|
||||
const list = []
|
||||
const { IS_TAG_COLOR_DISTINGUISHED } = BLOG
|
||||
const IS_TAG_COLOR_DISTINGUISHED = siteConfig(
|
||||
'IS_TAG_COLOR_DISTINGUISHED',
|
||||
false,
|
||||
NOTION_CONFIG
|
||||
)
|
||||
const TAG_SORT_BY_COUNT = siteConfig('TAG_SORT_BY_COUNT', true, NOTION_CONFIG)
|
||||
if (isIterable(tagOptions)) {
|
||||
if (!IS_TAG_COLOR_DISTINGUISHED) {
|
||||
// 如果不区分颜色, 那么不同颜色相同名称的tag当做同一种tag
|
||||
@@ -52,7 +64,10 @@ export function getAllTags({ allPages, sliceCount = 0, tagOptions }) {
|
||||
}
|
||||
|
||||
// 按照数量排序
|
||||
// list.sort((a, b) => b.count - a.count)
|
||||
if (TAG_SORT_BY_COUNT) {
|
||||
list.sort((a, b) => b.count - a.count)
|
||||
}
|
||||
|
||||
if (sliceCount && sliceCount > 0) {
|
||||
return list.slice(0, sliceCount)
|
||||
} else {
|
||||
|
||||
@@ -44,7 +44,7 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
return (
|
||||
<>
|
||||
{/* pc端分页按钮 */}
|
||||
<div className="hidden lg:flex justify-between items-end mt-10 mb-5 font-medium text-black duration-500 dark:text-gray-300 py-3 space-x-2 overflow-x-auto">
|
||||
<div className='hidden lg:flex justify-between items-end mt-10 font-medium text-black duration-500 dark:text-gray-300 pt-3 space-x-2 overflow-x-auto'>
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
href={{
|
||||
@@ -54,32 +54,29 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
: `${pagePrefix}/page/${currentPage - 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
rel="prev"
|
||||
className={`${currentPage === 1 ? 'invisible' : 'block'}`}
|
||||
>
|
||||
<div className="relative w-24 h-10 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-lg cursor-pointer group">
|
||||
<i className="fas fa-angle-left mr-2 transition-all duration-200 transform group-hover:-translate-x-4" />
|
||||
<div className="absolute translate-x-4 ml-2 opacity-0 transition-all duration-200 group-hover:opacity-100 group-hover:translate-x-0">
|
||||
rel='prev'
|
||||
className={`${currentPage === 1 ? 'invisible' : 'block'}`}>
|
||||
<div className='relative w-24 h-10 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-lg cursor-pointer group'>
|
||||
<i className='fas fa-angle-left mr-2 transition-all duration-200 transform group-hover:-translate-x-4' />
|
||||
<div className='absolute translate-x-4 ml-2 opacity-0 transition-all duration-200 group-hover:opacity-100 group-hover:translate-x-0'>
|
||||
{locale.PAGINATION.PREV}
|
||||
</div>
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{/* 分页 */}
|
||||
<div className="flex items-center space-x-2">
|
||||
<div className='flex items-center space-x-2'>
|
||||
{pages}
|
||||
|
||||
{/* 跳转页码 */}
|
||||
<div className="bg-white hover:bg-gray-100 dark:hover:bg-yellow-600 dark:bg-[#1e1e1e] h-10 border flex justify-center items-center rounded-lg group hover:border-indigo-600 transition-all duration-200">
|
||||
<div className='bg-white hover:bg-gray-100 dark:hover:bg-yellow-600 dark:bg-[#1e1e1e] h-10 border flex justify-center items-center rounded-lg group hover:border-indigo-600 transition-all duration-200'>
|
||||
<input
|
||||
value={value}
|
||||
className="w-0 group-hover:w-20 group-hover:px-3 transition-all duration-200 bg-gray-100 border-none outline-none h-full rounded-lg"
|
||||
onInput={handleInputChange}
|
||||
></input>
|
||||
className='w-0 group-hover:w-20 group-hover:px-3 transition-all duration-200 bg-gray-100 border-none outline-none h-full rounded-lg'
|
||||
onInput={handleInputChange}></input>
|
||||
<div
|
||||
onClick={jumpToPage}
|
||||
className="cursor-pointer hover:bg-indigo-600 dark:bg-[#1e1e1e] dark:hover:bg-yellow-600 hover:text-white px-4 py-2 group-hover:px-2 group-hover:mx-1 group-hover:rounded bg-white"
|
||||
>
|
||||
className='cursor-pointer hover:bg-indigo-600 dark:bg-[#1e1e1e] dark:hover:bg-yellow-600 hover:text-white px-4 py-2 group-hover:px-2 group-hover:mx-1 group-hover:rounded bg-white'>
|
||||
<ChevronDoubleRight className={'w-4 h-4'} />
|
||||
</div>
|
||||
</div>
|
||||
@@ -91,12 +88,11 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
rel="next"
|
||||
className={`${+showNext ? 'block' : 'invisible'} `}
|
||||
>
|
||||
<div className="relative w-24 h-10 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-lg cursor-pointer group">
|
||||
<i className="fas fa-angle-right mr-2 transition-all duration-200 transform group-hover:translate-x-6" />
|
||||
<div className="absolute -translate-x-10 ml-2 opacity-0 transition-all duration-200 group-hover:opacity-100 group-hover:-translate-x-2">
|
||||
rel='next'
|
||||
className={`${+showNext ? 'block' : 'invisible'} `}>
|
||||
<div className='relative w-24 h-10 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-lg cursor-pointer group'>
|
||||
<i className='fas fa-angle-right mr-2 transition-all duration-200 transform group-hover:translate-x-6' />
|
||||
<div className='absolute -translate-x-10 ml-2 opacity-0 transition-all duration-200 group-hover:opacity-100 group-hover:-translate-x-2'>
|
||||
{locale.PAGINATION.NEXT}
|
||||
</div>
|
||||
</div>
|
||||
@@ -105,7 +101,7 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
|
||||
{/* 移动端分页 */}
|
||||
|
||||
<div className="lg:hidden w-full flex flex-row">
|
||||
<div className='lg:hidden w-full flex flex-row'>
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
href={{
|
||||
@@ -115,13 +111,12 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
: `${pagePrefix}/page/${currentPage - 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
rel="prev"
|
||||
className={`${showPrev ? 'block' : 'hidden'} dark:text-white relative w-full flex-1 h-14 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-xl cursor-pointer`}
|
||||
>
|
||||
rel='prev'
|
||||
className={`${showPrev ? 'block' : 'hidden'} dark:text-white relative w-full flex-1 h-14 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-xl cursor-pointer`}>
|
||||
{locale.PAGINATION.PREV}
|
||||
</Link>
|
||||
|
||||
{showPrev && showNext && <div className="w-12"></div>}
|
||||
{showPrev && showNext && <div className='w-12'></div>}
|
||||
|
||||
{/* 下一页 */}
|
||||
<Link
|
||||
@@ -129,9 +124,8 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
rel="next"
|
||||
className={`${+showNext ? 'block' : 'hidden'} dark:text-white relative w-full flex-1 h-14 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-xl cursor-pointer`}
|
||||
>
|
||||
rel='next'
|
||||
className={`${+showNext ? 'block' : 'hidden'} dark:text-white relative w-full flex-1 h-14 flex items-center transition-all duration-200 justify-center py-2 px-2 bg-white dark:bg-[#1e1e1e] border rounded-xl cursor-pointer`}>
|
||||
{locale.PAGINATION.NEXT}
|
||||
</Link>
|
||||
</div>
|
||||
@@ -161,8 +155,7 @@ function getPageElement(page, currentPage, pagePrefix) {
|
||||
? 'bg-indigo-600 dark:bg-yellow-600 text-white '
|
||||
: 'dark:bg-[#1e1e1e] bg-white') +
|
||||
' hover:border-indigo-600 dark:hover:bg-yellow-600 dark:border-gray-600 px-4 border py-2 rounded-lg drop-shadow-sm duration-200 transition-colors'
|
||||
}
|
||||
>
|
||||
}>
|
||||
{page}
|
||||
</Link>
|
||||
)
|
||||
@@ -195,7 +188,7 @@ function generatePages(pagePrefix, page, currentPage, totalPage) {
|
||||
}
|
||||
if (startPage > 2) {
|
||||
pages.push(
|
||||
<div key={-1} className="-mt-2 mx-1">
|
||||
<div key={-1} className='-mt-2 mx-1'>
|
||||
...{' '}
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
import Live2D from '@/components/Live2D'
|
||||
import dynamic from 'next/dynamic'
|
||||
import { AnalyticsCard } from './AnalyticsCard'
|
||||
import Card from './Card'
|
||||
import TagGroups from './TagGroups'
|
||||
import Catalog from './Catalog'
|
||||
import { InfoCard } from './InfoCard'
|
||||
import dynamic from 'next/dynamic'
|
||||
import Live2D from '@/components/Live2D'
|
||||
import { AnalyticsCard } from './AnalyticsCard'
|
||||
import TouchMeCard from './TouchMeCard'
|
||||
import LatestPostsGroupMini from './LatestPostsGroupMini'
|
||||
import TagGroups from './TagGroups'
|
||||
import TouchMeCard from './TouchMeCard'
|
||||
|
||||
const FaceBookPage = dynamic(
|
||||
() => {
|
||||
@@ -27,46 +27,46 @@ const FaceBookPage = dynamic(
|
||||
* @returns
|
||||
*/
|
||||
export default function SideRight(props) {
|
||||
const {
|
||||
post, tagOptions,
|
||||
currentTag, rightAreaSlot
|
||||
} = props
|
||||
const { post, tagOptions, currentTag, rightAreaSlot } = props
|
||||
|
||||
// 只摘取标签的前60个,防止右侧过长
|
||||
const sortedTags = tagOptions?.slice(0, 60) || []
|
||||
|
||||
return (
|
||||
<div id='sideRight' className='hidden xl:block w-72 space-y-4 h-full'>
|
||||
<div id='sideRight' className='hidden xl:block w-72 space-y-4 h-full'>
|
||||
<InfoCard {...props} className='w-72' />
|
||||
|
||||
<InfoCard {...props} className='w-72' />
|
||||
<div className='sticky top-20 space-y-4'>
|
||||
{/* 文章页显示目录 */}
|
||||
{post && post.toc && post.toc.length > 0 && (
|
||||
<Card className='bg-white dark:bg-[#1e1e1e]'>
|
||||
<Catalog toc={post.toc} />
|
||||
</Card>
|
||||
)}
|
||||
|
||||
<div className='sticky top-20 space-y-4'>
|
||||
|
||||
{/* 文章页显示目录 */}
|
||||
{post && post.toc && post.toc.length > 0 && (
|
||||
<Card className='bg-white dark:bg-[#1e1e1e]'>
|
||||
<Catalog toc={post.toc} />
|
||||
</Card>
|
||||
)}
|
||||
|
||||
{/* 联系交流群 */}
|
||||
<TouchMeCard />
|
||||
|
||||
{/* 最新文章列表 */}
|
||||
<div className={'border dark:border-gray-700 dark:bg-[#1e1e1e] dark:text-white rounded-xl lg:p-6 p-4 hidden lg:block bg-white'}>
|
||||
<LatestPostsGroupMini {...props} />
|
||||
</div>
|
||||
|
||||
{rightAreaSlot}
|
||||
|
||||
<FaceBookPage />
|
||||
<Live2D />
|
||||
|
||||
{/* 标签和成绩 */}
|
||||
<Card className={'bg-white dark:bg-[#1e1e1e] dark:text-white'}>
|
||||
<TagGroups tags={tagOptions} currentTag={currentTag} />
|
||||
<hr className='mx-1 flex border-dashed relative my-4' />
|
||||
<AnalyticsCard {...props} />
|
||||
</Card>
|
||||
</div>
|
||||
{/* 联系交流群 */}
|
||||
<TouchMeCard />
|
||||
|
||||
{/* 最新文章列表 */}
|
||||
<div
|
||||
className={
|
||||
'border dark:border-gray-700 dark:bg-[#1e1e1e] dark:text-white rounded-xl lg:p-6 p-4 hidden lg:block bg-white'
|
||||
}>
|
||||
<LatestPostsGroupMini {...props} />
|
||||
</div>
|
||||
|
||||
{rightAreaSlot}
|
||||
|
||||
<FaceBookPage />
|
||||
<Live2D />
|
||||
|
||||
{/* 标签和成绩 */}
|
||||
<Card className={'bg-white dark:bg-[#1e1e1e] dark:text-white'}>
|
||||
<TagGroups tags={sortedTags} currentTag={currentTag} />
|
||||
<hr className='mx-1 flex border-dashed relative my-4' />
|
||||
<AnalyticsCard {...props} />
|
||||
</Card>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ const LayoutBase = props => {
|
||||
const router = useRouter()
|
||||
|
||||
const headerSlot = (
|
||||
<header className='shadow'>
|
||||
<header>
|
||||
{/* 顶部导航 */}
|
||||
<Header {...props} />
|
||||
|
||||
|
||||
@@ -12,74 +12,75 @@ const PaginationNumber = ({ page, totalPage }) => {
|
||||
const router = useRouter()
|
||||
const currentPage = +page
|
||||
const showNext = currentPage !== totalPage
|
||||
const pagePrefix = router.asPath.split('?')[0].replace(/\/page\/[1-9]\d*/, '').replace(/\/$/, '')
|
||||
const pagePrefix = router.asPath
|
||||
.split('?')[0]
|
||||
.replace(/\/page\/[1-9]\d*/, '')
|
||||
.replace(/\/$/, '')
|
||||
const pages = generatePages(pagePrefix, page, currentPage, totalPage)
|
||||
|
||||
return (
|
||||
<div
|
||||
data-aos="fade-down"
|
||||
data-aos-duration="300"
|
||||
data-aos-once="false"
|
||||
data-aos-anchor-placement="top-bottom"
|
||||
className="my-5 flex justify-center items-end font-medium text-black hover:shadow-xl duration-200 transition-all bg-white dark:bg-hexo-black-gray dark:text-gray-300 py-3 shadow space-x-2">
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
href={{
|
||||
pathname:
|
||||
currentPage - 1 === 1
|
||||
? `${pagePrefix}/`
|
||||
: `${pagePrefix}/page/${currentPage - 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<div
|
||||
rel="prev"
|
||||
className={`${currentPage === 1 ? 'invisible' : 'block'
|
||||
} hover:border-t-2 border-white hover:border-gray-400 dark:hover:border-gray-400 w-8 h-8 justify-center flex items-center cursor-pointer duration-200 transition-all hover:font-bold`}
|
||||
>
|
||||
<i className="fas fa-angle-left" />
|
||||
</div>
|
||||
</Link>
|
||||
data-aos='fade-down'
|
||||
data-aos-duration='300'
|
||||
data-aos-once='false'
|
||||
data-aos-anchor-placement='top-bottom'
|
||||
className='mt-5 py-3 flex justify-center items-end font-medium text-black hover:shadow-xl duration-200 transition-all bg-white dark:bg-hexo-black-gray dark:text-gray-300 shadow space-x-2'>
|
||||
{/* 上一页 */}
|
||||
<Link
|
||||
href={{
|
||||
pathname:
|
||||
currentPage - 1 === 1
|
||||
? `${pagePrefix}/`
|
||||
: `${pagePrefix}/page/${currentPage - 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<div
|
||||
rel='prev'
|
||||
className={`${
|
||||
currentPage === 1 ? 'invisible' : 'block'
|
||||
} hover:border-t-2 border-white hover:border-gray-400 dark:hover:border-gray-400 w-8 h-8 justify-center flex items-center cursor-pointer duration-200 transition-all hover:font-bold`}>
|
||||
<i className='fas fa-angle-left' />
|
||||
</div>
|
||||
</Link>
|
||||
|
||||
{pages}
|
||||
{pages}
|
||||
|
||||
{/* 下一页 */}
|
||||
<Link
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<div
|
||||
rel="next"
|
||||
className={`${+showNext ? 'block' : 'invisible'
|
||||
} hover:border-t-2 border-white hover:border-gray-400 dark:hover:border-gray-400 w-8 h-8 justify-center flex items-center cursor-pointer duration-200 transition-all hover:font-bold`}
|
||||
>
|
||||
<i className="fas fa-angle-right" />
|
||||
</div>
|
||||
</Link>
|
||||
{/* 下一页 */}
|
||||
<Link
|
||||
href={{
|
||||
pathname: `${pagePrefix}/page/${currentPage + 1}`,
|
||||
query: router.query.s ? { s: router.query.s } : {}
|
||||
}}
|
||||
passHref
|
||||
legacyBehavior>
|
||||
<div
|
||||
rel='next'
|
||||
className={`${
|
||||
+showNext ? 'block' : 'invisible'
|
||||
} hover:border-t-2 border-white hover:border-gray-400 dark:hover:border-gray-400 w-8 h-8 justify-center flex items-center cursor-pointer duration-200 transition-all hover:font-bold`}>
|
||||
<i className='fas fa-angle-right' />
|
||||
</div>
|
||||
</Link>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
function getPageElement(pagePrefix, page, currentPage) {
|
||||
return (
|
||||
(<Link
|
||||
<Link
|
||||
href={page === 1 ? `${pagePrefix}/` : `${pagePrefix}/page/${page}`}
|
||||
key={page}
|
||||
passHref
|
||||
className={
|
||||
(page + '' === currentPage + ''
|
||||
? 'font-bold bg-gray-500 dark:bg-gray-400 text-white '
|
||||
: 'hover:border-t-2 duration-200 transition-all border-white hover:border-gray-400 ') +
|
||||
' border-white dark:hover:border-gray-400 cursor-pointer w-8 h-8 justify-center flex items-center font-light hover:font-bold'
|
||||
(page + '' === currentPage + ''
|
||||
? 'font-bold bg-gray-500 dark:bg-gray-400 text-white '
|
||||
: 'hover:border-t-2 duration-200 transition-all border-white hover:border-gray-400 ') +
|
||||
' border-white dark:hover:border-gray-400 cursor-pointer w-8 h-8 justify-center flex items-center font-light hover:font-bold'
|
||||
}>
|
||||
|
||||
{page}
|
||||
|
||||
</Link>)
|
||||
</Link>
|
||||
)
|
||||
}
|
||||
function generatePages(pagePrefix, page, currentPage, totalPage) {
|
||||
@@ -100,7 +101,11 @@ function generatePages(pagePrefix, page, currentPage, totalPage) {
|
||||
startPage = totalPage - dynamicGroupCount
|
||||
}
|
||||
if (startPage > 2) {
|
||||
pages.push(<div key={-1} className='select-none'>... </div>)
|
||||
pages.push(
|
||||
<div key={-1} className='select-none'>
|
||||
...{' '}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
for (let i = 0; i < dynamicGroupCount; i++) {
|
||||
@@ -110,7 +115,11 @@ function generatePages(pagePrefix, page, currentPage, totalPage) {
|
||||
}
|
||||
|
||||
if (startPage + dynamicGroupCount < totalPage) {
|
||||
pages.push(<div key={-2} className='select-none'>... </div>)
|
||||
pages.push(
|
||||
<div key={-2} className='select-none'>
|
||||
...{' '}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
pages.push(getPageElement(pagePrefix, totalPage, page))
|
||||
|
||||
@@ -14,7 +14,11 @@ export const { THEMES = [] } = getConfig().publicRuntimeConfig
|
||||
*/
|
||||
export const getGlobalLayoutByTheme = themeQuery => {
|
||||
if (themeQuery !== BLOG.THEME) {
|
||||
return dynamic(() => import(`@/themes/${themeQuery}`).then(m => m[getLayoutNameByPath(-1)]), { ssr: true })
|
||||
return dynamic(
|
||||
() =>
|
||||
import(`@/themes/${themeQuery}`).then(m => m[getLayoutNameByPath(-1)]),
|
||||
{ ssr: true }
|
||||
)
|
||||
} else {
|
||||
return ThemeComponents[getLayoutNameByPath('-1')]
|
||||
}
|
||||
@@ -36,7 +40,8 @@ export const getLayoutByTheme = ({ router, theme }) => {
|
||||
checkThemeDOM()
|
||||
}, 500)
|
||||
|
||||
const components = m[getLayoutNameByPath(router.pathname, router.asPath)]
|
||||
const components =
|
||||
m[getLayoutNameByPath(router.pathname, router.asPath)]
|
||||
if (components) {
|
||||
return components
|
||||
} else {
|
||||
@@ -49,7 +54,8 @@ export const getLayoutByTheme = ({ router, theme }) => {
|
||||
setTimeout(() => {
|
||||
checkThemeDOM()
|
||||
}, 100)
|
||||
const components = ThemeComponents[getLayoutNameByPath(router.pathname, router.asPath)]
|
||||
const components =
|
||||
ThemeComponents[getLayoutNameByPath(router.pathname, router.asPath)]
|
||||
if (components) {
|
||||
return components
|
||||
} else {
|
||||
@@ -102,7 +108,7 @@ export const initDarkMode = (updateDarkMode, defaultDarkMode) => {
|
||||
const userDarkMode = loadDarkModeFromLocalStorage()
|
||||
if (userDarkMode) {
|
||||
newDarkMode = userDarkMode === 'dark' || userDarkMode === 'true'
|
||||
saveDarkModeToLocalStorage(newDarkMode) //用户手动的才保存
|
||||
saveDarkModeToLocalStorage(newDarkMode) // 用户手动的才保存
|
||||
}
|
||||
|
||||
// 如果站点强制设置默认深色,则优先级改过用
|
||||
@@ -117,7 +123,9 @@ export const initDarkMode = (updateDarkMode, defaultDarkMode) => {
|
||||
}
|
||||
|
||||
updateDarkMode(newDarkMode)
|
||||
document.getElementsByTagName('html')[0].setAttribute('class', newDarkMode ? 'dark' : 'light')
|
||||
document
|
||||
.getElementsByTagName('html')[0]
|
||||
.setAttribute('class', newDarkMode ? 'dark' : 'light')
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -131,11 +139,14 @@ export function isPreferDark() {
|
||||
if (BLOG.APPEARANCE === 'auto') {
|
||||
// 系统深色模式或时间是夜间时,强行置为夜间模式
|
||||
const date = new Date()
|
||||
const prefersDarkMode = window.matchMedia('(prefers-color-scheme: dark)').matches
|
||||
const prefersDarkMode = window.matchMedia(
|
||||
'(prefers-color-scheme: dark)'
|
||||
).matches
|
||||
return (
|
||||
prefersDarkMode ||
|
||||
(BLOG.APPEARANCE_DARK_TIME &&
|
||||
(date.getHours() >= BLOG.APPEARANCE_DARK_TIME[0] || date.getHours() < BLOG.APPEARANCE_DARK_TIME[1]))
|
||||
(date.getHours() >= BLOG.APPEARANCE_DARK_TIME[0] ||
|
||||
date.getHours() < BLOG.APPEARANCE_DARK_TIME[1]))
|
||||
)
|
||||
}
|
||||
return false
|
||||
|
||||
Reference in New Issue
Block a user