feat: switch to static tweets

This commit is contained in:
Travis Fischer
2021-02-14 23:31:06 -05:00
parent 07c5421248
commit 0add28665a
9 changed files with 906 additions and 17 deletions

View File

@@ -18,3 +18,6 @@
# Optional (for fathom analytics)
#NEXT_PUBLIC_FATHOM_ID=
# Optional (for rendering tweets efficiently)
TWITTER_ACCESS_TOKEN=

View File

@@ -0,0 +1,25 @@
import { NextApiRequest, NextApiResponse } from 'next'
import { fetchTweetAst } from 'static-tweets'
export default async (
req: NextApiRequest,
res: NextApiResponse
): Promise<void> => {
if (req.method !== 'GET') {
return res.status(405).send({ error: 'method not allowed' })
}
const tweetId = req.query.tweetId as string
if (!tweetId) {
return res
.status(400)
.send({ error: 'missing required parameter "tweetId"' })
}
console.log('getTweetAst', tweetId)
const tweetAst = await fetchTweetAst(tweetId)
console.log('tweetAst', tweetId, tweetAst)
res.status(200).json(tweetAst)
}

View File

@@ -9,6 +9,8 @@ import BodyClassName from 'react-body-classname'
import useDarkMode from 'use-dark-mode'
import { PageBlock } from 'notion-types'
import { Tweet, Twitter } from 'react-static-tweets'
// core notion renderer
import { NotionRenderer, Code, Collection, CollectionRow } from 'react-notion-x'
@@ -57,12 +59,9 @@ const Equation = dynamic(() =>
import('react-notion-x').then((notion) => notion.Equation)
)
const Tweet = dynamic(
() => import('react-notion-x').then((notion) => notion.Tweet),
{
ssr: false
}
)
// we're now using a much lighter-weight tweet renderer react-static-tweets
// instead of the official iframe-based embed widget from twitter
// const Tweet = dynamic(() => import('react-tweet-embed'))
const Modal = dynamic(
() => import('react-notion-x').then((notion) => notion.Modal),
@@ -162,7 +161,15 @@ export const NotionPage: React.FC<types.PageProps> = ({
}
return (
<>
<Twitter.Provider
value={{
tweetAstMap: recordMap.tweetAstMap || {},
swrOptions: {
fetcher: (id) =>
fetch(`/api/get-tweet-ast/${id}`).then((r) => r.json())
}
}}
>
<PageHead site={site} />
<Head>
@@ -274,6 +281,6 @@ export const NotionPage: React.FC<types.PageProps> = ({
<GitHubShareButton />
<CustomHtml site={site} />
</>
</Twitter.Provider>
)
}

View File

@@ -2,6 +2,8 @@ import { NotionAPI } from 'notion-client'
import { ExtendedRecordMap, SearchParams, SearchResults } from 'notion-types'
import { getPreviewImages } from './get-preview-images'
import { mapNotionImageUrl } from './map-image-url'
import { fetchTweetAst, getTweetAst } from 'static-tweets'
import pMap from 'p-map'
const notion = new NotionAPI({
apiBaseUrl: process.env.NOTION_API_BASE_URL
@@ -47,6 +49,50 @@ export async function getPage(pageId: string): Promise<ExtendedRecordMap> {
const previewImageMap = await getPreviewImages(urls)
;(recordMap as any).preview_images = previewImageMap
const tweetIds: string[] = blockIds
.map((blockId) => {
const block = recordMap.block[blockId]?.value
if (block) {
if (block.type === 'tweet') {
const src = block.properties?.source?.[0]?.[0]
if (src) {
const id = src.split('?')[0].split('/').pop()
if (id) return id
}
}
}
})
.filter(Boolean)
const tweetAsts = await pMap(
tweetIds,
async (tweetId) => {
try {
return {
tweetId,
tweetAst: await fetchTweetAst(tweetId)
}
} catch (err) {
console.error('error fetching tweet info', tweetId, err)
}
},
{
concurrency: 4
}
)
const tweetAstMap = tweetAsts.filter(Boolean).reduce(
(acc, t) => ({
...acc,
[t.tweetId]: t.tweetAst
}),
{}
)
;(recordMap as any).tweetAstMap = tweetAstMap
return recordMap
}

View File

@@ -4,4 +4,8 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true'
})
module.exports = withBundleAnalyzer({})
module.exports = withBundleAnalyzer({
images: {
domains: ['pbs.twimg.com']
}
})

View File

@@ -15,8 +15,8 @@
"start": "next start",
"deploy": "vercel --prod",
"deps": "run-s deps:*",
"deps:update": "[ -z $GITHUB_ACTIONS ] && yarn add notion-client notion-types notion-utils react-notion-x || echo 'Skipping deps:update on CI'",
"deps:link": "[ -z $GITHUB_ACTIONS ] && yarn link notion-client notion-types notion-utils react-notion-x || echo 'Skipping deps:link on CI'",
"deps:update": "[ -z $GITHUB_ACTIONS ] && yarn add notion-client notion-types notion-utils react-notion-x static-tweets react-static-tweets || echo 'Skipping deps:update on CI'",
"deps:link": "[ -z $GITHUB_ACTIONS ] && yarn link notion-client notion-types notion-utils react-notion-x static-tweets react-static-tweets || echo 'Skipping deps:link on CI'",
"analyze": "cross-env ANALYZE=true next build",
"analyze:server": "cross-env BUNDLE_ANALYZE=server next build",
"analyze:browser": "cross-env BUNDLE_ANALYZE=browser next build",
@@ -47,7 +47,9 @@
"react-dom": "17.0.1",
"react-icons": "^4.1.0",
"react-notion-x": "^4.2.17",
"react-static-tweets": "^0.2.3",
"react-use": "^15.3.3",
"static-tweets": "^0.2.1",
"use-dark-mode": "^2.3.1"
},
"devDependencies": {

View File

@@ -23,6 +23,9 @@ import 'styles/notion.css'
// global style overrides for prism theme
import 'styles/prism-theme.css'
// core styles for static tweet renderer
import 'react-static-tweets/styles.css'
// here we're bringing in any languages we want to support for
// syntax highlighting via Notion's Code block
import 'prismjs'

View File

@@ -22,3 +22,16 @@ body {
.utterances {
max-width: 100% !important;
}
.static-tweet blockquote {
margin: 0;
margin-block-start: 0;
margin-block-end: 0;
margin-inline-start: 0;
margin-inline-end: 0;
}
.static-tweet-emoji {
height: 1.2em !important;
width: 1.2em !important;
}

798
yarn.lock

File diff suppressed because it is too large Load Diff