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 = '
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}
-
- >
-
- {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}
+
+ >
+
+ {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 (
+
+ )
+}