mirror of
https://github.com/d0zingcat/NotionNext.git
synced 2026-05-14 07:26:52 +00:00
Merge branch 'tangly1024:main' into main
This commit is contained in:
@@ -1,2 +1,2 @@
|
||||
# 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables
|
||||
NEXT_PUBLIC_VERSION=3.8.1
|
||||
NEXT_PUBLIC_VERSION=3.8.2
|
||||
|
||||
@@ -75,6 +75,8 @@
|
||||
|
||||
<td align="center"><a href="https://github.com/xloong"><img src="https://avatars.githubusercontent.com/u/8479955" width="64px;" alt="xloong"/><br/><sub><b>xloong</b></sub></a><br/><a href="https://github.com/tangly1024/NotionNext/commits?author=xloong" title="xloong" >🔧 🐛</a></td>
|
||||
|
||||
<td align="center"><a href="https://github.com/expoli"><img src="https://avatars.githubusercontent.com/u/31023767" width="64px;" alt="expoli"/><br/><sub><b>expoli</b></sub></a><br/><a href="https://github.com/tangly1024/NotionNext/commits?author=expoli" title="expoli" >🔧 🐛</a></td>
|
||||
|
||||
</tr>
|
||||
</table>
|
||||
|
||||
|
||||
@@ -43,6 +43,7 @@ const BLOG = {
|
||||
|
||||
// PrismJs CDN
|
||||
PRISM_JS_PATH: 'https://npm.elemecdn.com/prismjs@1.29.0/components/',
|
||||
CODE_LINE_NUMBERS: process.env.NEXT_PUBLIC_CODE_LINE_NUMBERS || 'false',
|
||||
|
||||
BACKGROUND_LIGHT: '#eeeeee', // use hex value, don't forget '#' e.g #fffefc
|
||||
BACKGROUND_DARK: '#000000', // use hex value, don't forget '#'
|
||||
@@ -90,6 +91,7 @@ const BLOG = {
|
||||
MUSIC_PLAYER_VISIBLE: process.env.NEXT_PUBLIC_MUSIC_PLAYER_VISIBLE || true, // 是否在左下角显示播放和切换,如果使用播放器,打开自动播放再隐藏,就会以类似背景音乐的方式播放,无法取消和暂停
|
||||
MUSIC_PLAYER_AUTO_PLAY: process.env.NEXT_PUBLIC_MUSIC_PLAYER_AUTO_PLAY || true, // 是否自动播放,不过自动播放时常不生效(移动设备不支持自动播放)
|
||||
MUSIC_PLAYER_SHOW_LRC: process.env.NEXT_PUBLIC_MUSIC_PLAYER_SHOW_LRC || false, // 是否展示歌词(前提是有配置歌词路径,对 meting 无效)
|
||||
MUSIC_PLAYER_CDN_URL: process.env.NEXT_PUBLIC_MUSIC_PLAYER_CDN_URL || 'https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.js',
|
||||
MUSIC_PLAYER_ORDER: 'list', // 默认播放方式,顺序 list,随机 random
|
||||
MUSIC_PLAYER_AUDIO_LIST: [ // 示例音乐列表。除了以下配置外,还可配置歌词,具体配置项看此文档 https://aplayer.js.org/#/zh-Hans/
|
||||
{
|
||||
@@ -108,6 +110,7 @@ const BLOG = {
|
||||
MUSIC_PLAYER_METING: process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING || false, // 是否要开启 MetingJS,从平台获取歌单。会覆盖自定义的 MUSIC_PLAYER_AUDIO_LIST,更多配置信息:https://github.com/metowolf/MetingJS
|
||||
MUSIC_PLAYER_METING_SERVER: process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_SERVER || 'netease', // 音乐平台,[netease, tencent, kugou, xiami, baidu]
|
||||
MUSIC_PLAYER_METING_ID: process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_ID || '60198', // 对应歌单的 id
|
||||
MUSIC_PLAYER_METING_LRC_TYPE: process.env.NEXT_PUBLIC_MUSIC_PLAYER_METING_LRC_TYPE || '1', // 可选值: 3 | 1 | 0(0:禁用 lrc 歌词,1:lrc 格式的字符串,3:lrc 文件 url)
|
||||
|
||||
// ----> 评论互动 可同时开启多个支持 WALINE VALINE GISCUS CUSDIS UTTERRANCES GITALK
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ const CommonScript = () => {
|
||||
</>)}
|
||||
|
||||
{/* 引入音乐播放 */}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && <script async src="https://cdnjs.cloudflare.com/ajax/libs/aplayer/1.10.1/APlayer.min.js" />}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && <script async src={BLOG.MUSIC_PLAYER_CDN_URL} />}
|
||||
{JSON.parse(BLOG.MUSIC_PLAYER) && JSON.parse(BLOG.MUSIC_PLAYER_METING) && <script async src="https://cdnjs.cloudflare.com/ajax/libs/meting/2.0.1/Meting.min.js" />}
|
||||
</>)
|
||||
}
|
||||
|
||||
@@ -32,12 +32,14 @@ const Player = () => {
|
||||
<link
|
||||
rel="stylesheet"
|
||||
type="text/css"
|
||||
href="https://cdnjs.cloudflare.com/ajax/libs/aplayer/1.10.1/APlayer.min.css"
|
||||
href="https://lf9-cdn-tos.bytecdntp.com/cdn/expire-1-M/aplayer/1.10.1/APlayer.min.css"
|
||||
/>
|
||||
{meting
|
||||
? <meting-js
|
||||
fixed
|
||||
fixed="true"
|
||||
type="playlist"
|
||||
preload="auto"
|
||||
lrc-type={BLOG.MUSIC_PLAYER_METING_LRC_TYPE}
|
||||
autoplay={autoPlay}
|
||||
order={BLOG.MUSIC_PLAYER_ORDER}
|
||||
server={BLOG.MUSIC_PLAYER_METING_SERVER}
|
||||
|
||||
@@ -73,16 +73,17 @@ function renderPrismMac() {
|
||||
const container = document?.getElementById('container-inner')
|
||||
|
||||
// Add line numbers
|
||||
const codeBlocks = container?.getElementsByTagName('pre')
|
||||
if (codeBlocks) {
|
||||
Array.from(codeBlocks).forEach(item => {
|
||||
if (!item.classList.contains('line-numbers')) {
|
||||
item.classList.add('line-numbers')
|
||||
item.style.whiteSpace = 'pre-wrap'
|
||||
}
|
||||
})
|
||||
if (BLOG.CODE_LINE_NUMBERS === 'true') {
|
||||
const codeBlocks = container?.getElementsByTagName('pre')
|
||||
if (codeBlocks) {
|
||||
Array.from(codeBlocks).forEach(item => {
|
||||
if (!item.classList.contains('line-numbers')) {
|
||||
item.classList.add('line-numbers')
|
||||
item.style.whiteSpace = 'pre-wrap'
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// 重新渲染之前检查所有的多余text
|
||||
|
||||
try {
|
||||
|
||||
@@ -162,7 +162,7 @@ function createSakura() {
|
||||
sakura.draw(cxt)
|
||||
sakuraList.push(sakura)
|
||||
}
|
||||
stop = requestAnimationFrame(asd())
|
||||
stop = requestAnimationFrame(asd)
|
||||
function asd() {
|
||||
cxt.clearRect(0, 0, canvas.width, canvas.height)
|
||||
sakuraList.update()
|
||||
|
||||
@@ -22,7 +22,7 @@ const Utterances = ({ issueTerm, layout }) => {
|
||||
script.setAttribute('crossorigin', 'anonymous')
|
||||
script.setAttribute('async', true)
|
||||
script.setAttribute('repo', BLOG.COMMENT_UTTERRANCES_REPO)
|
||||
script.setAttribute('issue-term', issueTerm)
|
||||
script.setAttribute('issue-term', 'title')
|
||||
script.setAttribute('theme', theme)
|
||||
anchor.appendChild(script)
|
||||
return () => {
|
||||
|
||||
@@ -14,10 +14,18 @@ const GlobalContext = createContext()
|
||||
* @constructor
|
||||
*/
|
||||
export function GlobalContextProvider({ children }) {
|
||||
const [locale, updateLocale] = useState(generateLocaleDict('en-US'))
|
||||
const [lang, updateLang] = useState(BLOG.LANG)
|
||||
const [locale, updateLocale] = useState(generateLocaleDict(BLOG.LANG))
|
||||
const [theme, setTheme] = useState(BLOG.THEME)
|
||||
const [isDarkMode, updateDarkMode] = useState(false)
|
||||
const [onLoading, changeLoadingState] = useState(false)
|
||||
const [theme, setTheme] = useState(BLOG.THEME)
|
||||
|
||||
useEffect(() => {
|
||||
initLocale(lang, locale, updateLang, updateLocale)
|
||||
initDarkMode(isDarkMode, updateDarkMode)
|
||||
initTheme(theme, changeTheme)
|
||||
}, [])
|
||||
|
||||
Router.events.on('routeChangeStart', (...args) => {
|
||||
changeLoadingState(true)
|
||||
})
|
||||
@@ -42,12 +50,6 @@ export function GlobalContextProvider({ children }) {
|
||||
saveThemeToCookies(theme)
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
initLocale(locale, updateLocale)
|
||||
initDarkMode(isDarkMode, updateDarkMode)
|
||||
initTheme(theme, changeTheme)
|
||||
}, [])
|
||||
|
||||
return (
|
||||
<GlobalContext.Provider value={{ onLoading, changeLoadingState, locale, updateLocale, isDarkMode, updateDarkMode, theme, setTheme, switchTheme, changeTheme }}>
|
||||
{children}
|
||||
|
||||
34
lib/lang.js
34
lib/lang.js
@@ -3,6 +3,7 @@ import enUS from './lang/en-US'
|
||||
import zhHK from './lang/zh-HK'
|
||||
import zhTW from './lang/zh-TW'
|
||||
import frFR from '@/lib/lang/fr-FR'
|
||||
import cookie from 'react-cookies'
|
||||
import { getQueryVariable, isBrowser, mergeDeep } from './utils'
|
||||
|
||||
const lang = {
|
||||
@@ -43,16 +44,37 @@ export function generateLocaleDict(langString) {
|
||||
}
|
||||
|
||||
/**
|
||||
* 初始化语言
|
||||
* 初始化站点翻译
|
||||
* 根据用户当前浏览器语言进行切换
|
||||
*/
|
||||
export function initLocale(locale, changeLocale) {
|
||||
export function initLocale(lang, locale, changeLang, changeLocale) {
|
||||
if (isBrowser()) {
|
||||
const browserLocale = window.navigator.language
|
||||
const queryLocale = getQueryVariable('lang')
|
||||
const targetLocale = generateLocaleDict(queryLocale || browserLocale)
|
||||
if (JSON.stringify(locale) !== JSON.stringify(targetLocale)) {
|
||||
const queryLang = getQueryVariable('lang') || loadLangFromCookies() || window.navigator.language
|
||||
let currentLang = lang
|
||||
if (queryLang !== lang) {
|
||||
currentLang = queryLang
|
||||
}
|
||||
changeLang(currentLang)
|
||||
saveLangToCookies(currentLang)
|
||||
|
||||
const targetLocale = generateLocaleDict(currentLang)
|
||||
if (JSON.stringify(locale) !== JSON.stringify(currentLang)) {
|
||||
changeLocale(targetLocale)
|
||||
}
|
||||
}
|
||||
}
|
||||
/**
|
||||
* 读取语言
|
||||
* @returns {*}
|
||||
*/
|
||||
export const loadLangFromCookies = () => {
|
||||
return cookie.load('lang')
|
||||
}
|
||||
|
||||
/**
|
||||
* 保存语言
|
||||
* @param newTheme
|
||||
*/
|
||||
export const saveLangToCookies = (lang) => {
|
||||
cookie.save('lang', lang, { path: '/' })
|
||||
}
|
||||
|
||||
16
lib/theme.js
16
lib/theme.js
@@ -1,7 +1,7 @@
|
||||
import cookie from 'react-cookies'
|
||||
import BLOG from '@/blog.config'
|
||||
import { ALL_THEME } from '@/themes'
|
||||
import { getQueryVariable } from './utils'
|
||||
import { isBrowser, getQueryVariable } from './utils'
|
||||
|
||||
/**
|
||||
* 初始化主题 , 优先级 query > cookies > systemPrefer
|
||||
@@ -27,14 +27,14 @@ export const initDarkMode = (isDarkMode, updateDarkMode) => {
|
||||
* @param {*} changeTheme
|
||||
*/
|
||||
export const initTheme = (theme, changeTheme) => {
|
||||
const queryTheme = getQueryVariable('theme')
|
||||
if (queryTheme && ALL_THEME.indexOf(queryTheme) > -1) {
|
||||
changeTheme(queryTheme)
|
||||
} else {
|
||||
const userTheme = loadThemeFromCookies()
|
||||
if (userTheme !== theme) {
|
||||
changeTheme(userTheme)
|
||||
if (isBrowser()) {
|
||||
const queryTheme = getQueryVariable('theme') || loadThemeFromCookies() || BLOG.THEME
|
||||
let currentTheme = theme
|
||||
if (queryTheme !== theme && ALL_THEME.indexOf(queryTheme) > -1) {
|
||||
currentTheme = queryTheme
|
||||
}
|
||||
changeTheme(currentTheme)
|
||||
saveThemeToCookies(currentTheme)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "notion-next",
|
||||
"version": "3.8.1",
|
||||
"version": "3.8.2",
|
||||
"homepage": "https://github.com/tangly1024/NotionNext.git",
|
||||
"license": "MIT",
|
||||
"repository": {
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function getStaticProps({ params: { category } }) {
|
||||
if (BLOG.POST_LIST_STYLE === 'scroll') {
|
||||
// 滚动列表 给前端返回所有数据
|
||||
} else if (BLOG.POST_LIST_STYLE === 'page') {
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE - 1)
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE)
|
||||
}
|
||||
|
||||
delete props.allPages
|
||||
|
||||
@@ -38,7 +38,7 @@ export async function getStaticProps({ params: { category, page } }) {
|
||||
// 处理文章页数
|
||||
props.postCount = props.posts.length
|
||||
// 处理分页
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page - 1)
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page)
|
||||
|
||||
delete props.allPages
|
||||
props.page = page
|
||||
|
||||
@@ -43,7 +43,7 @@ export async function getStaticProps({ params: { keyword } }) {
|
||||
if (BLOG.POST_LIST_STYLE === 'scroll') {
|
||||
// 滚动列表 给前端返回所有数据
|
||||
} else if (BLOG.POST_LIST_STYLE === 'page') {
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE - 1)
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE)
|
||||
}
|
||||
props.keyword = keyword
|
||||
return {
|
||||
|
||||
@@ -40,7 +40,7 @@ export async function getStaticProps({ params: { keyword, page } }) {
|
||||
props.posts = await filterByMemCache(allPosts, keyword)
|
||||
props.postCount = props.posts.length
|
||||
// 处理分页
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page - 1)
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page)
|
||||
props.keyword = keyword
|
||||
props.page = page
|
||||
delete props.allPages
|
||||
|
||||
@@ -55,8 +55,7 @@ export async function getStaticProps() {
|
||||
pageType: ['Post']
|
||||
})
|
||||
const { allPages } = props
|
||||
const allPosts = allPages.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
props.posts = allPosts
|
||||
props.posts = allPages.filter(page => page.type === 'Post' && page.status === 'Published')
|
||||
return {
|
||||
props,
|
||||
revalidate: parseInt(BLOG.NEXT_REVALIDATE_SECOND)
|
||||
|
||||
@@ -37,7 +37,7 @@ export async function getStaticProps({ params: { tag } }) {
|
||||
if (BLOG.POST_LIST_STYLE === 'scroll') {
|
||||
// 滚动列表 给前端返回所有数据
|
||||
} else if (BLOG.POST_LIST_STYLE === 'page') {
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE - 1)
|
||||
props.posts = props.posts?.slice(0, BLOG.POSTS_PER_PAGE)
|
||||
}
|
||||
|
||||
props.tag = tag
|
||||
|
||||
@@ -31,7 +31,7 @@ export async function getStaticProps({ params: { tag, page } }) {
|
||||
// 处理文章数
|
||||
props.postCount = props.posts.length
|
||||
// 处理分页
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page - 1)
|
||||
props.posts = props.posts.slice(BLOG.POSTS_PER_PAGE * (page - 1), BLOG.POSTS_PER_PAGE * page)
|
||||
|
||||
props.tag = tag
|
||||
props.page = page
|
||||
|
||||
@@ -390,9 +390,12 @@
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
summary > .notion-h {
|
||||
display: inline;
|
||||
}
|
||||
|
||||
.notion-h {
|
||||
position: relative;
|
||||
/* display: block; */
|
||||
font-weight: 600;
|
||||
line-height: 1.3;
|
||||
padding: 3px 2px;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import React, { useRef } from 'react'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { uuidToId } from 'notion-utils'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 目录导航组件
|
||||
@@ -9,10 +10,8 @@ import { uuidToId } from 'notion-utils'
|
||||
* @constructor
|
||||
*/
|
||||
const Catalog = ({ toc }) => {
|
||||
// 无目录就直接返回空
|
||||
if (!toc || toc.length < 1) {
|
||||
return <></>
|
||||
}
|
||||
const { locale } = useGlobal()
|
||||
|
||||
// 监听滚动事件
|
||||
React.useEffect(() => {
|
||||
window.addEventListener('scroll', actionSectionScrollSpy)
|
||||
@@ -56,8 +55,13 @@ const Catalog = ({ toc }) => {
|
||||
tRef?.current?.scrollTo({ top: 28 * index, behavior: 'smooth' })
|
||||
}, throttleMs))
|
||||
|
||||
// 无目录就直接返回空
|
||||
if (!toc || toc.length < 1) {
|
||||
return <></>
|
||||
}
|
||||
|
||||
return <div>
|
||||
<div className='w-full dark:text-gray-300 mb-2'><i className='mr-1 fas fa-stream' /> 目录</div>
|
||||
<div className='w-full dark:text-gray-300 mb-2'><i className='mr-1 fas fa-stream' />{locale.COMMON.TABLE_OF_CONTENTS}</div>
|
||||
<div className='overflow-y-auto max-h-96 overscroll-none scroll-hidden' ref={tRef}>
|
||||
<nav className='h-full font-sans text-black'>
|
||||
{toc.map((tocItem) => {
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useRef } from 'react'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { uuidToId } from 'notion-utils'
|
||||
import Progress from './Progress'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 目录导航组件
|
||||
@@ -10,6 +11,7 @@ import Progress from './Progress'
|
||||
* @constructor
|
||||
*/
|
||||
const Catalog = ({ toc }) => {
|
||||
const { locale } = useGlobal()
|
||||
// 监听滚动事件
|
||||
React.useEffect(() => {
|
||||
window.addEventListener('scroll', actionSectionScrollSpy)
|
||||
@@ -60,7 +62,7 @@ const Catalog = ({ toc }) => {
|
||||
}
|
||||
|
||||
return <div className='px-3'>
|
||||
<div className='w-full'><i className='mr-1 fas fa-stream' /> 目录</div>
|
||||
<div className='w-full'><i className='mr-1 fas fa-stream' />{locale.COMMON.TABLE_OF_CONTENTS}</div>
|
||||
<div className='w-full py-3'>
|
||||
<Progress />
|
||||
</div>
|
||||
|
||||
@@ -2,6 +2,7 @@ import React, { useRef } from 'react'
|
||||
import throttle from 'lodash.throttle'
|
||||
import { uuidToId } from 'notion-utils'
|
||||
import Progress from './Progress'
|
||||
import { useGlobal } from '@/lib/global'
|
||||
|
||||
/**
|
||||
* 目录导航组件
|
||||
@@ -10,6 +11,7 @@ import Progress from './Progress'
|
||||
* @constructor
|
||||
*/
|
||||
const Catalog = ({ toc }) => {
|
||||
const { locale } = useGlobal()
|
||||
// 监听滚动事件
|
||||
React.useEffect(() => {
|
||||
window.addEventListener('scroll', actionSectionScrollSpy)
|
||||
@@ -59,7 +61,7 @@ const Catalog = ({ toc }) => {
|
||||
}
|
||||
|
||||
return <div className='px-3 '>
|
||||
<div className='dark:text-white'><i className='mr-1 fas fa-stream' /> 目录</div>
|
||||
<div className='dark:text-white'><i className='mr-1 fas fa-stream' />{locale.COMMON.TABLE_OF_CONTENTS}</div>
|
||||
<div className='w-full py-3'>
|
||||
<Progress />
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user