diff --git a/package.json b/package.json index 83ef30c6..b8af5cdf 100644 --- a/package.json +++ b/package.json @@ -17,6 +17,7 @@ "react-redux": "^8.0.5", "react-router-dom": "^6.5.0", "react-scripts": "5.0.1", + "react-twitter-embed": "^4.0.4", "uuid": "^9.0.0" }, "scripts": { diff --git a/public/index.html b/public/index.html index e34664d5..57dd0e50 100644 --- a/public/index.html +++ b/public/index.html @@ -8,7 +8,7 @@ + content="default-src 'self'; child-src 'none'; frame-src youtube.com www.youtube.com https://platform.twitter.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; connect-src wss://* 'self' https://*; img-src * data:; font-src https://fonts.gstatic.com; media-src *; script-src 'self' https://static.cloudflareinsights.com https://platform.twitter.com;" /> diff --git a/src/Const.js b/src/Const.js index 5a9292e4..7bba48f7 100644 --- a/src/Const.js +++ b/src/Const.js @@ -63,6 +63,11 @@ export const InvoiceRegex = /(lnbc\w+)/i; */ export const YoutubeUrlRegex = /(?:https?:\/\/)?(?:www|m\.)?(?:youtu\.be\/|youtube\.com\/(?:shorts\/|embed\/|v\/|watch\?v=|watch\?.+&v=))((\w|-){11})/; +/** + * Tweet Regex + */ +export const TweetUrlRegex = /https?:\/\/twitter\.com\/(?:#!\/)?(\w+)\/status(?:es)?\/(\d+)/ + /** * Hashtag regex */ diff --git a/src/Text.js b/src/Text.js index 9887bac7..883d5cbd 100644 --- a/src/Text.js +++ b/src/Text.js @@ -1,7 +1,8 @@ import { Link } from "react-router-dom"; +import { TwitterTweetEmbed } from "react-twitter-embed"; import Invoice from "./element/Invoice"; -import { UrlRegex, FileExtensionRegex, MentionRegex, InvoiceRegex, YoutubeUrlRegex, HashtagRegex } from "./Const"; +import { UrlRegex, FileExtensionRegex, MentionRegex, InvoiceRegex, YoutubeUrlRegex, TweetUrlRegex, HashtagRegex } from "./Const"; import { eventLink, hexToBech32, profileLink } from "./Util"; import LazyImage from "./element/LazyImage"; import Hashtag from "./element/Hashtag"; @@ -10,6 +11,7 @@ function transformHttpLink(a) { try { const url = new URL(a); const youtubeId = YoutubeUrlRegex.test(a) && RegExp.$1; + const tweetId = TweetUrlRegex.test(a) && RegExp.$2; const extension = FileExtensionRegex.test(url.pathname.toLowerCase()) && RegExp.$1; if (extension) { switch (extension) { @@ -31,6 +33,12 @@ function transformHttpLink(a) { default: return e.stopPropagation()}>{url.toString()} } + } else if (tweetId) { + return ( +
+ +
+ ) } else if (youtubeId) { return ( <> diff --git a/src/index.css b/src/index.css index 06162afb..b6fb1686 100644 --- a/src/index.css +++ b/src/index.css @@ -299,3 +299,21 @@ body.scroll-lock { .root-tab.active { border-bottom: 3px solid var(--highlight); } + +.tweet { + display: flex; + align-items: center; + justify-content: center; +} + +.tweet div { + width: 100%; +} + +.tweet div .twitter-tweet { + margin: 0 auto; +} + +.tweet div .twitter-tweet > iframe { + max-height: unset; +} diff --git a/yarn.lock b/yarn.lock index 900e9544..7605ca97 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7329,6 +7329,13 @@ react-scripts@5.0.1: optionalDependencies: fsevents "^2.3.2" +react-twitter-embed@^4.0.4: + version "4.0.4" + resolved "https://registry.yarnpkg.com/react-twitter-embed/-/react-twitter-embed-4.0.4.tgz#4a6b8354acc266876ff1110b9f648518ea20db6d" + integrity sha512-2JIL7qF+U62zRzpsh6SZDXNI3hRNVYf5vOZ1WRcMvwKouw+xC00PuFaD0aEp2wlyGaZ+f4x2VvX+uDadFQ3HVA== + dependencies: + scriptjs "^2.5.9" + react@^18.2.0: version "18.2.0" resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5" @@ -7679,6 +7686,11 @@ schema-utils@^4.0.0: ajv-formats "^2.1.1" ajv-keywords "^5.0.0" +scriptjs@^2.5.9: + version "2.5.9" + resolved "https://registry.yarnpkg.com/scriptjs/-/scriptjs-2.5.9.tgz#343915cd2ec2ed9bfdde2b9875cd28f59394b35f" + integrity sha512-qGVDoreyYiP1pkQnbnFAUIS5AjenNwwQBdl7zeos9etl+hYKWahjRTfzAZZYBv5xNHx7vNKCmaLDQZ6Fr2AEXg== + select-hose@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca"