Skip to content

Commit

Permalink
theme-plog
Browse files Browse the repository at this point in the history
  • Loading branch information
tangly1024 committed Jul 10, 2023
1 parent a91fb21 commit 463b356
Show file tree
Hide file tree
Showing 29 changed files with 1,387 additions and 2 deletions.
48 changes: 48 additions & 0 deletions components/FullScreenButton.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import { isBrowser } from '@/lib/utils'
import React, { useState } from 'react'

/**
* 全屏按钮
* @returns
*/
const FullScreenButton = () => {
const [isFullScreen, setIsFullScreen] = useState(false)

const handleFullScreenClick = () => {
if (!isBrowser()) {
return
}
const element = document.documentElement
if (!isFullScreen) {
if (element.requestFullscreen) {
element.requestFullscreen()
} else if (element.webkitRequestFullscreen) {
element.webkitRequestFullscreen()
} else if (element.mozRequestFullScreen) {
element.mozRequestFullScreen()
} else if (element.msRequestFullscreen) {
element.msRequestFullscreen()
}
setIsFullScreen(true)
} else {
if (document.exitFullscreen) {
document.exitFullscreen()
} else if (document.webkitExitFullscreen) {
document.webkitExitFullscreen()
} else if (document.mozCancelFullScreen) {
document.mozCancelFullScreen()
} else if (document.msExitFullscreen) {
document.msExitFullscreen()
}
setIsFullScreen(false)
}
}

return (
<button onClick={handleFullScreenClick} className='dark:text-gray-300'>
{isFullScreen ? '退出全屏' : <i className="fa-solid fa-expand"></i>}
</button>
)
}

export default FullScreenButton
2 changes: 1 addition & 1 deletion themes/hexo/components/Header.js
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ const Hero = props => {
</div>
</div>

<div id='header-cover' style={{ backgroundImage: `url('${siteInfo.pageCover}')` }}
<div id='header-cover' style={{ backgroundImage: `url('${siteInfo?.pageCover}')` }}
className={`header-cover bg-center w-full h-screen bg-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'bg-fixed' : ''}`} />

</header>
Expand Down
2 changes: 1 addition & 1 deletion themes/matery/components/Hero.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ const Hero = props => {
</div>
</div>

<div id='header-cover' style={{ backgroundImage: `url('${siteInfo.pageCover}')` }}
<div id='header-cover' style={{ backgroundImage: `url('${siteInfo?.pageCover}')` }}
className={`header-cover bg-center w-full h-screen bg-cover ${CONFIG.HOME_NAV_BACKGROUND_IMG_FIXED ? 'bg-fixed' : ''}`} />

</header>
Expand Down
18 changes: 18 additions & 0 deletions themes/plog/components/Announcement.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import dynamic from 'next/dynamic'

const NotionPage = dynamic(() => import('@/components/NotionPage'))

const Announcement = ({ notice, className }) => {
if (notice?.blockMap) {
return <div className={className}>
<section id='announcement-wrapper' className='mb-10'>
{notice && (<div id="announcement-content">
<NotionPage post={notice} className='text-center ' />
</div>)}
</section>
</div>
} else {
return null
}
}
export default Announcement
34 changes: 34 additions & 0 deletions themes/plog/components/ArticleFooter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import BLOG from '@/blog.config'
import { useRouter } from 'next/router'
import { useGlobal } from '@/lib/global'

/**
* 加密文章校验组件
* @param {password, validPassword} props
* @param password 正确的密码
* @param validPassword(bool) 回调函数,校验正确回调入参为true
* @returns
*/
export const ArticleFooter = props => {
const router = useRouter()
const { locale } = useGlobal()

return <div className="flex justify-between font-medium text-gray-500 dark:text-gray-400">
<a>
<button
onClick={() => router.push(BLOG.path || '/')}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.BACK}
</button>
</a>
<a>
<button
onClick={() => window.scrollTo({ top: 0, behavior: 'smooth' })}
className="mt-2 cursor-pointer hover:text-black dark:hover:text-gray-100"
>
{locale.POST.TOP}
</button>
</a>
</div>
}
59 changes: 59 additions & 0 deletions themes/plog/components/ArticleInfo.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@

import formatDate from '@/lib/formatDate'
import Image from 'next/image'
import BLOG from '@/blog.config'
import TagItem from './TagItem'
import md5 from 'js-md5'

export const ArticleInfo = (props) => {
const { post } = props

const emailHash = md5(BLOG.CONTACT_EMAIL)

return <section className="flex-wrap flex mt-2 text-gray--600 dark:text-gray-400 font-light leading-8">
<div>

<div className="font-bold text-3xl text-black dark:text-white">
{post?.title}
</div>

{post?.type !== 'Page' && <>
<nav className="flex mt-7 items-start text-gray-500 dark:text-gray-400">
<div className="flex mb-4">
<a href={BLOG.CONTACT_GITHUB || '#'} className="flex">
<Image
alt={BLOG.author}
width={24}
height={24}
src={`https://gravatar.com/avatar/${emailHash}`}
className="rounded-full"
/>
<p className="ml-2 md:block">{BLOG.author}</p>
</a>
<span className="block">&nbsp;/&nbsp;</span>
</div>
<div className="mr-2 mb-4 md:ml-0">
{formatDate(
post?.publishTime || post?.createdTime,
BLOG.LANG
)}
</div>
{post.tags && (
<div className="flex flex-nowrap max-w-full overflow-x-auto article-tags">
{post?.tags.map(tag => (
<TagItem key={tag} tag={tag} />
))}
</div>
)}
<span className="hidden busuanzi_container_page_pv mr-2">
<i className='mr-1 fas fa-eye' />
&nbsp;
<span className="mr-2 busuanzi_value_page_pv" />
</span>
</nav>
</>}

</div>

</section>
}
53 changes: 53 additions & 0 deletions themes/plog/components/ArticleLock.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import { useGlobal } from '@/lib/global'
import { useEffect, useRef } from 'react'

/**
* 加密文章校验组件
* @param {password, validPassword} props
* @param password 正确的密码
* @param validPassword(bool) 回调函数,校验正确回调入参为true
* @returns
*/
export const ArticleLock = props => {
const { validPassword } = props
const { locale } = useGlobal()

const submitPassword = () => {
const p = document.getElementById('password')
if (!validPassword(p?.value)) {
const tips = document.getElementById('tips')
if (tips) {
tips.innerHTML = ''
tips.innerHTML = `<div class='text-red-500 animate__shakeX animate__animated'>${locale.COMMON.PASSWORD_ERROR}</div>`
}
}
}

const passwordInputRef = useRef(null)
useEffect(() => {
// 选中密码输入框并将其聚焦
passwordInputRef.current.focus()
}, [])

return <div id='container' className='w-full flex justify-center items-center h-96 font-sans'>
<div className='text-center space-y-3'>
<div className='font-bold'>{locale.COMMON.ARTICLE_LOCK_TIPS}</div>
<div className='flex'>
<input id="password" type='password'
onKeyDown={(e) => {
if (e.key === 'Enter') {
submitPassword()
}
}}
ref={passwordInputRef} // 绑定ref到passwordInputRef变量
className='outline-none w-full text-sm pl-5 rounded-l transition focus:shadow-lg font-light leading-10 text-black dark:bg-gray-500 bg-gray-50'
></input>
<div onClick={submitPassword} className="px-3 whitespace-nowrap cursor-pointer items-center justify-center py-2 rounded-r duration-300 bg-gray-300" >
<i className={'duration-200 cursor-pointer fas fa-key dark:text-black'} >&nbsp;{locale.COMMON.SUBMIT}</i>
</div>
</div>
<div id='tips'>
</div>
</div>
</div>
}
41 changes: 41 additions & 0 deletions themes/plog/components/BlogArchiveItem.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
import BLOG from '@/blog.config'
import Link from 'next/link'

/**
* 归档分组文章
* @param {*} param0
* @returns
*/
export default function BlogArchiveItem({ archiveTitle, archivePosts }) {
return (
<div key={archiveTitle}>
<div id={archiveTitle} className="pt-16 pb-4 text-3xl dark:text-gray-300" >
{archiveTitle}
</div>

<ul>
{archivePosts[archiveTitle].map(post => (
<li
key={post.id}
className="border-l-2 p-1 text-xs md:text-base items-center hover:scale-x-105 hover:border-gray-500 dark:hover:border-gray-300 dark:border-gray-400 transform duration-500"
>
<div id={post?.publishTime}>
<span className="text-gray-400">
{post.date?.start_date}
</span>{' '}
&nbsp;
<Link
href={`${BLOG.SUB_PATH}/${post.slug}`}
passHref
className="dark:text-gray-400 dark:hover:text-gray-300 overflow-x-hidden hover:underline cursor-pointer text-gray-600">

{post.title}

</Link>
</div>
</li>
))}
</ul>
</div>
)
}
39 changes: 39 additions & 0 deletions themes/plog/components/BlogListBar.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import Tags from './Tags'

export default function BlogListBar(props) {
const { tag, setFilterKey } = props
const handleSearchChange = (val) => {
setFilterKey(val)
}
if (tag) {
return (<div className="mb-4">
<div className='relative'>
<input
type="text"
placeholder={
tag ? `Search in #${tag}` : 'Search Articles'
}
className="outline-none block w-full border px-4 py-2 border-black bg-white text-black dark:bg-night dark:border-white dark:text-white"
onChange={e => handleSearchChange(e.target.value)}
/>
<svg
className="absolute right-3 top-3 h-5 w-5 text-black dark:text-white"
xmlns="http://www.w3.org/2000/svg"
fill="none"
viewBox="0 0 24 24"
stroke="currentColor"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
strokeWidth="2"
d="M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0z"
></path>
</svg>
</div>
<Tags {...props} />
</div>)
} else {
return <></>
}
}
50 changes: 50 additions & 0 deletions themes/plog/components/BlogListPage.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@

import BLOG from '@/blog.config'
import { useGlobal } from '@/lib/global'
import { useRouter } from 'next/router'
import Link from 'next/link'
import BlogPost from './BlogPost'

export const BlogListPage = props => {
const { page = 1, posts, postCount } = props
const { locale } = useGlobal()
const router = useRouter()
const totalPage = Math.ceil(postCount / BLOG.POSTS_PER_PAGE)
const currentPage = +page

const showPrev = currentPage > 1
const showNext = page < totalPage
const pagePrefix = router.asPath.split('?')[0].replace(/\/page\/[1-9]\d*/, '').replace(/\/$/, '')

return (
<div className="w-full">

<div id="posts-wrapper" className='grid lg:grid-cols-3 grid-cols-2'>
{posts?.map(post => (
<BlogPost key={post.id} post={post} {...props}/>
))}
</div>

<div className="flex justify-between text-xs">
<Link
href={{ pathname: currentPage - 1 === 1 ? `${pagePrefix}/` : `${pagePrefix}/page/${currentPage - 1}`, query: router.query.s ? { s: router.query.s } : {} }}
className={`${showPrev ? ' ' : ' invisible block pointer-events-none '}no-underline py-2 px-3 rounded`}>

<button rel="prev" className="block cursor-pointer">
{locale.PAGINATION.PREV}
</button>

</Link>
<Link
href={{ pathname: `${pagePrefix}/page/${currentPage + 1}`, query: router.query.s ? { s: router.query.s } : {} }}
className={`${showNext ? ' ' : 'invisible pointer-events-none '} no-underline py-2 px-3 rounded`}>

<button rel="next" className="block cursor-pointer">
{locale.PAGINATION.NEXT}
</button>

</Link>
</div>
</div>
)
}
Loading

0 comments on commit 463b356

Please sign in to comment.