diff --git a/site/components/Paragraph.js b/site/components/Paragraph.js index 3940a5d..c3e985d 100644 --- a/site/components/Paragraph.js +++ b/site/components/Paragraph.js @@ -1,15 +1,21 @@ import LiteYouTubeEmbed from "react-lite-youtube-embed"; -import { YOUTUBE_REGEX } from "../lib/constants"; +import TwitterEmbed from "./TwitterEmbed"; +import { YOUTUBE_REGEX, TWITTER_REGEX } from "../lib/constants"; export const Paragraph = (props) => { if ( typeof props.children == "object" && props.children.props && - props.children.props.href && - YOUTUBE_REGEX.test(props.children.props.href) + props.children.props.href ) { - const youtubeId = props.children.props.href.split(/^|=|\//).pop(); - return ; + if (YOUTUBE_REGEX.test(props.children.props.href)) { + const youtubeId = props.children.props.href.split(/^|=|\//).pop(); + return ; + } + + if (TWITTER_REGEX.test(props.children.props.href)) { + return ; + } } return

; }; diff --git a/site/components/TwitterEmbed.js b/site/components/TwitterEmbed.js new file mode 100644 index 0000000..6f35ffd --- /dev/null +++ b/site/components/TwitterEmbed.js @@ -0,0 +1,98 @@ +import { useEffect, useState, useRef } from "react"; + +const twitterWidgetJs = "https://platform.twitter.com/widgets.js"; +const message = "Loading tweet..."; + +export default function TwitterEmbed({ url, ...props }) { + let ref = useRef(null); + const [state, setState] = useState({ + isLoading: true, + message: message, + }); + + const tweetId = url.split("status/").pop(); + + const renderTweet = () => { + window.twttr.widgets + .createTweet(tweetId, ref.current, { + theme: "dark", + }) + .then((el) => { + if (el) return setState((prev) => ({ ...prev, isLoading: false })); + return setState((prev) => ({ + ...prev, + message: null + })); + }); + return window.twttr.widgets.load(ref.current); + }; + + useEffect(() => { + let componentMounted = true; + + const script = document.createElement("script"); + script.src = twitterWidgetJs; + script.async = true; + script.onload = () => renderTweet(); + + if (componentMounted) { + if (!window.twttr) { + document.head.appendChild(script); + } else { + renderTweet(); + } + } + + return () => { + setState({ isLoading: true, message: message }); + componentMounted = false; + }; + }, []); + + return ( + <> + {state.isLoading && state.message && ( +

+
+ + Twitter + + +
+ {state.message} +
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ )} +
+ {!state.message &&

} + + ); +} diff --git a/site/content/test.md b/site/content/test.md index adcf563..2ceb017 100644 --- a/site/content/test.md +++ b/site/content/test.md @@ -2,11 +2,24 @@ title: Test frontmatter in markdown created: 2022-04-26 date: 2022-04-26 -description: 'In this test episode with somebody about their work to make community finance transparent and sustainable with Open Collective, their commitment ot steward ownership and the value of an exit to community.' +description: 'This description is from the frontmatter field.' youtube: https://youtube.com/ featured: false --- +*** + +## Test twitter embeds in markdown + +*eg. if this twitter link https://twitter.com/rufuspollock/status/1524012242777395201 is on a separate line, then it will be rendered as seen below* + +https://twitter.com/rufuspollock/status/1524012242777395201 + +*tweets that have been deleted or are private would show the link instead as seen below* + +https://twitter.com/polka_ether_up/status/1524052691692908544 + +*** ## Test (Obsidian) wiki link syntax @@ -30,7 +43,6 @@ featured: false *`[[#Our Approach]]`* [[#Our Approach]] - *** ## Test video embed links in markdown diff --git a/site/lib/constants.js b/site/lib/constants.js index 2ebe063..7df911b 100644 --- a/site/lib/constants.js +++ b/site/lib/constants.js @@ -1,2 +1,3 @@ -export const YOUTUBE_REGEX = - /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; +export const YOUTUBE_REGEX = /^.*((youtu.be\/)|(v\/)|(\/u\/\w\/)|(embed\/)|(watch\?))\??v?=?([^#\&\?]*).*/; + +export const TWITTER_REGEX = /^https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(es)?\/(\d+)/; diff --git a/site/public/img/a-macro-economics-thumbnail.png b/site/public/img/a-macro-economics-thumbnail.png index 40d63a6..9a11765 100644 Binary files a/site/public/img/a-macro-economics-thumbnail.png and b/site/public/img/a-macro-economics-thumbnail.png differ diff --git a/site/public/img/anti-auth-thumbnail.png b/site/public/img/anti-auth-thumbnail.png index 1043f07..6c3af6c 100644 Binary files a/site/public/img/anti-auth-thumbnail.png and b/site/public/img/anti-auth-thumbnail.png differ diff --git a/site/public/img/klima-one-thumbnail.png b/site/public/img/klima-one-thumbnail.png index bc12af8..0754ee8 100644 Binary files a/site/public/img/klima-one-thumbnail.png and b/site/public/img/klima-one-thumbnail.png differ diff --git a/site/styles/global.css b/site/styles/global.css index 357cc57..7ebb796 100644 --- a/site/styles/global.css +++ b/site/styles/global.css @@ -8,6 +8,10 @@ h1, h2, h3, h4, h5 { @apply font-sans; } + + .twitter-tweet iframe { + @apply !border !border-2 !border-neutral-900 !rounded-2xl !bg-neutral-900 shadow; + } } /* OTHERS */