[site/components][md]: refactor twitter embed component and modify styles for mobile
This commit is contained in:
parent
f2b08a248c
commit
007742af23
|
|
@ -1,65 +1,64 @@
|
||||||
import { useEffect, useState, useRef } from "react";
|
import { useEffect, useState, useRef } from "react";
|
||||||
|
|
||||||
const twitterWidgetJs = "https://platform.twitter.com/widgets.js";
|
const twitterWidgetJs = "https://platform.twitter.com/widgets.js";
|
||||||
const message = "Loading tweet..."
|
const message = "Loading tweet...";
|
||||||
|
|
||||||
export default function TwitterEmbed({ url }) {
|
export default function TwitterEmbed({ url, ...props }) {
|
||||||
let ref = useRef(null)
|
let ref = useRef(null);
|
||||||
const [state, setState] = useState({
|
const [state, setState] = useState({
|
||||||
isLoading: true,
|
isLoading: true,
|
||||||
message: message
|
message: message,
|
||||||
})
|
});
|
||||||
|
|
||||||
const tweetId = url.split("status/").pop()
|
|
||||||
|
|
||||||
var callbacks = [];
|
const tweetId = url.split("status/").pop();
|
||||||
|
|
||||||
const loadScript = (src, cb) => {
|
const renderTweet = () => {
|
||||||
if (callbacks.length === 0) {
|
window.twttr.widgets
|
||||||
callbacks.push(cb);
|
.createTweet(tweetId, ref.current, {
|
||||||
var s = document.createElement("script");
|
theme: "dark",
|
||||||
s.setAttribute("src", src);
|
})
|
||||||
s.setAttribute("async", "true");
|
.then((el) => {
|
||||||
s.onload = () => callbacks.forEach((cb) => cb());
|
if (el) return setState((prev) => ({ ...prev, isLoading: false }));
|
||||||
document.head.appendChild(s);
|
return setState((prev) => ({
|
||||||
} else {
|
...prev,
|
||||||
callbacks.push(cb);
|
message: null
|
||||||
}
|
}));
|
||||||
}
|
});
|
||||||
|
return window.twttr.widgets.load(ref.current);
|
||||||
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!ref.current) return;
|
let componentMounted = true;
|
||||||
|
|
||||||
const renderTweet = () => {
|
const script = document.createElement("script");
|
||||||
window.twttr.widgets.createTweet(tweetId, ref.current, {
|
script.src = twitterWidgetJs;
|
||||||
theme: "dark"
|
script.async = true;
|
||||||
}).then((el) => {
|
script.onload = () => renderTweet();
|
||||||
if (el) return setState(prev => ({ ...prev, isLoading: false }))
|
|
||||||
return setState(prev => ({ ...prev, message: "Sorry, this tweet could not be found." }))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!window.twttr) {
|
if (componentMounted) {
|
||||||
loadScript(twitterWidgetJs, renderTweet)
|
if (!window.twttr) {
|
||||||
} else {
|
document.head.appendChild(script);
|
||||||
renderTweet()
|
} else {
|
||||||
|
renderTweet();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
setState(prev => ({ ...prev, isLoading: true }));
|
setState({ isLoading: true, message: message });
|
||||||
|
componentMounted = false;
|
||||||
};
|
};
|
||||||
},[]);
|
}, []);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
{state.isLoading && (
|
{state.isLoading && state.message && (
|
||||||
<div className="relative my-4 w-full sm:max-w-lg bg-neutral-900 drop-shadow-md rounded-lg ">
|
<div className="relative my-4 w-full sm:max-w-xl bg-neutral-900 drop-shadow-md rounded-lg">
|
||||||
<div className="absolute flex flex-col items-center justify-center bg-slate-700/60 w-full h-full rounded-lg top-0 left-0 z-10">
|
<div className="absolute flex flex-col flex-wrap break-all items-center justify-center bg-slate-700/60 w-full h-full px-4 py-2 rounded-lg top-0 left-0 z-10">
|
||||||
<svg
|
<svg
|
||||||
role="img"
|
role="img"
|
||||||
viewBox="0 0 24 24"
|
viewBox="0 0 24 24"
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
className="w-10"
|
className="w-6 absolute right-4 top-4"
|
||||||
>
|
>
|
||||||
<title>Twitter</title>
|
<title>Twitter</title>
|
||||||
<path
|
<path
|
||||||
|
|
@ -67,7 +66,9 @@ export default function TwitterEmbed({ url }) {
|
||||||
d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"
|
d="M23.953 4.57a10 10 0 01-2.825.775 4.958 4.958 0 002.163-2.723c-.951.555-2.005.959-3.127 1.184a4.92 4.92 0 00-8.384 4.482C7.69 8.095 4.067 6.13 1.64 3.162a4.822 4.822 0 00-.666 2.475c0 1.71.87 3.213 2.188 4.096a4.904 4.904 0 01-2.228-.616v.06a4.923 4.923 0 003.946 4.827 4.996 4.996 0 01-2.212.085 4.936 4.936 0 004.604 3.417 9.867 9.867 0 01-6.102 2.105c-.39 0-.779-.023-1.17-.067a13.995 13.995 0 007.557 2.209c9.053 0 13.998-7.496 13.998-13.985 0-.21 0-.42-.015-.63A9.935 9.935 0 0024 4.59z"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<p className="text-gray-300 font-bold my-2">{state.message}</p>
|
<div className="text-gray-300 font-bold my-2 italic">
|
||||||
|
{state.message}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
className={`p-3 space-y-4 ${
|
className={`p-3 space-y-4 ${
|
||||||
|
|
@ -82,7 +83,6 @@ export default function TwitterEmbed({ url }) {
|
||||||
<div className="w-2/3 h-3 bg-slate-700"></div>
|
<div className="w-2/3 h-3 bg-slate-700"></div>
|
||||||
<div className="w-2/3 h-3 bg-slate-700"></div>
|
<div className="w-2/3 h-3 bg-slate-700"></div>
|
||||||
</div>
|
</div>
|
||||||
<div className="w-2/3 h-20 rounded bg-slate-700"></div>
|
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<div className="w-1/4 h-3 bg-slate-700"></div>
|
<div className="w-1/4 h-3 bg-slate-700"></div>
|
||||||
<div className="w-1/4 h-3 bg-slate-700"></div>
|
<div className="w-1/4 h-3 bg-slate-700"></div>
|
||||||
|
|
@ -92,6 +92,7 @@ export default function TwitterEmbed({ url }) {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
<div className="twitter-tweet" ref={ref} />
|
<div className="twitter-tweet" ref={ref} />
|
||||||
|
{!state.message && <p {...props} />}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue