From 803d4315c82bbcbf8b506cc317bdfc0a144981de Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Fri, 25 Mar 2022 14:35:53 +0800 Subject: [PATCH] =?UTF-8?q?=E6=96=87=E7=AB=A0=E5=8A=A0=E9=94=81=E5=8A=9F?= =?UTF-8?q?=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- themes/empty/LayoutSlug.js | 59 ++++++++++- themes/empty/components/ArticleLock.js | 37 +++++++ themes/fukasawa/LayoutSlug.js | 16 ++- themes/fukasawa/components/ArticleLock.js | 48 +++++++++ themes/hexo/LayoutSlug.js | 17 +++- themes/hexo/components/ArticleLock.js | 37 +++++++ themes/medium/LayoutSlug.js | 117 ++++------------------ themes/medium/components/ArticleDetail.js | 102 +++++++++++++++++++ themes/medium/components/ArticleLock.js | 37 +++++++ themes/next/LayoutSlug.js | 32 +++--- themes/next/components/ArticleLock.js | 48 +++++++++ 11 files changed, 432 insertions(+), 118 deletions(-) create mode 100644 themes/empty/components/ArticleLock.js create mode 100644 themes/fukasawa/components/ArticleLock.js create mode 100644 themes/hexo/components/ArticleLock.js create mode 100644 themes/medium/components/ArticleDetail.js create mode 100644 themes/medium/components/ArticleLock.js create mode 100644 themes/next/components/ArticleLock.js diff --git a/themes/empty/LayoutSlug.js b/themes/empty/LayoutSlug.js index caa2bbb2..d2808e51 100644 --- a/themes/empty/LayoutSlug.js +++ b/themes/empty/LayoutSlug.js @@ -14,6 +14,9 @@ import { NotionRenderer } from 'react-notion-x' import LayoutBase from './LayoutBase' +import { useState, useRef, useEffect } from 'react' +import { ArticleLock } from './components/ArticleLock' +import mediumZoom from 'medium-zoom' const mapPageUrl = id => { return 'https://www.notion.so/' + id.replace(/-/g, '') @@ -27,18 +30,46 @@ export const LayoutSlug = props => { type: 'article', tags: post.tags } + // 文章加锁 + const articleLock = post.password && post.password !== '' + const [lock, setLock] = useState(articleLock) + const validPassword = result => { + if (result) { + setLock(false) + } + } - if (post?.blockMap?.block) { + if (!lock && post?.blockMap?.block) { post.content = Object.keys(post.blockMap.block) post.toc = getPageTableOfContents(post, post.blockMap) } + const zoom = + typeof window !== 'undefined' && + mediumZoom({ + container: '.notion-viewport', + background: 'rgba(0, 0, 0, 0.2)', + margin: getMediumZoomMargin() + }) + const zoomRef = useRef(zoom ? zoom.clone() : null) + useEffect(() => { + // 将所有container下的所有图片添加medium-zoom + const container = document.getElementById('notion-article') + const imgList = container?.getElementsByTagName('img') + if (imgList && zoomRef.current) { + for (let i = 0; i < imgList.length; i++) { + zoomRef.current.attach(imgList[i]) + } + } + }) return (

{post?.title}

-

-

+ + {lock && } + + {!lock &&
{post.blockMap && ( { }} /> )} -
-

+
} +
) } + +function getMediumZoomMargin () { + const width = window.innerWidth + + if (width < 500) { + return 8 + } else if (width < 800) { + return 20 + } else if (width < 1280) { + return 30 + } else if (width < 1600) { + return 40 + } else if (width < 1920) { + return 48 + } else { + return 72 + } +} diff --git a/themes/empty/components/ArticleLock.js b/themes/empty/components/ArticleLock.js new file mode 100644 index 00000000..c9188165 --- /dev/null +++ b/themes/empty/components/ArticleLock.js @@ -0,0 +1,37 @@ + +/** + * 加密文章校验组件 + * @param {password, validPassword} props + * @param password 正确的密码 + * @param validPassword(bool) 回调函数,校验正确回调入参为true + * @returns + */ +export const ArticleLock = props => { + const { password, validPassword } = props + const submitPassword = () => { + const p = document.getElementById('password') + if (p && p.value && p.value === password) { + validPassword(true) + } else { + const tips = document.getElementById('tips') + if (tips) { + tips.innerHTML = '' + tips.innerHTML = '
密码输入错误
' + } + } + } + + return
+
+
文章已加锁,请输入访问密码:
+
+ +
+  提交 +
+
+
+
+
+
+} diff --git a/themes/fukasawa/LayoutSlug.js b/themes/fukasawa/LayoutSlug.js index 6834da3e..90e53ecf 100644 --- a/themes/fukasawa/LayoutSlug.js +++ b/themes/fukasawa/LayoutSlug.js @@ -8,6 +8,8 @@ import 'prismjs/components/prism-python' import 'prismjs/components/prism-typescript' import ArticleDetail from './components/ArticleDetail' import LayoutBase from './LayoutBase' +import { useState } from 'react' +import { ArticleLock } from './components/ArticleLock' export const LayoutSlug = (props) => { const { post } = props @@ -18,6 +20,15 @@ export const LayoutSlug = (props) => { tags: post.tags } + // 文章加锁 + const articleLock = post.password && post.password !== '' + const [lock, setLock] = useState(articleLock) + const validPassword = result => { + if (result) { + setLock(false) + } + } + if (post?.blockMap?.block) { post.content = Object.keys(post.blockMap.block) post.toc = getPageTableOfContents(post, post.blockMap) @@ -25,7 +36,8 @@ export const LayoutSlug = (props) => { return ( - - + {!lock && } + {lock && } + ) } diff --git a/themes/fukasawa/components/ArticleLock.js b/themes/fukasawa/components/ArticleLock.js new file mode 100644 index 00000000..a25f1fc2 --- /dev/null +++ b/themes/fukasawa/components/ArticleLock.js @@ -0,0 +1,48 @@ +/** + * 加密文章校验组件 + * @param {password, validPassword} props + * @param password 正确的密码 + * @param validPassword(bool) 回调函数,校验正确回调入参为true + * @returns + */ +export const ArticleLock = props => { + const { password, validPassword } = props + const submitPassword = () => { + const p = document.getElementById('password') + if (p && p.value && p.value === password) { + validPassword(true) + } else { + const tips = document.getElementById('tips') + if (tips) { + tips.innerHTML = '' + tips.innerHTML = + "
密码输入错误
" + } + } + } + + return ( +
+
+
+
文章已加锁,请输入访问密码:
+
+ +
+ +  提交 + +
+
+
+
+
+
+ ) +} diff --git a/themes/hexo/LayoutSlug.js b/themes/hexo/LayoutSlug.js index 5e152c72..8628e521 100644 --- a/themes/hexo/LayoutSlug.js +++ b/themes/hexo/LayoutSlug.js @@ -7,8 +7,9 @@ import 'prismjs/components/prism-javascript' import 'prismjs/components/prism-markup' import 'prismjs/components/prism-python' import 'prismjs/components/prism-typescript' -import { useRef } from 'react' +import { useRef, useState } from 'react' import ArticleDetail from './components/ArticleDetail' +import { ArticleLock } from './components/ArticleLock' import HeaderArticle from './components/HeaderArticle' import JumpToCommentButton from './components/JumpToCommentButton' import TocDrawer from './components/TocDrawer' @@ -24,7 +25,16 @@ export const LayoutSlug = props => { tags: post.tags } - if (post?.blockMap?.block) { + // 文章加锁 + const articleLock = post.password && post.password !== '' + const [lock, setLock] = useState(articleLock) + const validPassword = result => { + if (result) { + setLock(false) + } + } + + if (!lock && post?.blockMap?.block) { post.content = Object.keys(post.blockMap.block) post.toc = getPageTableOfContents(post, post.blockMap) } @@ -53,7 +63,8 @@ export const LayoutSlug = props => { floatSlot={floatSlot} >
- + {!lock && } + {lock && }
diff --git a/themes/hexo/components/ArticleLock.js b/themes/hexo/components/ArticleLock.js new file mode 100644 index 00000000..95b60749 --- /dev/null +++ b/themes/hexo/components/ArticleLock.js @@ -0,0 +1,37 @@ + +/** + * 加密文章校验组件 + * @param {password, validPassword} props + * @param password 正确的密码 + * @param validPassword(bool) 回调函数,校验正确回调入参为true + * @returns + */ +export const ArticleLock = props => { + const { password, validPassword } = props + const submitPassword = () => { + const p = document.getElementById('password') + if (p && p.value && p.value === password) { + validPassword(true) + } else { + const tips = document.getElementById('tips') + if (tips) { + tips.innerHTML = '' + tips.innerHTML = '
密码输入错误
' + } + } + } + + return
+
+
文章已加锁,请输入访问密码:
+
+ +
+  提交 +
+
+
+
+
+
+} diff --git a/themes/medium/LayoutSlug.js b/themes/medium/LayoutSlug.js index ad12f872..ef54d6c7 100644 --- a/themes/medium/LayoutSlug.js +++ b/themes/medium/LayoutSlug.js @@ -1,38 +1,16 @@ import BLOG from '@/blog.config' import { getPageTableOfContents } from 'notion-utils' -import 'prismjs' -import 'prismjs/components/prism-bash' -import 'prismjs/components/prism-javascript' -import 'prismjs/components/prism-markup' -import 'prismjs/components/prism-python' -import 'prismjs/components/prism-typescript' -import { - Code, - Collection, - CollectionRow, - Equation, - NotionRenderer -} from 'react-notion-x' -import LayoutBase from './LayoutBase' -import Comment from '@/components/Comment' -import Image from 'next/image' -import { useGlobal } from '@/lib/global' -import formatDate from '@/lib/formatDate' -import Link from 'next/link' -import mediumZoom from 'medium-zoom' -import React, { useEffect, useRef } from 'react' -import ArticleAround from './components/ArticleAround' -import Catalog from './components/Catalog' -import CategoryItem from './components/CategoryItem' -import TagItemMini from './components/TagItemMini' -import CONFIG_MEDIUM from './config_medium' -const mapPageUrl = id => { - return 'https://www.notion.so/' + id.replace(/-/g, '') -} +import LayoutBase from './LayoutBase' +import { useGlobal } from '@/lib/global' +import mediumZoom from 'medium-zoom' +import React, { useEffect, useRef, useState } from 'react' +import Catalog from './components/Catalog' +import { ArticleDetail } from './components/ArticleDetail' +import { ArticleLock } from './components/ArticleLock' export const LayoutSlug = props => { - const { post, prev, next } = props + const { post } = props const meta = { title: `${post.title} | ${BLOG.TITLE}`, description: post.summary, @@ -40,15 +18,20 @@ export const LayoutSlug = props => { tags: post.tags } - if (post?.blockMap?.block) { + // 文章加锁 + const articleLock = post.password && post.password !== '' + const [lock, setLock] = useState(articleLock) + const validPassword = result => { + if (result) { + setLock(false) + } + } + + if (!lock && post?.blockMap?.block) { post.content = Object.keys(post.blockMap.block) post.toc = getPageTableOfContents(post, post.blockMap) } const { locale } = useGlobal() - const date = formatDate( - post?.date?.start_date || post.createdTime, - locale.LOCALE - ) const zoom = typeof window !== 'undefined' && @@ -83,68 +66,10 @@ export const LayoutSlug = props => { showInfoCard={true} slotRight={slotRight} > -

{post?.title}

-
- - <> - {BLOG.AUTHOR} -
- {BLOG.AUTHOR} -
- - -
{date}
-
- -   - -
-
- {/* Notion文章主体 */} -
- {post.blockMap && ( - - )} -
-
- {/* 文章内嵌广告 */} - -
-
-
- { CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category && } -
- { CONFIG_MEDIUM.POST_DETAIL_TAG && post?.tagItems?.map(tag => )} -
-
- - -
+ {!lock && } + + {lock && } ) } diff --git a/themes/medium/components/ArticleDetail.js b/themes/medium/components/ArticleDetail.js new file mode 100644 index 00000000..6c454198 --- /dev/null +++ b/themes/medium/components/ArticleDetail.js @@ -0,0 +1,102 @@ +import { + Code, + Collection, + CollectionRow, + Equation, + NotionRenderer +} from 'react-notion-x' +import Comment from '@/components/Comment' +import Image from 'next/image' +import Link from 'next/link' +import ArticleAround from './ArticleAround' +import CategoryItem from './CategoryItem' +import TagItemMini from './TagItemMini' +import CONFIG_MEDIUM from '../config_medium' +import formatDate from '@/lib/formatDate' +import { useGlobal } from '@/lib/global' + +import 'prismjs' +import 'prismjs/components/prism-bash' +import 'prismjs/components/prism-javascript' +import 'prismjs/components/prism-markup' +import 'prismjs/components/prism-python' +import 'prismjs/components/prism-typescript' +import BLOG from '@/blog.config' + +const mapPageUrl = id => { + return 'https://www.notion.so/' + id.replace(/-/g, '') +} + +export const ArticleDetail = props => { + const { post, prev, next } = props + const { locale } = useGlobal() + + const date = formatDate( + post?.date?.start_date || post.createdTime, + locale.LOCALE + ) + return <> +

{post?.title}

+
+ + <> + {BLOG.AUTHOR} +
+ {BLOG.AUTHOR} +
+ + +
{date}
+
+ +   + +
+
+ {/* Notion文章主体 */} +
+ {post.blockMap && ( + + )} +
+ +
+ {/* 文章内嵌广告 */} + +
+
+
+ { CONFIG_MEDIUM.POST_DETAIL_CATEGORY && post.category && } +
+ { CONFIG_MEDIUM.POST_DETAIL_TAG && post?.tagItems?.map(tag => )} +
+
+ + +
+ +} diff --git a/themes/medium/components/ArticleLock.js b/themes/medium/components/ArticleLock.js new file mode 100644 index 00000000..1b38febc --- /dev/null +++ b/themes/medium/components/ArticleLock.js @@ -0,0 +1,37 @@ + +/** + * 加密文章校验组件 + * @param {password, validPassword} props + * @param password 正确的密码 + * @param validPassword(bool) 回调函数,校验正确回调入参为true + * @returns + */ +export const ArticleLock = props => { + const { password, validPassword } = props + const submitPassword = () => { + const p = document.getElementById('password') + if (p && p.value && p.value === password) { + validPassword(true) + } else { + const tips = document.getElementById('tips') + if (tips) { + tips.innerHTML = '' + tips.innerHTML = '
密码输入错误
' + } + } + } + + return
+
+
文章已加锁,请输入访问密码:
+
+ +
+  提交 +
+
+
+
+
+
+} diff --git a/themes/next/LayoutSlug.js b/themes/next/LayoutSlug.js index 6a3deaa0..7e555454 100644 --- a/themes/next/LayoutSlug.js +++ b/themes/next/LayoutSlug.js @@ -6,11 +6,12 @@ import Card from './components/Card' import LatestPostsGroup from './components/LatestPostsGroup' import ArticleDetail from './components/ArticleDetail' import TocDrawer from './components/TocDrawer' -import { useRef } from 'react' +import { useRef, useState } from 'react' import CONFIG_NEXT from './config_next' +import { ArticleLock } from './components/ArticleLock' export const LayoutSlug = (props) => { - const { post, prev, next, recommendPosts, latestPosts, showArticleInfo } = props + const { post, latestPosts } = props const meta = { title: `${post.title} | ${BLOG.TITLE}`, description: post.summary, @@ -18,12 +19,22 @@ export const LayoutSlug = (props) => { tags: post.tags } - const drawerRight = useRef(null) - const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null - if (post?.blockMap?.block) { + // 文章加锁 + const articleLock = post.password && post.password !== '' + const [lock, setLock] = useState(articleLock) + const validPassword = result => { + if (result) { + setLock(false) + } + } + + if (!lock && post?.blockMap?.block) { post.content = Object.keys(post.blockMap.block) post.toc = getPageTableOfContents(post, post.blockMap) } + + const drawerRight = useRef(null) + const targetRef = typeof window !== 'undefined' ? document.getElementById('container') : null const floatSlot = post?.toc?.length > 1 ?
{ drawerRight?.current?.handleSwitchVisible() @@ -39,13 +50,10 @@ export const LayoutSlug = (props) => { CONFIG_NEXT.RIGHT_LATEST_POSTS && } > - + + {!lock && } + + {lock && } {/* 悬浮目录按钮 */}
diff --git a/themes/next/components/ArticleLock.js b/themes/next/components/ArticleLock.js new file mode 100644 index 00000000..baccc61c --- /dev/null +++ b/themes/next/components/ArticleLock.js @@ -0,0 +1,48 @@ +/** + * 加密文章校验组件 + * @param {password, validPassword} props + * @param password 正确的密码 + * @param validPassword(bool) 回调函数,校验正确回调入参为true + * @returns + */ +export const ArticleLock = props => { + const { password, validPassword } = props + const submitPassword = () => { + const p = document.getElementById('password') + if (p && p.value && p.value === password) { + validPassword(true) + } else { + const tips = document.getElementById('tips') + if (tips) { + tips.innerHTML = '' + tips.innerHTML = + "
密码输入错误
" + } + } + } + + return ( +
+
+
+
文章已加锁,请输入访问密码:
+
+ +
+ +  提交 + +
+
+
+
+
+
+ ) +}