头像读取Notion

This commit is contained in:
tangly1024
2022-05-11 10:59:37 +08:00
parent ce046bff22
commit c5167d9fdd
10 changed files with 52 additions and 66 deletions

View File

@@ -3,7 +3,6 @@ const BLOG = {
AUTHOR: 'tangly1024', // 作者
BIO: '一个普通的干饭人🍚', // 作者简介
LINK: 'https://tangly1024.com', // 网站地址
AVATAR: '/avatar.png', // 个人头像 默认取public目录下的avatar.png
KEYWORDS: 'Notion, 博客', // 网站关键词 英文逗号隔开
NOTION_PAGE_ID:
process.env.NOTION_PAGE_ID || '02ab3b8678004aa69e9e415905ef32a5', // Important page_idDuplicate Template from https://www.notion.so/tanghh/02ab3b8678004aa69e9e415905ef32a5
@@ -122,6 +121,7 @@ const BLOG = {
ADSENSE_GOOGLE_ID: process.env.NEXT_PUBLIC_ADSENSE_GOOGLE_ID || '', // 谷歌广告ID e.g ca-pub-xxxxxxxxxxxxxxxx
// 无关紧要的配置
AVATAR: '/avatar.png', // 作者头像被notion中的ICON覆盖。如果没有ICON则取public目录下的avatar.png
TITLE: process.env.NEXT_PUBLIC_TITLE || 'NotionNext BLOG', // 站点标题 被notion中的页面标题覆盖
DESCRIPTION:
process.env.NEXT_PUBLIC_DESCRIPTION || '这是一个由NotionNext生成的站点', // 站点描述被notion中的页面描述覆盖

View File

@@ -25,12 +25,11 @@ export async function getGlobalNotionData({
from,
pageType = ['Post']
}) {
// 深拷贝数据
// 获取Notion数据
const notionPageData = deepClone(await getNotionPageData({ pageId, from }))
const allPosts = await getAllPosts({ notionPageData, from, pageType })
notionPageData.allPosts = allPosts
// 删除前端不需要的数据
// 获取文章列表
notionPageData.allPosts = await getAllPosts({ notionPageData, from, pageType })
delete notionPageData.block
delete notionPageData.collection
delete notionPageData.collectionQuery
@@ -49,14 +48,10 @@ export async function getGlobalNotionData({
*/
function getLatestPosts({ allPosts, from, latestPostCount }) {
const latestPosts = Object.create(allPosts).sort((a, b) => {
console.log('排序过程', a, b)
const dateA = new Date(a?.lastEditedTime || a?.createdTime || a?.date?.start_date)
const dateB = new Date(b?.lastEditedTime || b?.createdTime || b?.date?.start_date)
// const dateA = new Date(a.date?.start_date)
// const dateB = new Date(b.date?.start_date)
return dateB - dateA
})
console.log('排序结果', latestPosts)
return latestPosts.slice(0, latestPostCount)
}
@@ -171,22 +166,35 @@ function getAllCategories({ allPosts, categoryOptions, sliceCount = 0 }) {
function getBlogInfo({ collection, block }) {
const title = collection?.name?.[0][0] || BLOG.TITLE
const description = collection?.description?.[0][0] || BLOG.DESCRIPTION
const pageCover = mapCoverUrl(collection?.cover, block)
return { title, description, pageCover }
const pageCover = collection?.cover ? mapImgUrl(collection?.cover, block[idToUuid(BLOG.NOTION_PAGE_ID)]?.value) : BLOG.HOME_BANNER_IMAGE
const icon = collection?.icon ? mapCollectionImg(collection?.icon, collection) : BLOG.AVATAR
return { title, description, pageCover, icon }
}
/**
* 网站封面背景图
* Notion图片映射
* @param pageCover
* @returns {string}
*/
const mapCoverUrl = (pageCover, block) => {
if (!pageCover || pageCover === '') {
return BLOG.HOME_BANNER_IMAGE
const mapImgUrl = (img, value) => {
if (img) {
if (img.startsWith('/')) return 'https://www.notion.so' + img
if (img.startsWith('http')) return defaultMapImageUrl(img, value)
}
if (pageCover) {
if (pageCover.startsWith('/')) return 'https://www.notion.so' + pageCover
if (pageCover.startsWith('http')) return defaultMapImageUrl(pageCover, block[idToUuid(BLOG.NOTION_PAGE_ID)].value)
}
/**
* collection 图片映射
* @param {*} img
* @param {*} value
* @returns
*/
const mapCollectionImg = (img, value) => {
if (img) {
if (img.startsWith('/')) return 'https://www.notion.so' + img
if (img.startsWith('http')) {
return 'https://www.notion.so/image/' + encodeURIComponent(img) + '?table=collection&id=' + value.id
}
}
}
@@ -246,9 +254,10 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
const categories = getAllCategories({ allPosts, categoryOptions, sliceCount: BLOG.PREVIEW_CATEGORY_COUNT })
const tags = getAllTags({ allPosts, tagOptions, sliceCount: BLOG.PREVIEW_TAG_COUNT })
const latestPosts = getLatestPosts({ allPosts, from, latestPostCount: 5 })
const siteInfo = getBlogInfo({ collection, block })
const siteInfo = getBlogInfo({ collection: collection, block: block })
return {
siteInfo,
collection,
collectionQuery,
collectionId,
@@ -259,7 +268,6 @@ async function getPageRecordMapByNotionAPI({ pageId, from }) {
tagOptions,
categoryOptions,
rawMetadata,
siteInfo,
customNav,
postCount,
pageIds,

View File

@@ -6,12 +6,13 @@ module.exports = withBundleAnalyzer({
webpack5: true
},
images: {
// 允许next/image加载的图片 域名
domains: [
'gravatar.com',
'www.notion.so',
'avatars.githubusercontent.com',
'images.unsplash.com'
] // 允许next/image加载的图片 域名
]
},
async headers() {
return [

View File

@@ -1,11 +1,10 @@
import BLOG from '@/blog.config'
import Image from 'next/image'
import { useRouter } from 'next/router'
import Card from './Card'
import SocialButton from './SocialButton'
import MenuGroupCard from './MenuGroupCard'
export function InfoCard (props) {
const { className } = props
const { className, siteInfo } = props
const router = useRouter()
return <Card className={className}>
<div
@@ -14,14 +13,8 @@ export function InfoCard (props) {
router.push('/')
}}
>
<Image
alt={BLOG.AUTHOR}
width={120}
height={120}
loading='lazy'
src={BLOG.AVATAR}
className='rounded-full'
/>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full' width={120}/>
</div>
<div className='text-center text-xl pb-4'>{BLOG.AUTHOR}</div>
<div className='text-sm text-center'>{BLOG.BIO}</div>

View File

@@ -46,7 +46,7 @@ const LayoutBase = props => {
{slotRight}
<div key={locale.NAV.ABOUT}>
{router.pathname !== '/search' && <SearchInput className='mt-6 mb-12' />}
{showInfoCard && <InfoCard />}
{showInfoCard && <InfoCard {...props} />}
{CONFIG_MEDIUM.WIDGET_REVOLVER_MAPS === 'true' && <RevolverMaps />}
</div>
</Tabs>

View File

@@ -1,5 +1,4 @@
import Comment from '@/components/Comment'
import Image from 'next/image'
import Link from 'next/link'
import ArticleAround from './ArticleAround'
import CategoryItem from './CategoryItem'
@@ -11,7 +10,7 @@ import BLOG from '@/blog.config'
import NotionPage from '@/components/NotionPage'
export const ArticleDetail = props => {
const { post, prev, next } = props
const { post, prev, next, siteInfo } = props
const { locale } = useGlobal()
const date = formatDate(
@@ -23,14 +22,10 @@ export const ArticleDetail = props => {
<section className="flex py-4 items-center font-sans px-1">
<Link href="/about" passHref>
<>
<Image
alt={BLOG.AUTHOR}
width={25}
height={25}
loading="lazy"
src="/avatar.jpg"
className="rounded-full cursor-pointer"
/>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full cursor-pointer' width={25}/>
<div className="mr-3 ml-1 text-green-500 cursor-pointer">
{BLOG.AUTHOR}
</div>

View File

@@ -1,22 +1,16 @@
import BLOG from '@/blog.config'
import Image from 'next/image'
import Router from 'next/router'
import React from 'react'
import SocialButton from './SocialButton'
const InfoCard = () => {
const InfoCard = (props) => {
const { siteInfo } = props
return <div id='info-card' className='py-4'>
<div className='items-center justify-center font-sans '>
<div className='hover:scale-105 transform duration-200 cursor-pointer flex justify-center' onClick={ () => { Router.push('/about') }}>
<Image
alt={BLOG.AUTHOR}
width={120}
height={120}
loading='lazy'
src={BLOG.AVATAR}
className='rounded-full'
/>
</div>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full' width={120}/>
</div>
<div className='text-xl py-2 hover:scale-105 transform duration-200 flex justify-center dark:text-gray-300'>{BLOG.AUTHOR}</div>
<div className='font-light text-gray-600 mb-2 hover:scale-105 transform duration-200 flex justify-center dark:text-gray-400'>{BLOG.BIO}</div>
<SocialButton/>

View File

@@ -1,21 +1,15 @@
import BLOG from '@/blog.config'
import Image from 'next/image'
import Router from 'next/router'
import React from 'react'
import SocialButton from './SocialButton'
const InfoCard = () => {
const InfoCard = (props) => {
const { siteInfo } = props
return <>
<div className='flex flex-col items-center justify-center '>
<div className='hover:rotate-45 hover:scale-125 transform duration-200 cursor-pointer' onClick={ () => { Router.push('/') }}>
<Image
alt={BLOG.AUTHOR}
width={120}
height={120}
loading='lazy'
src={BLOG.AVATAR}
className='rounded-full'
/>
{/* eslint-disable-next-line @next/next/no-img-element */}
<img src={siteInfo?.icon} className='rounded-full' width={120}/>
</div>
<div className='text-2xl font-serif dark:text-white py-2 hover:scale-105 transform duration-200'>{BLOG.AUTHOR}</div>
<div className='font-light dark:text-white py-2 hover:scale-105 transform duration-200'>{BLOG.BIO}</div>

View File

@@ -47,7 +47,7 @@ const SideAreaLeft = props => {
)}
<div key={locale.NAV.ABOUT} className='mb-5 bg-white dark:bg-hexo-black-gray duration-200 py-6'>
<InfoCard />
<InfoCard {...props} />
<>
<div className='mt-2 text-center dark:text-gray-300 font-light text-xs'>
<span className='px-1 '>

View File

@@ -16,14 +16,15 @@ import React from 'react'
* @returns {JSX.Element}
* @constructor
*/
const SideBar = ({ tags, currentTag, post, slot, categories, currentCategory }) => {
const SideBar = (props) => {
const { tags, currentTag, post, slot, categories, currentCategory } = props
const { locale } = useGlobal()
return <aside id='sidebar' className='bg-white dark:bg-gray-900 w-80 z-10 dark:border-gray-500 border-gray-200 scroll-hidden h-full'>
<div className={(!post ? 'sticky top-0' : '') + ' bg-white dark:bg-gray-900 pb-4'}>
<section className='py-5'>
<InfoCard />
<InfoCard {...props} />
</section>
{/* 分类 */}