From f2b756b715465d0a3af83e517df2057ee0370cb6 Mon Sep 17 00:00:00 2001 From: Kuizuo Date: Thu, 3 Oct 2024 12:55:54 +0800 Subject: [PATCH] feat: add tweet component --- ...\250 Hono \346\216\245\347\256\241 API.md" | 2 +- ...14\344\270\216\346\204\237\346\202\237.md" | 2 + docusaurus.config.ts | 4 +- package.json | 1 + pnpm-lock.yaml | 49 +++++++ src/components/Tweet/index.tsx | 14 ++ src/css/custom.css | 6 +- src/css/tweet-theme.css | 133 ++++++++++++++++++ src/theme/MDXComponents/A.tsx | 7 +- 9 files changed, 208 insertions(+), 10 deletions(-) create mode 100644 src/components/Tweet/index.tsx create mode 100644 src/css/tweet-theme.css diff --git "a/blog/develop/Next js \344\275\277\347\224\250 Hono \346\216\245\347\256\241 API.md" "b/blog/develop/Next js \344\275\277\347\224\250 Hono \346\216\245\347\256\241 API.md" index 2e2af9ed7..66ea16b74 100644 --- "a/blog/develop/Next js \344\275\277\347\224\250 Hono \346\216\245\347\256\241 API.md" +++ "b/blog/develop/Next js \344\275\277\347\224\250 Hono \346\216\245\347\256\241 API.md" @@ -102,7 +102,7 @@ export default app ::: -因为 zod-validator 默认以 json 格式返回整个 result,代码详见 https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts#L68-L70 +因为 zod-validator 默认以 json 格式返回整个 result,代码详见 [zod-validator/src/index.ts#L68-L70](https://github.com/honojs/middleware/blob/main/packages/zod-validator/src/index.ts#L68-L70) 这就是坑点之一,返回给客户端的错误信息肯定不会是以这种格式。这里我将其更改为全局错误捕获,做法如下 diff --git "a/blog/lifestyle/\350\256\260 \302\267 \345\234\250 AI \345\205\254\345\217\270\345\205\245\350\201\214\344\270\200\344\270\252\346\234\210\347\232\204\344\275\223\351\252\214\344\270\216\346\204\237\346\202\237.md" "b/blog/lifestyle/\350\256\260 \302\267 \345\234\250 AI \345\205\254\345\217\270\345\205\245\350\201\214\344\270\200\344\270\252\346\234\210\347\232\204\344\275\223\351\252\214\344\270\216\346\204\237\346\202\237.md" index 584cdfe35..804e5268d 100644 --- "a/blog/lifestyle/\350\256\260 \302\267 \345\234\250 AI \345\205\254\345\217\270\345\205\245\350\201\214\344\270\200\344\270\252\346\234\210\347\232\204\344\275\223\351\252\214\344\270\216\346\204\237\346\202\237.md" +++ "b/blog/lifestyle/\350\256\260 \302\267 \345\234\250 AI \345\205\254\345\217\270\345\205\245\350\201\214\344\270\200\344\270\252\346\234\210\347\232\204\344\275\223\351\252\214\344\270\216\346\204\237\346\202\237.md" @@ -21,6 +21,8 @@ import Tweet from '@site/src/components/Tweet'; ::: + + 已经在一家 AI 公司入职了一个月,对坐班有些厌恶的我,没想到有一天也会开始通勤打卡。而经历了这一个月的工作,我对坐班的态度有所转变,开始理解这种工作方式对我的意义。是时候分享入职这期间的工作内容与感受。 diff --git a/docusaurus.config.ts b/docusaurus.config.ts index d3ce091b7..94904d686 100644 --- a/docusaurus.config.ts +++ b/docusaurus.config.ts @@ -179,7 +179,7 @@ const config: Config = { }, blog: false, theme: { - customCss: ['./src/css/custom.css'], + customCss: ['./src/css/custom.css', './src/css/tweet-theme.css'], }, sitemap: { priority: 0.5, @@ -224,7 +224,7 @@ const config: Config = { editLocalizedFiles: false, blogDescription: '代码人生:编织技术与生活的博客之旅', blogSidebarCount: 10, - blogSidebarTitle: 'Blogs', + blogSidebarTitle: '博文', postsPerPage: 12, showReadingTime: true, readingTime: ({ content, frontMatter, defaultReadingTime }) => diff --git a/package.json b/package.json index 3a5489b75..6487f5c90 100644 --- a/package.json +++ b/package.json @@ -53,6 +53,7 @@ "react-github-calendar": "^4.1.6", "react-icon-cloud": "^4.1.4", "react-popper": "^2.3.0", + "react-tweet": "^3.2.1", "tailwind-merge": "^2.3.0", "tailwindcss": "^3.4.4" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c04b2bad4..4debd2ffc 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -80,6 +80,9 @@ importers: react-popper: specifier: ^2.3.0 version: 2.3.0(@popperjs/core@2.11.8)(react-dom@18.3.1(react@18.3.1))(react@18.3.1) + react-tweet: + specifier: ^3.2.1 + version: 3.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1) tailwind-merge: specifier: ^2.3.0 version: 2.3.0 @@ -1416,6 +1419,9 @@ packages: resolution: {integrity: sha512-LnhVjMWyMQV9ZmeEy26maJk+8HTIbd59cH4F2MJ439k9DqejRisfFNGAPvRYlKETuh9LrImlS8aKsBgKjMA8WA==} engines: {node: '>=14'} + '@swc/helpers@0.5.13': + resolution: {integrity: sha512-UoKGxQ3r5kYI9dALKJapMmuK+1zWM/H17Z1+iwnNmzcJRnfFuevZs375TA5rW31pu4BS4NoSy1fRsexDXfWn5w==} + '@szmarczak/http-timer@5.0.1': resolution: {integrity: sha512-+PmQX0PiAYPMeVYe237LJAYvOMYW1j2rH5YROyS3b4CTVJum34HfRvKvAzozHAQG0TnHNdUfY9nCeUyRAs//cw==} engines: {node: '>=14.16'} @@ -2033,6 +2039,9 @@ packages: resolution: {integrity: sha512-w5Jac5SykAeZJKntOxJCrm63Eg5/4dhMWIcuTbo9rpE+brgaSZo0RuNJZeOyMgsUdhDeojvgyQLmjI+K50ZGyg==} engines: {node: 10.* || >= 12.*} + client-only@0.0.1: + resolution: {integrity: sha512-IV3Ou0jSMzZrd3pZ48nLkT9DA7Ag1pnPzaiQhpW7c3RbcqqzvzzVu+L8gfqMp/8IM2MQtSiqaCxrrcfu8I8rMA==} + clone-deep@4.0.1: resolution: {integrity: sha512-neHB9xuzh/wk0dIHweyAXv2aPGZIVk3pLMe+/RNzINf17fe0OG96QroktYAUm7SM1PBnzTabaLboqqxDyMU+SQ==} engines: {node: '>=6'} @@ -4628,6 +4637,12 @@ packages: peerDependencies: react: '>=15' + react-tweet@3.2.1: + resolution: {integrity: sha512-dktP3RMuwRB4pnSDocKpSsW5Hq1IXRW6fONkHhxT5EBIXsKZzdQuI70qtub1XN2dtZdkJWWxfBm/Q+kN+vRYFA==} + peerDependencies: + react: '>= 18.0.0' + react-dom: '>= 18.0.0' + react-waypoint@10.3.0: resolution: {integrity: sha512-iF1y2c1BsoXuEGz08NoahaLFIGI9gTUAAOKip96HUmylRT6DUtpgoBPjk/Y8dfcFVmfVDvUzWjNXpZyKTOV0SQ==} peerDependencies: @@ -5134,6 +5149,11 @@ packages: engines: {node: '>=14.0.0'} hasBin: true + swr@2.2.5: + resolution: {integrity: sha512-QtxqyclFeAsxEUeZIYmsaQ0UjimSq1RZ9Un7I68/0ClKK/U3LoyQunwkQfJZr2fc22DfIXLNDc2wFyTEikCUpg==} + peerDependencies: + react: ^16.11.0 || ^17.0.0 || ^18.0.0 + tailwind-merge@2.3.0: resolution: {integrity: sha512-vkYrLpIP+lgR0tQCG6AP7zZXCTLc1Lnv/CCRT3BqJ9CZ3ui2++GPaGb1x/ILsINIMSYqqvrpqjUFsMNLlW99EA==} @@ -5382,6 +5402,11 @@ packages: file-loader: optional: true + use-sync-external-store@1.2.2: + resolution: {integrity: sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==} + peerDependencies: + react: ^16.8.0 || ^17.0.0 || ^18.0.0 + util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -7721,6 +7746,10 @@ snapshots: - supports-color - typescript + '@swc/helpers@0.5.13': + dependencies: + tslib: 2.6.2 + '@szmarczak/http-timer@5.0.1': dependencies: defer-to-connect: 2.0.1 @@ -8428,6 +8457,8 @@ snapshots: optionalDependencies: '@colors/colors': 1.5.0 + client-only@0.0.1: {} + clone-deep@4.0.1: dependencies: is-plain-object: 2.0.4 @@ -11457,6 +11488,14 @@ snapshots: tiny-invariant: 1.3.1 tiny-warning: 1.0.3 + react-tweet@3.2.1(react-dom@18.3.1(react@18.3.1))(react@18.3.1): + dependencies: + '@swc/helpers': 0.5.13 + clsx: 2.0.0 + react: 18.3.1 + react-dom: 18.3.1(react@18.3.1) + swr: 2.2.5(react@18.3.1) + react-waypoint@10.3.0(react@18.3.1): dependencies: '@babel/runtime': 7.24.6 @@ -12096,6 +12135,12 @@ snapshots: csso: 5.0.5 picocolors: 1.0.0 + swr@2.2.5(react@18.3.1): + dependencies: + client-only: 0.0.1 + react: 18.3.1 + use-sync-external-store: 1.2.2(react@18.3.1) + tailwind-merge@2.3.0: dependencies: '@babel/runtime': 7.24.6 @@ -12395,6 +12440,10 @@ snapshots: optionalDependencies: file-loader: 6.2.0(webpack@5.88.2) + use-sync-external-store@1.2.2(react@18.3.1): + dependencies: + react: 18.3.1 + util-deprecate@1.0.2: {} utila@0.4.0: {} diff --git a/src/components/Tweet/index.tsx b/src/components/Tweet/index.tsx new file mode 100644 index 000000000..eafefa3e6 --- /dev/null +++ b/src/components/Tweet/index.tsx @@ -0,0 +1,14 @@ +import BrowserOnly from '@docusaurus/BrowserOnly' +import { Tweet as ReactTweet } from 'react-tweet' + +export default function Tweet({ id }: { id: string }) { + return ( + Loading...}> + {() => ( + + + + )} + + ) +} diff --git a/src/css/custom.css b/src/css/custom.css index 6f6aa06f6..8a8b844a0 100644 --- a/src/css/custom.css +++ b/src/css/custom.css @@ -117,15 +117,15 @@ html[data-theme='dark'] .theme-code-block { --prism-background-color: #1e1e1e !important; } -article .markdown a:not(.hash-link) { +article .markdown a.link { text-decoration: none; font-weight: inherit; border-bottom: 1px solid rgba(125, 125, 125, 0.3); transition: border 0.3s ease-in-out; } -article .markdown a:not(.hash-link):hover, -article .markdown a:not(.hash-link):focus { +article .markdown a.link:hover, +article .markdown a.link:focus { border-bottom: 1px solid var(--ifm-color-primary-light); } diff --git a/src/css/tweet-theme.css b/src/css/tweet-theme.css new file mode 100644 index 000000000..f56c36482 --- /dev/null +++ b/src/css/tweet-theme.css @@ -0,0 +1,133 @@ +.react-tweet-theme { + --tweet-container-margin: 1.5rem 0; + + /* Header */ + --tweet-header-font-size: 0.9375rem; + --tweet-header-line-height: 1.25rem; + + /* Text */ + --tweet-body-font-size: 1.25rem; + --tweet-body-font-weight: 400; + --tweet-body-line-height: 1.5rem; + --tweet-body-margin: 0; + + /* Quoted Tweet */ + --tweet-quoted-container-margin: 0.75rem 0; + --tweet-quoted-body-font-size: 0.938rem; + --tweet-quoted-body-font-weight: 400; + --tweet-quoted-body-line-height: 1.25rem; + --tweet-quoted-body-margin: 0.25rem 0 0.75rem 0; + + /* Info */ + --tweet-info-font-size: 0.9375rem; + --tweet-info-line-height: 1.25rem; + + /* Actions like the like, reply and copy buttons */ + --tweet-actions-font-size: 0.875rem; + --tweet-actions-line-height: 1rem; + --tweet-actions-font-weight: 700; + --tweet-actions-icon-size: 1.25em; + --tweet-actions-icon-wrapper-size: calc( + var(--tweet-actions-icon-size) + 0.75em + ); + + /* Reply button */ + --tweet-replies-font-size: 0.875rem; + --tweet-replies-line-height: 1rem; + --tweet-replies-font-weight: 700; +} + +:where(.react-tweet-theme) * { + margin: 0; + padding: 0; + box-sizing: border-box; +} + +:is([data-theme='light'], .light) :where(.react-tweet-theme), +:where(.react-tweet-theme) { + --tweet-skeleton-gradient: linear-gradient( + 270deg, + #fafafa, + #eaeaea, + #eaeaea, + #fafafa + ); + --tweet-border: 1px solid rgb(207, 217, 222); + --tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Helvetica, Arial, sans-serif; + --tweet-font-color: rgb(15, 20, 25); + --tweet-font-color-secondary: rgb(83, 100, 113); + --tweet-bg-color: #fff; + --tweet-bg-color-hover: rgb(247, 249, 249); + --tweet-quoted-bg-color-hover: rgba(0, 0, 0, 0.03); + --tweet-color-blue-primary: rgb(29, 155, 240); + --tweet-color-blue-primary-hover: rgb(26, 140, 216); + --tweet-color-blue-secondary: rgb(0, 111, 214); + --tweet-color-blue-secondary-hover: rgba(0, 111, 214, 0.1); + --tweet-color-red-primary: rgb(249, 24, 128); + --tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1); + --tweet-color-green-primary: rgb(0, 186, 124); + --tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1); + --tweet-twitter-icon-color: var(--tweet-font-color); + --tweet-verified-old-color: rgb(130, 154, 171); + --tweet-verified-blue-color: var(--tweet-color-blue-primary); +} + +:is([data-theme='dark'], .dark) :where(.react-tweet-theme) { + --tweet-skeleton-gradient: linear-gradient( + 270deg, + #15202b, + rgb(30, 39, 50), + rgb(30, 39, 50), + rgb(21, 32, 43) + ); + --tweet-border: 1px solid rgb(66, 83, 100); + --tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Helvetica, Arial, sans-serif; + --tweet-font-color: rgb(247, 249, 249); + --tweet-font-color-secondary: rgb(139, 152, 165); + --tweet-bg-color: rgb(21, 32, 43); + --tweet-bg-color-hover: rgb(30, 39, 50); + --tweet-quoted-bg-color-hover: rgba(255, 255, 255, 0.03); + --tweet-color-blue-primary: rgb(29, 155, 240); + --tweet-color-blue-primary-hover: rgb(26, 140, 216); + --tweet-color-blue-secondary: rgb(107, 201, 251); + --tweet-color-blue-secondary-hover: rgba(107, 201, 251, 0.1); + --tweet-color-red-primary: rgb(249, 24, 128); + --tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1); + --tweet-color-green-primary: rgb(0, 186, 124); + --tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1); + --tweet-twitter-icon-color: var(--tweet-font-color); + --tweet-verified-old-color: rgb(130, 154, 171); + --tweet-verified-blue-color: #fff; +} + +@media (prefers-color-scheme: dark) { + :where(.react-tweet-theme) { + --tweet-skeleton-gradient: linear-gradient( + 270deg, + #15202b, + rgb(30, 39, 50), + rgb(30, 39, 50), + rgb(21, 32, 43) + ); + --tweet-border: 1px solid rgb(66, 83, 100); + --tweet-font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, + Helvetica, Arial, sans-serif; + --tweet-font-color: rgb(247, 249, 249); + --tweet-font-color-secondary: rgb(139, 152, 165); + --tweet-bg-color: rgb(21, 32, 43); + --tweet-bg-color-hover: rgb(30, 39, 50); + --tweet-color-blue-primary: rgb(29, 155, 240); + --tweet-color-blue-primary-hover: rgb(26, 140, 216); + --tweet-color-blue-secondary: rgb(107, 201, 251); + --tweet-color-blue-secondary-hover: rgba(107, 201, 251, 0.1); + --tweet-color-red-primary: rgb(249, 24, 128); + --tweet-color-red-primary-hover: rgba(249, 24, 128, 0.1); + --tweet-color-green-primary: rgb(0, 186, 124); + --tweet-color-green-primary-hover: rgba(0, 186, 124, 0.1); + --tweet-twitter-icon-color: var(--tweet-font-color); + --tweet-verified-old-color: rgb(130, 154, 171); + --tweet-verified-blue-color: #fff; + } +} diff --git a/src/theme/MDXComponents/A.tsx b/src/theme/MDXComponents/A.tsx index f92b6aae7..3adcc1058 100644 --- a/src/theme/MDXComponents/A.tsx +++ b/src/theme/MDXComponents/A.tsx @@ -1,6 +1,5 @@ import Link from '@docusaurus/Link' import type { Props } from '@theme/MDXComponents/A' -import React from 'react' import { Icon } from '@iconify/react' @@ -11,7 +10,7 @@ export default function MDXA(props: Props): JSX.Element { const iconMappings = { 'github.com': 'simple-icons:github', - 'twitter.com': 'logos:twitter', + 'x.com': 'ri:twitter-x-fill', } const foundKey = Object.keys(iconMappings).find(key => { @@ -25,10 +24,10 @@ export default function MDXA(props: Props): JSX.Element { return ( {icon && } - + ) } - return + return }