-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
9 changed files
with
271 additions
and
13 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
import 'css/prism.css' | ||
import 'katex/dist/katex.css' | ||
|
||
import PageTitle from '@/components/PageTitle' | ||
import { components } from '@/components/MDXComponents' | ||
import { MDXLayoutRenderer } from 'pliny/mdx-components' | ||
import { sortPosts, coreContent, allCoreContent } from 'pliny/utils/contentlayer' | ||
import { allAuthors, allRandomThoughts } from 'contentlayer/generated' | ||
import type { Authors, RandomThoughts } from 'contentlayer/generated' | ||
import PostSimple from '@/layouts/PostSimple' | ||
import PostLayout from '@/layouts/PostLayout' | ||
import PostBanner from '@/layouts/PostBanner' | ||
import { Metadata } from 'next' | ||
import siteMetadata from '@/data/siteMetadata' | ||
|
||
const defaultLayout = 'PostLayout' | ||
const layouts = { | ||
PostSimple, | ||
PostLayout, | ||
PostBanner, | ||
} | ||
|
||
export async function generateMetadata({ | ||
params, | ||
}: { | ||
params: { slug: string[] } | ||
}): Promise<Metadata | undefined> { | ||
const slug = decodeURI(params.slug.join('/')) | ||
const post = allRandomThoughts.find((p) => p.slug === slug) | ||
const authorList = post?.authors || ['default'] | ||
const authorDetails = authorList.map((author) => { | ||
const authorResults = allAuthors.find((p) => p.slug === author) | ||
return coreContent(authorResults as Authors) | ||
}) | ||
if (!post) { | ||
return | ||
} | ||
|
||
const publishedAt = new Date(post.date).toISOString() | ||
const modifiedAt = new Date(post.lastmod || post.date).toISOString() | ||
const authors = authorDetails.map((author) => author.name) | ||
let imageList = [siteMetadata.socialBanner] | ||
if (post.images) { | ||
imageList = typeof post.images === 'string' ? [post.images] : post.images | ||
} | ||
const ogImages = imageList.map((img) => { | ||
console.log(img) | ||
return { | ||
url: img.includes('http') ? img : siteMetadata.siteUrl + img, | ||
} | ||
}) | ||
|
||
return { | ||
title: post.title, | ||
description: post.summary, | ||
openGraph: { | ||
title: post.title, | ||
description: post.summary, | ||
siteName: siteMetadata.title, | ||
locale: 'en_US', | ||
type: 'article', | ||
publishedTime: publishedAt, | ||
modifiedTime: modifiedAt, | ||
url: './', | ||
images: ogImages, | ||
authors: authors.length > 0 ? authors : [siteMetadata.author], | ||
}, | ||
twitter: { | ||
card: 'summary_large_image', | ||
title: post.title, | ||
description: post.summary, | ||
images: imageList, | ||
}, | ||
} | ||
} | ||
|
||
export const generateStaticParams = async () => { | ||
const paths = allRandomThoughts.map((p) => ({ slug: p.slug.split('/') })) | ||
|
||
return paths | ||
} | ||
|
||
export default async function Page({ params }: { params: { slug: string[] } }) { | ||
const slug = decodeURI(params.slug.join('/')) | ||
// Filter out drafts in production | ||
const sortedCoreContents = allCoreContent(sortPosts(allRandomThoughts)) | ||
const postIndex = sortedCoreContents.findIndex((p) => p.slug === slug) | ||
if (postIndex === -1) { | ||
return ( | ||
<div className="mt-24 text-center"> | ||
<PageTitle> | ||
Under Construction{' '} | ||
<span role="img" aria-label="roadwork sign"> | ||
🚧 | ||
</span> | ||
</PageTitle> | ||
</div> | ||
) | ||
} | ||
|
||
const prev = sortedCoreContents[postIndex + 1] | ||
const next = sortedCoreContents[postIndex - 1] | ||
const post = allRandomThoughts.find((p) => p.slug === slug) as RandomThoughts | ||
const authorList = post?.authors || ['default'] | ||
const authorDetails = authorList.map((author) => { | ||
const authorResults = allAuthors.find((p) => p.slug === author) | ||
return coreContent(authorResults as Authors) | ||
}) | ||
const mainContent = coreContent(post) | ||
const jsonLd = post.structuredData | ||
jsonLd['author'] = authorDetails.map((author) => { | ||
return { | ||
'@type': 'Person', | ||
name: author.name, | ||
} | ||
}) | ||
|
||
const Layout = layouts[post.layout || defaultLayout] | ||
|
||
return ( | ||
<> | ||
<script | ||
type="application/ld+json" | ||
dangerouslySetInnerHTML={{ __html: JSON.stringify(jsonLd) }} | ||
/> | ||
<Layout content={mainContent} authorDetails={authorDetails} next={next} prev={prev}> | ||
<MDXLayoutRenderer code={post.body.code} components={components} toc={post.toc} /> | ||
</Layout> | ||
</> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
import ListLayout from '@/layouts/ListLayout' | ||
import {allCoreContent, sortPosts} from 'pliny/utils/contentlayer' | ||
import {allRandomThoughts} from 'contentlayer/generated' | ||
import {genPageMetadata} from 'app/seo' | ||
|
||
const POSTS_PER_PAGE = 8 | ||
|
||
export const metadata = genPageMetadata({title: '随笔'}) | ||
|
||
export default function BlogPage() { | ||
const posts = allCoreContent(sortPosts(allRandomThoughts)) | ||
const pageNumber = 1 | ||
const initialDisplayPosts = posts.slice( | ||
POSTS_PER_PAGE * (pageNumber - 1), | ||
POSTS_PER_PAGE * pageNumber | ||
) | ||
const pagination = { | ||
currentPage: pageNumber, | ||
totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), | ||
} | ||
|
||
return ( | ||
<ListLayout | ||
posts={posts} | ||
initialDisplayPosts={initialDisplayPosts} | ||
pagination={pagination} | ||
subtitle="生活不只有事业,还有诗和远方。" | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,34 @@ | ||
import ListLayout from '@/layouts/ListLayoutWithTags' | ||
import { allCoreContent, sortPosts } from 'pliny/utils/contentlayer' | ||
import { allRandomThoughts } from 'contentlayer/generated' | ||
|
||
const POSTS_PER_PAGE = 5 | ||
|
||
export const generateStaticParams = async () => { | ||
const totalPages = Math.ceil(allRandomThoughts.length / POSTS_PER_PAGE) | ||
const paths = Array.from({ length: totalPages }, (_, i) => ({ page: (i + 1).toString() })) | ||
|
||
return paths | ||
} | ||
|
||
export default function Page({ params }: { params: { page: string } }) { | ||
const posts = allCoreContent(sortPosts(allRandomThoughts)) | ||
const pageNumber = parseInt(params.page as string) | ||
const initialDisplayPosts = posts.slice( | ||
POSTS_PER_PAGE * (pageNumber - 1), | ||
POSTS_PER_PAGE * pageNumber | ||
) | ||
const pagination = { | ||
currentPage: pageNumber, | ||
totalPages: Math.ceil(posts.length / POSTS_PER_PAGE), | ||
} | ||
|
||
return ( | ||
<ListLayout | ||
posts={posts} | ||
initialDisplayPosts={initialDisplayPosts} | ||
pagination={pagination} | ||
title="All Posts" | ||
/> | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
{"robots":1,"functional-programming":1,"data-structure":1,"embedding":1,"search":1,"channel-pruning":1,"deployment":1,"shufflenet-v2":1,"efficient-neural-network":1,"int8":1,"quantization":1,"inference":2,"tree":1,"redisjson":1,"materialized-view":1,"feature-engineering":1,"model-serving":1,"staff-eng":1,"bear-market":2,"immigration":1,"life":2,"gpu-programming":1,"ml":1,"vc":1,"crypto-wallet":1,"industrial-research":1,"dlvm":1,"gpu":1,"low-cost":1,"chatgpt":4,"ai":1,"llm":4,"movie-review":1,"hong-kong":1,"prompt":1,"search-query":1,"search-engine":1,"career":1,"robotics":1,"gpt-4":1,"vision":1,"parenthood":1,"sampling":1,"text2sql":1} | ||
{"text2sql":1,"sampling":1,"parenthood":1,"llm":4,"chatgpt":4,"robotics":1,"gpt-4":1,"vision":1,"career":1,"prompt":1,"search-query":1,"search-engine":1,"movie-review":1,"life":2,"hong-kong":1,"ai":1,"dlvm":1,"gpu":1,"low-cost":1,"vc":1,"crypto-wallet":1,"industrial-research":1,"gpu-programming":1,"ml":1,"bear-market":2,"immigration":1,"staff-eng":1,"materialized-view":1,"feature-engineering":1,"model-serving":1,"redisjson":1,"tree":1,"inference":2,"int8":1,"quantization":1,"shufflenet-v2":1,"efficient-neural-network":1,"channel-pruning":1,"deployment":1,"embedding":1,"search":1,"functional-programming":1,"data-structure":1,"robots":1} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,11 +1,12 @@ | ||
const headerNavLinks = [ | ||
{ href: '/', title: 'Home' }, | ||
{ href: '/about', title: 'About' }, | ||
{ href: '/blog', title: 'Blog' }, | ||
{ href: '/services', title: 'Services' }, | ||
{ href: '/tags', title: 'Tags' }, | ||
// { href: '/tags', title: 'Tags' }, | ||
{ href: '/projects', title: 'Projects' }, | ||
{ href: '/speaking', title: 'Speaking' }, | ||
{ href: '/about', title: 'Who am I' }, | ||
{ href: '/services', title: 'Services' }, | ||
{ href: '/random', title: '随笔' }, | ||
] | ||
|
||
export default headerNavLinks |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
--- | ||
title: 让生活慢一点 | ||
date: '2024-04-27' | ||
tags: ['Movie'] | ||
draft: false | ||
--- | ||
|
||
当一个人经常用二倍速看视频, 听podcast, 看电影简评, 就会越来越难静下心来欣赏一部电影. 今天, 走路去Dr.Ink买了一杯咖啡回到家, 突然心血来潮想好好地看一部电影. 于是, 就完整得看完了2023年出品的"不虚此行". 缓慢的节奏, 莫名得让我的内心平静下来了. 所以想记录一下自己的感想. | ||
|
||
电影讲述了一个编剧转型去写悼词, 并从中看到不同人的人生故事. 写悼词的故事主角有餐厅老板, 有患癌症的病人, 有因抑郁症去世的配音网红, 有传统中国父亲形象的小学老师. 每个人都普普通通, 但通过他们亲人, 朋友, 同事的描述拼凑出一个个有血有肉的人. 整部电影的叙事风格就像是平静的水面下藏着很多暗涌. 在这个追求快节奏, 刺激观感的年代, 是非常难能可贵的. | ||
|
||
我感受最深的是那位为父亲预约悼词的王先生. 这是一个很典型的中国父子关系. 儿子从乡下来到了北京打拼, 父亲非常想和儿子多交流, 却因为儿子太忙直到去世都没有多少机会. 在胡歌采访这位王先生的时候, 王先生都拿着两部手机在处理工作. 胡歌通过王先生父亲的遗物察觉到了父子交流太少的这个遗憾, 也从王先生的儿子侧面得到了更多的信息. 于是他在悼词里面悄悄地放进去了自己的观察. 可惜电影没有给出具体的悼词, 里面写了什么也不得而知. 如果有机会的话, 大家还是要珍惜每次跟父母交流的机会, 减少日后的遗憾. | ||
|
||
最后, 用一小段诗总结一下: | ||
|
||
``` | ||
被快进键控制的世界 | ||
被忽略的细腻情感 | ||
让生活慢一点 | ||
故事的完结, 不应仓促 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters