vue-tweet
Version:
Embed tweets just by giving the ID of a Tweet
182 lines (181 loc) • 6.85 kB
JavaScript
import { defineComponent as B, ref as _, onMounted as O, onUnmounted as U, watch as $, toRef as x, nextTick as F, createElementBlock as N, openBlock as P, Fragment as V, renderSlot as E, createCommentVNode as W, createElementVNode as j, mergeProps as z } from "vue";
const D = /* @__PURE__ */ B({
__name: "vue-tweet",
props: {
tweetId: {
type: String,
default: ""
},
tweetUrl: {
type: String,
default: ""
},
conversation: {
type: String,
default: "all",
validator: (i) => ["all", "none"].includes(i)
},
cards: {
type: String,
default: "visible",
validator: (i) => ["visible", "hidden"].includes(i)
},
width: {
type: [String, Number],
default: "auto",
validator: (i) => typeof i == "string" ? i === "auto" : typeof i == "number" ? i >= 250 && i <= 550 : !1
},
align: {
type: [String, void 0],
default: void 0,
validator: (i) => ["left", "right", "center", void 0].includes(i)
},
theme: {
type: String,
default: "system",
validator: (i) => ["light", "dark", "system"].includes(i)
},
lang: {
type: String,
default: "en"
},
dnt: {
type: Boolean,
default: !1
}
},
emits: ["tweet-load-success", "tweet-load-error"],
setup(i, { emit: T }) {
const u = i, m = T, w = _(!0), s = _(!1), f = _(), g = _("light"), o = _(!1), h = _(!0);
function I() {
return u.theme === "system" ? g.value : u.theme;
}
function S() {
typeof window < "u" && window.matchMedia && (g.value = window.matchMedia("(prefers-color-scheme: dark)").matches ? "dark" : "light");
}
let p = null, r = null;
const e = {
loaded: !1,
loading: !1,
element: null
};
function k() {
if (typeof window > "u") return;
window.___$twitterScriptLoaded___ && (e.loaded = !0), window.___$twitterScriptLoading___ && (e.loading = !0);
const t = document.getElementById("twitter-widgets-script");
t && (e.element = t, window.twttr && window.twttr.ready && (e.loaded = !0, e.loading = !1, window.___$twitterScriptLoaded___ === void 0 && (window.___$twitterScriptLoaded___ = !0), window.___$twitterScriptLoading___ === void 0 && (window.___$twitterScriptLoading___ = !1)));
}
O(() => {
k(), S(), typeof window < "u" && window.matchMedia && (p = window.matchMedia("(prefers-color-scheme: dark)"), p.addEventListener("change", S)), h.value = !1, y();
}), U(() => {
p && p.removeEventListener("change", S), r && (clearInterval(r), r = null), o.value = !1, h.value = !0;
}), $(x(u), y, {
deep: !0
}), $(g, () => {
u.theme === "system" && !h.value && y();
});
function y() {
if (!o.value) {
if (r && (clearInterval(r), r = null), (window.___$twitterScriptLoaded___ || e.loaded) && window.twttr && window.twttr.ready) {
v();
return;
}
if (window.twttr && window.twttr.ready) {
v();
return;
}
if (window.___$twitterScriptLoading___ || e.loading) {
r = setInterval(() => {
(window.___$twitterScriptLoaded___ || e.loaded) && window.twttr && window.twttr.ready && (r && (clearInterval(r), r = null), v());
}, 100);
return;
}
R("https://platform.twitter.com/widgets.js", v);
}
}
function v() {
if (!o.value) {
if (o.value = !0, !window.twttr || !window.twttr.ready) {
console.error("Twitter widget not available"), s.value = !0, w.value = !1, o.value = !1;
return;
}
window.twttr.ready().then(({ widgets: t }) => {
if (w.value = !0, s.value = !1, f.value)
f.value.innerHTML = "";
else {
console.error("tweetContainerRef is null"), o.value = !1;
return;
}
const { tweetId: n, tweetOptions: c } = C();
t.createTweet(n, f.value, c).then(async (a) => {
await F(), a ? m("tweet-load-success", a) : (s.value = !0, m("tweet-load-error", new Error("Failed to load tweet.")));
}).finally(() => {
w.value = !1, o.value = !1;
});
}).catch((t) => {
console.error("Error loading Twitter widget:", t), s.value = !0, o.value = !1;
}).finally(() => {
w.value = !1, o.value = !1;
});
}
}
function C() {
let { tweetId: t, tweetUrl: n, theme: c, ...a } = u;
const d = I(), M = { ...a, theme: d };
let l = null;
if (t && n)
l = new Error("Cannot provide both tweet-id and tweet-url.");
else if (t)
/^\d+$/.test(t) || (l = new Error(
"Invalid tweet-id, please provide a valid numerical tweet-id."
));
else if (n) {
const b = /^(https?:\/\/)?(www\.)?(twitter|x)\.com\/.*\/status(?:es)?\/([^/?]\d+)$/i, L = n.trim().match(b);
L && L[4] ? t = L[4] : l = new Error("Invalid tweet-url.");
} else
l = new Error("Must provide either tweet-id or tweet-url.");
if (l)
throw s.value = !0, w.value = !1, m("tweet-load-error", l), l;
return {
tweetId: t,
tweetOptions: M
};
}
function R(t, n) {
const c = "twitter-widgets-script";
if (window.___$twitterScriptLoaded___ === void 0 && (window.___$twitterScriptLoaded___ = e.loaded), window.___$twitterScriptLoading___ === void 0 && (window.___$twitterScriptLoading___ = e.loading), window.___$twitterScriptLoaded___ || e.loaded) {
n();
return;
}
const a = document.getElementById(c);
if (a) {
if (e.element = a, window.___$twitterScriptLoaded___ || e.loaded) {
n();
return;
}
if (window.___$twitterScriptLoading___ || e.loading)
return;
}
if (window.___$twitterScriptLoading___ || e.loading)
return;
window.___$twitterScriptLoading___ = !0, e.loading = !0;
const d = document.createElement("script");
d.id = c, d.setAttribute("src", t), d.async = !0, d.addEventListener("load", () => {
window.___$twitterScriptLoaded___ = !0, window.___$twitterScriptLoading___ = !1, e.loaded = !0, e.loading = !1, n();
}, !1), d.addEventListener("error", () => {
window.___$twitterScriptLoading___ = !1, e.loading = !1, console.error("Failed to load Twitter widgets script");
}, !1), e.element = d, document.body.appendChild(d);
}
return (t, n) => (P(), N(V, null, [
s.value ? E(t.$slots, "error", { key: 0 }) : w.value ? E(t.$slots, "loading", { key: 1 }) : W("", !0),
j("div", z({
ref_key: "tweetContainerRef",
ref: f
}, t.$attrs), null, 16)
], 64));
}
});
export {
D as VueTweet,
D as default
};