1import { r as reactExports, j as jsxRuntimeExports } from "./vendor-react-Bay9Y7Lb.js"; 2import { a as api } from "./index-D0Bmh-UX.js"; 3import { u as useShouldShowAd, A as AdSlot } from "./AdSlot-CPW4Sb2o.js"; 4import { u as useTranslation } from "./vendor-i18n-R-bMoYp_.js"; 5import { bg as Music, bA as Eye, dM as Calendar, aX as ArrowLeft, cm as ArrowRight } from "./vendor-dVNaLJx_.js"; 6const LyricsPage = ({ id, onNavigate }) => { 7 var _a; 8 const { t } = useTranslation(); 9 const shouldShowInArticleAd = useShouldShowAd("inArticleText"); 10 const [lyric, setLyric] = reactExports.useState(null); 11 const [loading, setLoading] = reactExports.useState(true); 12 const [error, setError] = reactExports.useState(null); 13 reactExports.useEffect(() => { 14 const effectiveId = id || window.location.pathname.replace(/^\/lyrics/, "").replace(/\.html$/, "").replace(/^\/+/, ""); 15 if (!effectiveId) { 16 setError("No lyrics ID provided."); 17 setLoading(false); 18 return; 19 } 20 setLoading(true); 21 api.getLyricsById(effectiveId).then((res) => { 22 setLyric(res); 23 setError(null); 24 }).catch((err) => { 25 setError(err.message || "Failed to load lyrics."); 26 }).finally(() => { 27 setLoading(false); 28 }); 29 }, [id]); 30 if (loading) { 31 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex h-full items-center justify-center min-h-[50vh] animate-pulse", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 border-4 border-indigo-500 border-t-transparent rounded-full animate-spin" }) }); 32 } 33 if (error || !lyric) { 34 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-8 max-w-2xl mx-auto text-center", children: [
35 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-16 bg-red-100 dark:bg-red-900/20 rounded-full flex items-center justify-center text-red-500 mx-auto mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Music, { size: 28 }) }), 36 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-bold text-zinc-900 dark:text-white mb-2", children: "Lyrics Offline" }), 37 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-zinc-500 dark:text-zinc-400 mb-6", children: error || "This lyrics record could not be found." }), 38 /* @__PURE__ */ jsxRuntimeExports.jsx( 39 "button", 40 { 41 onClick: () => onNavigate("home"), 42 className: "px-6 py-2.5 bg-indigo-600 text-white rounded-xl font-bold hover:bg-indigo-700 transition", 43 children: "Return to Portal" 44 } 45 ) 46 ] }); 47 } 48 const addedDate = lyric.createdAt ? new Date(lyric.createdAt).toLocaleDateString() : ""; 49 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 max-w-4xl mx-auto animate-in fade-in slide-in-from-bottom-4 duration-300", children: [ 50 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-sm text-zinc-500 mb-6", children: [
51 /* @__PURE__ */ jsxRuntimeExports.jsx("button", { onClick: () => onNavigate("home"), className: "hover:underline", children: t("lyrics.portal", "Portal") }), 52 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: "/" }), 53 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-zinc-800 dark:text-zinc-200 truncate", children: lyric.title }) 54 ] }), 55 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-r from-zinc-950 via-indigo-950/20 to-zinc-950 border border-zinc-200 dark:border-zinc-800/80 rounded-2xl p-6 sm:p-8 mb-8 shadow-xl", children: [ 56 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col sm:flex-row sm:items-center justify-between gap-4", children: [ 57 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 58 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-3xl sm:text-4xl font-extrabold text-zinc-900 dark:text-white mb-2 leading-tight", children: lyric.title }), 59 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-x-4 gap-y-2 text-zinc-400 text-sm", children: [ 60 lyric.artist && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1.5 text-indigo-400 font-semibold", children: [
61 /* @__PURE__ */ jsxRuntimeExports.jsx(Music, { size: 14 }), 62 lyric.artist 63 ] }), 64 lyric.album && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ 65 t("lyrics.album", "Album"), 66 ": ", 67 /* @__PURE__ */ jsxRuntimeExports.jsx("strong", { className: "text-zinc-200", children: lyric.album }) 68 ] }) 69 ] }) 70 ] }), 71 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 text-xs text-zinc-500", children: [ 72 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 73 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { size: 14 }), 74 lyric.views 75 ] }), 76 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1", children: [ 77 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { size: 14 }), 78 addedDate 79 ] }) 80 ] }) 81 ] }),
82 lyric.description && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 pt-4 border-t border-zinc-200 dark:border-zinc-800 text-sm text-zinc-400 italic", children: [ 83 '"', 84 lyric.description, 85 '"' 86 ] }) 87 ] }), 88 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-8", children: [ 89 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "lg:col-span-2 flex flex-col gap-6", children: [ 90 shouldShowInArticleAd && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full", children: /* @__PURE__ */ jsxRuntimeExports.jsx(AdSlot, { type: "inArticleText", className: "!my-0 min-h-[90px]" }) }), 91 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-white dark:bg-zinc-900 border border-zinc-200 dark:border-zinc-800/80 rounded-2xl p-6 sm:p-8 shadow-md", children: /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "font-sans text-lg text-zinc-800 dark:text-zinc-100 whitespace-pre-wrap leading-relaxed tracking-wide select-text", children: lyric.contents }) }) 92 ] }),
93 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-zinc-100 dark:bg-zinc-900/50 border border-zinc-200 dark:border-zinc-800/80 rounded-2xl p-6", children: [ 94 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-bold text-zinc-900 dark:text-white mb-4 text-sm uppercase tracking-wider", children: t("lyrics.details", "Lyrics Info") }), 95 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col gap-4 text-sm", children: [ 96 lyric.visitorName ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 97 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-500", children: [ 98 t("lyrics.submittedBy", "Submitted by"), 99 ":" 100 ] }), 101 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-zinc-800 dark:text-zinc-200 mt-0.5", children: lyric.visitorName }) 102 ] }) : ((_a = lyric.user) == null ? void 0 : _a.username) ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
103 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-500", children: [ 104 t("lyrics.submittedBy", "Submitted by"), 105 ":" 106 ] }), 107 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-semibold text-indigo-400 mt-0.5", children: lyric.user.username }) 108 ] }) : null, 109 lyric.tags && lyric.tags.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ 110 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-zinc-500", children: [ 111 t("lyrics.tags", "Tags"), 112 ":" 113 ] }), 114 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-wrap gap-1.5 mt-2", children: lyric.tags.map((tag) => /* @__PURE__ */ jsxRuntimeExports.jsxs( 115 "span", 116 { 117 onClick: () => onNavigate("tag", tag), 118 className: "px-2.5 py-1 bg-zinc-200 dark:bg-zinc-800 hover:bg-indigo-600 hover:text-white dark:hover:bg-indigo-600 transition text-zinc-700 dark:text-zinc-300 rounded-lg text-xs font-medium cursor-pointer", 119 children: [ 120 "#", 121 tag 122 ] 123 }, 124 tag 125 )) }) 126 ] }) 127 ] }) 128 ] }) }) 129 ] }), 130 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-t border-zinc-200 dark:border-zinc-800 mt-12 pt-6", children: [
131 /* @__PURE__ */ jsxRuntimeExports.jsxs( 132 "button", 133 { 134 onClick: () => onNavigate("home"), 135 className: "flex items-center gap-2 text-zinc-500 hover:text-indigo-500 text-sm font-medium transition", 136 children: [ 137 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { size: 16 }), 138 t("lyrics.previousSong", "Previous") 139 ] 140 } 141 ), 142 /* @__PURE__ */ jsxRuntimeExports.jsxs( 143 "button", 144 { 145 onClick: () => onNavigate("home"), 146 className: "flex items-center gap-2 text-zinc-500 hover:text-indigo-500 text-sm font-medium transition", 147 children: [ 148 t("lyrics.nextSong", "Next"), 149 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowRight, { size: 16 }) 150 ] 151 } 152 ) 153 ] }) 154 ] }); 155}; 156export { 157 LyricsPage as default 158};
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.