vue-tweet-pure
Version:
A Vue 3 component for embedding tweets in your Vue.js applications.
1,115 lines (1,114 loc) • 36.6 kB
JavaScript
import { defineComponent as d, useAttrs as H, openBlock as i, createElementBlock as u, normalizeClass as n, unref as a, createElementVNode as l, renderSlot as W, createBlock as h, withCtx as B, mergeProps as A, createStaticVNode as N, withModifiers as Y, useCssModule as Q, computed as T, resolveDynamicComponent as q, createCommentVNode as g, createVNode as f, toDisplayString as $, Fragment as M, renderList as S, ref as k, normalizeStyle as G, createTextVNode as K, watch as J, onBeforeUnmount as ee, onMounted as U, resolveComponent as te } from "vue";
import { T as se } from "./fetch-tweet-CzGg1NgE.js";
const oe = /* @__PURE__ */ d({
__name: "tweet-container",
setup(t) {
const o = H();
return (e, s) => (i(), u("div", {
class: n(["vue-tweet-theme", e.$style.root, a(o).class])
}, [
l("article", {
class: n(e.$style.article)
}, [
W(e.$slots, "default")
], 2)
], 2));
}
}), ne = "JrPdna_article", re = "JrPdna_root", ae = {
article: ne,
root: re
}, m = (t, o) => {
const e = t.__vccOpts || t;
for (const [s, c] of o)
e[s] = c;
return e;
}, le = {
$style: ae
}, V = /* @__PURE__ */ m(oe, [["__cssModules", le]]), ie = /* @__PURE__ */ d({
__name: "tweet-not-found",
props: {
error: {}
},
setup(t) {
return (o, e) => (i(), h(V, null, {
default: B(() => [
l("div", {
class: n(o.$style.root)
}, e[0] || (e[0] = [
l("h3", null, "Tweet not found", -1),
l("p", null, "The embedded tweet could not be found…", -1)
]), 2)
]),
_: 1
}));
}
}), ce = "nN86_W_root", ue = {
root: ce
}, de = {
$style: ue
}, pe = /* @__PURE__ */ m(ie, [["__cssModules", de]]), _e = ["src", "alt", "width", "height"], O = /* @__PURE__ */ d({
__name: "avatar-img",
props: {
src: {},
alt: {},
width: {},
height: {}
},
setup(t) {
return (o, e) => (i(), u("img", {
src: o.src,
alt: o.alt,
width: o.width,
height: o.height
}, null, 8, _e));
}
}), fe = ["src", "alt", "draggable"], X = /* @__PURE__ */ d({
__name: "media-img",
props: {
src: {},
alt: {},
draggable: { type: Boolean }
},
setup(t) {
return (o, e) => (i(), u("img", A(o.$attrs, {
src: o.src,
alt: o.alt,
draggable: o.draggable
}), null, 16, fe));
}
}), me = {
TweetNotFound: pe,
AvatarImg: O,
MediaImg: X
}, he = "_81i5Cq_verified", z = {
verified: he
}, ye = /* @__PURE__ */ d({
__name: "verified",
setup(t) {
return (o, e) => (i(), u("svg", {
viewBox: "0 0 24 24",
"aria-label": "Verified account",
role: "img",
class: n(a(z).verified)
}, e[0] || (e[0] = [
l("g", null, [
l("path", { d: "M22.25 12c0-1.43-.88-2.67-2.19-3.34.46-1.39.2-2.9-.81-3.91s-2.52-1.27-3.91-.81c-.66-1.31-1.91-2.19-3.34-2.19s-2.67.88-3.33 2.19c-1.4-.46-2.91-.2-3.92.81s-1.26 2.52-.8 3.91c-1.31.67-2.2 1.91-2.2 3.34s.89 2.67 2.2 3.34c-.46 1.39-.21 2.9.8 3.91s2.52 1.26 3.91.81c.67 1.31 1.91 2.19 3.34 2.19s2.68-.88 3.34-2.19c1.39.45 2.9.2 3.91-.81s1.27-2.52.81-3.91c1.31-.67 2.19-1.91 2.19-3.34zm-11.71 4.2L6.8 12.46l1.41-1.42 2.26 2.26 4.8-5.23 1.47 1.36-6.2 6.77z" })
], -1)
]), 2));
}
}), we = /* @__PURE__ */ d({
__name: "verified-business",
setup(t) {
return (o, e) => (i(), u("svg", {
viewBox: "0 0 22 22",
"aria-label": "Verified account",
role: "img",
class: n(a(z).verified)
}, e[0] || (e[0] = [
N('<g><linearGradient id="0-a" gradientUnits="userSpaceOnUse" x1="4.411" x2="18.083" y1="2.495" y2="21.508"><stop offset="0" stop-color="#f4e72a"></stop><stop offset=".539" stop-color="#cd8105"></stop><stop offset=".68" stop-color="#cb7b00"></stop><stop offset="1" stop-color="#f4ec26"></stop><stop offset="1" stop-color="#f4e72a"></stop></linearGradient><linearGradient id="0-b" gradientUnits="userSpaceOnUse" x1="5.355" x2="16.361" y1="3.395" y2="19.133"><stop offset="0" stop-color="#f9e87f"></stop><stop offset=".406" stop-color="#e2b719"></stop><stop offset=".989" stop-color="#e2b719"></stop></linearGradient><g clip-rule="evenodd" fill-rule="evenodd"><path d="M13.324 3.848L11 1.6 8.676 3.848l-3.201-.453-.559 3.184L2.06 8.095 3.48 11l-1.42 2.904 2.856 1.516.559 3.184 3.201-.452L11 20.4l2.324-2.248 3.201.452.559-3.184 2.856-1.516L18.52 11l1.42-2.905-2.856-1.516-.559-3.184zm-7.09 7.575l3.428 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z" fill="url(#0-a)"></path><path d="M13.101 4.533L11 2.5 8.899 4.533l-2.895-.41-.505 2.88-2.583 1.37L4.2 11l-1.284 2.627 2.583 1.37.505 2.88 2.895-.41L11 19.5l2.101-2.033 2.895.41.505-2.88 2.583-1.37L17.8 11l1.284-2.627-2.583-1.37-.505-2.88zm-6.868 6.89l3.429 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z" fill="url(#0-b)"></path><path d="M6.233 11.423l3.429 3.428 5.65-6.17.038-.033-.005 1.398-5.683 6.206-3.429-3.429-.003-1.405.005.003z" fill="#d18800"></path></g></g>', 1)
]), 2));
}
}), ve = /* @__PURE__ */ d({
__name: "verified-government",
setup(t) {
return (o, e) => (i(), u("svg", {
viewBox: "0 0 22 22",
"aria-label": "Verified account",
role: "img",
class: n(a(z).verified)
}, e[0] || (e[0] = [
l("g", null, [
l("path", {
"clip-rule": "evenodd",
d: "M12.05 2.056c-.568-.608-1.532-.608-2.1 0l-1.393 1.49c-.284.303-.685.47-1.1.455L5.42 3.932c-.832-.028-1.514.654-1.486 1.486l.069 2.039c.014.415-.152.816-.456 1.1l-1.49 1.392c-.608.568-.608 1.533 0 2.101l1.49 1.393c.304.284.47.684.456 1.1l-.07 2.038c-.027.832.655 1.514 1.487 1.486l2.038-.069c.415-.014.816.152 1.1.455l1.392 1.49c.569.609 1.533.609 2.102 0l1.393-1.49c.283-.303.684-.47 1.099-.455l2.038.069c.832.028 1.515-.654 1.486-1.486L18 14.542c-.015-.415.152-.815.455-1.099l1.49-1.393c.608-.568.608-1.533 0-2.101l-1.49-1.393c-.303-.283-.47-.684-.455-1.1l.068-2.038c.029-.832-.654-1.514-1.486-1.486l-2.038.07c-.415.013-.816-.153-1.1-.456zm-5.817 9.367l3.429 3.428 5.683-6.206-1.347-1.247-4.4 4.795-2.072-2.072z",
"fill-rule": "evenodd"
})
], -1)
]), 2));
}
}), $e = /* @__PURE__ */ d({
__name: "quoted-tweet-container",
props: {
tweet: {}
},
setup(t) {
const o = (e) => {
window.open(e, "_blank");
};
return (e, s) => (i(), u("div", {
class: n(e.$style.root),
onClick: s[0] || (s[0] = Y((c) => o(e.tweet.url), ["prevent"]))
}, [
l("article", {
class: n(e.$style.article)
}, [
W(e.$slots, "default")
], 2)
], 2));
}
}), ge = "RsfEUq_article", ke = "RsfEUq_root", be = {
article: ge,
root: ke
}, Te = {
$style: be
}, Me = /* @__PURE__ */ m($e, [["__cssModules", Te]]), Ie = /* @__PURE__ */ d({
__name: "verified-badge",
props: {
user: {}
},
setup(t) {
const o = Q(), e = H(), s = t, c = T(
() => s.user.verified || s.user.is_blue_verified || s.user.verified_type
), r = T(() => c.value ? s.user.verified_type === "Government" ? ve : s.user.verified_type === "Business" ? we : ye : null), p = T(() => c.value ? s.user.verified_type === "Government" ? o.verifiedGovernment : s.user.verified_type === "Business" ? null : s.user.is_blue_verified ? o.verifiedBlue : o.verifiedOld : null);
return (_, R) => c.value ? (i(), u("div", {
key: 0,
class: n([a(e).class, p.value])
}, [
(i(), h(q(r.value)))
], 2)) : g("", !0);
}
}), Be = "dT-upq_verifiedBlue", Re = "dT-upq_verifiedGovernment", Le = "dT-upq_verifiedOld", qe = {
verifiedBlue: Be,
verifiedGovernment: Re,
verifiedOld: Le
}, Ge = {
$style: qe
}, F = /* @__PURE__ */ m(Ie, [["__cssModules", Ge]]), Ce = ["href"], We = ["title"], Se = ["title"], Ve = /* @__PURE__ */ d({
__name: "quoted-tweet-header",
props: {
tweet: {}
},
setup(t) {
const o = t, { user: e } = o.tweet;
return (s, c) => (i(), u("div", {
class: n(s.$style.header)
}, [
l("a", {
href: s.tweet.url,
class: n(s.$style.avatar),
target: "_blank",
rel: "noopener noreferrer"
}, [
l("div", {
class: n([
s.$style.avatarOverflow,
{ [s.$style.avatarSquare]: a(e).profile_image_shape === "Square" }
])
}, [
f(O, {
src: a(e).profile_image_url_https,
alt: a(e).name,
width: 20,
height: 20
}, null, 8, ["src", "alt"])
], 2)
], 10, Ce),
l("div", {
class: n(s.$style.author)
}, [
l("div", {
class: n(s.$style.authorText)
}, [
l("span", {
title: a(e).name
}, $(a(e).name), 9, We)
], 2),
f(F, { user: a(e) }, null, 8, ["user"]),
l("div", {
class: n(s.$style.username)
}, [
l("span", {
title: `@${a(e).screen_name}`
}, "@" + $(a(e).screen_name), 9, Se)
], 2)
], 2)
], 2));
}
}), Oe = "_2tBG3G_author", ze = "_2tBG3G_authorText", De = "_2tBG3G_avatar", je = "_2tBG3G_avatarSquare", He = "_2tBG3G_header", Ue = "_2tBG3G_username", Xe = {
author: Oe,
authorText: ze,
avatar: De,
avatarSquare: je,
header: He,
username: Ue
}, Fe = {
$style: Xe
}, Ze = /* @__PURE__ */ m(Ve, [["__cssModules", Fe]]), xe = ["lang"], Ee = ["innerHTML"], Pe = /* @__PURE__ */ d({
__name: "quoted-tweet-body",
props: {
tweet: {}
},
setup(t) {
return (o, e) => (i(), u("p", {
class: n(o.$style.root),
lang: o.tweet.lang,
dir: "auto"
}, [
(i(!0), u(M, null, S(o.tweet.entities, (s, c) => (i(), u("span", {
key: c,
innerHTML: s.text
}, null, 8, Ee))), 128))
], 10, xe));
}
}), Ae = "_3hXyqa_root", Ne = {
root: Ae
}, Ye = {
$style: Ne
}, Qe = /* @__PURE__ */ m(Pe, [["__cssModules", Ye]]), D = (t) => `https://x.com/${t.user.screen_name}/status/${t.id_str}`, Z = (t) => `https://x.com/${typeof t == "string" ? t : t.user.screen_name}`, Ke = (t) => `https://x.com/intent/like?tweet_id=${t.id_str}`, Je = (t) => `https://x.com/intent/tweet?in_reply_to=${t.id_str}`, et = (t) => `https://x.com/intent/follow?screen_name=${t.user.screen_name}`, tt = (t) => `https://x.com/hashtag/${t.text}`, st = (t) => `https://x.com/search?q=%24${t.text}`, ot = (t) => `https://x.com/${t.in_reply_to_screen_name}/status/${t.in_reply_to_status_id_str}`, x = (t, o) => {
const e = new URL(t.media_url_https), s = e.pathname.split(".").pop();
return s ? (e.pathname = e.pathname.replace(`.${s}`, ""), e.searchParams.set("format", s), e.searchParams.set("name", o), e.toString()) : t.media_url_https;
}, nt = (t) => {
const { variants: o } = t.video_info;
return o.filter((s) => s.content_type === "video/mp4").sort((s, c) => (c.bitrate ?? 0) - (s.bitrate ?? 0));
}, rt = (t) => {
const o = nt(t);
return o.length > 1 ? o[1] : o[0];
}, C = (t) => t > 999999 ? `${(t / 1e6).toFixed(1)}M` : t > 999 ? `${(t / 1e3).toFixed(1)}K` : t.toString();
function j(t) {
const o = Array.from(t.text), e = [{ indices: t.display_text_range, type: "text" }];
return I(e, "hashtag", t.entities.hashtags), I(e, "mention", t.entities.user_mentions), I(e, "url", t.entities.urls), I(e, "symbol", t.entities.symbols), t.entities.media && I(e, "media", t.entities.media), at(t, e), e.map((s) => {
const c = o.slice(s.indices[0], s.indices[1]).join("");
switch (s.type) {
case "hashtag":
return Object.assign(s, { href: tt(s), text: c });
case "mention":
return Object.assign(s, {
href: Z(s.screen_name),
text: c
});
case "url":
case "media":
return Object.assign(s, {
href: s.expanded_url,
text: s.display_url
});
case "symbol":
return Object.assign(s, { href: st(s), text: c });
default:
return Object.assign(s, { text: c });
}
});
}
function I(t, o, e) {
for (const s of e)
for (const [c, r] of t.entries()) {
if (r.indices[0] > s.indices[0] || r.indices[1] < s.indices[1])
continue;
const p = [{ ...s, type: o }];
r.indices[0] < s.indices[0] && p.unshift({
indices: [r.indices[0], s.indices[0]],
type: "text"
}), r.indices[1] > s.indices[1] && p.push({
indices: [s.indices[1], r.indices[1]],
type: "text"
}), t.splice(c, 1, ...p);
break;
}
}
function at(t, o) {
t.entities.media && t.entities.media[0].indices[0] < t.display_text_range[1] && (t.display_text_range[1] = t.entities.media[0].indices[0]);
const e = o.at(-1);
e && e.indices[1] > t.display_text_range[1] && (e.indices[1] = t.display_text_range[1]);
}
const lt = (t) => ({
...t,
url: D(t),
user: {
...t.user,
url: Z(t),
follow_url: et(t)
},
like_url: Ke(t),
reply_url: Je(t),
in_reply_to_url: t.in_reply_to_screen_name ? ot(t) : void 0,
entities: j(t),
quoted_tweet: t.quoted_tweet ? {
...t.quoted_tweet,
url: D(t.quoted_tweet),
entities: j(t.quoted_tweet)
} : void 0
}), it = "nYjDHW_grid2Columns", ct = "nYjDHW_grid2x2", ut = "nYjDHW_grid3", dt = "nYjDHW_image", pt = "nYjDHW_mediaContainer", _t = "nYjDHW_mediaLink", ft = "nYjDHW_mediaWrapper", mt = "nYjDHW_root", ht = "nYjDHW_rounded", yt = "nYjDHW_skeleton", w = {
grid2Columns: it,
grid2x2: ct,
grid3: ut,
image: dt,
mediaContainer: pt,
mediaLink: _t,
mediaWrapper: ft,
root: mt,
rounded: ht,
skeleton: yt
}, wt = ["poster", "controls", "tabindex"], vt = ["src", "type"], $t = ["href"], gt = ["href"], kt = /* @__PURE__ */ d({
__name: "tweet-media-video",
props: {
tweet: {},
media: {}
},
setup(t) {
const o = t, e = k(!0), s = k(!1), c = k(!1), r = rt(o.media);
let p = 0;
const _ = () => {
p && window.clearTimeout(p), s.value || (s.value = !0), c.value && (c.value = !1);
}, R = () => {
p && window.clearTimeout(p), p = window.setTimeout(() => {
s.value && (s.value = !1), p = 0;
}, 100);
}, P = (v) => {
const b = v.currentTarget.previousElementSibling;
v.preventDefault(), e.value = !1, s.value = !0, b.play(), b.focus();
};
return (v, b) => (i(), u(M, null, [
l("video", {
class: n(a(w).image),
poster: a(x)(v.media, "small"),
controls: !e.value,
muted: "",
preload: "none",
tabindex: e.value ? -1 : 0,
onPlay: _,
onPause: R,
onEnded: b[0] || (b[0] = (Lo) => c.value = !0)
}, [
l("source", {
src: a(r).url,
type: a(r).content_type
}, null, 8, vt)
], 42, wt),
e.value ? (i(), u("button", {
key: 0,
type: "button",
class: n(v.$style.videoButton),
"aria-label": "View video on X",
onClick: P
}, [
(i(), u("svg", {
viewBox: "0 0 24 24",
class: n(v.$style.videoButtonIcon),
"aria-hidden": "true"
}, b[1] || (b[1] = [
l("g", null, [
l("path", { d: "M21 12L4 2v20l17-10z" })
], -1)
]), 2))
], 2)) : g("", !0),
!s.value && !c.value ? (i(), u("div", {
key: 1,
class: n(v.$style.watchOnTwitter)
}, [
l("a", {
href: v.tweet.url,
class: n(v.$style.anchor),
target: "_blank",
rel: "noopener noreferrer"
}, $(e.value ? "Watch on X" : "Continue watching on X"), 11, $t)
], 2)) : g("", !0),
c.value ? (i(), u("a", {
key: 2,
href: v.tweet.url,
class: n([v.$style.anchor, v.$style.viewReplies]),
target: "_blank",
rel: "noopener noreferrer"
}, " View replies ", 10, gt)) : g("", !0)
], 64));
}
}), bt = "rnM63W_anchor", Tt = "rnM63W_videoButton", Mt = "rnM63W_videoButtonIcon", It = "rnM63W_viewReplies", Bt = "rnM63W_watchOnTwitter", Rt = {
anchor: bt,
videoButton: Tt,
videoButtonIcon: Mt,
viewReplies: It,
watchOnTwitter: Bt
}, Lt = {
$style: Rt
}, qt = /* @__PURE__ */ m(kt, [["__cssModules", Lt]]), Gt = ["href"], E = /* @__PURE__ */ d({
__name: "tweet-media",
props: {
tweet: {},
components: {},
quoted: { type: Boolean }
},
setup(t) {
const o = t, e = (r, p) => {
let _ = 56.25;
return p === 1 && (_ = 100 / r.original_info.width * r.original_info.height), p === 2 && (_ = _ * 2), {
width: r.type === "photo" ? void 0 : "unset",
paddingBottom: `${_}%`
};
}, s = T(() => {
var r;
return ((r = o.tweet.mediaDetails) == null ? void 0 : r.length) ?? 0;
}), c = T(() => {
var r;
return ((r = o.components) == null ? void 0 : r.MediaImg) ?? X;
});
return (r, p) => (i(), u("div", {
class: n([a(w).root, { [a(w).rounded]: !r.quoted }])
}, [
l("div", {
class: n([
a(w).mediaWrapper,
{
[a(w).grid2Columns]: s.value > 1,
[a(w).grid3]: s.value === 3,
[a(w).grid2x2]: s.value > 4
}
])
}, [
(i(!0), u(M, null, S(r.tweet.mediaDetails, (_) => (i(), u(M, {
key: _.media_url_https
}, [
_.type === "photo" ? (i(), u("a", {
key: 0,
href: r.tweet.url,
class: n([a(w).mediaContainer, a(w).mediaLink]),
target: "_blank",
rel: "noopener noreferrer"
}, [
l("div", {
class: n(a(w).skeleton),
style: G(e(_, s.value))
}, null, 6),
(i(), h(q(c.value), {
src: a(x)(_, "small"),
alt: _.ext_alt_text || "Image",
class: n(a(w).image),
draggable: ""
}, null, 8, ["src", "alt", "class"]))
], 10, Gt)) : (i(), u("div", {
key: 1,
class: n(a(w).mediaContainer)
}, [
l("div", {
class: n(a(w).skeleton),
style: G(e(_, s.value))
}, null, 6),
f(qt, {
tweet: r.tweet,
media: _
}, null, 8, ["tweet", "media"])
], 2))
], 64))), 128))
], 2)
], 2));
}
}), Ct = /* @__PURE__ */ d({
__name: "quoted-tweet",
props: {
tweet: {}
},
setup(t) {
return (o, e) => (i(), h(Me, { tweet: o.tweet }, {
default: B(() => {
var s;
return [
f(Ze, { tweet: o.tweet }, null, 8, ["tweet"]),
f(Qe, { tweet: o.tweet }, null, 8, ["tweet"]),
(s = o.tweet.mediaDetails) != null && s.length ? (i(), h(E, {
key: 0,
tweet: o.tweet,
quoted: ""
}, null, 8, ["tweet"])) : g("", !0)
];
}),
_: 1
}, 8, ["tweet"]));
}
}), Wt = ["href"], St = ["href"], Vt = ["title"], Ot = ["href"], zt = ["title"], Dt = ["href"], jt = ["href"], Ht = /* @__PURE__ */ d({
__name: "tweet-header",
props: {
tweet: {},
components: {}
},
setup(t) {
var c;
const o = t, e = ((c = o.components) == null ? void 0 : c.AvatarImg) ?? O, { user: s } = o.tweet;
return (r, p) => (i(), u("div", {
class: n(r.$style.header)
}, [
l("a", {
href: r.tweet.url,
class: n(r.$style.avatar),
target: "_blank",
rel: "noopener noreferrer"
}, [
l("div", {
class: n([
r.$style.avatarOverflow,
{ [r.$style.avatarSquare]: a(s).profile_image_shape === "Square" }
])
}, [
(i(), h(q(a(e)), {
src: a(s).profile_image_url_https,
alt: a(s).name,
width: 48,
height: 48
}, null, 8, ["src", "alt"]))
], 2),
l("div", {
class: n(r.$style.avatarOverflow)
}, [
l("div", {
class: n(r.$style.avatarShadow)
}, null, 2)
], 2)
], 10, Wt),
l("div", {
class: n(r.$style.author)
}, [
l("a", {
href: r.tweet.url,
class: n(r.$style.authorLink),
target: "_blank",
rel: "noopener noreferrer"
}, [
l("div", {
class: n(r.$style.authorLinkText)
}, [
l("span", {
title: a(s).name
}, $(a(s).name), 9, Vt)
], 2),
f(F, {
user: a(s),
class: n(r.$style.authorVerified)
}, null, 8, ["user", "class"])
], 10, St),
l("div", {
class: n(r.$style.authorMeta)
}, [
l("a", {
href: r.tweet.url,
class: n(r.$style.username),
target: "_blank",
rel: "noopener noreferrer"
}, [
l("span", {
title: `@${a(s).screen_name}`
}, "@" + $(a(s).screen_name), 9, zt)
], 10, Ot),
l("div", {
class: n(r.$style.authorFollow)
}, [
l("span", {
class: n(r.$style.separator)
}, "·", 2),
l("a", {
href: a(s).follow_url,
class: n(r.$style.follow),
target: "_blank",
rel: "noopener noreferrer"
}, " Follow ", 10, Dt)
], 2)
], 2)
], 2),
l("a", {
href: r.tweet.url,
class: n(r.$style.brand),
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "View on Twitter"
}, [
(i(), u("svg", {
viewBox: "0 0 24 24",
"aria-hidden": "true",
class: n(r.$style.twitterIcon)
}, p[0] || (p[0] = [
l("g", null, [
l("path", { d: "M18.244 2.25h3.308l-7.227 8.26 8.502 11.24H16.17l-5.214-6.817L4.99 21.75H1.68l7.73-8.835L1.254 2.25H8.08l4.713 6.231zm-1.161 17.52h1.833L7.084 4.126H5.117z" })
], -1)
]), 2))
], 10, jt)
], 2));
}
}), Ut = "ZbIw1a_author", Xt = "ZbIw1a_authorFollow", Ft = "ZbIw1a_authorLink", Zt = "ZbIw1a_authorLinkText", xt = "ZbIw1a_authorMeta", Et = "ZbIw1a_authorVerified", Pt = "ZbIw1a_avatar", At = "ZbIw1a_avatarOverflow", Nt = "ZbIw1a_avatarShadow", Yt = "ZbIw1a_avatarSquare", Qt = "ZbIw1a_brand", Kt = "ZbIw1a_follow", Jt = "ZbIw1a_header", es = "ZbIw1a_separator", ts = "ZbIw1a_twitterIcon", ss = "ZbIw1a_username", os = {
author: Ut,
authorFollow: Xt,
authorLink: Ft,
authorLinkText: Zt,
authorMeta: xt,
authorVerified: Et,
avatar: Pt,
avatarOverflow: At,
avatarShadow: Nt,
avatarSquare: Yt,
brand: Qt,
follow: Kt,
header: Jt,
separator: es,
twitterIcon: ts,
username: ss
}, ns = {
$style: os
}, rs = /* @__PURE__ */ m(Ht, [["__cssModules", ns]]), as = ["href"], ls = /* @__PURE__ */ d({
__name: "tweet-in-reply-to",
props: {
tweet: {}
},
setup(t) {
return (o, e) => (i(), u("a", {
href: o.tweet.in_reply_to_url,
class: n(o.$style.root),
target: "_blank",
rel: "noopener noreferrer"
}, " Replying to @" + $(o.tweet.in_reply_to_screen_name), 11, as));
}
}), is = "_5nZaGq_root", cs = {
root: is
}, us = {
$style: cs
}, ds = /* @__PURE__ */ m(ls, [["__cssModules", us]]), ps = ["href"], _s = /* @__PURE__ */ d({
__name: "tweet-link",
props: {
href: {}
},
setup(t) {
return (o, e) => (i(), u("a", {
href: o.href,
class: n(o.$style.root),
target: "_blank",
rel: "noopener noreferrer nofollow"
}, [
W(o.$slots, "default")
], 10, ps));
}
}), fs = "KevUKq_root", ms = {
root: fs
}, hs = {
$style: ms
}, ys = /* @__PURE__ */ m(_s, [["__cssModules", hs]]), ws = ["lang"], vs = ["innerHTML"], $s = /* @__PURE__ */ d({
__name: "tweet-body",
props: {
tweet: {}
},
setup(t) {
const o = (e) => ["hashtag", "mention", "url", "symbol"].includes(e.type);
return (e, s) => (i(), u("p", {
class: n(e.$style.root),
lang: e.tweet.lang,
dir: "auto"
}, [
(i(!0), u(M, null, S(e.tweet.entities, (c, r) => (i(), u(M, { key: r }, [
o(c) ? (i(), h(ys, {
key: 0,
href: c.href
}, {
default: B(() => [
K($(c.text), 1)
]),
_: 2
}, 1032, ["href"])) : c.type === "text" ? (i(), u("span", {
key: 1,
innerHTML: c.text
}, null, 8, vs)) : g("", !0)
], 64))), 128))
], 10, ws));
}
}), gs = "b5eIca_root", ks = {
root: gs
}, bs = {
$style: ks
}, Ts = /* @__PURE__ */ m($s, [["__cssModules", bs]]), Ms = {
hour: "numeric",
minute: "2-digit",
hour12: !0,
weekday: "short",
month: "short",
day: "numeric",
year: "numeric"
}, Is = new Intl.DateTimeFormat("en-US", Ms), Bs = (t) => {
const o = {};
for (const e of t)
o[e.type] = e.value;
return o;
}, Rs = (t) => {
const o = Bs(Is.formatToParts(t)), e = `${o.hour}:${o.minute} ${o.dayPeriod}`, s = `${o.month} ${o.day}, ${o.year}`;
return `${e} · ${s}`;
}, Ls = ["href", "aria-label"], qs = ["datetime"], Gs = /* @__PURE__ */ d({
__name: "tweet-info-created-at",
props: {
tweet: {}
},
setup(t) {
const o = t, e = new Date(o.tweet.created_at), s = Rs(e);
return (c, r) => (i(), u("a", {
class: n(c.$style.root),
href: c.tweet.url,
target: "_blank",
rel: "noopener noreferrer",
"aria-label": a(s)
}, [
l("time", {
datetime: a(e).toISOString()
}, $(a(s)), 9, qs)
], 10, Ls));
}
}), Cs = "Oh6FCq_root", Ws = {
root: Cs
}, Ss = {
$style: Ws
}, Vs = /* @__PURE__ */ m(Gs, [["__cssModules", Ss]]), Os = /* @__PURE__ */ d({
__name: "tweet-info",
props: {
tweet: {}
},
setup(t) {
return (o, e) => (i(), u("div", {
class: n(o.$style.info)
}, [
f(Vs, { tweet: o.tweet }, null, 8, ["tweet"]),
l("a", {
class: n(o.$style.infoLink),
href: "https://help.x.com/en/x-for-websites-ads-info-and-privacy",
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "Twitter for Websites, Ads Information and Privacy"
}, [
(i(), u("svg", {
viewBox: "0 0 24 24",
"aria-hidden": "true",
class: n(o.$style.infoIcon)
}, e[0] || (e[0] = [
l("g", null, [
l("path", { d: "M13.5 8.5c0 .83-.67 1.5-1.5 1.5s-1.5-.67-1.5-1.5S11.17 7 12 7s1.5.67 1.5 1.5zM13 17v-5h-2v5h2zm-1 5.25c5.66 0 10.25-4.59 10.25-10.25S17.66 1.75 12 1.75 1.75 6.34 1.75 12 6.34 22.25 12 22.25zM20.25 12c0 4.56-3.69 8.25-8.25 8.25S3.75 16.56 3.75 12 7.44 3.75 12 3.75s8.25 3.69 8.25 8.25z" })
], -1)
]), 2))
], 2)
], 2));
}
}), zs = "Mff3nG_info", Ds = "Mff3nG_infoIcon", js = "Mff3nG_infoLink", Hs = {
info: zs,
infoIcon: Ds,
infoLink: js
}, Us = {
$style: Hs
}, Xs = /* @__PURE__ */ m(Os, [["__cssModules", Us]]), Fs = "aX6RRG_actions", Zs = "aX6RRG_copy", xs = "aX6RRG_copyIcon", Es = "aX6RRG_copyIconWrapper", Ps = "aX6RRG_copyText", As = "aX6RRG_like", Ns = "aX6RRG_likeCount", Ys = "aX6RRG_likeIcon", Qs = "aX6RRG_likeIconWrapper", Ks = "aX6RRG_reply", Js = "aX6RRG_replyIcon", eo = "aX6RRG_replyIconWrapper", to = "aX6RRG_replyText", y = {
actions: Fs,
copy: Zs,
copyIcon: xs,
copyIconWrapper: Es,
copyText: Ps,
like: As,
likeCount: Ns,
likeIcon: Ys,
likeIconWrapper: Qs,
reply: Ks,
replyIcon: Js,
replyIconWrapper: eo,
replyText: to
}, so = /* @__PURE__ */ d({
__name: "tweet-actions-copy",
props: {
tweet: {}
},
setup(t) {
const o = t, e = k(!1), s = () => {
navigator.clipboard.writeText(o.tweet.url), e.value = !0;
};
return J(e, (c) => {
if (c) {
const r = setTimeout(() => {
e.value = !1;
}, 6e3);
ee(() => clearTimeout(r));
}
}), (c, r) => (i(), u("button", {
type: "button",
class: n(a(y).copy),
"aria-label": "Copy link",
onClick: s
}, [
l("div", {
class: n(a(y).copyIconWrapper)
}, [
e.value ? (i(), u("svg", {
key: 0,
viewBox: "0 0 24 24",
class: n(a(y).copyIcon),
"aria-hidden": "true"
}, r[0] || (r[0] = [
l("g", null, [
l("path", { d: "M9.64 18.952l-5.55-4.861 1.317-1.504 3.951 3.459 8.459-10.948L19.4 6.32 9.64 18.952z" })
], -1)
]), 2)) : (i(), u("svg", {
key: 1,
viewBox: "0 0 24 24",
class: n(a(y).copyIcon),
"aria-hidden": "true"
}, r[1] || (r[1] = [
l("g", null, [
l("path", { d: "M18.36 5.64c-1.95-1.96-5.11-1.96-7.07 0L9.88 7.05 8.46 5.64l1.42-1.42c2.73-2.73 7.16-2.73 9.9 0 2.73 2.74 2.73 7.17 0 9.9l-1.42 1.42-1.41-1.42 1.41-1.41c1.96-1.96 1.96-5.12 0-7.07zm-2.12 3.53l-7.07 7.07-1.41-1.41 7.07-7.07 1.41 1.41zm-12.02.71l1.42-1.42 1.41 1.42-1.41 1.41c-1.96 1.96-1.96 5.12 0 7.07 1.95 1.96 5.11 1.96 7.07 0l1.41-1.41 1.42 1.41-1.42 1.42c-2.73 2.73-7.16 2.73-9.9 0-2.73-2.74-2.73-7.17 0-9.9z" })
], -1)
]), 2))
], 2),
l("span", {
class: n(a(y).copyText)
}, $(e.value ? "Copied!" : "Copy link"), 3)
], 2));
}
}), oo = ["href", "aria-label"], no = ["href"], ro = /* @__PURE__ */ d({
__name: "tweet-actions",
props: {
tweet: {}
},
setup(t) {
const e = C(t.tweet.favorite_count);
return (s, c) => (i(), u("div", {
class: n(a(y).actions)
}, [
l("a", {
class: n(a(y).like),
href: s.tweet.like_url,
target: "_blank",
rel: "noopener noreferrer",
"aria-label": `Like. This Tweet has ${a(e)} likes`
}, [
l("div", {
class: n(a(y).likeIconWrapper)
}, [
(i(), u("svg", {
viewBox: "0 0 24 24",
class: n(a(y).likeIcon),
"aria-hidden": "true"
}, c[0] || (c[0] = [
l("g", null, [
l("path", { d: "M20.884 13.19c-1.351 2.48-4.001 5.12-8.379 7.67l-.503.3-.504-.3c-4.379-2.55-7.029-5.19-8.382-7.67-1.36-2.5-1.41-4.86-.514-6.67.887-1.79 2.647-2.91 4.601-3.01 1.651-.09 3.368.56 4.798 2.01 1.429-1.45 3.146-2.1 4.796-2.01 1.954.1 3.714 1.22 4.601 3.01.896 1.81.846 4.17-.514 6.67z" })
], -1)
]), 2))
], 2),
l("span", {
class: n(a(y).likeCount)
}, $(a(e)), 3)
], 10, oo),
l("a", {
class: n(a(y).reply),
href: s.tweet.reply_url,
target: "_blank",
rel: "noopener noreferrer",
"aria-label": "Reply to this Tweet on Twitter"
}, [
l("div", {
class: n(a(y).replyIconWrapper)
}, [
(i(), u("svg", {
viewBox: "0 0 24 24",
class: n(a(y).replyIcon),
"aria-hidden": "true"
}, c[1] || (c[1] = [
l("g", null, [
l("path", { d: "M1.751 10c0-4.42 3.584-8 8.005-8h4.366c4.49 0 8.129 3.64 8.129 8.13 0 2.96-1.607 5.68-4.196 7.11l-8.054 4.46v-3.69h-.067c-4.49.1-8.183-3.51-8.183-8.01z" })
], -1)
]), 2))
], 2),
l("span", {
class: n(a(y).replyText)
}, "Reply", 2)
], 10, no),
f(so, { tweet: s.tweet }, null, 8, ["tweet"])
], 2));
}
}), ao = ["href"], lo = /* @__PURE__ */ d({
__name: "tweet-replies",
props: {
tweet: {}
},
setup(t) {
const o = t, e = T(() => o.tweet.conversation_count === 0 ? "Read more on X" : o.tweet.conversation_count === 1 ? `Read ${C(o.tweet.conversation_count)} reply` : `Read ${C(o.tweet.conversation_count)} replies`);
return (s, c) => (i(), u("div", {
class: n(s.$style.replies)
}, [
l("a", {
class: n(s.$style.link),
href: s.tweet.url,
target: "_blank",
rel: "noopener noreferrer"
}, [
l("span", {
class: n(s.$style.text)
}, $(e.value), 3)
], 10, ao)
], 2));
}
}), io = "ykg4nq_link", co = "ykg4nq_replies", uo = "ykg4nq_text", po = {
link: io,
replies: co,
text: uo
}, _o = {
$style: po
}, fo = /* @__PURE__ */ m(lo, [["__cssModules", _o]]), mo = /* @__PURE__ */ d({
__name: "embedded-tweet",
props: {
tweet: {},
components: {}
},
setup(t) {
const o = t, e = T(() => lt(o.tweet));
return (s, c) => (i(), h(V, null, {
default: B(() => {
var r;
return [
f(rs, {
tweet: e.value,
components: s.components
}, null, 8, ["tweet", "components"]),
e.value.in_reply_to_status_id_str ? (i(), h(ds, {
key: 0,
tweet: e.value
}, null, 8, ["tweet"])) : g("", !0),
f(Ts, { tweet: e.value }, null, 8, ["tweet"]),
(r = e.value.mediaDetails) != null && r.length ? (i(), h(E, {
key: 1,
tweet: e.value,
components: s.components
}, null, 8, ["tweet", "components"])) : g("", !0),
e.value.quoted_tweet ? (i(), h(a(Ct), {
key: 2,
tweet: e.value.quoted_tweet
}, null, 8, ["tweet"])) : g("", !0),
f(Xs, { tweet: e.value }, null, 8, ["tweet"]),
f(ro, { tweet: e.value }, null, 8, ["tweet"]),
f(fo, { tweet: e.value }, null, 8, ["tweet"])
];
}),
_: 1
}));
}
}), ho = /* @__PURE__ */ d({
__name: "skeleton",
props: {
style: {}
},
setup(t) {
return (o, e) => (i(), u("span", {
class: n(o.$style.skeleton),
style: G(o.style)
}, null, 6));
}
}), yo = "l4VFjW_loading", wo = "l4VFjW_skeleton", vo = {
loading: yo,
skeleton: wo
}, $o = {
$style: vo
}, L = /* @__PURE__ */ m(ho, [["__cssModules", $o]]), go = /* @__PURE__ */ d({
__name: "tweet-skeleton",
setup(t) {
return (o, e) => (i(), h(V, {
class: n(o.$style.root)
}, {
default: B(() => [
f(L, { style: { height: "3rem", marginBottom: "0.75rem" } }),
f(L, { style: { height: "6rem", margin: "0.5rem 0" } }),
e[0] || (e[0] = l("div", { style: { borderTop: "var(--tweet-border)", margin: "0.5rem 0" } }, null, -1)),
f(L, { style: {
height: "2rem"
} }),
f(L, { style: {
height: "2rem",
borderRadius: "9999px",
marginTop: "0.5rem"
} })
]),
_: 1
}, 8, ["class"]));
}
}), ko = "Wi8Y9q_root", bo = {
root: ko
}, To = {
$style: bo
}, Mo = /* @__PURE__ */ m(go, [["__cssModules", To]]);
async function Io(t, o) {
const e = await fetch(t, o), s = await e.json();
if (e.ok) return s.data || null;
throw new se({
message: `Failed to fetch tweet at "${t}" with "${e.status}".`,
data: s,
status: e.status
});
}
function Bo(t, o, e) {
const s = k(!0), c = k(), r = k(null), p = async () => {
if (!o && !t) {
s.value = !1;
return;
}
try {
const _ = `${o}/${t}`, R = await Io(_, e);
c.value = R;
} catch (_) {
r.value = _;
} finally {
s.value = !1;
}
};
return U(() => {
p();
}), {
isLoading: s,
data: c,
error: r
};
}
function Co() {
const t = k(!1);
return U(() => {
t.value = !0;
}), t;
}
const Ro = "https://react-tweet.vercel.app", Wo = /* @__PURE__ */ d({
__name: "tweet",
props: {
id: {},
apiUrl: { default: `${Ro}/api/tweet` },
fallback: { default: Mo },
components: { default: () => me },
fetchOptions: { default: () => ({}) },
onError: { type: Function, default: (t) => t }
},
setup(t) {
const o = t, { isLoading: e, data: s, error: c } = Bo(o.id, o.apiUrl, o.fetchOptions);
return (r, p) => {
const _ = te("fallback");
return a(e) ? (i(), h(_, { key: 0 })) : (i(), u(M, { key: 1 }, [
a(c) || !a(s) ? (i(), h(q(r.components.TweetNotFound), {
key: 0,
error: r.onError(a(c))
}, null, 8, ["error"])) : (i(), h(a(mo), {
key: 1,
tweet: a(s),
components: r.components
}, null, 8, ["tweet", "components"]))
], 64));
};
}
});
export {
mo as EmbeddedTweet,
Ct as QuotedTweet,
Qe as QuotedTweetBody,
Me as QuotedTweetContainer,
Ze as QuotedTweetHeader,
Wo as Tweet,
ro as TweetActions,
so as TweetActionsCopy,
Ts as TweetBody,
V as TweetContainer,
rs as TweetHeader,
ds as TweetInReplyTo,
Xs as TweetInfo,
Vs as TweetInfoCreatedAt,
ys as TweetLink,
E as TweetMedia,
qt as TweetMediaVideo,
pe as TweetNotFound,
fo as TweetReplies,
Mo as TweetSkeleton,
ye as Verified,
we as VerifiedBusiness,
ve as VerifiedGovernment,
me as defaultTwitterComponents,
lt as enrichTweet,
C as formatNumber,
x as getMediaUrl,
rt as getMp4Video,
nt as getMp4Videos,
Co as useMounted,
Bo as useTweet
};