UNPKG

vue-tweet-pure

Version:

A Vue 3 component for embedding tweets in your Vue.js applications.

812 lines (811 loc) 31 kB
import { TwitterApiError as e } from "./api.es.js"; import { Fragment as t, computed as n, createBlock as r, createCommentVNode as i, createElementBlock as a, createElementVNode as o, createStaticVNode as s, createTextVNode as c, createVNode as l, defineComponent as u, mergeProps as ee, normalizeClass as d, normalizeStyle as f, onBeforeUnmount as p, onMounted as te, openBlock as m, ref as h, renderList as g, renderSlot as _, resolveDynamicComponent as v, toDisplayString as y, unref as b, useAttrs as ne, useCssModule as re, watch as ie, withCtx as x, withModifiers as ae } from "vue"; //#region src/twitter-theme/tweet-container.vue?vue&type=script&setup=true&lang.ts var oe = /* @__PURE__ */ u({ __name: "tweet-container", setup(e) { let t = ne(); return (e, n) => (m(), a("div", { class: d([ "vue-tweet-theme", e.$style.root, b(t).class ]) }, [o("article", { class: d(e.$style.article) }, [_(e.$slots, "default")], 2)], 2)); } }), se = { article: "JrPdna_article", root: "JrPdna_root" }, S = (e, t) => { let n = e.__vccOpts || e; for (let [e, r] of t) n[e] = r; return n; }, C = /* @__PURE__ */ S(oe, [["__cssModules", { $style: se }]]), ce = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-not-found", props: { error: {} }, setup(e) { return (e, t) => (m(), r(C, null, { default: x(() => [o("div", { class: d(e.$style.root) }, [...t[0] ||= [o("h3", null, "Tweet not found", -1), o("p", null, "The embedded tweet could not be found…", -1)]], 2)]), _: 1 })); } }), [["__cssModules", { $style: { root: "nN86_W_root" } }]]), le = [ "src", "alt", "width", "height" ], w = /* @__PURE__ */ u({ __name: "avatar-img", props: { src: {}, alt: {}, width: {}, height: {} }, setup(e) { return (t, n) => (m(), a("img", { src: e.src, alt: e.alt, width: e.width, height: e.height }, null, 8, le)); } }), ue = [ "src", "alt", "draggable" ], T = /* @__PURE__ */ u({ __name: "media-img", props: { src: {}, alt: {}, draggable: { type: Boolean } }, setup(e) { return (t, n) => (m(), a("img", ee(t.$attrs, { src: e.src, alt: e.alt, draggable: e.draggable }), null, 16, ue)); } }), E = { TweetNotFound: ce, AvatarImg: w, MediaImg: T }, D = { verified: "_81i5Cq_verified" }, O = /* @__PURE__ */ u({ __name: "verified", setup(e) { return (e, t) => (m(), a("svg", { viewBox: "0 0 24 24", "aria-label": "Verified account", role: "img", class: d(b(D).verified) }, [...t[0] ||= [o("g", null, [o("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)); } }), k = /* @__PURE__ */ u({ __name: "verified-business", setup(e) { return (e, t) => (m(), a("svg", { viewBox: "0 0 22 22", "aria-label": "Verified account", role: "img", class: d(b(D).verified) }, [...t[0] ||= [s("<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)); } }), A = /* @__PURE__ */ u({ __name: "verified-government", setup(e) { return (e, t) => (m(), a("svg", { viewBox: "0 0 22 22", "aria-label": "Verified account", role: "img", class: d(b(D).verified) }, [...t[0] ||= [o("g", null, [o("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)); } }), j = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "quoted-tweet-container", props: { tweet: {} }, setup(e) { let t = (e) => { window.open(e, "_blank"); }; return (n, r) => (m(), a("div", { class: d(n.$style.root), onClick: r[0] ||= ae((n) => t(e.tweet.url), ["prevent"]) }, [o("article", { class: d(n.$style.article) }, [_(n.$slots, "default")], 2)], 2)); } }), [["__cssModules", { $style: { article: "RsfEUq_article", root: "RsfEUq_root" } }]]), M = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "verified-badge", props: { user: {} }, setup(e) { let t = re(), o = ne(), s = e, c = n(() => s.user.verified || s.user.is_blue_verified || s.user.verified_type), l = n(() => c.value ? s.user.verified_type === "Government" ? A : s.user.verified_type === "Business" ? k : O : null), u = n(() => c.value ? s.user.verified_type === "Government" ? t.verifiedGovernment : s.user.verified_type === "Business" ? null : s.user.is_blue_verified ? t.verifiedBlue : t.verifiedOld : null); return (e, t) => c.value ? (m(), a("div", { key: 0, class: d([b(o).class, u.value]) }, [(m(), r(v(l.value)))], 2)) : i("", !0); } }), [["__cssModules", { $style: { verifiedBlue: "dT-upq_verifiedBlue", verifiedGovernment: "dT-upq_verifiedGovernment", verifiedOld: "dT-upq_verifiedOld" } }]]), de = ["href"], fe = ["title"], pe = ["title"], N = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "quoted-tweet-header", props: { tweet: {} }, setup(e) { let { user: t } = e.tweet; return (n, r) => (m(), a("div", { class: d(n.$style.header) }, [o("a", { href: e.tweet.url, class: d(n.$style.avatar), target: "_blank", rel: "noopener noreferrer" }, [o("div", { class: d([n.$style.avatarOverflow, { [n.$style.avatarSquare]: b(t).profile_image_shape === "Square" }]) }, [l(w, { src: b(t).profile_image_url_https, alt: b(t).name, width: 20, height: 20 }, null, 8, ["src", "alt"])], 2)], 10, de), o("div", { class: d(n.$style.author) }, [ o("div", { class: d(n.$style.authorText) }, [o("span", { title: b(t).name }, y(b(t).name), 9, fe)], 2), l(M, { user: b(t) }, null, 8, ["user"]), o("div", { class: d(n.$style.username) }, [o("span", { title: `@${b(t).screen_name}` }, "@" + y(b(t).screen_name), 9, pe)], 2) ], 2)], 2)); } }), [["__cssModules", { $style: { author: "_2tBG3G_author", authorText: "_2tBG3G_authorText", avatar: "_2tBG3G_avatar", avatarSquare: "_2tBG3G_avatarSquare", header: "_2tBG3G_header", username: "_2tBG3G_username" } }]]), me = ["lang"], he = ["innerHTML"], P = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "quoted-tweet-body", props: { tweet: {} }, setup(e) { return (n, r) => (m(), a("p", { class: d(n.$style.root), lang: e.tweet.lang, dir: "auto" }, [(m(!0), a(t, null, g(e.tweet.entities, (e, t) => (m(), a("span", { key: t, innerHTML: e.text }, null, 8, he))), 128))], 10, me)); } }), [["__cssModules", { $style: { root: "_3hXyqa_root" } }]]), F = (e) => `https://x.com/${e.user.screen_name}/status/${e.id_str}`, I = (e) => `https://x.com/${typeof e == "string" ? e : e.user.screen_name}`, ge = (e) => `https://x.com/intent/like?tweet_id=${e.id_str}`, _e = (e) => `https://x.com/intent/tweet?in_reply_to=${e.id_str}`, ve = (e) => `https://x.com/intent/follow?screen_name=${e.user.screen_name}`, ye = (e) => `https://x.com/hashtag/${e.text}`, be = (e) => `https://x.com/search?q=%24${e.text}`, xe = (e) => `https://x.com/${e.in_reply_to_screen_name}/status/${e.in_reply_to_status_id_str}`, L = (e, t) => { let n = new URL(e.media_url_https), r = n.pathname.split(".").pop(); return r ? (n.pathname = n.pathname.replace(`.${r}`, ""), n.searchParams.set("format", r), n.searchParams.set("name", t), n.toString()) : e.media_url_https; }, R = (e) => { let { variants: t } = e.video_info; return t.filter((e) => e.content_type === "video/mp4").sort((e, t) => (t.bitrate ?? 0) - (e.bitrate ?? 0)); }, z = (e) => { let t = R(e); return t.length > 1 ? t[1] : t[0]; }, B = (e) => e > 999999 ? `${(e / 1e6).toFixed(1)}M` : e > 999 ? `${(e / 1e3).toFixed(1)}K` : e.toString(); function V(e) { let t = Array.from(e.text), n = [{ indices: e.display_text_range, type: "text" }]; return H(n, "hashtag", e.entities.hashtags), H(n, "mention", e.entities.user_mentions), H(n, "url", e.entities.urls), H(n, "symbol", e.entities.symbols), e.entities.media && H(n, "media", e.entities.media), Se(e, n), n.map((e) => { let n = t.slice(e.indices[0], e.indices[1]).join(""); switch (e.type) { case "hashtag": return Object.assign(e, { href: ye(e), text: n }); case "mention": return Object.assign(e, { href: I(e.screen_name), text: n }); case "url": case "media": return Object.assign(e, { href: e.expanded_url, text: e.display_url }); case "symbol": return Object.assign(e, { href: be(e), text: n }); default: return Object.assign(e, { text: n }); } }); } function H(e, t, n) { for (let r of n) for (let [n, i] of e.entries()) { if (i.indices[0] > r.indices[0] || i.indices[1] < r.indices[1]) continue; let a = [{ ...r, type: t }]; i.indices[0] < r.indices[0] && a.unshift({ indices: [i.indices[0], r.indices[0]], type: "text" }), i.indices[1] > r.indices[1] && a.push({ indices: [r.indices[1], i.indices[1]], type: "text" }), e.splice(n, 1, ...a); break; } } function Se(e, t) { let n = e.entities.media?.[0]; n && n.indices[0] < e.display_text_range[1] && (e.display_text_range[1] = n.indices[0]); let r = t.at(-1); r && r.indices[1] > e.display_text_range[1] && (r.indices[1] = e.display_text_range[1]); } var U = (e) => ({ ...e, url: F(e), user: { ...e.user, url: I(e), follow_url: ve(e) }, like_url: ge(e), reply_url: _e(e), in_reply_to_url: e.in_reply_to_screen_name ? xe(e) : void 0, entities: V(e), quoted_tweet: e.quoted_tweet ? { ...e.quoted_tweet, url: F(e.quoted_tweet), entities: V(e.quoted_tweet) } : void 0 }), W = { grid2Columns: "nYjDHW_grid2Columns", grid2x2: "nYjDHW_grid2x2", grid3: "nYjDHW_grid3", image: "nYjDHW_image", mediaContainer: "nYjDHW_mediaContainer", mediaLink: "nYjDHW_mediaLink", mediaWrapper: "nYjDHW_mediaWrapper", root: "nYjDHW_root", rounded: "nYjDHW_rounded", skeleton: "nYjDHW_skeleton" }, Ce = [ "poster", "controls", "tabindex" ], we = ["src", "type"], Te = ["href"], Ee = ["href"], G = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-media-video", props: { tweet: {}, media: {} }, setup(e) { let n = e, r = h(!0), s = h(!1), c = h(!1), l = z(n.media), u = 0, ee = () => { u && window.clearTimeout(u), s.value ||= !0, c.value &&= !1; }, f = () => { u && window.clearTimeout(u), u = window.setTimeout(() => { s.value &&= !1, u = 0; }, 100); }, p = (e) => { let t = e.currentTarget.previousElementSibling; e.preventDefault(), r.value = !1, s.value = !0, t.play(), t.focus(); }; return (n, u) => b(l) ? (m(), a(t, { key: 0 }, [ o("video", { class: d(b(W).image), poster: b(L)(e.media, "small"), controls: !r.value, muted: "", preload: "none", tabindex: r.value ? -1 : 0, onPlay: ee, onPause: f, onEnded: u[0] ||= (e) => c.value = !0 }, [o("source", { src: b(l).url, type: b(l).content_type }, null, 8, we)], 42, Ce), r.value ? (m(), a("button", { key: 0, type: "button", class: d(n.$style.videoButton), "aria-label": "View video on X", onClick: p }, [(m(), a("svg", { viewBox: "0 0 24 24", class: d(n.$style.videoButtonIcon), "aria-hidden": "true" }, [...u[1] ||= [o("g", null, [o("path", { d: "M21 12L4 2v20l17-10z" })], -1)]], 2))], 2)) : i("", !0), !s.value && !c.value ? (m(), a("div", { key: 1, class: d(n.$style.watchOnTwitter) }, [o("a", { href: e.tweet.url, class: d(n.$style.anchor), target: "_blank", rel: "noopener noreferrer" }, y(r.value ? "Watch on X" : "Continue watching on X"), 11, Te)], 2)) : i("", !0), c.value ? (m(), a("a", { key: 2, href: e.tweet.url, class: d([n.$style.anchor, n.$style.viewReplies]), target: "_blank", rel: "noopener noreferrer" }, " View replies ", 10, Ee)) : i("", !0) ], 64)) : i("", !0); } }), [["__cssModules", { $style: { anchor: "rnM63W_anchor", videoButton: "rnM63W_videoButton", videoButtonIcon: "rnM63W_videoButtonIcon", viewReplies: "rnM63W_viewReplies", watchOnTwitter: "rnM63W_watchOnTwitter" } }]]), De = ["href"], K = /* @__PURE__ */ u({ __name: "tweet-media", props: { tweet: {}, components: {}, quoted: { type: Boolean } }, setup(e) { let i = e, s = (e, t) => { let n = 56.25; return t === 1 && (n = 100 / e.original_info.width * e.original_info.height), t === 2 && (n *= 2), { width: e.type === "photo" ? void 0 : "unset", paddingBottom: `${n}%` }; }, c = n(() => i.tweet.mediaDetails?.length ?? 0), u = n(() => i.components?.MediaImg ?? T); return (n, i) => (m(), a("div", { class: d([b(W).root, !e.quoted && b(W).rounded]) }, [o("div", { class: d([ b(W).mediaWrapper, c.value > 1 && b(W).grid2Columns, c.value === 3 && b(W).grid3, c.value > 4 && b(W).grid2x2 ]) }, [(m(!0), a(t, null, g(e.tweet.mediaDetails, (n) => (m(), a(t, { key: n.media_url_https }, [n.type === "photo" ? (m(), a("a", { key: 0, href: e.tweet.url, class: d([b(W).mediaContainer, b(W).mediaLink]), target: "_blank", rel: "noopener noreferrer" }, [o("div", { class: d(b(W).skeleton), style: f(s(n, c.value)) }, null, 6), (m(), r(v(u.value), { src: b(L)(n, "small"), alt: n.ext_alt_text || "Image", class: d(b(W).image), draggable: "" }, null, 8, [ "src", "alt", "class" ]))], 10, De)) : (m(), a("div", { key: 1, class: d(b(W).mediaContainer) }, [o("div", { class: d(b(W).skeleton), style: f(s(n, c.value)) }, null, 6), l(G, { tweet: e.tweet, media: n }, null, 8, ["tweet", "media"])], 2))], 64))), 128))], 2)], 2)); } }), q = /* @__PURE__ */ u({ __name: "quoted-tweet", props: { tweet: {} }, setup(e) { return (t, n) => (m(), r(j, { tweet: e.tweet }, { default: x(() => [ l(N, { tweet: e.tweet }, null, 8, ["tweet"]), l(P, { tweet: e.tweet }, null, 8, ["tweet"]), e.tweet.mediaDetails?.length ? (m(), r(K, { key: 0, tweet: e.tweet, quoted: "" }, null, 8, ["tweet"])) : i("", !0) ]), _: 1 }, 8, ["tweet"])); } }), Oe = ["href"], ke = ["href"], Ae = ["title"], je = ["href"], Me = ["title"], Ne = ["href"], Pe = ["href"], J = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-header", props: { tweet: {}, components: {} }, setup(e) { let t = e, n = t.components?.AvatarImg ?? w, { user: i } = t.tweet; return (t, s) => (m(), a("div", { class: d(t.$style.header) }, [ o("a", { href: e.tweet.url, class: d(t.$style.avatar), target: "_blank", rel: "noopener noreferrer" }, [o("div", { class: d([t.$style.avatarOverflow, { [t.$style.avatarSquare]: b(i).profile_image_shape === "Square" }]) }, [(m(), r(v(b(n)), { src: b(i).profile_image_url_https, alt: b(i).name, width: 48, height: 48 }, null, 8, ["src", "alt"]))], 2), o("div", { class: d(t.$style.avatarOverflow) }, [o("div", { class: d(t.$style.avatarShadow) }, null, 2)], 2)], 10, Oe), o("div", { class: d(t.$style.author) }, [o("a", { href: e.tweet.url, class: d(t.$style.authorLink), target: "_blank", rel: "noopener noreferrer" }, [o("div", { class: d(t.$style.authorLinkText) }, [o("span", { title: b(i).name }, y(b(i).name), 9, Ae)], 2), l(M, { user: b(i), class: d(t.$style.authorVerified) }, null, 8, ["user", "class"])], 10, ke), o("div", { class: d(t.$style.authorMeta) }, [o("a", { href: e.tweet.url, class: d(t.$style.username), target: "_blank", rel: "noopener noreferrer" }, [o("span", { title: `@${b(i).screen_name}` }, "@" + y(b(i).screen_name), 9, Me)], 10, je), o("div", { class: d(t.$style.authorFollow) }, [o("span", { class: d(t.$style.separator) }, "·", 2), o("a", { href: b(i).follow_url, class: d(t.$style.follow), target: "_blank", rel: "noopener noreferrer" }, " Follow ", 10, Ne)], 2)], 2)], 2), o("a", { href: e.tweet.url, class: d(t.$style.brand), target: "_blank", rel: "noopener noreferrer", "aria-label": "View on Twitter" }, [(m(), a("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", class: d(t.$style.twitterIcon) }, [...s[0] ||= [o("g", null, [o("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, Pe) ], 2)); } }), [["__cssModules", { $style: { author: "ZbIw1a_author", authorFollow: "ZbIw1a_authorFollow", authorLink: "ZbIw1a_authorLink", authorLinkText: "ZbIw1a_authorLinkText", authorMeta: "ZbIw1a_authorMeta", authorVerified: "ZbIw1a_authorVerified", avatar: "ZbIw1a_avatar", avatarOverflow: "ZbIw1a_avatarOverflow", avatarShadow: "ZbIw1a_avatarShadow", avatarSquare: "ZbIw1a_avatarSquare", brand: "ZbIw1a_brand", follow: "ZbIw1a_follow", header: "ZbIw1a_header", separator: "ZbIw1a_separator", twitterIcon: "ZbIw1a_twitterIcon", username: "ZbIw1a_username" } }]]), Fe = ["href"], Ie = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-in-reply-to", props: { tweet: {} }, setup(e) { return (t, n) => (m(), a("a", { href: e.tweet.in_reply_to_url, class: d(t.$style.root), target: "_blank", rel: "noopener noreferrer" }, " Replying to @" + y(e.tweet.in_reply_to_screen_name), 11, Fe)); } }), [["__cssModules", { $style: { root: "_5nZaGq_root" } }]]), Le = ["href"], Re = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-link", props: { href: {} }, setup(e) { return (t, n) => (m(), a("a", { href: e.href, class: d(t.$style.root), target: "_blank", rel: "noopener noreferrer nofollow" }, [_(t.$slots, "default")], 10, Le)); } }), [["__cssModules", { $style: { root: "KevUKq_root" } }]]), ze = ["lang"], Be = ["innerHTML"], Ve = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-body", props: { tweet: {} }, setup(e) { let n = (e) => [ "hashtag", "mention", "url", "symbol" ].includes(e.type); return (o, s) => (m(), a("p", { class: d(o.$style.root), lang: e.tweet.lang, dir: "auto" }, [(m(!0), a(t, null, g(e.tweet.entities, (e, o) => (m(), a(t, { key: o }, [n(e) ? (m(), r(Re, { key: 0, href: e.href }, { default: x(() => [c(y(e.text), 1)]), _: 2 }, 1032, ["href"])) : e.type === "text" ? (m(), a("span", { key: 1, innerHTML: e.text }, null, 8, Be)) : i("", !0)], 64))), 128))], 10, ze)); } }), [["__cssModules", { $style: { root: "b5eIca_root" } }]]), He = new Intl.DateTimeFormat(navigator.language, { hour: "numeric", minute: "2-digit", hour12: !0, weekday: "short", month: "short", day: "numeric", year: "numeric" }), Ue = (e) => { let t = {}; for (let n of e) t[n.type] = n.value; return t; }, We = (e) => { let t = Ue(He.formatToParts(e)); return `${`${t.hour}:${t.minute} ${t.dayPeriod}`} · ${`${t.month} ${t.day}, ${t.year}`}`; }, Ge = ["href", "aria-label"], Ke = ["datetime"], qe = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-info-created-at", props: { tweet: {} }, setup(e) { let t = new Date(e.tweet.created_at), n = We(t); return (r, i) => (m(), a("a", { class: d(r.$style.root), href: e.tweet.url, target: "_blank", rel: "noopener noreferrer", "aria-label": b(n) }, [o("time", { datetime: b(t).toISOString() }, y(b(n)), 9, Ke)], 10, Ge)); } }), [["__cssModules", { $style: { root: "Oh6FCq_root" } }]]), Je = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-info", props: { tweet: {} }, setup(e) { return (t, n) => (m(), a("div", { class: d(t.$style.info) }, [l(qe, { tweet: e.tweet }, null, 8, ["tweet"]), o("a", { class: d(t.$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" }, [(m(), a("svg", { viewBox: "0 0 24 24", "aria-hidden": "true", class: d(t.$style.infoIcon) }, [...n[0] ||= [o("g", null, [o("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)); } }), [["__cssModules", { $style: { info: "Mff3nG_info", infoIcon: "Mff3nG_infoIcon", infoLink: "Mff3nG_infoLink" } }]]), Y = { actions: "aX6RRG_actions", copy: "aX6RRG_copy", copyIcon: "aX6RRG_copyIcon", copyIconWrapper: "aX6RRG_copyIconWrapper", copyText: "aX6RRG_copyText", like: "aX6RRG_like", likeCount: "aX6RRG_likeCount", likeIcon: "aX6RRG_likeIcon", likeIconWrapper: "aX6RRG_likeIconWrapper", reply: "aX6RRG_reply", replyIcon: "aX6RRG_replyIcon", replyIconWrapper: "aX6RRG_replyIconWrapper", replyText: "aX6RRG_replyText" }, Ye = /* @__PURE__ */ u({ __name: "tweet-actions-copy", props: { tweet: {} }, setup(e) { let t = e, n = h(!1), r = () => { navigator.clipboard.writeText(t.tweet.url), n.value = !0; }, i; return ie(n, (e) => { e && (clearTimeout(i), i = setTimeout(() => { n.value = !1; }, 6e3)); }), p(() => clearTimeout(i)), (e, t) => (m(), a("button", { type: "button", class: d(b(Y).copy), "aria-label": "Copy link", onClick: r }, [o("div", { class: d(b(Y).copyIconWrapper) }, [n.value ? (m(), a("svg", { key: 0, viewBox: "0 0 24 24", class: d(b(Y).copyIcon), "aria-hidden": "true" }, [...t[0] ||= [o("g", null, [o("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)) : (m(), a("svg", { key: 1, viewBox: "0 0 24 24", class: d(b(Y).copyIcon), "aria-hidden": "true" }, [...t[1] ||= [o("g", null, [o("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), o("span", { class: d(b(Y).copyText) }, y(n.value ? "Copied!" : "Copy link"), 3)], 2)); } }), Xe = ["href", "aria-label"], Ze = ["href"], Qe = /* @__PURE__ */ u({ __name: "tweet-actions", props: { tweet: {} }, setup(e) { let t = B(e.tweet.favorite_count); return (n, r) => (m(), a("div", { class: d(b(Y).actions) }, [ o("a", { class: d(b(Y).like), href: e.tweet.like_url, target: "_blank", rel: "noopener noreferrer", "aria-label": `Like. This Tweet has ${b(t)} likes` }, [o("div", { class: d(b(Y).likeIconWrapper) }, [(m(), a("svg", { viewBox: "0 0 24 24", class: d(b(Y).likeIcon), "aria-hidden": "true" }, [...r[0] ||= [o("g", null, [o("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), o("span", { class: d(b(Y).likeCount) }, y(b(t)), 3)], 10, Xe), o("a", { class: d(b(Y).reply), href: e.tweet.reply_url, target: "_blank", rel: "noopener noreferrer", "aria-label": "Reply to this Tweet on Twitter" }, [o("div", { class: d(b(Y).replyIconWrapper) }, [(m(), a("svg", { viewBox: "0 0 24 24", class: d(b(Y).replyIcon), "aria-hidden": "true" }, [...r[1] ||= [o("g", null, [o("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), o("span", { class: d(b(Y).replyText) }, "Reply", 2)], 10, Ze), l(Ye, { tweet: e.tweet }, null, 8, ["tweet"]) ], 2)); } }), $e = ["href"], et = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-replies", props: { tweet: {} }, setup(e) { let t = e, r = n(() => t.tweet.conversation_count === 0 ? "Read more on X" : t.tweet.conversation_count === 1 ? `Read ${B(t.tweet.conversation_count)} reply` : `Read ${B(t.tweet.conversation_count)} replies`); return (t, n) => (m(), a("div", { class: d(t.$style.replies) }, [o("a", { class: d(t.$style.link), href: e.tweet.url, target: "_blank", rel: "noopener noreferrer" }, [o("span", { class: d(t.$style.text) }, y(r.value), 3)], 10, $e)], 2)); } }), [["__cssModules", { $style: { link: "ykg4nq_link", replies: "ykg4nq_replies", text: "ykg4nq_text" } }]]), X = /* @__PURE__ */ u({ __name: "embedded-tweet", props: { tweet: {}, components: {} }, setup(e) { let t = e, a = n(() => U(t.tweet)); return (t, n) => (m(), r(C, null, { default: x(() => [ l(J, { tweet: a.value, components: e.components }, null, 8, ["tweet", "components"]), a.value.in_reply_to_status_id_str ? (m(), r(Ie, { key: 0, tweet: a.value }, null, 8, ["tweet"])) : i("", !0), l(Ve, { tweet: a.value }, null, 8, ["tweet"]), a.value.mediaDetails?.length ? (m(), r(K, { key: 1, tweet: a.value, components: e.components }, null, 8, ["tweet", "components"])) : i("", !0), a.value.quoted_tweet ? (m(), r(b(q), { key: 2, tweet: a.value.quoted_tweet }, null, 8, ["tweet"])) : i("", !0), l(Je, { tweet: a.value }, null, 8, ["tweet"]), l(Qe, { tweet: a.value }, null, 8, ["tweet"]), l(et, { tweet: a.value }, null, 8, ["tweet"]) ]), _: 1 })); } }), Z = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "skeleton", props: { style: {} }, setup(e) { return (t, n) => (m(), a("span", { class: d(t.$style.skeleton), style: f(e.style) }, null, 6)); } }), [["__cssModules", { $style: { loading: "l4VFjW_loading", skeleton: "l4VFjW_skeleton" } }]]), tt = /* @__PURE__ */ S(/* @__PURE__ */ u({ __name: "tweet-skeleton", setup(e) { return (e, t) => (m(), r(C, { class: d(e.$style.root) }, { default: x(() => [ l(Z, { style: { height: "3rem", marginBottom: "0.75rem" } }), l(Z, { style: { height: "6rem", margin: "0.5rem 0" } }), t[0] ||= o("div", { style: { borderTop: "var(--tweet-border)", margin: "0.5rem 0" } }, null, -1), l(Z, { style: { height: "2rem" } }), l(Z, { style: { height: "2rem", borderRadius: "9999px", marginTop: "0.5rem" } }) ]), _: 1 }, 8, ["class"])); } }), [["__cssModules", { $style: { root: "Wi8Y9q_root" } }]]); //#endregion //#region src/composables/useTweet.ts async function nt(t, n) { let r = await fetch(t, n), i = await r.json(); if (r.ok) return i.data || null; throw new e({ message: `Failed to fetch tweet at "${t}" with "${r.status}".`, data: i, status: r.status }); } var Q = /* @__PURE__ */ new Map(); function rt() { Q.clear(); } function it(e, t) { let n = Q.get(e); if (n) return n; let r = nt(e, t).catch((t) => { throw Q.delete(e), t; }); return Q.set(e, r), r; } function $(e, t, n) { let r = h(!0), i = h(), a = h(null), o = async () => { if (!t && !e) { r.value = !1; return; } try { i.value = await it(`${t}/${e}`, n); } catch (e) { a.value = e; } finally { r.value = !1; } }; return te(() => { o(); }), { isLoading: r, data: i, error: a }; } function at() { let e = h(!1); return te(() => { e.value = !0; }), e; } //#endregion //#region src/tweet.vue var ot = /* @__PURE__ */ u({ __name: "tweet", props: { id: {}, apiUrl: { default: "https://react-tweet.vercel.app/api/tweet" }, fallback: { default: tt }, components: { default: () => E }, fetchOptions: { default: () => ({}) }, onError: { type: Function, default: (e) => e } }, setup(e) { let n = e, { isLoading: i, data: o, error: s } = $(n.id, n.apiUrl, n.fetchOptions); return (n, c) => b(i) ? (m(), r(b(e.fallback), { key: 0 })) : (m(), a(t, { key: 1 }, [b(s) || !b(o) ? (m(), r(v(e.components.TweetNotFound), { key: 0, error: e.onError(b(s)) }, null, 8, ["error"])) : (m(), r(b(X), { key: 1, tweet: b(o), components: e.components }, null, 8, ["tweet", "components"]))], 64)); } }); //#endregion export { X as EmbeddedTweet, q as QuotedTweet, P as QuotedTweetBody, j as QuotedTweetContainer, N as QuotedTweetHeader, ot as Tweet, Qe as TweetActions, Ye as TweetActionsCopy, Ve as TweetBody, C as TweetContainer, J as TweetHeader, Ie as TweetInReplyTo, Je as TweetInfo, qe as TweetInfoCreatedAt, Re as TweetLink, K as TweetMedia, G as TweetMediaVideo, ce as TweetNotFound, et as TweetReplies, tt as TweetSkeleton, O as Verified, k as VerifiedBusiness, A as VerifiedGovernment, it as cachedFetcher, rt as clearCache, E as defaultTwitterComponents, U as enrichTweet, B as formatNumber, L as getMediaUrl, z as getMp4Video, R as getMp4Videos, at as useMounted, $ as useTweet };