Skip to content

Commit

Permalink
♻️ Make config injectable
Browse files Browse the repository at this point in the history
* New hook: useConfig
* Avoid sending private fields from config file to client
  • Loading branch information
SilentDepth committed Mar 31, 2023
1 parent 2f15a92 commit ea3bd33
Show file tree
Hide file tree
Showing 33 changed files with 278 additions and 190 deletions.
4 changes: 3 additions & 1 deletion components/BlogPost.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import Link from 'next/link'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import FormattedDate from '@/components/FormattedDate'

const BlogPost = ({ post }) => {
const BLOG = useConfig()

return (
<Link href={`${BLOG.path}/${post.slug}`}>
<article key={post.id} className="mb-6 md:mb-8">
Expand Down
5 changes: 3 additions & 2 deletions components/Comments.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useRouter } from 'next/router'
import dynamic from 'next/dynamic'
import cn from 'classnames'
import { fetchCusdisLang } from '@/lib/cusdisLang'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'

const GitalkComponent = dynamic(
() => {
Expand All @@ -26,6 +26,7 @@ const CusdisComponent = dynamic(

const Comments = ({ frontMatter }) => {
const router = useRouter()
const BLOG = useConfig()

const fullWidth = frontMatter.fullWidth ?? false

Expand Down Expand Up @@ -55,7 +56,7 @@ const Comments = ({ frontMatter }) => {
)}
{BLOG.comment && BLOG.comment.provider === 'cusdis' && (
<CusdisComponent
lang={fetchCusdisLang()}
lang={fetchCusdisLang(BLOG.lang)}
attrs={{
host: BLOG.comment.cusdisConfig.host,
appId: BLOG.comment.cusdisConfig.appId,
Expand Down
4 changes: 3 additions & 1 deletion components/Container.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
import Header from '@/components/Header'
import Footer from '@/components/Footer'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import Head from 'next/head'
import PropTypes from 'prop-types'
import cn from 'classnames'
// import BlogPost from './BlogPost'

const Container = ({ children, layout, fullWidth, ...customMeta }) => {
const BLOG = useConfig()

const url = BLOG.path.length ? `${BLOG.link}/${BLOG.path}` : BLOG.link
const meta = {
title: BLOG.title,
Expand Down
4 changes: 3 additions & 1 deletion components/Footer.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import Vercel from '@/components/Vercel'
const Footer = ({ fullWidth }) => {
const BLOG = useConfig()

const d = new Date()
const y = d.getFullYear()
const from = +BLOG.since
Expand Down
29 changes: 20 additions & 9 deletions components/FormattedDate.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,29 @@
'use client'

import { useEffect, useState } from 'react'
import dayjs from 'dayjs'
import localizedFormat from 'dayjs/plugin/localizedFormat'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'

dayjs.extend(localizedFormat)

const lang = BLOG.lang.slice(0, 2)
import(`dayjs/locale/${lang}`)
.then(() => {
dayjs.locale(BLOG.lang.slice(0, 2))
})
.catch(() => console.warn(`dayjs locale \`${lang}\` not found`))
const loaded = {}

export default function FormattedDate ({ date }) {
const lang = useConfig().lang.slice(0, 2)
const [isLocaleLoaded, setIsLocaleLoaded] = useState(loaded[lang] === true)

useEffect(() => {
if (!isLocaleLoaded) {
loaded[lang] ??= import(`dayjs/locale/${lang}`).then(
() => {
loaded[lang] = true
dayjs.locale(lang)
},
() => console.warn(`dayjs locale \`${lang}\` not found`)
)
loaded[lang].then(() => setIsLocaleLoaded(true))
}

}, [isLocaleLoaded, lang])

return <span>{dayjs(date).format('ll')}</span>
}
6 changes: 4 additions & 2 deletions components/Gtag.js
Original file line number Diff line number Diff line change
@@ -1,18 +1,20 @@
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import { useConfig } from '@/lib/config'
import * as gtag from '@/lib/gtag'

const Gtag = () => {
const config = useConfig()
const router = useRouter()
useEffect(() => {
const handleRouteChange = url => {
gtag.pageview(url)
gtag.pageview(config.analytics.gaConfig.measurementId, url)
}
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
}, [config, router.events])
return null
}
export default Gtag
4 changes: 3 additions & 1 deletion components/Header.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { forwardRef, useCallback, useEffect, useRef, useState } from 'react'
import Link from 'next/link'
import Image from 'next/image'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import { useLocale } from '@/lib/locale'
import useTheme from '@/lib/theme'

const NavBar = () => {
const BLOG = useConfig()
const locale = useLocale()
const links = [
{ id: 0, name: locale.NAV.INDEX, to: BLOG.path || '/', show: true },
Expand Down Expand Up @@ -33,6 +34,7 @@ const NavBar = () => {
}

export default function Header ({ navBarTitle, fullWidth }) {
const BLOG = useConfig()
const { dark } = useTheme()

// Favicon
Expand Down
12 changes: 7 additions & 5 deletions components/NotionRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ import { createElement as h } from 'react'
import dynamic from 'next/dynamic'
import { NotionRenderer as Renderer } from 'react-notion-x'
import { getTextContent } from 'notion-utils'
import BLOG from '@/blog.config'
import tailwindConfig from '@/tailwind.config'
import { FONTS_SANS, FONTS_SERIF } from '@/consts'
import { useConfig } from '@/lib/config'
import Toggle from '@/components/notion-blocks/Toggle'

// Lazy-load some heavy components & override the renderers of some block types
Expand Down Expand Up @@ -106,10 +106,12 @@ const mapPageUrl = id => `https://www.notion.so/${id.replace(/-/g, '')}`
* @param props - Anything that react-notion-x/NotionRenderer supports
*/
export default function NotionRenderer (props) {
const config = useConfig()

const font = {
'sans-serif': tailwindConfig.theme.extend.fontFamily.sans,
'serif': tailwindConfig.theme.extend.fontFamily.serif
}[BLOG.font]
'sans-serif': FONTS_SANS,
'serif': FONTS_SERIF
}[config.font]

// Mark block types to be custom rendered by appending a suffix
if (props.recordMap) {
Expand Down
3 changes: 2 additions & 1 deletion components/Pagination.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import Link from 'next/link'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import { useLocale } from '@/lib/locale'

const Pagination = ({ page, showNext }) => {
const BLOG = useConfig()
const locale = useLocale()
const currentPage = +page
let additionalClassName = 'justify-between'
Expand Down
5 changes: 3 additions & 2 deletions components/Post.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import PropTypes from 'prop-types'
import Image from 'next/image'
import cn from 'classnames'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import useTheme from '@/lib/theme'
import FormattedDate from '@/components/FormattedDate'
import TagItem from '@/components/TagItem'
Expand All @@ -19,7 +19,8 @@ import TableOfContents from '@/components/TableOfContents'
* @prop {string} emailHash - Author email hash (for Gravatar)
* @prop {boolean} [fullWidth] - Whether in full-width mode
*/
export default function Post(props) {
export default function Post (props) {
const BLOG = useConfig()
const { post, blockMap, emailHash, fullWidth = false } = props
const { dark } = useTheme()

Expand Down
54 changes: 29 additions & 25 deletions components/Scripts.js
Original file line number Diff line number Diff line change
@@ -1,31 +1,35 @@
import Script from 'next/script'
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'

const Scripts = () => (
<>
{BLOG.analytics && BLOG.analytics.provider === 'ackee' && (
<Script
src={BLOG.analytics.ackeeConfig.tracker}
data-ackee-server={BLOG.analytics.ackeeConfig.dataAckeeServer}
data-ackee-domain-id={BLOG.analytics.ackeeConfig.domainId}
/>
)}
{BLOG.analytics && BLOG.analytics.provider === 'ga' && (
<>
const Scripts = () => {
const BLOG = useConfig()

return (
<>
{BLOG.analytics && BLOG.analytics.provider === 'ackee' && (
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${BLOG.analytics.gaConfig.measurementId}`}
src={BLOG.analytics.ackeeConfig.tracker}
data-ackee-server={BLOG.analytics.ackeeConfig.dataAckeeServer}
data-ackee-domain-id={BLOG.analytics.ackeeConfig.domainId}
/>
<Script strategy="lazyOnload" id="ga">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${BLOG.analytics.gaConfig.measurementId}', {
page_path: window.location.pathname,
});`}
</Script>
</>
)}
</>
)
)}
{BLOG.analytics && BLOG.analytics.provider === 'ga' && (
<>
<Script
src={`https://www.googletagmanager.com/gtag/js?id=${BLOG.analytics.gaConfig.measurementId}`}
/>
<Script strategy="lazyOnload" id="ga">
{`window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '${BLOG.analytics.gaConfig.measurementId}', {
page_path: window.location.pathname,
});`}
</Script>
</>
)}
</>
)
}

export default Scripts
4 changes: 3 additions & 1 deletion components/Utterances.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import BLOG from '@/blog.config'
import { useConfig } from '@/lib/config'
import { useEffect } from 'react'
const Utterances = ({ issueTerm, layout }) => {
const BLOG = useConfig()

useEffect(() => {
const theme =
BLOG.appearance === 'auto'
Expand Down
51 changes: 51 additions & 0 deletions consts.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
exports.FONTS_SANS = [
'"IBM Plex Sans"',
'ui-sans-serif',
'system-ui',
'-apple-system',
'BlinkMacSystemFont',
'Segoe UI',
'Roboto',
'"Noto Sans"',
'"Helvetica Neue"',
'Helvetica',
'"Nimbus Sans L"',
'Arial',
'"Liberation Sans"',
'"PingFang SC"',
'"Hiragino Sans GB"',
'"Noto Sans CJK SC"',
'"Source Han Sans SC"',
'"Source Han Sans CN"',
'"Microsoft YaHei"',
'"Wenquanyi Micro Hei"',
'"WenQuanYi Zen Hei"',
'"ST Heiti"',
'SimHei',
'"WenQuanYi Zen Hei Sharp"',
'sans-serif'
]
exports.FONTS_SERIF = [
'"Source Serif"',
'ui-serif',
'Georgia',
'"Nimbus Roman No9 L"',
'"Songti SC"',
'"Noto Serif CJK SC"',
'"Source Han Serif SC"',
'"Source Han Serif CN"',
'STSong',
'"AR PL New Sung"',
'"AR PL SungtiL GB"',
'NSimSun',
'SimSun',
'"TW-Sung"',
'"WenQuanYi Bitmap Song"',
'"AR PL UMing CN"',
'"AR PL UMing HK"',
'"AR PL UMing TW"',
'"AR PL UMing TW MBE"',
'PMingLiU',
'MingLiU',
'serif'
]
2 changes: 1 addition & 1 deletion lib/cjk.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
const BLOG = require('../blog.config')
const { config: BLOG } = require('../lib/server/config')

function cjk() {
switch (BLOG.lang.toLowerCase()) {
Expand Down
15 changes: 15 additions & 0 deletions lib/config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import { createContext, useContext } from 'react'

const ConfigContext = createContext(undefined)

export function ConfigProvider ({ value, children }) {
return (
<ConfigContext.Provider value={value}>
{children}
</ConfigContext.Provider>
)
}

export function useConfig () {
return useContext(ConfigContext)
}
10 changes: 3 additions & 7 deletions lib/cusdisLang.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import BLOG from '@/blog.config'

const cusdisI18n = [
'ca',
'en',
Expand All @@ -15,18 +13,16 @@ const cusdisI18n = [
'zh-tw'
]

const loweredLang = BLOG.lang.toLowerCase()

export const fetchCusdisLang = () => {
if (BLOG.comment.provider !== 'cusdis') return null
export const fetchCusdisLang = lang => {
const loweredLang = lang.toLowerCase()
if (loweredLang.startsWith('zh')) {
return (
cusdisI18n.find(i => loweredLang === i.toLocaleLowerCase()) ?? 'zh-cn'
)
} else {
return (
cusdisI18n.find(i =>
BLOG.lang.toLowerCase().startsWith(i.toLowerCase())
loweredLang.startsWith(i.toLowerCase())
) ?? 'en'
)
}
Expand Down
6 changes: 4 additions & 2 deletions lib/dayjs.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import dayjs from 'dayjs'
import utc from 'dayjs/plugin/utc'
import timezone from 'dayjs/plugin/timezone'
import BLOG from '@/blog.config'

dayjs.extend(utc)
dayjs.extend(timezone)
dayjs.tz.setDefault(BLOG.timezone)

export function prepareDayjs (timezone) {
dayjs.tz.setDefault(timezone)
}

export default dayjs
Loading

0 comments on commit ea3bd33

Please sign in to comment.