diff --git a/.env.local b/.env.local
index fd53e2f4..35e50011 100644
--- a/.env.local
+++ b/.env.local
@@ -1,2 +1,2 @@
# 环境变量 @see https://www.nextjs.cn/docs/basic-features/environment-variables
-NEXT_PUBLIC_VERSION=3.13.4
\ No newline at end of file
+NEXT_PUBLIC_VERSION=3.13.5
\ No newline at end of file
diff --git a/README.md b/README.md
index 2fefab40..2505564c 100644
--- a/README.md
+++ b/README.md
@@ -40,7 +40,10 @@
- [个性配置手册 - 如何配置功能插件](https://tangly1024.com/article/notion-next-guide)
- [二次开发指引 - 如何进行本地开发](https://tangly1024.com/article/how-to-develop-with-notion-next)
-
+
+- [更新操作指南 - 获取最新升级补丁](https://tangly1024.com/article/how-to-update-notionnext)
+
+- [历史版本汇总 - 查询版本功能特性](https://tangly1024.com/article/notion-next-changelogs)
## 致谢
感谢Craig Hart发起的Nobelium项目
diff --git a/README_EN.md b/README_EN.md
index b2a9f85c..dbb75684 100644
--- a/README_EN.md
+++ b/README_EN.md
@@ -35,12 +35,15 @@ Live Demo:[https://preview.tangly1024.com/](https://preview.tangly1024.com/)
It only takes a few minutes to set up your personal site:
-- [快速部署教程 - 多种方案可供选择](https://tangly1024.com/article/notion-next)
+- [Quick Deployment Tutorial - Multiple Options Available](https://tangly1024.com/article/notion-next)
-- [个性配置手册 - 如何配置功能插件](https://tangly1024.com/article/notion-next-guide)
+- [Customization Guide - How to Configure Feature Plugins](https://tangly1024.com/article/notion-next-guide)
-- [二次开发指引 - 如何进行本地开发](https://tangly1024.com/article/how-to-develop-with-notion-next)
+- [Development Guide - How to Conduct Local Development](https://tangly1024.com/article/how-to-develop-with-notion-next)
+- [Update Guide - How to Get the Latest Upgrade Patch](https://tangly1024.com/article/how-to-update-notionnext)
+
+- [Version History - Check Feature Highlights for Each Version](https://tangly1024.com/article/notion-next-changelogs)
## Acknowledgements
diff --git a/blog.config.js b/blog.config.js
index 1b6755f8..7ea32205 100644
--- a/blog.config.js
+++ b/blog.config.js
@@ -96,6 +96,10 @@ const BLOG = {
BACKGROUND_DARK: '#000000', // use hex value, don't forget '#'
SUB_PATH: '', // leave this empty unless you want to deploy in a folder
+ POST_SHARE_BAR_ENABLE: process.env.NEXT_PUBLIC_POST_SHARE_BAR || 'true', // 文章分享功能 ,将在底部显示一个分享条
+ POSTS_SHARE_SERVICES: process.env.NEXT_PUBLIC_POST_SHARE_SERVICES || 'link,wechat,qq,weibo,email,facebook,twitter,telegram,messenger,line,reddit,whatsapp,linkedin', // 分享的服務,按顺序显示,逗号隔开
+ // 所有支持的分享服务:link(复制链接),wechat(微信),qq,weibo(微博),email(邮件),facebook,twitter,telegram,messenger,line,reddit,whatsapp,linkedin,vkshare,okshare,tumblr,livejournal,mailru,viber,workplace,pocket,instapaper,hatena
+
POST_URL_PREFIX: process.env.NEXT_PUBLIC_POST_URL_PREFIX || 'article',
// POST类型文章的默认路径前缀,例如默认POST类型的路径是 /article/[slug]
// 如果此项配置为 '' 空, 则文章将没有前缀路径,使用场景: 希望文章前缀路径为 /post 的情况 支持多级
diff --git a/components/ShareBar.js b/components/ShareBar.js
new file mode 100644
index 00000000..347dc16e
--- /dev/null
+++ b/components/ShareBar.js
@@ -0,0 +1,27 @@
+import BLOG from '@/blog.config'
+import { useRouter } from 'next/router'
+import React from 'react'
+import ShareButtons from './ShareButtons'
+
+const ShareBar = ({ post }) => {
+ const router = useRouter()
+
+ if (!JSON.parse(BLOG.POST_SHARE_BAR_ENABLE) || !post || post?.type !== 'Post') {
+ return <>>
+ }
+
+ const shareUrl = BLOG.LINK + router.asPath
+
+ return
+
+
+}
+export default ShareBar
diff --git a/components/ShareButtons.js b/components/ShareButtons.js
new file mode 100644
index 00000000..2aee7a78
--- /dev/null
+++ b/components/ShareButtons.js
@@ -0,0 +1,372 @@
+import BLOG from '@/blog.config'
+import { useGlobal } from '@/lib/global'
+import copy from 'copy-to-clipboard'
+import QRCode from 'qrcode.react'
+import { useState } from 'react'
+
+import {
+ FacebookShareButton,
+ FacebookIcon,
+ FacebookMessengerShareButton,
+ FacebookMessengerIcon,
+ RedditShareButton,
+ RedditIcon,
+ LineShareButton,
+ LineIcon,
+ EmailShareButton,
+ EmailIcon,
+ TwitterShareButton,
+ TwitterIcon,
+ TelegramShareButton,
+ TelegramIcon,
+ WhatsappShareButton,
+ WhatsappIcon,
+ LinkedinShareButton,
+ LinkedinIcon,
+ PinterestShareButton,
+ PinterestIcon,
+ VKIcon,
+ VKShareButton,
+ OKShareButton,
+ OKIcon,
+ TumblrShareButton,
+ TumblrIcon,
+ LivejournalIcon,
+ LivejournalShareButton,
+ MailruShareButton,
+ MailruIcon,
+ ViberIcon,
+ ViberShareButton,
+ WorkplaceShareButton,
+ WorkplaceIcon,
+ WeiboShareButton,
+ WeiboIcon,
+ PocketShareButton,
+ PocketIcon,
+ InstapaperShareButton,
+ InstapaperIcon,
+ HatenaShareButton,
+ HatenaIcon
+} from 'react-share'
+
+/**
+ * @author https://github.com/txs
+ * @param {*} param0
+ * @returns
+ */
+const ShareButtons = ({ shareUrl, title, body, image }) => {
+ const services = BLOG.POSTS_SHARE_SERVICES.split(',')
+ const titleWithSiteInfo = title + ' | ' + BLOG.TITLE
+ const { locale } = useGlobal()
+ const [qrCodeShow, setQrCodeShow] = useState(false)
+
+ const copyUrl = () => {
+ copy(shareUrl)
+ alert(locale.COMMON.URL_COPIED)
+ }
+
+ const openPopover = () => {
+ setQrCodeShow(true)
+ }
+ const closePopover = () => {
+ setQrCodeShow(false)
+ }
+
+ return (
+ <>
+ {services.map(singleService => {
+ if (singleService === 'facebook') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'messenger') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'line') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'reddit') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'email') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'twitter') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'telegram') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'whatsapp') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'linkedin') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'pinterest') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'vkshare') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'okshare') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'tumblr') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'livejournal') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'mailru') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'viber') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'workplace') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'weibo') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'pocket') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'instapaper') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'hatena') {
+ return (
+
+
+
+ )
+ }
+ if (singleService === 'qq') {
+ return
+ }
+ if (singleService === 'wechat') {
+ return
+ }
+ if (singleService === 'link') {
+ return
+ }
+ return <>>
+ })}
+ >
+ )
+}
+
+export default ShareButtons
diff --git a/lib/lang/zh-CN.js b/lib/lang/zh-CN.js
index 1dddddb9..8379c75f 100644
--- a/lib/lang/zh-CN.js
+++ b/lib/lang/zh-CN.js
@@ -17,7 +17,7 @@ export default {
NO_TAG: 'NoTag',
CATEGORY: '分类',
SHARE: '分享',
- SCAN_QR_CODE: '扫一扫二维码',
+ SCAN_QR_CODE: '微信扫码分享',
URL_COPIED: '链接已复制!',
TABLE_OF_CONTENTS: '目录',
RELATE_POSTS: '相关文章',
diff --git a/lib/notion/getNotionData.js b/lib/notion/getNotionData.js
index e723a83d..9b586e65 100644
--- a/lib/notion/getNotionData.js
+++ b/lib/notion/getNotionData.js
@@ -65,7 +65,7 @@ export async function getNotionPageData({ pageId, from }) {
const cacheKey = 'page_block_' + pageId
const data = await getDataFromCache(cacheKey)
if (data && data.pageIds?.length > 0) {
- console.log('[命中缓存]:', `from:${from}`, `root-page-id:${pageId}`)
+ console.log('[缓存]:', `from:${from}`, `root-page-id:${pageId}`)
return data
}
const pageRecordMap = await getDataBaseInfoByNotionAPI({ pageId, from })
diff --git a/lib/notion/getPostBlocks.js b/lib/notion/getPostBlocks.js
index 5fe2af84..8e764f7b 100644
--- a/lib/notion/getPostBlocks.js
+++ b/lib/notion/getPostBlocks.js
@@ -14,7 +14,7 @@ export async function getPostBlocks(id, from, slice) {
const cacheKey = 'page_block_' + id
let pageBlock = await getDataFromCache(cacheKey)
if (pageBlock) {
- console.log('[命中缓存]:', `from:${from}`, cacheKey)
+ console.log('[缓存]:', `from:${from}`, cacheKey)
return filterPostBlocks(id, pageBlock, slice)
}
diff --git a/package.json b/package.json
index 58e579fd..db5d13fc 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "notion-next",
- "version": "3.13.4",
+ "version": "3.13.5",
"homepage": "https://github.com/tangly1024/NotionNext.git",
"license": "MIT",
"repository": {
@@ -22,7 +22,6 @@
"dependencies": {
"@giscus/react": "^2.2.6",
"@next/bundle-analyzer": "^12.1.1",
- "@popperjs/core": "^2.9.3",
"@vercel/analytics": "^1.0.0",
"animate.css": "^4.1.1",
"animejs": "^3.2.1",
@@ -53,7 +52,7 @@
"react-facebook": "^8.1.4",
"react-messenger-customer-chat": "^0.8.0",
"react-notion-x": "6.16.0",
- "react-share": "^4.4.0",
+ "react-share": "^4.4.1",
"react-tweet-embed": "~2.0.0",
"smoothscroll-polyfill": "^0.4.4",
"twikoo": "^1.6.16",
diff --git a/themes/example/LayoutSlug.js b/themes/example/LayoutSlug.js
index b16892b7..b19f51ff 100644
--- a/themes/example/LayoutSlug.js
+++ b/themes/example/LayoutSlug.js
@@ -3,6 +3,7 @@ import { ArticleLock } from './components/ArticleLock'
import NotionPage from '@/components/NotionPage'
import { ArticleInfo } from './components/ArticleInfo'
import Comment from '@/components/Comment'
+import ShareBar from '@/components/ShareBar'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
@@ -17,10 +18,10 @@ export const LayoutSlug = props => {
{lock && }
{!lock && }
diff --git a/themes/fukasawa/components/ArticleDetail.js b/themes/fukasawa/components/ArticleDetail.js
index 65af8400..e9e82b0f 100644
--- a/themes/fukasawa/components/ArticleDetail.js
+++ b/themes/fukasawa/components/ArticleDetail.js
@@ -1,5 +1,6 @@
import Comment from '@/components/Comment'
import NotionPage from '@/components/NotionPage'
+import ShareBar from '@/components/ShareBar'
import formatDate from '@/lib/formatDate'
import { useGlobal } from '@/lib/global'
import Link from 'next/link'
@@ -84,6 +85,11 @@ export default function ArticleDetail(props) {
{post && }
+
+
{/* 文章内嵌广告 */}
{
const { post, lock, validPassword } = props
@@ -68,6 +69,8 @@ export const LayoutSlug = props => {
data-ad-slot="3806269138" />
+ {/* 分享 */}
+
{post.type === 'Post' && }
{post.type === 'Post' && }
{post.type === 'Post' && }
diff --git a/themes/matery/LayoutSlug.js b/themes/matery/LayoutSlug.js
index 12fefce4..da07db06 100644
--- a/themes/matery/LayoutSlug.js
+++ b/themes/matery/LayoutSlug.js
@@ -10,6 +10,7 @@ import { ArticleInfo } from './components/ArticleInfo'
import Catalog from './components/Catalog'
import JumpToCommentButton from './components/JumpToCommentButton'
import throttle from 'lodash.throttle'
+import ShareBar from '@/components/ShareBar'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
@@ -80,7 +81,8 @@ export const LayoutSlug = props => {
data-ad-client="ca-pub-2708419466378217"
data-ad-slot="3806269138" />
-
+ {/* 分享 */}
+
{/* 文章版权说明 */}
{post.type === 'Post' && }
diff --git a/themes/medium/LayoutSlug.js b/themes/medium/LayoutSlug.js
index 6000c3f3..401c4a03 100644
--- a/themes/medium/LayoutSlug.js
+++ b/themes/medium/LayoutSlug.js
@@ -13,6 +13,7 @@ import ArticleAround from './components/ArticleAround'
import TocDrawer from './components/TocDrawer'
import CategoryItem from './components/CategoryItem'
import TagItemMini from './components/TagItemMini'
+import ShareBar from '@/components/ShareBar'
export const LayoutSlug = props => {
const { post, prev, next, siteInfo, lock, validPassword } = props
@@ -85,12 +86,17 @@ export const LayoutSlug = props => {
+
+ {/* 分享 */}
+
+ {/* 文章分类和标签信息 */}
{CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category &&
}
{CONFIG_MEDIUM.POST_DETAIL_TAG && post?.tagItems?.map(tag => )}
+
{post.type === 'Post' && }
diff --git a/themes/next/components/ArticleDetail.js b/themes/next/components/ArticleDetail.js
index e5b8dba2..c0c2efac 100644
--- a/themes/next/components/ArticleDetail.js
+++ b/themes/next/components/ArticleDetail.js
@@ -2,7 +2,7 @@ import BLOG from '@/blog.config'
import BlogAround from './BlogAround'
import Comment from '@/components/Comment'
import RecommendPosts from './RecommendPosts'
-import ShareBar from './ShareBar'
+import ShareBar from '@/components/ShareBar'
import TagItem from './TagItem'
import formatDate from '@/lib/formatDate'
import { useGlobal } from '@/lib/global'
@@ -94,6 +94,10 @@ export default function ArticleDetail(props) {
{showArticleInfo && <>
+
+ {/* 分享 */}
+
+
{/* 版权声明 */}
{post.type === 'Post' && }
@@ -124,7 +128,6 @@ export default function ArticleDetail(props) {
))}
)}
-
>
)}
diff --git a/themes/next/components/ShareBar.js b/themes/next/components/ShareBar.js
deleted file mode 100644
index c595da13..00000000
--- a/themes/next/components/ShareBar.js
+++ /dev/null
@@ -1,88 +0,0 @@
-import BLOG from '@/blog.config'
-import { useRouter } from 'next/router'
-import React from 'react'
-import { createPopper } from '@popperjs/core'
-import copy from 'copy-to-clipboard'
-import QRCode from 'qrcode.react'
-import { useGlobal } from '@/lib/global'
-import CONFIG_NEXT from '../config_next'
-
-const ShareBar = ({ post }) => {
- const router = useRouter()
- const [qrCodeShow, setQrCodeShow] = React.useState(false)
- const { locale } = useGlobal()
- if (!CONFIG_NEXT.ARTICLE_SHARE) {
- return <>>
- }
- const shareUrl = BLOG.LINK + router.asPath
-
- // 二维码悬浮
- const btnRef = React.createRef()
- const popoverRef = React.createRef()
-
- const openPopover = () => {
- createPopper(btnRef.current, popoverRef.current, {
- placement: 'top'
- })
- setQrCodeShow(true)
- }
- const closePopover = () => {
- setQrCodeShow(false)
- }
-
- const copyUrl = () => {
- copy(shareUrl)
- alert(locale.COMMON.URL_COPIED)
- }
-
- return <>
-
-
{locale.COMMON.SHARE}:
-
-
-
-
-
-
-
-
- >
-}
-export default ShareBar
diff --git a/themes/next/components/ShareButton.js b/themes/next/components/ShareButton.js
deleted file mode 100644
index 39fea1f2..00000000
--- a/themes/next/components/ShareButton.js
+++ /dev/null
@@ -1,34 +0,0 @@
-import React from 'react'
-import ShareBar from './ShareBar'
-
-/**
- * 悬浮在屏幕右下角,分享按钮
- * @returns {JSX.Element}
- * @constructor
- */
-const ShareButton = ({ post }) => {
- const [popoverShow, setPopoverShow] = React.useState(false)
- const btnRef = React.createRef()
-
- const openPopover = () => {
- setPopoverShow(true)
- }
- const closePopover = () => {
- setPopoverShow(false)
- }
- return (
- { openPopover() }}
- onMouseLeave={() => { closePopover() }}>
-
-
-
-
-
-
-
- )
-}
-
-export default ShareButton
diff --git a/themes/next/config_next.js b/themes/next/config_next.js
index 5504b8df..d341cee0 100644
--- a/themes/next/config_next.js
+++ b/themes/next/config_next.js
@@ -30,7 +30,6 @@ const CONFIG_NEXT = {
WIDGET_DARK_MODE: false, // 显示日间/夜间模式切换
WIDGET_TOC: true, // 移动端显示悬浮目录
- ARTICLE_SHARE: process.env.NEXT_PUBLIC_ARTICLE_SHARE || false, // 文章分享功能
ARTICLE_RELATE_POSTS: true, // 相关文章推荐
ARTICLE_COPYRIGHT: true // 文章版权声明
diff --git a/themes/nobelium/LayoutSlug.js b/themes/nobelium/LayoutSlug.js
index d60062a0..d27628af 100644
--- a/themes/nobelium/LayoutSlug.js
+++ b/themes/nobelium/LayoutSlug.js
@@ -4,6 +4,7 @@ import NotionPage from '@/components/NotionPage'
import { ArticleInfo } from './components/ArticleInfo'
import Comment from '@/components/Comment'
import { ArticleFooter } from './components/ArticleFooter'
+import ShareBar from '@/components/ShareBar'
export const LayoutSlug = props => {
const { post, lock, validPassword } = props
@@ -21,6 +22,7 @@ export const LayoutSlug = props => {
{post && <>
+
>}
diff --git a/themes/simple/LayoutSlug.js b/themes/simple/LayoutSlug.js
index 6cf7c82b..96f42c3e 100644
--- a/themes/simple/LayoutSlug.js
+++ b/themes/simple/LayoutSlug.js
@@ -4,6 +4,7 @@ import NotionPage from '@/components/NotionPage'
import { ArticleInfo } from './components/ArticleInfo'
import Comment from '@/components/Comment'
import ArticleAround from './components/ArticleAround'
+import ShareBar from '@/components/ShareBar'
export const LayoutSlug = props => {
const { post, lock, validPassword, prev, next } = props
@@ -22,6 +23,8 @@ export const LayoutSlug = props => {
{post && <>
+ {/* 分享 */}
+
{post.type === 'Post' && }
>}