From 56ffca17587046bfc6da2e82c4574e4e1cb77c38 Mon Sep 17 00:00:00 2001 From: tangly1024 Date: Tue, 29 Mar 2022 10:55:16 +0800 Subject: [PATCH] =?UTF-8?q?=E8=B4=A1=E7=8C=AE=E4=BB=A3=E7=A0=81=E7=9B=B8?= =?UTF-8?q?=E5=85=B3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 20 ++-- components/DebugPanel.js | 2 +- lib/global.js | 3 +- lib/theme.js | 1 - themes/empty/Layout404.js | 6 -- themes/empty/LayoutArchive.js | 69 ------------- themes/empty/LayoutBase.js | 135 ------------------------- themes/empty/LayoutCategory.js | 48 --------- themes/empty/LayoutCategoryIndex.js | 25 ----- themes/empty/LayoutIndex.js | 52 ---------- themes/empty/LayoutPage.js | 52 ---------- themes/empty/LayoutSearch.js | 60 ----------- themes/empty/LayoutSlug.js | 100 ------------------ themes/empty/LayoutTag.js | 49 --------- themes/empty/LayoutTagIndex.js | 24 ----- themes/empty/components/ArticleLock.js | 40 -------- themes/empty/components/SearchInput.js | 87 ---------------- themes/empty/config_empty.js | 4 - themes/empty/index.js | 25 ----- themes/index.js | 12 +-- 20 files changed, 19 insertions(+), 795 deletions(-) delete mode 100644 themes/empty/Layout404.js delete mode 100644 themes/empty/LayoutArchive.js delete mode 100644 themes/empty/LayoutBase.js delete mode 100644 themes/empty/LayoutCategory.js delete mode 100644 themes/empty/LayoutCategoryIndex.js delete mode 100644 themes/empty/LayoutIndex.js delete mode 100644 themes/empty/LayoutPage.js delete mode 100644 themes/empty/LayoutSearch.js delete mode 100644 themes/empty/LayoutSlug.js delete mode 100644 themes/empty/LayoutTag.js delete mode 100644 themes/empty/LayoutTagIndex.js delete mode 100644 themes/empty/components/ArticleLock.js delete mode 100644 themes/empty/components/SearchInput.js delete mode 100644 themes/empty/config_empty.js delete mode 100644 themes/empty/index.js diff --git a/README.md b/README.md index dbec7c25..92b2c1b6 100644 --- a/README.md +++ b/README.md @@ -50,12 +50,9 @@ |--|--|--|--| | [预览NEXT](https://preview.tangly1024.com/?theme=next) | [预览MEDIUM](https://preview.tangly1024.com/?theme=medium) | [预览HEXO](https://preview.tangly1024.com/?theme=hexo) | [预览FUKASAWA](https://preview.tangly1024.com/?theme=fukasawa) | +*只需修改`blog.config.js`文件的`THEME`即可实现主题切换。* 没找到喜欢的主题?[贡献](/CONTRIBUTING.md)一个吧~ -*只需修改`blog.config.js`文件的`THEME`即可实现主题切换。* - -## 更新日志 -请移步 [更新文档](https://docs.tangly1024.com/zh/changelog)查看 ## 快速起步 @@ -80,11 +77,15 @@ yarn run start # 本地启动NextJS服务 ## 引用技术 -- **框架**: Next.js +- **框架**: [Next.js](https://nextjs.org) - **样式**: [Tailwind CSS](https://www.tailwindcss.cn/) 和 `@tailwindcss/jit` compiler - **渲染**: [React-notion-x](https://github.com/NotionX/react-notion-x) -- **评论**: Gitalk, Cusdis, Utterances -- **图标**:[fontawesome](https://fontawesome.com/v5.15/icons?d=gallery) +- **评论**: [Giscus](https://giscus.app/zh-CN), [Gitalk](https://gitalk.github.io), [Cusdis](https://gitalk.github.io), [Utterances](https://utteranc.es) +- **图标**:[fontawesome v5.15](https://fontawesome.com/v5.15/icons?d=gallery) + +## 更新日志 +请移步 [更新文档](https://docs.tangly1024.com/zh/changelog)查看 + ## 致谢 感谢Craig Hart发起的Nobelium项目 @@ -92,13 +93,16 @@ yarn run start # 本地启动NextJS服务 Craig Hart
Craig Hart -## Contributors +## 贡献者
tangly1024
tangly1024

🎫 🔧 🎨 🐛
uWayLu
uWayLu

🔧 🐛
+十分期待你的[贡献](/CONTRIBUTING.md),一起来完善这个项目~ + + ## License The MIT License. diff --git a/components/DebugPanel.js b/components/DebugPanel.js index b1623e50..50add94a 100644 --- a/components/DebugPanel.js +++ b/components/DebugPanel.js @@ -2,7 +2,7 @@ import BLOG from '@/blog.config' import * as ThemeMap from '@/themes' import { useState } from 'react' import Select from './Select' -import { ALL_THEME } from '@/lib/theme' +import { ALL_THEME } from '@/themes' import { useGlobal } from '@/lib/global' /** * diff --git a/lib/global.js b/lib/global.js index 8ca8deed..e1692217 100644 --- a/lib/global.js +++ b/lib/global.js @@ -2,7 +2,8 @@ import { generateLocaleDict, initLocale } from './lang' import { createContext, useContext, useEffect, useState } from 'react' import Router from 'next/router' import BLOG from '@/blog.config' -import { ALL_THEME, initDarkMode, initTheme, saveThemeToCookies } from '@/lib/theme' +import { initDarkMode, initTheme, saveThemeToCookies } from '@/lib/theme' +import { ALL_THEME } from '@/themes' const GlobalContext = createContext() let hasInit = false diff --git a/lib/theme.js b/lib/theme.js index 55d47aad..1cecad78 100644 --- a/lib/theme.js +++ b/lib/theme.js @@ -1,7 +1,6 @@ import cookie from 'react-cookies' import BLOG from '@/blog.config' -export const ALL_THEME = ['hexo', 'next', 'medium', 'fukasawa', 'empty'] /** * 初始化主题 * @param isDarkMode diff --git a/themes/empty/Layout404.js b/themes/empty/Layout404.js deleted file mode 100644 index cd28a607..00000000 --- a/themes/empty/Layout404.js +++ /dev/null @@ -1,6 +0,0 @@ - -export const Layout404 = () => { - return
- 404 Not found. -
-} diff --git a/themes/empty/LayoutArchive.js b/themes/empty/LayoutArchive.js deleted file mode 100644 index 04a6d647..00000000 --- a/themes/empty/LayoutArchive.js +++ /dev/null @@ -1,69 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import LayoutBase from './LayoutBase' - -export const LayoutArchive = props => { - const { posts } = props - const { locale } = useGlobal() - const postsSortByDate = Object.create(posts) - - postsSortByDate.sort((a, b) => { - const dateA = new Date(a?.date.start_date || a.createdTime) - const dateB = new Date(b?.date.start_date || b.createdTime) - return dateB - dateA - }) - - const meta = { - title: `${locale.NAV.ARCHIVE} | ${BLOG.TITLE}`, - description: BLOG.DESCRIPTION, - type: 'website' - } - - const archivePosts = {} - - postsSortByDate.forEach(post => { - const date = post.date.start_date.slice(0, 7) - if (archivePosts[date]) { - archivePosts[date].push(post) - } else { - archivePosts[date] = [post] - } - }) - return ( - -
- {Object.keys(archivePosts).map(archiveTitle => ( -
-
- {archiveTitle} -
-
    - {archivePosts[archiveTitle].map(post => ( -
  • -
    - - {post.date.start_date} - {' '} -   - - - {post.title} - - -
    -
  • - ))} -
-
- ))} -
-
- ) -} diff --git a/themes/empty/LayoutBase.js b/themes/empty/LayoutBase.js deleted file mode 100644 index 7898c47d..00000000 --- a/themes/empty/LayoutBase.js +++ /dev/null @@ -1,135 +0,0 @@ -import CommonHead from '@/components/CommonHead' -import Live2D from '@/components/Live2D' -import Link from 'next/link' -import React from 'react' -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -/** - * 基础布局 采用左右两侧布局,移动端使用顶部导航栏 - - * @returns {JSX.Element} - * @constructor - */ -const LayoutBase = props => { - const { children, meta, customNav } = props - const { locale } = useGlobal() - const d = new Date() - const currentYear = d.getFullYear() - const startYear = BLOG.SINCE && BLOG.SINCE !== currentYear && BLOG.SINCE + '-' - - let links = [ - { icon: 'fas fa-search', name: locale.NAV.SEARCH, to: '/search' }, - { icon: 'fas fa-archive', name: locale.NAV.ARCHIVE, to: '/archive' }, - { icon: 'fas fa-folder', name: locale.COMMON.CATEGORY, to: '/category' }, - { icon: 'fas fa-tag', name: locale.COMMON.TAGS, to: '/tag' } - ] - - if (customNav) { - links = links.concat(customNav) - } - - return ( -
- - {/* 导航菜单 */} -
-
-
- - - -
{BLOG.TITLE}
-
- -
- -
-
- - {/* 内容主体 */} -
-
{children}
-
-
- -
-
-
- - {/* 页脚 */} - -
- ) -} - -export default LayoutBase diff --git a/themes/empty/LayoutCategory.js b/themes/empty/LayoutCategory.js deleted file mode 100644 index 85d399f6..00000000 --- a/themes/empty/LayoutCategory.js +++ /dev/null @@ -1,48 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useState } from 'react' -import LayoutBase from './LayoutBase' - -export const LayoutCategory = props => { - const { category, posts } = props - const { locale } = useGlobal() - - const [page, updatePage] = useState(1) - let hasMore = false - const postsToShow = posts - ? Object.assign(posts).slice(0, BLOG.POSTS_PER_PAGE * page) - : [] - - if (posts) { - const totalCount = posts.length - hasMore = page * BLOG.POSTS_PER_PAGE < totalCount - } - const handleGetMore = () => { - if (!hasMore) return - updatePage(page + 1) - } - - return ( - - Category - {category} - {postsToShow.map(p => ( -
- - {p.title} - -
{p.summary}
-
- ))} -
-
- {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} -
-
-
- ) -} diff --git a/themes/empty/LayoutCategoryIndex.js b/themes/empty/LayoutCategoryIndex.js deleted file mode 100644 index b748b140..00000000 --- a/themes/empty/LayoutCategoryIndex.js +++ /dev/null @@ -1,25 +0,0 @@ -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import LayoutBase from './LayoutBase' - -export const LayoutCategoryIndex = (props) => { - const { categories } = props - const { locale } = useGlobal() - return -
-
- {locale.COMMON.CATEGORY}: -
-
- {categories && categories.map(category => { - return -
- {category.name}({category.count}) -
- - })} -
-
-
-} diff --git a/themes/empty/LayoutIndex.js b/themes/empty/LayoutIndex.js deleted file mode 100644 index 817bcdfb..00000000 --- a/themes/empty/LayoutIndex.js +++ /dev/null @@ -1,52 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useRouter } from 'next/router' -import LayoutBase from './LayoutBase' - -export const LayoutIndex = props => { - const { posts, postCount } = props - - const { locale } = useGlobal() - const router = useRouter() - const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE) - - const page = 1 - const showNext = page < totalPage && posts.length === BLOG.POSTS_PER_PAGE && posts.length < postCount - - const currentPage = +page - return ( - - {posts.map(p => ( -
- - {p.title} - -
{p.summary}
-
- ))} - - -
- ) -} diff --git a/themes/empty/LayoutPage.js b/themes/empty/LayoutPage.js deleted file mode 100644 index 2f5f795a..00000000 --- a/themes/empty/LayoutPage.js +++ /dev/null @@ -1,52 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useRouter } from 'next/router' -import LayoutBase from './LayoutBase' - -export const LayoutPage = (props) => { - const { page } = props - const { posts, postCount } = props - - const { locale } = useGlobal() - const router = useRouter() - const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE) - - const showNext = page < totalPage && posts.length === BLOG.POSTS_PER_PAGE && posts.length < postCount - - const currentPage = +page - return ( - - {posts.map(p => ( -
- - {p.title} - -
{p.summary}
-
- ))} - - -
- ) -} diff --git a/themes/empty/LayoutSearch.js b/themes/empty/LayoutSearch.js deleted file mode 100644 index d24024a5..00000000 --- a/themes/empty/LayoutSearch.js +++ /dev/null @@ -1,60 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useEffect, useState } from 'react' -import SearchInput from './components/SearchInput' -import LayoutBase from './LayoutBase' - -export const LayoutSearch = props => { - const { keyword, posts } = props - useEffect(() => { - setTimeout(() => { - const container = document.getElementById('container') - if (container && container.innerHTML) { - const re = new RegExp(`${keyword}`, 'gim') - container.innerHTML = container.innerHTML.replace(re, `${keyword}`) - } - }, 100) - }) - - const { locale } = useGlobal() - - const [page, updatePage] = useState(1) - let hasMore = false - const postsToShow = posts - ? Object.assign(posts).slice(0, BLOG.POSTS_PER_PAGE * page) - : [] - - if (posts) { - const totalCount = posts.length - hasMore = page * BLOG.POSTS_PER_PAGE < totalCount - } - const handleGetMore = () => { - if (!hasMore) return - updatePage(page + 1) - } - - return ( - -

Search - {keyword}

- - {postsToShow.map(p => ( -
- - {p.title} - -
{p.summary}
-
- ))} -
-
- {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} -
-
-
- ) -} diff --git a/themes/empty/LayoutSlug.js b/themes/empty/LayoutSlug.js deleted file mode 100644 index 7ff9b624..00000000 --- a/themes/empty/LayoutSlug.js +++ /dev/null @@ -1,100 +0,0 @@ -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 { 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, '') -} - -export const LayoutSlug = props => { - const { post, lock, validPassword } = props - const meta = { - title: `${post.title} | ${BLOG.TITLE}`, - description: post.summary, - type: 'article', - tags: post.tags - } - - 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/LayoutTag.js b/themes/empty/LayoutTag.js deleted file mode 100644 index e1a549f4..00000000 --- a/themes/empty/LayoutTag.js +++ /dev/null @@ -1,49 +0,0 @@ -import BLOG from '@/blog.config' -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import { useState } from 'react' -import LayoutBase from './LayoutBase' - -export const LayoutTag = props => { - const { tag, posts } = props - const { locale } = useGlobal() - - const [page, updatePage] = useState(1) - - let hasMore = false - const postsToShow = posts - ? Object.assign(posts).slice(0, BLOG.POSTS_PER_PAGE * page) - : [] - - if (posts) { - const totalCount = posts.length - hasMore = page * BLOG.POSTS_PER_PAGE < totalCount - } - const handleGetMore = () => { - if (!hasMore) return - updatePage(page + 1) - } - - return ( - - Tag - {tag} - {postsToShow.map(p => ( -
- - {p.title} - -
{p.summary}
-
- ))} -
-
- {' '} - {hasMore ? locale.COMMON.MORE : `${locale.COMMON.NO_MORE} 😰`}{' '} -
-
-
- ) -} diff --git a/themes/empty/LayoutTagIndex.js b/themes/empty/LayoutTagIndex.js deleted file mode 100644 index 3fb41c9f..00000000 --- a/themes/empty/LayoutTagIndex.js +++ /dev/null @@ -1,24 +0,0 @@ -import { useGlobal } from '@/lib/global' -import Link from 'next/link' -import LayoutBase from './LayoutBase' - -export const LayoutTagIndex = (props) => { - const { tags } = props - const { locale } = useGlobal() - return -
-
{locale.COMMON.TAGS}:
-
- { tags.map(tag => { - return - }) } -
-
-} diff --git a/themes/empty/components/ArticleLock.js b/themes/empty/components/ArticleLock.js deleted file mode 100644 index bfdd00ce..00000000 --- a/themes/empty/components/ArticleLock.js +++ /dev/null @@ -1,40 +0,0 @@ -import { useGlobal } from '@/lib/global' - -/** - * 加密文章校验组件 - * @param {password, validPassword} props - * @param password 正确的密码 - * @param validPassword(bool) 回调函数,校验正确回调入参为true - * @returns - */ -export const ArticleLock = props => { - const { password, validPassword } = props - const { locale } = useGlobal() - - 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 = `
${locale.COMMON.PASSWORD_ERROR}
` - } - } - } - - return
-
-
{locale.COMMON.ARTICLE_LOCK_TIPS}
-
- -
-  {locale.COMMON.SUBMIT} -
-
-
-
-
-
-} diff --git a/themes/empty/components/SearchInput.js b/themes/empty/components/SearchInput.js deleted file mode 100644 index 6a95ba01..00000000 --- a/themes/empty/components/SearchInput.js +++ /dev/null @@ -1,87 +0,0 @@ -import { useRouter } from 'next/router' -import { useGlobal } from '@/lib/global' -import { useImperativeHandle, useRef, useState } from 'react' - -let lock = false - -const SearchInput = ({ currentTag, currentSearch, cRef }) => { - const { locale } = useGlobal() - const router = useRouter() - const searchInputRef = useRef(null) - useImperativeHandle(cRef, () => { - return { - focus: () => { - searchInputRef?.current?.focus() - } - } - }) - const handleSearch = () => { - const key = searchInputRef.current.value - if (key && key !== '') { - router.push({ pathname: '/search/' + key }).then(r => { - console.log('搜索', key) - }) - } else { - router.push({ pathname: '/' }).then(r => { - }) - } - } - const handleKeyUp = (e) => { - if (e.keyCode === 13) { // 回车 - handleSearch(searchInputRef.current.value) - } else if (e.keyCode === 27) { // ESC - cleanSearch() - } - } - const cleanSearch = () => { - searchInputRef.current.value = '' - setShowClean(false) - } - function lockSearchInput () { - lock = true - } - - function unLockSearchInput () { - lock = false - } - const [showClean, setShowClean] = useState(false) - const updateSearchKey = (val) => { - if (lock) { - return - } - searchInputRef.current.value = val - if (val) { - setShowClean(true) - } else { - setShowClean(false) - } - } - - return
- updateSearchKey(e.target.value)} - defaultValue={currentSearch || ''} - /> - -
- -
- - {(showClean && -
- -
- )} -
-} - -export default SearchInput diff --git a/themes/empty/config_empty.js b/themes/empty/config_empty.js deleted file mode 100644 index 9f1ac567..00000000 --- a/themes/empty/config_empty.js +++ /dev/null @@ -1,4 +0,0 @@ -const CONFIG_EMPTY = { - TEST_CONFIG: 'TESET' -} -export default CONFIG_EMPTY diff --git a/themes/empty/index.js b/themes/empty/index.js deleted file mode 100644 index 95b0a6b2..00000000 --- a/themes/empty/index.js +++ /dev/null @@ -1,25 +0,0 @@ -import CONFIG_EMPTY from './config_empty' -import { LayoutIndex } from './LayoutIndex' -import { LayoutSearch } from './LayoutSearch' -import { LayoutArchive } from './LayoutArchive' -import { LayoutSlug } from './LayoutSlug' -import { Layout404 } from './Layout404' -import { LayoutCategory } from './LayoutCategory' -import { LayoutCategoryIndex } from './LayoutCategoryIndex' -import { LayoutPage } from './LayoutPage' -import { LayoutTag } from './LayoutTag' -import { LayoutTagIndex } from './LayoutTagIndex' - -export { - CONFIG_EMPTY as THEME_CONFIG, - LayoutIndex, - LayoutSearch, - LayoutArchive, - LayoutSlug, - Layout404, - LayoutCategory, - LayoutCategoryIndex, - LayoutPage, - LayoutTag, - LayoutTagIndex -} diff --git a/themes/index.js b/themes/index.js index 286446ca..e13cd4b3 100644 --- a/themes/index.js +++ b/themes/index.js @@ -5,11 +5,7 @@ import * as next from './next' import * as fukasawa from './fukasawa' import * as hexo from './hexo' import * as medium from './medium' -import * as empty from './empty' -export { - next, - fukasawa, - hexo, - medium, - empty -} +import * as example from './example' + +export const ALL_THEME = ['hexo', 'next', 'medium', 'fukasawa', 'example'] +export { hexo, next, medium, fukasawa, example }