PageSourceSearch

https://gas769-lunatv.hf.space/_next/static/chunks/06l5xe1vxasmp.js

js gas769-lunatv.hf.space collected 2026-10-03 16:52:58 UTC 239,307 bytes, 1 lines download raw bytes

1(globalThis.TURBOPACK||(globalThis.TURBOPACK=[])).push(["object"==typeof document?document.currentScript:void 0,826771,e=>{"use strict";let a=(0,e.i(596779).default)("bug",[["path",{d:"M12 20v-9",key:"1qisl0"}],["path",{d:"M14 7a4 4 0 0 1 4 4v3a6 6 0 0 1-12 0v-3a4 4 0 0 1 4-4z",key:"uouzyp"}],["path",{d:"M14.12 3.88 16 2",key:"qol33r"}],["path",{d:"M21 21a4 4 0 0 0-3.81-4",key:"1b0z45"}],["path",{d:"M21 5a4 4 0 0 1-3.55 3.97",key:"5cxbf6"}],["path",{d:"M22 13h-4",key:"1jl80f"}],["path",{d:"M3 21a4 4 0 0 1 3.81-4",key:"1fjd4g"}],["path",{d:"M3 5a4 4 0 0 0 3.55 3.97",key:"1d7oge"}],["path",{d:"M6 13H2",key:"82j7cp"}],["path",{d:"m8 2 1.88 1.88",key:"fmnt4t"}],["path",{d:"M9 7.13V6a3 3 0 1 1 6 0v1.13",key:"1vgav8"}]]);e.s(["Bug",0,a],826771)},355570,e=>{"use strict";let a=(0,e.i(596779).default)("calendar",[["path",{d:"M8 2v4",key:"1cmpym"}],["path",{d:"M16 2v4",key:"4m81vk"}],["rect",{width:"18",height:"18",x:"3",y:"4",rx:"2",key:"1hopcy"}],["path",{d:"M3 10h18",key:"8toen8"}]]);e.s(["Calendar",0,a],355570)},761339,213200,e=>{"use strict";var a=e.i(596779);let r=(0,a.default)("cat",[["path",{d:"M12 5c.67 0 1.35.09 2 .26 1.78-2 5.03-2.84 6.42-2.26 1.4.58-.42 7-.42 7 .57 1.07 1 2.24 1 3.44C21 17.9 16.97 21 12 21s-9-3-9-7.56c0-1.25.5-2.4 1-3.44 0 0-1.89-6.42-.5-7 1.39-.58 4.72.23 6.5 2.23A9.04 9.04 0 0 1 12 5Z",key:"x6xyqk"}],["path",{d:"M8 14v.5",key:"1nzgdb"}],["path",{d:"M16 14v.5",key:"1lajdz"}],["path",{d:"M11.25 16.25h1.5L12 17l-.75-.75Z",key:"12kq1m"}]]);e.s(["Cat",0,r],761339);let t=(0,a.default)("clover",[["path",{d:"M16.17 7.83 2 22",key:"t58vo8"}],["path",{d:"M4.02 12a2.827 2.827 0 1 1 3.81-4.17A2.827 2.827 0 1 1 12 4.02a2.827 2.827 0 1 1 4.17 3.81A2.827 2.827 0 1 1 19.98 12a2.827 2.827 0 1 1-3.81 4.17A2.827 2.827 0 1 1 12 19.98a2.827 2.827 0 1 1-4.17-3.81A1 1 0 1 1 4 12",key:"17k36q"}],["path",{d:"m7.83 7.83 8.34 8.34",key:"1d7sxk"}]]);e.s(["Clover",0,t],213200)},555629,e=>{"use strict";let a=(0,e.i(596779).default)("chart-column",[["path",{d:"M3 3v16a2 2 0 0 0 2 2h16",key:"c24i48"}],["path",{d:"M18 17V9",key:"2bz60n"}],["path",{d:"M13 17V5",key:"1frdt8"}],["path",{d:"M8 17v-3",key:"17ska0"}]]);e.s(["BarChart3",0,a],555629)},687060,e=>{"use strict";let a=(0,e.i(596779).default)("check",[["path",{d:"M20 6 9 17l-5-5",key:"1gmf2c"}]]);e.s(["Check",0,a],687060)},590782,e=>{"use strict";let a=(0,e.i(596779).default)("chevron-up",[["path",{d:"m18 15-6-6-6 6",key:"153udz"}]]);e.s(["ChevronUp",0,a],590782)},672677,e=>{"use strict";var a=e.i(400900);e.s(["PlayCircle",()=>a.default])},420465,e=>{"use strict";let a=(0,e.i(596779).default)("download",[["path",{d:"M12 15V3",key:"m9g1x1"}],["path",{d:"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4",key:"ih7n3h"}],["path",{d:"m7 10 5 5 5-5",key:"brsn70"}]]);e.s(["Download",0,a],420465)},839475,e=>{"use strict";let a=(0,e.i(596779).default)("film",[["rect",{width:"18",height:"18",x:"3",y:"3",rx:"2",key:"afitv7"}],["path",{d:"M7 3v18",key:"bbkbws"}],["path",{d:"M3 7.5h4",key:"zfgn84"}],["path",{d:"M3 12h18",key:"1i2n21"}],["path",{d:"M3 16.5h4",key:"1230mu"}],["path",{d:"M17 3v18",key:"in4fa5"}],["path",{d:"M17 7.5h4",key:"myr1c1"}],["path",{d:"M17 16.5h4",key:"go4c1d"}]]);e.s(["Film",0,a],839475)},86502,e=>{"use strict";let a=(0,e.i(596779).default)("globe",[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M12 2a14.5 14.5 0 0 0 0 20 14.5 14.5 0 0 0 0-20",key:"13o1zl"}],["path",{d:"M2 12h20",key:"9i4pu4"}]]);e.s(["Globe",0,a],86502)},758453,441586,e=>{"use strict";var a=e.i(596779);let r=(0,a.default)("house",[["path",{d:"M15 21v-8a1 1 0 0 0-1-1h-4a1 1 0 0 0-1 1v8",key:"5wwlr5"}],["path",{d:"M3 10a2 2 0 0 1 .709-1.528l7-6a2 2 0 0 1 2.582 0l7 6A2 2 0 0 1 21 10v9a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z",key:"r6nss1"}]]);e.s(["Home",0,r],758453);let t=(0,a.default)("square-play",[["rect",{x:"3",y:"3",width:"18",height:"18",rx:"2",key:"h1oib"}],["path",{d:"M9 9.003a1 1 0 0 1 1.517-.859l4.997 2.997a1 1 0 0 1 0 1.718l-4.997 2.997A1 1 0 0 1 9 14.996z",key:"kmsa83"}]]);e.s(["PlaySquare",0,t],441586)},117406,e=>{"use strict";let a=(0,e.i(596779).default)("key-round",[["path",{d:"M2.586 17.414A2 2 0 0 0 2 18.828V21a1 1 0 0 0 1 1h3a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h1a1 1 0 0 0 1-1v-1a1 1 0 0 1 1-1h.172a2 2 0 0 0 1.414-.586l.814-.814a6.5 6.5 0 1 0-4-4z",key:"1s6t7t"}],["circle",{cx:"16.5",cy:"7.5",r:".5",fill:"currentColor",key:"w0ekpg"}]]);e.s(["KeyRound",0,a],117406)},381013,e=>{"use strict";let a=(0,e.i(596779).default)("plus",[["path",{d:"M5 12h14",key:"1ays0h"}],["path",{d:"M12 5v14",key:"s699le"}]]);e.s(["Plus",0,a],381013)},928413,e=>{"use strict";let a=(0,e.i(596779).default)("search",[["path",{d:"m21 21-4.34-4.34",key:"14j7rj"}],["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}]]);e.s(["Search",0,a],928413)},270221,e=>{"use strict";let a=(0,e.i(596779).default)("settings",[["path",{d:"M9.671 4.136a2.34 2.34 0 0 1 4.659 0 2.34 2.34 0 0 0 3.319 1.915 2.34 2.34 0 0 1 2.33 4.033 2.34 2.34 0 0 0 0 3.831 2.34 2.34 0 0 1-2.33 4.033 2.34 2.34 0 0 0-3.319 1.915 2.34 2.34 0 0 1-4.659 0 2.34 2.34 0 0 0-3.32-1.915 2.34 2.34 0 0 1-2.33-4.033 2.34 2.34 0 0 0 0-3.831A2.34 2.34 0 0 1 6.35 6.051a2.34 2.34 0 0 0 3.319-1.915",key:"1i5ecw"}],["circle",{cx:"12",cy:"12",r:"3",key:"1v7zrd"}]]);e.s(["Settings",0,a],270221)},532157,e=>{"use strict";let a=(0,e.i(596779).default)("tv",[["path",{d:"m17 2-5 5-5-5",key:"16satq"}],["rect",{width:"20",height:"15",x:"2",y:"7",rx:"2",key:"1e6viu"}]]);e.s(["Tv",0,a],532157)},962413,601057,e=>{"use strict";var a=e.i(228219),r=e.i(687060),t=e.i(82515),s=e.i(236390),l=e.i(419573),d=e.i(312614),o=e.i(502502),i=e.i(86502),n=e.i(381013),c=e.i(402458),x=e.i(475529),g=e.i(227222),u=e.i(539710);let m=(0,d.memo)(({initialConfig:e})=>{let r=(0,x.useQueryClient)(),[t,s]=(0,d.useState)(e.sources||[]),o=(0,d.useDeferredValue)(t),[m,h]=(0,d.useState)(null),[y,p]=(0,d.useState)(!1),[b,f]=(0,d.useState)(!1),[v,k]=(0,d.useState)(null),[j,N]=(0,d.useState)("apikey"),{data:w}
1=(0,c.useQuery)((0,g.queryOptions)({queryKey:["emby","public-sources"],queryFn:async()=>{let e=await fetch("/api/emby/public-sources");return e.ok?e.json():{sources:[]}},staleTime:3e5})),I=w?.sources||[];(0,d.useEffect)(()=>{s(e.sources||[])},[e]);let[S,P]=(0,d.useState)({enabled:!0,removeEmbyPrefix:!1,appendMediaSourceId:!1,transcodeMp4:!1,proxyPlay:!1}),A=(0,d.useRef)(null),C=(0,d.useRef)(null),T=(0,d.useRef)(null),R=(0,d.useRef)(null),E=(0,d.useRef)(null),U=(0,d.useRef)(null),M=(0,d.useRef)(null),D=()=>{P({enabled:!0,removeEmbyPrefix:!1,appendMediaSourceId:!1,transcodeMp4:!1,proxyPlay:!1}),h(null),p(!1),N("apikey"),A.current&&(A.current.value=""),C.current&&(C.current.value=""),T.current&&(T.current.value=""),R.current&&(R.current.value=""),E.current&&(E.current.value=""),U.current&&(U.current.value=""),M.current&&(M.current.value="")},_=async e=>{if(!confirm("确定要删除这个 Emby 源吗?"))return;let a=t.filter((a,r)=>r!==e);s(a);try{await fetch("/api/user/emby-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({config:{sources:a}})}),u.toast.success("删除成功"),r.invalidateQueries({queryKey:["user","emby-config"]})}catch{u.toast.error("删除失败")}},B=async e=>{let a=t[e];k(e);try{let e=await fetch("/api/emby/test",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),r=await e.json();r.success?u.toast.success(`连接成功!用户: ${r.user?.Name||"未知"}`):u.toast.error(`连接失败: ${r.error}`)}catch{u.toast.error("测试连接失败")}finally{k(null)}},O=async()=>{let e=A.current?.value||"",a=C.current?.value||"",l=T.current?.value||"",d=R.current?.value||"",o=E.current?.value||"",i=U.current?.value||"",n=M.current?.value||"";if(!e||!a||!l)return void u.toast.error("请填写必填字段:标识符、名称、服务器地址");if("apikey"===j&&!d)return void u.toast.error("使用密钥认证时,API Key 为必填项");if("password"===j&&!o)return void u.toast.error("使用账号认证时,用户名为必填项");if(null===m&&t.some(a=>a.key===e))return void u.toast.error("标识符已存在,请使用其他标识符");f(!0);try{let c={key:e,name:a,ServerURL:l,ApiKey:d,Username:o,Password:i,UserId:n,...S},x=null!==m?t.map((e,a)=>a===m?c:e):[...t,c],g=await fetch("/api/user/emby-config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({config:{sources:x}})}),h=await g.json();h.success?(s(x),u.toast.success("保存成功!"),r.invalidateQueries({queryKey:["user","emby-config"]}),D()):u.toast.error(`保存失败: ${h.error}`)}catch{u.toast.error("保存失败,请重试")}finally{f(!1)}};return(0,a.jsxs)("div",{className:"space-y-4",children:[I.length>0&&!y&&null===m&&(0,a.jsxs)("div",{className:"space-y-2",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 text-xs font-medium text-purple-700 dark:text-purple-400 uppercase tracking-wide",children:[(0,a.jsx)(i.Globe,{className:"w-3.5 h-3.5"}),(0,a.jsx)("span",{children:"公共源"}),(0,a.jsx)("span",{className:"text-purple-400 dark:text-purple-600 normal-case font-normal",children:"由管理员提供,自动可用"})]}),I.map(e=>(0,a.jsx)("div",{className:"p-3 border border-purple-200 dark:border-purple-800 rounded-lg bg-purple-50/50 dark:bg-purple-900/10",children:(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("h5",{className:"text-sm font-medium text-gray-900 dark:text-gray-100",children:e.name}),(0,a.jsx)("span",{className:"px-1.5 py-0.5 text-xs bg-purple-100 text-purple-700 dark:bg-purple-900/40 dark:text-purple-300 rounded",children:"公共"})]}),(0,a.jsx)("span",{className:"text-xs text-gray-400 dark:text-gray-500",children:"只读"})]})},e.key))]}),I.length>0&&o.length>0&&!y&&null===m&&(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),o.length>0&&!y&&null===m&&(0,a.jsxs)("div",{className:"space-y-3",children:[I.length>0&&(0,a.jsx)("div",{className:"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wide",children:"私人源"}),o.map((e,r)=>(0,a.jsx)("div",{className:"p-4 border border-gray-200 dark:border-gray-700 rounded-lg bg-gray-50 dark:bg-gray-800/50",children:(0,a.jsxs)("div",{className:"flex items-start justify-between",children:[(0,a.jsxs)("div",{className:"flex-1",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("h5",{className:"font-medium text-gray-900 dark:text-gray-100",children:e.name}),e.enabled?(0,a.jsx)("span",{className:"px-2 py-0.5 text-xs bg-green-100 text-green-700 dark:bg-green-900/30 dark:text-green-400 rounded",children:"已启用"}):(0,a.jsx)("span",{className:"px-2 py-0.5 text-xs bg-gray-100 text-gray-600 dark:bg-gray-700 dark:text-gray-400 rounded",children:"已禁用"})]}),(0,a.jsx)("p",{className:"text-sm text-gray-600 dark:text-gray-400 mt-1",children:e.ServerURL}
1),(0,a.jsxs)("p",{className:"text-xs text-gray-500 dark:text-gray-500 mt-1",children:["标识符: ",e.key]})]}),(0,a.jsxs)("div",{className:"flex items-center gap-2",children:[(0,a.jsx)("button",{onClick:()=>B(r),disabled:v===r,className:"px-3 py-1 text-xs text-blue-600 hover:text-blue-700 dark:text-blue-400 border border-blue-200 dark:border-blue-800 rounded transition-colors disabled:opacity-50",children:v===r?"测试中...":"测试"}),(0,a.jsx)("button",{onClick:()=>{let e;P({enabled:(e=t[r]).enabled??!0,removeEmbyPrefix:e.removeEmbyPrefix??!1,appendMediaSourceId:e.appendMediaSourceId??!1,transcodeMp4:e.transcodeMp4??!1,proxyPlay:e.proxyPlay??!1}),e.ApiKey?N("apikey"):e.Username?N("password"):N("apikey"),h(r),p(!1),setTimeout(()=>{A.current&&(A.current.value=e.key||""),C.current&&(C.current.value=e.name||""),T.current&&(T.current.value=e.ServerURL||""),R.current&&(R.current.value=e.ApiKey||""),E.current&&(E.current.value=e.Username||""),U.current&&(U.current.value=e.Password||""),M.current&&(M.current.value=e.UserId||"")},0)},className:"px-3 py-1 text-xs text-gray-600 dark:text-gray-400 border border-gray-200 dark:border-gray-700 rounded transition-colors",children:"编辑"}),(0,a.jsx)("button",{onClick:()=>_(r),className:"px-3 py-1 text-xs text-red-600 dark:text-red-400 border border-red-200 dark:border-red-800 rounded transition-colors",children:"删除"})]})]})},e.key))]}),!y&&null===m&&(0,a.jsxs)("button",{onClick:()=>{D(),p(!0)},className:"w-full px-4 py-2 text-sm font-medium text-blue-600 dark:text-blue-400 border-2 border-dashed border-blue-300 dark:border-blue-700 hover:border-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 rounded-lg transition-colors flex items-center justify-center gap-2",children:[(0,a.jsx)(n.Plus,{className:"w-4 h-4"}),"添加 Emby 源"]}),(y||null!==m)&&(0,a.jsxs)("div",{className:"p-4 border border-gray-200 dark:border-gray-700 rounded-lg space-y-3 bg-white dark:bg-gray-800",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-3",children:[(0,a.jsx)("h5",{className:"font-medium text-gray-900 dark:text-gray-100",children:null!==m?"编辑 Emby 源":"添加 Emby 源"}),(0,a.jsx)("button",{onClick:D,className:"text-gray-500 hover:text-gray-700 dark:text-gray-400",children:(0,a.jsx)(l.X,{className:"w-5 h-5"})})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"标识符 *"}),(0,a.jsx)("input",{ref:A,type:"text",disabled:null!==m,className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 disabled:opacity-50",placeholder:"例如: wumei"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"名称 *"}),(0,a.jsx)("input",{ref:C,type:"text",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",placeholder:"例如: 无名Emby"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"服务器地址 *"}),(0,a.jsx)("input",{ref:T,type:"text",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",placeholder:"http://192.168.1.100:8096"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"认证方式 *"}),(0,a.jsxs)("div",{className:"flex gap-2",children:[(0,a.jsx)("button",{type:"button",onClick:()=>{N("apikey"),E.current&&(E.current.value=""),U.current&&(U.current.value="")},className:`flex-1 px-3 py-1.5 text-sm rounded-lg font-medium transition-colors ${"apikey"===j?"bg-blue-600 text-white":"bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600"}`,children:"密钥认证"}),(0,a.jsx)("button",{type:"button",onClick:()=>{N("password"),R.current&&(R.current.value="")},className:`flex-1 px-3 py-1.5 text-sm rounded-lg font-medium transition-colors ${"password"===j?"bg-blue-600 text-white":"bg-gray-100 dark:bg-gray-700 text-gray-700 dark:text-gray-300 hover:bg-gray-200 dark:hover:bg-gray-600"}`,children:"账号认证"})]})]}),"apikey"===j&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"API Key *"}),(0,a.jsx)("input",{ref:R,type:"text",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",placeholder:"在 Emby 控制台的 API 密钥页面生成"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"用户 ID(可选)"}),(0,a.jsx)("input",{ref:M,type:"text",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",placeholder:"留空则自动获取"}),(0,a.jsx)("p",{className:"mt-1 text-xs text-gray-500 dark:text-gray-400",children:"不填则自动获取;å¦
1‚需指定其他用户可手动填写"})]})]}),"password"===j&&(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-2",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"用户名 *"}),(0,a.jsx)("input",{ref:E,type:"text",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100"})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1",children:"密码(可选)"}),(0,a.jsx)("input",{ref:U,type:"password",className:"w-full px-3 py-1.5 text-sm border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",placeholder:"没有密码可留空"})]})]}),(0,a.jsxs)("label",{className:"flex items-center gap-2 text-sm",children:[(0,a.jsx)("input",{type:"checkbox",checked:S.enabled,onChange:e=>P(a=>({...a,enabled:e.target.checked})),className:"w-4 h-4 text-green-500 border-gray-300 rounded focus:ring-green-500"}),(0,a.jsx)("span",{className:"text-gray-700 dark:text-gray-300",children:"启用此源"})]}),(0,a.jsxs)("details",{className:"mt-2",children:[(0,a.jsx)("summary",{className:"text-xs text-gray-600 dark:text-gray-400 cursor-pointer hover:text-gray-800 dark:hover:text-gray-200",children:"高级选项"}),(0,a.jsx)("div",{className:"mt-2 space-y-2 pl-2 border-l-2 border-gray-200 dark:border-gray-700",children:[{key:"transcodeMp4",label:"转码mp4(推荐MKV格式启用)"},{key:"proxyPlay",label:"视频播放代理"},{key:"removeEmbyPrefix",label:"移除/emby前缀"},{key:"appendMediaSourceId",label:"拼接MediaSourceId参数"}].map(({key:e,label:r})=>(0,a.jsxs)("label",{className:"flex items-center gap-2 text-xs",children:[(0,a.jsx)("input",{type:"checkbox",checked:S[e],onChange:a=>P(r=>({...r,[e]:a.target.checked})),className:"w-3 h-3 text-blue-500 border-gray-300 rounded focus:ring-blue-500"}),(0,a.jsx)("span",{className:"text-gray-600 dark:text-gray-400",children:r})]},e))})]}),(0,a.jsxs)("div",{className:"flex gap-2 pt-2",children:[(0,a.jsx)("button",{onClick:O,disabled:b,className:"flex-1 px-4 py-2 text-sm font-medium text-white bg-blue-500 hover:bg-blue-600 disabled:bg-gray-400 rounded-lg transition-colors",children:b?"保存中...":"保存"}),(0,a.jsx)("button",{onClick:D,className:"px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-700 hover:bg-gray-200 dark:hover:bg-gray-600 rounded-lg transition-colors",children:"取消"})]})]})]})});var h=e.i(977456),y=e.i(974412);let p=(0,g.queryOptions)({queryKey:["user","emby-config"],queryFn:async()=>{let e=await fetch("/api/user/emby-config"),a=await e.json();return a.success&&a.config?a.config:{sources:[]}},staleTime:3e5,gcTime:18e5});function b(e){return(0,c.useQuery)({...p,enabled:e})}function f(e,a){let r=localStorage.getItem(e);if(null===r)return a;try{return JSON.parse(r)}catch{return r}}e.s(["useChangePasswordMutation",0,function(){return(0,h.useMutation)({mutationFn:async({oldPassword:e,newPassword:a})=>{let r=await fetch("/api/change-password",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({oldPassword:e,newPassword:a})}),t=await r.json();if(!r.ok)throw Error(t.error||"修改密码失败");return t}})},"useEmbyConfigQuery",0,b,"useFavoritesQuery",0,function({enabled:e}){return(0,c.useQuery)({...(0,g.queryOptions)({queryKey:["favorites","userMenu"],queryFn:async()=>{let e=await fetch("/api/favorites");return e.ok?Object.entries(await e.json()).map(([e,a])=>({...a,key:e})).sort((e,a)=>a.save_time-e.save_time):[]},staleTime:12e4,gcTime:6e5}),enabled:e})},"useInvalidateUserMenuData",0,function(){let e=(0,x.useQueryClient)();return{invalidatePlayRecords:()=>{e.invalidateQueries({queryKey:["playRecords"]})},invalidateFavorites:()=>{e.invalidateQueries({queryKey:["favorites"]})},invalidateAll:()=>{e.invalidateQueries({queryKey:["playRecords"]}),e.invalidateQueries({queryKey:["favorites"]})}}},"usePlayRecordsQuery",0,function({enabled:e,enableFilter:a,minProgress:r,maxProgress:t}){return(0,c.useQuery)({...(0,g.queryOptions)({queryKey:["playRecords","userMenu",a,r,t],queryFn:async()=>{let e=await fetch("/api/playrecords");if(!e.ok)throw Error(`Failed to fetch play records: ${e.status}`);return Object.entries(await e.json()).map(([e,a])=>({...a,key:e})).filter(e=>{let s=0===e.total_time?0:e.play_time/e.total_time*100;return!(e.play_time<120)&&(!a||s>=r&&s<=t)}).sort((e,a)=>a.save_time-e.save_time).slice(0,12)},staleTime:12e4,gcTime:6e5}),enabled:e})},"useServerConfigQuery",0,function(){return(0,c.useQuery)((0,g.queryOptions)({queryKey:["serverConfig"],queryFn:async()=>{let e=await fetch("/api/server-config");return e.ok?{downloadEnabled:(await e.json()).DownloadEnabled??!0}:{downloadEnabled:!0}},staleTime:6e5,gcTime:18e5}))},"useVersionCheckQuery",0,function(){return(0,c.useQuery)((0,g.queryOptions)({queryKey:["versionCheck"],queryFn:()=>(0,y.checkForUpdates)(),staleTime:18e5,gcTime:36e5,retry:1}))},"useWatchRoomConfigQuery",0,function(){return(0,c.useQuery)((0,g.queryOptions)({queryKey:["watchRoomConfig"],queryFn:async()=>{let e=await fetch("/api/watch-room/config");return!0===(await e.json()).enabled},staleTime:6e5,gcTime:18e5}))}],601057);let v=[{value:"direct",label:"直连(服务器直接请求豆瓣)"},{value:"cors-proxy-zwei",label:"Cors Proxy By Zwei"},{value:"cmliussss-cdn-tencent",label:"豆瓣 CDN By CMLiussss(腾讯云)"},{value:"cmliussss-cdn-ali",label:"豆瓣 CDN By CMLiussss(阿里云)"},{value:"cmliussss-unified",label:"豆瓣 CDN By CMLiussss(统一域名)"},{value:"custom",label:"自定义代理"}],k=[{value:"server",label:"服务端转发(默认,访问官方 api.bgm.tv)"},{value:"cmliussss",label:"Bangumi 反代 By CMLiussss(解决服务器被墙)"},{value:"corsapi",label:"Cloudflare Worker 代理 By Smone"},{value:"sakura",label:"桜色镜像站(bangumi.lol,第三方镜像)"},{value:"custom",label:"自定义反代地址"}],j=[{value:"server",label:"服务器代理(默认,由服务器代理请求)"},{value:"cmliussss",label:"Bangumi 图片 CDN By CMLiussss"},{value:"corsapi",label:"Cloudflare Worker 代理 By Smone"},{value:"sakura",label:"桜色镜像站(bangumi.lol,第三方镜像)"},{value:"direct",label:"直连(浏览器直接请求 lain.bgm.tv)"},{value:"custom",label:"自定义代理"}],N=[{value:"direct",label:"直连(浏览器直接请求豆瓣)"},{value:"server",label:"服务器代理(由服务器代理请求豆瓣)"},{value:"img3",label:"豆瓣官方精品 CDN(阿里云)"},{value:"cmliussss-cdn-tencent",label:"豆瓣 CDN By CMLiussss(腾讯云)"},{value:"cmliussss-cdn-ali",label:"豆瓣 CDN By CMLiussss(阿里云)"},{value:"baidu",label:"百度图片代理(境内CDN,Chrome可能触发下载)"},{value:"custom",label:"自定义代理"}],w=[{value:"standard",label:"默认模式",description:"标准缓冲设置,适合网络稳
1定的环境",icon:"🎯",color:"green"},{value:"enhanced",label:"增强模式",description:"1.5倍缓冲,适合偶尔卡顿的网络环境",icon:"⚡",color:"blue"},{value:"max",label:"强力模式",description:"3倍大缓冲,起播稍慢但播放更流畅",icon:"🚀",color:"purple"}];function I(e){switch(e){case"cors-proxy-zwei":return{text:"Thanks to @Zwei",url:"https://github.com/bestzwei"};case"cmliussss-cdn-tencent":case"cmliussss-cdn-ali":case"cmliussss-unified":return{text:"Thanks to @CMLiussss",url:"https://github.com/cmliu"};default:return null}}let S=(0,d.memo)(({checked:e,onChange:r})=>(0,a.jsx)("label",{className:"flex items-center cursor-pointer",children:(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)("input",{type:"checkbox",className:"sr-only peer",checked:e,onChange:e=>r(e.target.checked)}),(0,a.jsx)("div",{className:"w-11 h-6 bg-gray-300 rounded-full peer-checked:bg-green-500 transition-colors dark:bg-gray-600"}),(0,a.jsx)("div",{className:"absolute top-0.5 left-0.5 w-5 h-5 bg-white rounded-full transition-transform peer-checked:translate-x-5"})]})}));S.displayName="Toggle";let P=(0,d.memo)(({isOpen:e,onClose:i})=>{let[n,c]=(0,d.useState)(!0),[x,g]=(0,d.useState)(""),[u,h]=(0,d.useState)(!1),[y,p]=(0,d.useState)(!0),[P,A]=(0,d.useState)(!1),[C,T]=(0,d.useState)("standard"),[R,E]=(0,d.useState)("direct"),[U,M]=(0,d.useState)("direct"),[D,_]=(0,d.useState)(""),[B,O]=(0,d.useState)(5),[L,V]=(0,d.useState)(100),[$,H]=(0,d.useState)(!1),[z,W]=(0,d.useState)(!0),[F,G]=(0,d.useState)(!0),[Q,q]=(0,d.useState)(!1),[K,Y]=(0,d.useState)("TS"),[X,J]=(0,d.useState)(!0),[Z,ee]=(0,d.useState)(!1),[ea,er]=(0,d.useState)(!1),[et,es]=(0,d.useState)(!1),[el,ed]=(0,d.useState)(!1),[eo,ei]=(0,d.useState)("cmliussss"),[en,ec]=(0,d.useState)(""),[ex,eg]=(0,d.useState)("cmliussss"),[eu,em]=(0,d.useState)(""),{data:eh={sources:[]}}=b(e);(0,d.useEffect)(()=>{let e=window.RUNTIME_CONFIG||{};c(f("defaultAggregateSearch",!0)),h(f("enableOptimization",!1)),p(f("fluidSearch",!1!==e.FLUID_SEARCH)),A(f("liveDirectConnect",!1)),g(f("doubanProxyUrl",e.DOUBAN_PROXY||"")),E(localStorage.getItem("doubanDataSource")??e.DOUBAN_PROXY_TYPE??"direct"),M(localStorage.getItem("doubanImageProxyType")??e.DOUBAN_IMAGE_PROXY_TYPE??"server"),_(f("doubanImageProxyUrl",e.DOUBAN_IMAGE_PROXY||"")),ei(localStorage.getItem("bangumiApiType")??"cmliussss"),ec(f("bangumiApiProxy","")),eg(localStorage.getItem("bangumiImageProxyType")??e.BANGUMI_IMAGE_PROXY_TYPE??"cmliussss"),em(f("bangumiImageProxyUrl",e.BANGUMI_IMAGE_PROXY||"")),O(f("continueWatchingMinProgress",5)),V(f("continueWatchingMaxProgress",100)),H(f("enableContinueWatchingFilter",!1)),W(f("enableAutoSkip",!0)),G(f("enableAutoNextEpisode",!0)),q(f("requireClearConfirmation",!1));let a=localStorage.getItem("downloadFormat");("TS"===a||"MP4"===a)&&Y(a);let r=localStorage.getItem("exactSearch");null!==r&&J("true"===r),T(f("playerBufferMode","standard"))},[]);let ey=(e,a,r=!0)=>t=>{e(t),localStorage.setItem(a,r?JSON.stringify(t):String(t))},ep=ey(c,"defaultAggregateSearch"),eb=ey(h,"enableOptimization"),ef=ey(p,"fluidSearch"),ev=ey(A,"liveDirectConnect"),ek=ey(q,"requireClearConfirmation"),ej=ey(Y,"downloadFormat",!1),eN=ey(H,"enableContinueWatchingFilter");if(!e)return null;let ew=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:i,onTouchMove:e=>e.preventDefault(),onWheel:e=>e.preventDefault(),style:{touchAction:"none"}}),(0,a.jsx)("div",{className:"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-xl max-h-[90vh] bg-white dark:bg-gray-900 rounded-xl shadow-xl z-1001 flex flex-col",children:(0,a.jsxs)("div",{className:"flex-1 p-6 overflow-y-auto","data-
1panel-content":!0,style:{touchAction:"pan-y",overscrollBehavior:"contain"},children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-6",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("h3",{className:"text-xl font-bold text-gray-800 dark:text-gray-200",children:"本地设置"}),(0,a.jsx)("button",{onClick:()=>{let e=window.RUNTIME_CONFIG||{},a=e.DOUBAN_PROXY_TYPE||"direct",r=e.DOUBAN_PROXY||"",t=e.DOUBAN_IMAGE_PROXY_TYPE||"server",s=e.DOUBAN_IMAGE_PROXY||"",l=!1!==e.FLUID_SEARCH;c(!0),h(!1),p(l),A(!1),g(r),E(a),M(t),_(s),ei(e.BANGUMI_API_TYPE||"cmliussss"),ec(e.BANGUMI_API_PROXY||""),eg(e.BANGUMI_IMAGE_PROXY_TYPE||"cmliussss"),em(e.BANGUMI_IMAGE_PROXY||""),O(5),V(100),H(!1),W(!0),G(!0),T("standard"),Y("TS"),localStorage.setItem("defaultAggregateSearch",JSON.stringify(!0)),localStorage.setItem("enableOptimization",JSON.stringify(!1)),localStorage.setItem("fluidSearch",JSON.stringify(l)),localStorage.setItem("liveDirectConnect",JSON.stringify(!1)),localStorage.setItem("doubanProxyUrl",r),localStorage.setItem("doubanDataSource",a),localStorage.setItem("doubanImageProxyType",t),localStorage.setItem("doubanImageProxyUrl",s),localStorage.setItem("bangumiApiType",e.BANGUMI_API_TYPE||"cmliussss"),localStorage.setItem("bangumiApiProxy",e.BANGUMI_API_PROXY||""),localStorage.setItem("bangumiImageProxyType",e.BANGUMI_IMAGE_PROXY_TYPE||"cmliussss"),localStorage.setItem("bangumiImageProxyUrl",e.BANGUMI_IMAGE_PROXY||""),localStorage.setItem("continueWatchingMinProgress","5"),localStorage.setItem("continueWatchingMaxProgress","100"),localStorage.setItem("enableContinueWatchingFilter",JSON.stringify(!1)),localStorage.setItem("enableAutoSkip",JSON.stringify(!0)),localStorage.setItem("enableAutoNextEpisode",JSON.stringify(!0)),localStorage.setItem("requireClearConfirmation",JSON.stringify(!1)),localStorage.setItem("playerBufferMode","standard"),localStorage.setItem("downloadFormat","TS")},className:"px-2 py-1 text-xs text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300 border border-red-200 hover:border-red-300 dark:border-red-800 dark:hover:border-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors",title:"重置为默认设置",children:"恢复默认"})]}),(0,a.jsx)("button",{onClick:i,className:"w-8 h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors","aria-label":"Close",children:(0,a.jsx)(l.X,{className:"w-full h-full"})})]}),(0,a.jsxs)("div",{className:"space-y-6",children:[(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Emby私人影库"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"配置你的私人 Emby 服务器"})]}),(0,a.jsx)(m,{initialConfig:eh})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"豆瓣数据代理"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"选择获取豆瓣数据的方式"})]}),(0,a.jsxs)("div",{className:"relative","data-dropdown":"douban-datasource",children:[(0,a.jsx)("button",{type:"button",onClick:()=>ee(!Z),className:"w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left",children:v.find(e=>e.value===R)?.label}),(0,a.jsx)("div",{className:"absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none",children:(0,a.jsx)(t.ChevronDown,{className:`w-4 h-4 text-gray-400 dark:text-gray-500 transition-transform duration-200 ${Z?"rotate-180":""}`})}),Z&&(0,a.jsx)("div",{className:"absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto",children:v.map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{var a;E(a=e.value),localStorage.setItem("doubanDataSource",a),ee(!1)},className:`w-full px-3 py-2.5 text-left text-sm transition-colors duration-150 flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-700 ${R===e.value?"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400":"text-gray-900 dark:text-gray-100"}`,children:[(0,a.jsx)("span",{className:"truncate",children:e.label}),R===e.value&&(0,a.jsx)(r.Check,{className:"w-4 h-4 text-green-600 dark:text-green-400 shrink-0 ml-2"})]},e.value))})]}),I(R)&&(0,a.jsx)("div",{className:"mt-3",children:(0,a.jsxs)("button",{type:"button",onClick:()=>window.open(I(R).url,"_blank"),className:"flex items-center justify-center gap-1.5 w-full px-3 text-xs text-gray-500 dark:text-gray-400 cursor-pointer",children:[(0,a.jsx)("span",{className:"font-medium",children:I(R).text}),(0,a.jsx)(s.ExternalLink,{className:"w-3.5 opacity-70"})]})})]}),"custom"===R&&(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"豆瓣代理地址"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"自定义代理服务器地址"})]}),(0,a.jsx)("input",{type:"text",className:"w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500",placeholder:"ä¾
1‹å¦‚: https://proxy.example.com/fetch?url=",value:x,onChange:e=>{var a;g(a=e.target.value),localStorage.setItem("doubanProxyUrl",a)}})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"豆瓣图片代理"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"选择获取豆瓣图片的方式"})]}),(0,a.jsxs)("div",{className:"relative","data-dropdown":"douban-image-proxy",children:[(0,a.jsx)("button",{type:"button",onClick:()=>er(!ea),className:"w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left",children:N.find(e=>e.value===U)?.label}),(0,a.jsx)("div",{className:"absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none",children:(0,a.jsx)(t.ChevronDown,{className:`w-4 h-4 text-gray-400 dark:text-gray-500 transition-transform duration-200 ${ea?"rotate-180":""}`})}),ea&&(0,a.jsx)("div",{className:"absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto",children:N.map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{var a;M(a=e.value),localStorage.setItem("doubanImageProxyType",a),er(!1)},className:`w-full px-3 py-2.5 text-left text-sm transition-colors duration-150 flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-700 ${U===e.value?"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400":"text-gray-900 dark:text-gray-100"}`,children:[(0,a.jsx)("span",{className:"truncate",children:e.label}),U===e.value&&(0,a.jsx)(r.Check,{className:"w-4 h-4 text-green-600 dark:text-green-400 shrink-0 ml-2"})]},e.value))})]}),I(U)&&(0,a.jsx)("div",{className:"mt-3",children:(0,a.jsxs)("button",{type:"button",onClick:()=>window.open(I(U).url,"_blank"),className:"flex items-center justify-center gap-1.5 w-full px-3 text-xs text-gray-500 dark:text-gray-400 cursor-pointer",children:[(0,a.jsx)("span",{className:"font-medium",children:I(U).text}),(0,a.jsx)(s.ExternalLink,{className:"w-3.5 opacity-70"})]})})]}),"custom"===U&&(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"豆瓣图片代理地址"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"自定义图片代理服务器地址"})]}),(0,a.jsx)("input",{type:"text",className:"w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500",placeholder:"例如: https://proxy.example.com/fetch?url=",value:D,onChange:e=>{var a;_(a=e.target.value),localStorage.setItem("doubanImageProxyUrl",a)}})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Bangumi 数据代理"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"服务器无法访问 api.bgm.tv 时可切换反代"})]}),(0,a.jsxs)("div",{className:"relative","data-dropdown":"bangumi-api",children:[(0,a.jsx)("button",{type:"button",onClick:()=>es(!et),className:"w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left",children:k.find(e=>e.value===eo)?.label}),(0,a.jsx)("div",{className:"absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none",children:(0,a.jsx)(t.ChevronDown,{className:`w-4 h-4 text-gray-400 dark:text-gray-500 transition-transform duration-200 ${et?"rotate-180":""}`})}),et&&(0,a.jsx)("div",{className:"absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto",children:k.map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{var a;ei(a=e.value),localStorage.setItem("bangumiApiType",a),es(!1)},className:`w-full px-3 py-2.5 text-left text-sm transition-colors duration-150 flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-700 ${eo===e.value?"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400":"text-gray-900 dark:text-gray-100"}`,children:[(0,a.jsx)("span",{className:"truncate",children:e.label}),eo===e.value&&(0,a.jsx)(r.Check,{className:"w-4 h-4 text-green-600 dark:text-green-400 shrink-0 ml-2"})]},e.value))})]}),"cmliussss"===eo&&(0,a.jsx)("div",{className:"mt-3",children:(0,a.jsxs)("button",{type:"button",onClick:()=>window.open("https://github.com/cmliu","_blank"),className:"flex items-center justify-center gap-1.5 w-full px-3 text-xs text-gray-500 dark:text-gray-400 cursor-pointer",children:[(0,a.jsx)("span",{className:"font-medium",children:"Thanks to @CMLiussss"}),(0,a.jsx)(s.ExternalLink,{className:"w-3.5 opacity-70"})]})})]}),"custom"===eo&&(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Bangumi 反代地址"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"与官方 api.bgm.tv 路径兼容的反代地址,不含末尾斜杠"})]}),(0,a.jsx)("input",{type:"text",className:"w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500",placeholder:"ä¾
1‹å¦‚: https://bgm-proxy.example.com",value:en,onChange:e=>{var a;ec(a=e.target.value),localStorage.setItem("bangumiApiProxy",a)}})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Bangumi 图片代理"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"选择获取 Bangumi 封面图片的方式"})]}),(0,a.jsxs)("div",{className:"relative","data-dropdown":"bangumi-image-proxy",children:[(0,a.jsx)("button",{type:"button",onClick:()=>ed(!el),className:"w-full px-3 py-2.5 pr-10 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 shadow-sm hover:border-gray-400 dark:hover:border-gray-500 text-left",children:j.find(e=>e.value===ex)?.label}),(0,a.jsx)("div",{className:"absolute inset-y-0 right-0 flex items-center pr-3 pointer-events-none",children:(0,a.jsx)(t.ChevronDown,{className:`w-4 h-4 text-gray-400 dark:text-gray-500 transition-transform duration-200 ${el?"rotate-180":""}`})}),el&&(0,a.jsx)("div",{className:"absolute z-50 w-full mt-1 bg-white dark:bg-gray-800 border border-gray-300 dark:border-gray-600 rounded-lg shadow-lg max-h-60 overflow-auto",children:j.map(e=>(0,a.jsxs)("button",{type:"button",onClick:()=>{var a;eg(a=e.value),localStorage.setItem("bangumiImageProxyType",a),ed(!1)},className:`w-full px-3 py-2.5 text-left text-sm transition-colors duration-150 flex items-center justify-between hover:bg-gray-100 dark:hover:bg-gray-700 ${ex===e.value?"bg-green-50 dark:bg-green-900/20 text-green-600 dark:text-green-400":"text-gray-900 dark:text-gray-100"}`,children:[(0,a.jsx)("span",{className:"truncate",children:e.label}),ex===e.value&&(0,a.jsx)(r.Check,{className:"w-4 h-4 text-green-600 dark:text-green-400 shrink-0 ml-2"})]},e.value))})]}),"cmliussss"===ex&&(0,a.jsx)("div",{className:"mt-3",children:(0,a.jsxs)("button",{type:"button",onClick:()=>window.open("https://github.com/cmliu","_blank"),className:"flex items-center justify-center gap-1.5 w-full px-3 text-xs text-gray-500 dark:text-gray-400 cursor-pointer",children:[(0,a.jsx)("span",{className:"font-medium",children:"Thanks to @CMLiussss"}),(0,a.jsx)(s.ExternalLink,{className:"w-3.5 opacity-70"})]})})]}),"custom"===ex&&(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"Bangumi 图片代理地址"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"自定义图片代理地址,图片 URL 将以编码形式拼接在后面"})]}),(0,a.jsx)("input",{type:"text",className:"w-full px-3 py-2.5 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400 shadow-sm hover:border-gray-400 dark:hover:border-gray-500",placeholder:"例如: https://proxy.example.com/fetch?url=",value:eu,onChange:e=>{var a;em(a=e.target.value),localStorage.setItem("bangumiImageProxyUrl",a)}})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"默认聚合搜索结果"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"搜索时默认按标题和年份聚合显示结果"})]}),(0,a.jsx)(S,{checked:n,onChange:ep})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"优选和测速"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"如出现播放器劫持问题可关闭"})]}),(0,a.jsx)(S,{checked:u,onChange:eb})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"流式搜索输出"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"启用搜索结果实时流式输出,关闭后使用传统一次性搜索"})]}),(0,a.jsx)(S,{checked:y,onChange:ef})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"精确搜索"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"开启后,搜索结果将过滤掉不包含搜索词的内容"})]}),(0,a.jsx)(S,{checked:X,onChange:e=>{J(e),localStorage.setItem("exactSearch",String(e))}})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"IPTV 视频浏览器直连"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"开启 IPTV 视频浏览器直连æ—
1¶ï¼Œéœ€è¦è‡ªå¤‡ Allow CORS 插件"})]}),(0,a.jsx)(S,{checked:P,onChange:ev})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"播放缓冲优化"}),(0,a.jsx)("p",{className:"text-xs text-gray-400 dark:text-gray-500 mt-1",children:"根据网络环境选择合适的缓冲模式,减少播放卡顿"})]}),(0,a.jsx)("div",{className:"space-y-2",children:w.map(e=>{let r=C===e.value,t={green:{selected:"border-transparent bg-linear-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 ring-2 ring-green-400/60 dark:ring-green-500/50 shadow-[0_0_15px_-3px_rgba(34,197,94,0.4)] dark:shadow-[0_0_15px_-3px_rgba(34,197,94,0.3)]",icon:"bg-linear-to-br from-green-100 to-emerald-100 dark:from-green-800/50 dark:to-emerald-800/50",check:"text-green-500",label:"text-green-700 dark:text-green-300"},blue:{selected:"border-transparent bg-linear-to-r from-blue-50 to-cyan-50 dark:from-blue-900/20 dark:to-cyan-900/20 ring-2 ring-blue-400/60 dark:ring-blue-500/50 shadow-[0_0_15px_-3px_rgba(59,130,246,0.4)] dark:shadow-[0_0_15px_-3px_rgba(59,130,246,0.3)]",icon:"bg-linear-to-br from-blue-100 to-cyan-100 dark:from-blue-800/50 dark:to-cyan-800/50",check:"text-blue-500",label:"text-blue-700 dark:text-blue-300"},purple:{selected:"border-transparent bg-linear-to-r from-purple-50 to-pink-50 dark:from-purple-900/20 dark:to-pink-900/20 ring-2 ring-purple-400/60 dark:ring-purple-500/50 shadow-[0_0_15px_-3px_rgba(168,85,247,0.4)] dark:shadow-[0_0_15px_-3px_rgba(168,85,247,0.3)]",icon:"bg-linear-to-br from-purple-100 to-pink-100 dark:from-purple-800/50 dark:to-pink-800/50",check:"text-purple-500",label:"text-purple-700 dark:text-purple-300"}}[e.color];return(0,a.jsxs)("button",{type:"button",onClick:()=>{var a;T(a=e.value),localStorage.setItem("playerBufferMode",a)},className:`w-full p-3 rounded-xl border-2 transition-all duration-300 text-left flex items-center gap-3 ${r?t.selected:"border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600 hover:shadow-sm bg-white dark:bg-gray-800"}`,children:[(0,a.jsx)("div",{className:`w-10 h-10 rounded-lg flex items-center justify-center text-xl transition-all duration-300 ${r?t.icon:"bg-gray-100 dark:bg-gray-700"}`,children:e.icon}),(0,a.jsxs)("div",{className:"flex-1 min-w-0",children:[(0,a.jsx)("div",{className:"flex items-center gap-2",children:(0,a.jsx)("span",{className:`font-medium transition-colors duration-300 ${r?t.label:"text-gray-900 dark:text-gray-100"}`,children:e.label})}),(0,a.jsx)("p",{className:"text-xs text-gray-400 dark:text-gray-500 mt-0.5 line-clamp-1",children:e.description})]}),(0,a.jsx)("div",{className:`w-5 h-5 rounded-full flex items-center justify-center transition-all duration-300 ${r?`${t.check} scale-100`:"text-transparent scale-75"}`,children:(0,a.jsx)("svg",{className:"w-5 h-5",fill:"currentColor",viewBox:"0 0 20 20",children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})})})]},e.value)})})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"跳过片头片尾设置"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"控制播放器默认的片头片尾跳过行为"})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h5",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"启用自动跳过"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"开启后将自动跳过片头片尾,关闭则显示手动跳过按钮"})]}),(0,a.jsx)(S,{checked:z,onChange:e=>{W(e),localStorage.setItem("enableAutoSkip",JSON.stringify(e)),window.dispatchEvent(new Event("localStorageChanged"))}})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h5",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"片尾自动播放下一集"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"开启后片尾结束时自动跳转到下一集"})]}),(0,a.jsx)(S,{checked:F,onChange:e=>{G(e),localStorage.setItem("enableAutoNextEpisode",JSON.stringify(e)),window.dispatchEvent(new Event("localStorageChanged"))}})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h5",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"清空记录确认提示"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"开启后点击清空按钮时会弹出确认对话框,防止误操作"})]}),(0,a.jsx)(S,{checked:Q,onChange:ek})]}),(0,a.jsx)("div",{className:"text-xs text-gray-500 dark:text-gray-400 bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg border border-blue-200 dark:border-blue-800",children:'💡 这些设置会作为新视频的默认配置。对于已配置的视频,请在播放页面的"跳过设置"中单独调整。'})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"继续观看进度筛选"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:'是否启用"继续观看"的播放进度筛选功能'})]}),(0,a.jsx)(S,{checked:$,onChange:eN})]}),$&&(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{children:(0,a.jsx)("h5",{className:"text-sm font-medium text-gray-600 dark:text-gray-400 mb-3",children:"进度范围设置"})}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-600 dark:text-gray-400 mb-2",children:"最小进度 (%)"}),(0,a.jsx)("input",{type:"number",min:"0",max:"100",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",value:
1B,onChange:e=>{var a;O(a=Math.max(0,Math.min(100,parseInt(e.target.value)||0))),localStorage.setItem("continueWatchingMinProgress",a.toString())}})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-600 dark:text-gray-400 mb-2",children:"最大进度 (%)"}),(0,a.jsx)("input",{type:"number",min:"0",max:"100",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-green-500 transition-all duration-200 bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100",value:L,onChange:e=>{var a;V(a=Math.max(0,Math.min(100,parseInt(e.target.value)||100))),localStorage.setItem("continueWatchingMaxProgress",a.toString())}})]})]}),(0,a.jsxs)("div",{className:"text-xs text-gray-500 dark:text-gray-400 bg-gray-50 dark:bg-gray-800 p-3 rounded-lg",children:["当前设置:显示播放进度在 ",B,"% - ",L,"% 之间的内容"]})]}),!$&&(0,a.jsx)("div",{className:"text-xs text-gray-500 dark:text-gray-400 bg-orange-50 dark:bg-orange-900/20 p-3 rounded-lg border border-orange-200 dark:border-orange-800",children:"筛选已关闭:将显示所有播放时间超过2分钟的内容"})]}),(0,a.jsx)("div",{className:"border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("div",{className:"space-y-3",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("h4",{className:"text-sm font-medium text-gray-700 dark:text-gray-300",children:"下载格式"}),(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"选择视频下载时的默认格式"})]}),(0,a.jsxs)("div",{className:"grid grid-cols-2 gap-3",children:[(0,a.jsx)("button",{type:"button",onClick:()=>ej("TS"),className:`p-4 rounded-lg border-2 transition-all duration-200 ${"TS"===K?"border-green-500 bg-green-50 dark:bg-green-900/20":"border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500"}`,children:(0,a.jsxs)("div",{className:"flex flex-col items-center gap-2",children:[(0,a.jsx)("div",{className:`text-2xl ${"TS"===K?"text-green-600 dark:text-green-400":"text-gray-500 dark:text-gray-400"}`,children:"📦"}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:`text-sm font-semibold ${"TS"===K?"text-green-700 dark:text-green-300":"text-gray-900 dark:text-gray-100"}`,children:"TS格式"}),(0,a.jsx)("div",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"推荐,兼容性好"})]}),"TS"===K&&(0,a.jsx)("div",{className:"w-5 h-5 rounded-full bg-green-500 text-white flex items-center justify-center",children:(0,a.jsx)("svg",{className:"w-3 h-3",fill:"currentColor",viewBox:"0 0 20 20",children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})})})]})}),(0,a.jsx)("button",{type:"button",onClick:()=>ej("MP4"),className:`p-4 rounded-lg border-2 transition-all duration-200 ${"MP4"===K?"border-blue-500 bg-blue-50 dark:bg-blue-900/20":"border-gray-300 dark:border-gray-600 hover:border-gray-400 dark:hover:border-gray-500"}`,children:(0,a.jsxs)("div",{className:"flex flex-col items-center gap-2",children:[(0,a.jsx)("div",{className:`text-2xl ${"MP4"===K?"text-blue-600 dark:text-blue-400":"text-gray-500 dark:text-gray-400"}`,children:"🎬"}),(0,a.jsxs)("div",{className:"text-center",children:[(0,a.jsx)("div",{className:`text-sm font-semibold ${"MP4"===K?"text-blue-700 dark:text-blue-300":"text-gray-900 dark:text-gray-100"}`,children:"MP4格式"}),(0,a.jsx)("div",{className:"text-xs text-gray-500 dark:text-gray-400 mt-1",children:"通用格式"})]}),"MP4"===K&&(0,a.jsx)("div",{className:"w-5 h-5 rounded-full bg-blue-500 text-white flex items-center justify-center",children:(0,a.jsx)("svg",{className:"w-3 h-3",fill:"currentColor",viewBox:"0 0 20 20",children:(0,a.jsx)("path",{fillRule:"evenodd",d:"M16.707 5.293a1 1 0 010 1.414l-8 8a1 1 0 01-1.414 0l-4-4a1 1 0 011.414-1.414L8 12.586l7.293-7.293a1 1 0 011.414 0z",clipRule:"evenodd"})})})]})})]}),(0,a.jsx)("div",{className:"text-xs text-gray-500 dark:text-gray-400 bg-blue-50 dark:bg-blue-900/20 p-3 rounded-lg border border-blue-200 dark:border-blue-800",children:"💡 TS格式下载速度快,兼容性好;MP4格式经过转码,体积略小,兼容性更广"})]})]}),(0,a.jsx)("div",{className:"mt-6 pt-4 border-t border-gray-200 dark:border-gray-700",children:(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 text-center",children:"这些设置保存在本地浏览器中"})})]})})]});return(0,o.createPortal)(ew,document.body)});P.displayName="SettingsPanel",e.s(["SettingsPanel",0,P],962413)},144972,e=>{"use strict";var a=e.i(228219),r=e.i(555629),t=e.i(268919),s=e.i(355570),l=e.i(420465),d=e.i(689927),o=e.i(117406),i=e.i(529536),n=e.i(672677),c=e.i(270221),x=e.i(835813),g=e.i(532157),u=e.i(369924),m=e.i(495796),h=e.i(419573),y=e.i(589818),p=e.i(312614),b=e.i(502502),f=e.i(475529),v=e.i(386909),k=e.i(810239),j=e.i(974412),N=e.i(333947),w=e.i(426015),I=e.i(992824),S=e.i(962413),P=e.i(601057),A=e.i(734918);e.s(["UserMenu",0,()=>{let e=(0,y.useRouter)();(0,f.useQueryClient)();let[C,T]=(0,p.useState)(!1),[R,E]=(0,p.useState)(!1),[U,M]=(0,p.useState)(!1),[D,_]=(0,p.useState)(!1),[B,O]=(0,p.useState)(!1),[L,V]=(0,p.useState)(!1),[$,H]=(0,p.useState)(!1),[z,W]=(0,p.useState)(null),[F,G]=(0,p.useState)(()=>window.RUNTIME_CONFIG?.STORAGE_TYPE||"localstorage"),[Q,q]=(0,p.useState)(!1),[K,Y]=(0,p.useState)(()=>
1{try{let e=localStorage.getItem("moontv_dismissed_releases");return e?new Set(JSON.parse(e)):new Set}catch{return new Set}}),X=z?.username&&"localstorage"!==F,{data:J}=(0,A.useWatchingUpdatesQuery)({enabled:X}),Z=(0,A.useRefreshWatchingUpdates)(),ee=J&&((J.updatedCount||0)>0||J.updatedSeries.filter(e=>e.hasNewRelease&&!K.has(`${e.sourceKey}+${e.videoId}`)).length>0),ea=(J?.updatedCount||0)+(J?.updatedSeries.filter(e=>e.hasNewRelease&&!K.has(`${e.sourceKey}+${e.videoId}`)).length||0),{data:er=!1}=(0,P.useWatchRoomConfigQuery)(),{data:et}=(0,P.useServerConfigQuery)(),es=et?.downloadEnabled??!0,{tasks:el,setShowDownloadPanel:ed}=(0,N.useDownload)(),{invalidatePlayRecords:eo}=(0,P.useInvalidateUserMenuData)();(0,p.useEffect)(()=>{if(R||U||B||L||$){let e=document.body,a=document.documentElement,r=e.style.overflow,t=a.style.overflow;return e.style.overflow="hidden",a.style.overflow="hidden",()=>{e.style.overflow=r,a.style.overflow=t}}},[R,U,B,L,$]);let[ei]=(0,p.useState)(()=>Number(localStorage.getItem("continueWatchingMinProgress"))||5),[en]=(0,p.useState)(()=>Number(localStorage.getItem("continueWatchingMaxProgress"))||100),[ec]=(0,p.useState)(()=>"true"===localStorage.getItem("enableContinueWatchingFilter")),[ex,eg]=(0,p.useState)(""),[eu,em]=(0,p.useState)(""),[eh,ey]=(0,p.useState)(""),[ep,eb]=(0,p.useState)(!1),[ef,ev]=(0,p.useState)(""),{data:ek=null,isLoading:ej}=(0,P.useVersionCheckQuery)(),eN=!!z?.username&&"localstorage"!==F,{data:ew=[]}=(0,P.usePlayRecordsQuery)({enabled:eN,enableFilter:ec,minProgress:ei,maxProgress:en}),{data:eI=[]}=(0,P.useFavoritesQuery)({enabled:eN}),eS=(0,P.useChangePasswordMutation)();(0,p.useEffect)(()=>{q(!0)},[]),(0,p.useEffect)(()=>{W((0,v.getAuthInfoFromBrowserCookie)())},[]);let eP=async()=>{let e=!C;T(e),e&&X&&(console.log("打开菜单时强制刷新追番更新..."),Z())},eA=()=>{T(!1)},eC=async()=>{try{await fetch("/api/logout",{method:"POST",headers:{"Content-Type":"application/json"}})}catch(e){console.error("注销请求失败:",e)}window.location.href="/"},eT=()=>{O(!1)},eR=()=>{V(!1)},eE=()=>{H(!1)},eU=e=>{let[a,r]=e.split("+");return{source:a,id:r}},eM=e=>0===e.total_time?0:e.play_time/e.total_time*100,eD=()=>{M(!1),eg(""),em(""),ey(""),ev("")},e_=async()=>{(ev(""),ex)?eu?eu.length<6?ev("新密码至少 6 位"):eu===ex?ev("新密码不得与旧密码相同"):eu!==eh?ev("两次输入的密码不一致"):(eb(!0),eS.mutate({oldPassword:ex,newPassword:eu},{onSuccess:async()=>{M(!1),await eC()},onError:e=>{ev(e.message||"网络错误,请稍后重试")},onSettled:()=>{eb(!1)}})):ev("新密码不得为空"):ev("旧密码不得为空")},eB=z?.role==="owner"||z?.role==="admin",eO=z?.role!=="owner"&&"localstorage"!==F,eL=z?.username&&"localstorage"!==F;console.log("UserMenu 更新提醒调试:",{username:z?.username,storageType:F,watchingUpdates:J,showWatchingUpdates:X,hasActualUpdates:ee,totalUpdates:ea});let eV=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-transparent z-1000",onClick:eA}),(0,a.jsxs)("div",{className:"fixed top-14 right-4 w-56 bg-white dark:bg-gray-900 rounded-lg shadow-xl z-1001 border border-gray-200/50 dark:border-gray-700/50 overflow-hidden select-none",children:[(0,a.jsx)("div",{className:"px-3 py-2.5 border-b border-gray-200 dark:border-gray-700 bg-linear-to-r from-gray-50 to-gray-100/50 dark:from-gray-800 dark:to-gray-800/50",children:(0,a.jsxs)("div",{className:"space-y-1",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("span",{className:"text-xs font-medium text-gray-500 dark:text-gray-400 uppercase tracking-wider",children:"当前用户"}),(0,a.jsx)("span",{className:`inline-flex items-center px-1.5 py-0.5 rounded-full text-xs font-medium ${"owner"===(z?.role||"user")?"bg-purple-100 text-purple-800 dark:bg-purple-900/30 dark:text-purple-300":"admin"===(z?.role||"user")?"bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300":"bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300"}`,children:(e=>{switch(e){case"owner":return"站长";case"admin":return"管理员";case"user":return"用户";default:return""}})(z?.role||"user")})]}),(0,a.jsxs)("div",{className:"flex items-center justify-between",children:[(0,a.jsx)("div",{className:"font-semibold text-gray-900 dark:text-gray-100 text-sm truncate",children:z?.username||"default"}),(0,a.jsxs)("div",{className:"text-[10px] text-gray-400 dark:text-gray-500",children:["数据存储:","localstorage"===F?"本地":F]})]})]})}),(0,a.jsxs)("div",{className:"py-1",children:[(0,a.jsxs)("button",{onClick:()=>{T(!1),E(!0)},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(c.Settings,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"设置"})]}),X&&(0,a.jsxs)("button",{onClick:()=>{T(!1),O(!0)},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm relative",children:[(0,a.jsx)(t.Bell,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"更新提醒"}),ee&&ea>0&&(0,a.jsx)("div",{className:"ml-auto flex items-center gap-1",children:(0,a.jsx)("span",{className:"inline-flex items-center justify-center w-5 h-5 text-xs font-bold text-white bg-red-500 rounded-full",children:ea>99?"99+":ea})})]}),X&&(0,a.jsxs)("button",{onClick:()=>{T(!1),V(!0)},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm relative",children:[(0,a.jsx)(n.PlayCircle,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"继续观看"}),ew.length>0&&(0,a.jsx)("span",{className:"ml-auto text-xs text-gray-400",children:ew.length})]}),X&&(0,a.jsxs)("button",{onClick:()=>{T(!1),H(!0)},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm relative",children:[(0,a.jsx)(d.Heart,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"我的收藏"}),eI.length>0&&(0,a.jsx)("span",{className:"ml-auto text-xs text-gray-400",children:eI.length})]}),eB&&(0,a.jsxs)("button",{onClick:()=>{T(!1),e.push("/admin")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(x.Shield,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"管理面板"})]}),eL&&(0,a.jsxs)("button",{onClick:()=>{T(!1),e.push("/play-stats")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(r.BarChart3,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:z?.role==="owner"||z?.role==="admin"?"播放统计":"个人统计"})]}),(0,a.jsxs)("button",{onClick:()=>{T(!1),e.push("/release-calendar")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(s.Calendar,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"上映日程"})]}),(0,a.jsxs)("button",{onClick:()=>{T(!1),e.push("/tvbox")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(g.Tv,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"TVBox 配置"})]}),er&&(0,a.jsxs)("button",{onClick:()=>{T(!1),e.push("/watch-room")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(m.Users,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"观影室"})]}),es&&(0,a.jsxs)("button",{onClick:()=>{ed(!0),eA()},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(l.Download,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"下载管理"}),el.filter(e=>"downloading"===e.status).length>0&&(0,a.jsxs)("span",{className:"ml-auto flex items-center gap-1",children:[(0,a.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,a.jsx)("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"}),(0,a.jsx)("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-green-500"})]}),(0,a.jsx)("span",{className:"text-xs text-green-600 dark:text-green-400",children:el.filter(e=>"downloading"===e.status).length})]}),el.length>0&&0===el.filter(e=>"downloading"===e.status).length&&(0,a.jsx)("span",{className:"ml-auto text-xs text-gray-400",children:el.length})]}),eO&&(0,a.jsxs)("button",{onClick:()=>{T(!1),M(!0),eg(""),em(""),ey(""),ev("")},className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(o.KeyRound,{className:"w-4 h-4 text-gray-500 dark:text-gray-400"}),(0,a.jsx)("span",{className:"font-medium",children:"修改密码"})]}),(0,a.jsx)("div",{className:"my-1 border-t border-gray-200 dark:border-gray-700"}),(0,a.jsxs)("button",{onClick:eC,className:"w-full px-3 py-2 text-left flex items-center gap-2.5 text-red-600 dark:text-red-400 hover:bg-red-50 dark:hover:bg-red-900/20 transition-[background-color] duration-150 ease-in-out text-sm",children:[(0,a.jsx)(i.LogOut,{className:"w-4 h-4"}),(0,a.jsx)("span",{className:"font-medium",children:"登出"})]}),(0,a.jsx)("div",{className:"my-1 border-t border-gray-200 dark:border-gray-700"}),(0,a.jsx)("button",{onClick:()=>{_(!0),eA()},className:"w-full px-3 py-2 text-center flex items-center justify-center text-gray-500 dark:text-gray-400 hover:bg-gray-50 dark:hover:bg-gray-800/50 transition-colors text-xs",children:(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsxs)("span",{className:"font-mono",children:["v",k.CURRENT_VERSION]}),!ej&&ek&&ek!==j.UpdateStatus.FETCH_FAILED&&(0,a.jsx)("div",{className:`w-2 h-2 rounded-full -translate-y-2 ${ek===j.UpdateStatus.HAS_UPDATE?"bg-yellow-500":ek===j.UpdateStatus.NO_UPDATE?"bg-green-400":""}`})]})})]})]})]}),e$=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:eD,onTouchMove:e=>{e.preventDefault()},onWheel:e=>{e.preventDefault()},style:{touchAction:"none"}}),(0,a.jsx)("div",{className:"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-md bg-white dark:bg-gray-900 rounded-xl shadow-xl z-1001 overflow-hidden",children:(0,a.jsxs)("div",{className:"h-full p-6","data-
1panel-content":!0,onTouchMove:e=>{e.stopPropagation()},style:{touchAction:"auto"},children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-6",children:[(0,a.jsx)("h3",{className:"text-xl font-bold text-gray-800 dark:text-gray-200",children:"修改密码"}),(0,a.jsx)("button",{onClick:eD,className:"w-8 h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors","aria-label":"Close",children:(0,a.jsx)(h.X,{className:"w-full h-full"})})]}),(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"旧密码"}),(0,a.jsx)("input",{type:"password",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent transition-colors bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400",placeholder:"请输入旧密码",value:ex,onChange:e=>eg(e.target.value),disabled:ep})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"新密码"}),(0,a.jsx)("input",{type:"password",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent transition-colors bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400",placeholder:"请输入新密码(至少6位)",value:eu,onChange:e=>em(e.target.value),disabled:ep})]}),(0,a.jsxs)("div",{children:[(0,a.jsx)("label",{className:"block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2",children:"确认密码"}),(0,a.jsx)("input",{type:"password",className:"w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md text-sm focus:outline-none focus:ring-2 focus:ring-green-500 focus:border-transparent transition-colors bg-white dark:bg-gray-800 text-gray-900 dark:text-gray-100 placeholder-gray-500 dark:placeholder-gray-400",placeholder:"请再次输入新密码",value:eh,onChange:e=>ey(e.target.value),disabled:ep})]}),ef&&(0,a.jsx)("div",{className:"text-red-500 text-sm bg-red-50 dark:bg-red-900/20 p-3 rounded-md border border-red-200 dark:border-red-800",children:ef})]}),(0,a.jsxs)("div",{className:"flex gap-3 mt-6 pt-4 border-t border-gray-200 dark:border-gray-700",children:[(0,a.jsx)("button",{onClick:eD,className:"flex-1 px-4 py-2 text-sm font-medium text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-800 hover:bg-gray-200 dark:hover:bg-gray-700 rounded-md transition-colors",disabled:ep,children:"取消"}),(0,a.jsx)("button",{onClick:e_,className:"flex-1 px-4 py-2 text-sm font-medium text-white bg-green-600 hover:bg-green-700 dark:bg-green-700 dark:hover:bg-green-600 rounded-md transition-colors disabled:opacity-50 disabled:cursor-not-allowed",disabled:ep||!ex||!eu||!eh,children:ep?"修改中...":"确认修改"})]}),(0,a.jsx)("div",{className:"mt-4 pt-4 border-t border-gray-200 dark:border-gray-700",children:(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 text-center",children:"修改密码后需要重新登录"})})]})})]}),eH=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:eT,onTouchMove:e=>{e.preventDefault()},onWheel:e=>{e.preventDefault()},style:{touchAction:"none"}}),(0,a.jsx)("div",{className:"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-4xl max-h-[90vh] bg-white dark:bg-gray-900 rounded-xl shadow-xl z-1001 flex flex-col",children:(0,a.jsxs)("div",{className:"flex-1 p-6 overflow-y-auto","data-
1panel-content":!0,style:{touchAction:"pan-y",overscrollBehavior:"contain"},children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-6",children:[(0,a.jsxs)("div",{className:"flex items-center gap-3",children:[(0,a.jsx)("h3",{className:"text-xl font-bold text-gray-800 dark:text-gray-200",children:"更新提醒"}),(0,a.jsx)("div",{className:"flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:J&&J.updatedCount>0&&(0,a.jsxs)("span",{className:"inline-flex items-center gap-1",children:[(0,a.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full animate-pulse"}),J.updatedCount,"部有新集"]})})]}),(0,a.jsx)("button",{onClick:eT,className:"w-8 h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors","aria-label":"Close",children:(0,a.jsx)(h.X,{className:"w-full h-full"})})]}),(0,a.jsxs)("div",{className:"space-y-8",children:[!ee&&(0,a.jsxs)("div",{className:"text-center py-8",children:[(0,a.jsx)("div",{className:"text-gray-500 dark:text-gray-400 text-sm",children:"暂无新剧集更新"}),(0,a.jsx)("div",{className:"text-xs text-gray-400 dark:text-gray-500 mt-2",children:"系统会定期检查您观看过的剧集是否有新集数更新"})]}),J&&J.updatedSeries.filter(e=>e.hasNewRelease&&!K.has(`${e.sourceKey}+${e.videoId}`)).length>0&&(0,a.jsxs)("div",{className:"mb-8",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 mb-4",children:[(0,a.jsx)("h4",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"🎬 新上映"}),(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsx)("div",{className:"w-2 h-2 bg-green-500 rounded-full animate-pulse"}),(0,a.jsxs)("span",{className:"text-sm text-green-500 font-medium",children:[J.updatedSeries.filter(e=>e.hasNewRelease&&!K.has(`${e.sourceKey}+${e.videoId}`)).length,"部新上映"]})]})]}),(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4",children:J.updatedSeries.filter(e=>e.hasNewRelease&&!K.has(`${e.sourceKey}+${e.videoId}`)).map((e,r)=>(0,a.jsxs)("div",{className:"relative group/card",children:[(0,a.jsx)("div",{className:"relative group-hover/card:z-5 transition-all duration-300",children:(0,a.jsx)(I.default,{title:e.title,poster:e.cover,year:e.year,source:e.sourceKey,source_name:e.source_name,episodes:e.totalEpisodes,id:e.videoId,onDelete:void 0,type:e.totalEpisodes>1?"tv":"movie",from:"favorite",remarks:e.remarks,releaseDate:e.releaseDate})}),(0,a.jsx)("div",{className:"absolute -top-2 -right-2 bg-green-600 text-white text-xs px-2 py-0.5 rounded-md shadow-lg animate-pulse z-10 font-bold",children:"新上映"}),(0,a.jsx)("button",{onClick:a=>{a.preventDefault(),a.stopPropagation(),((e,a)=>{let r=`${e}+${a}`,t=new Set(K);t.add(r),Y(t);try{localStorage.setItem("moontv_dismissed_releases",JSON.stringify([...t]))}catch(e){console.error("保存已忽略列表失败:",e)}})(e.sourceKey,e.videoId)},className:"absolute -top-2 -left-2 bg-gray-800/80 hover:bg-gray-900 text-white rounded-full p-1 shadow-lg z-10 opacity-0 group-hover/card:opacity-100 transition-opacity",title:"不再提醒",children:(0,a.jsx)(h.X,{className:"w-3 h-3"})})]},`release-${e.title}_${e.year}_${r}`))})]}),J&&J.updatedSeries.filter(e=>e.hasNewEpisode).length>0&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 mb-4",children:[(0,a.jsx)("h4",{className:"text-lg font-semibold text-gray-900 dark:text-white",children:"新集更新"}),(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsx)("div",{className:"w-2 h-2 bg-red-500 rounded-full animate-pulse"}),(0,a.jsxs)("span",{className:"text-sm text-red-500 font-medium",children:[J.updatedSeries.filter(e=>e.hasNewEpisode).length,"部剧集有更新"]})]})]}),(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4",children:J.updatedSeries.filter(e=>e.hasNewEpisode).map((e,r)=>(0,a.jsxs)("div",{className:"relative group/card",children:[(0,a.jsx)("div",{className:"relative group-hover/card:z-5 transition-all duration-300",children:(0,a.jsx)(I.default,{title:e.title,poster:e.cover,year:e.year,source:e.sourceKey,source_name:e.source_name,episodes:e.totalEpisodes,currentEpisode:e.currentEpisode,id:e.videoId,onDelete:void 0,type:e.totalEpisodes>1?"tv":"",from:"playrecord"})}),(0,a.jsxs)("div",{className:"absolute -top-2 -right-2 bg-red-600 text-white text-xs px-2 py-0.5 rounded-md shadow-lg animate-pulse z-10 font-bold",children:["+",e.newEpisodes]})]},`new-${e.title}_${e.year}_${r}`))})]})]}),(0,a.jsx)("div",{className:"mt-6 pt-4 border-t border-gray-200 dark:border-gray-700",children:(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 text-center",children:"点击海报即可观看新更新的剧集"})})]})})]}),ez=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:eR,onTouchMove:e=>{e.preventDefault()},onWheel:e=>{e.preventDefault()},style:{touchAction:"none"}}),(0,a.jsx)("div",{className:"fixed inset-x-4 top-1/2 transform -translate-y-1/2 max-w-4xl mx-auto bg-white dark:bg-gray-900 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 z-1001 max-h-[80vh] overflow-y-auto",onClick:e=>e.stopPropagation(),children:(0,a.jsxs)("div",{className:"p-6",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("h3",{className:"text-xl font-bold text-gray-900 dark:text-white flex items-center gap-2",children:[(0,a.jsx)(n.PlayCircle,{className:"w-6 h-6 text-blue-500"}),"继续观看"]}),(0,a.jsx)("button",{onClick:eR,className:"p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors",children:(0,a.jsx)(h.X,{className:"w-5 h-5"})})]}),(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4",children:ew.map(e=>{let{source:r,id:t}=eU(e.key),s=(e=>
1{if(!J||!J.updatedSeries)return 0;let{source:a,id:r}=eU(e.key),t=J.updatedSeries.find(e=>e.sourceKey===a&&e.videoId===r&&e.hasNewEpisode);return t&&t.newEpisodes||0})(e);return(0,a.jsxs)("div",{className:"relative group/card",children:[(0,a.jsx)("div",{className:"relative group-hover/card:z-5 transition-all duration-300",children:(0,a.jsx)(I.default,{id:t,title:e.title,poster:e.cover,year:e.year,source:r,source_name:e.source_name,progress:eM(e),episodes:e.total_episodes,currentEpisode:e.index,query:e.search_title,from:"playrecord",type:e.total_episodes>1?"tv":"",remarks:e.remarks})}),s>0&&(0,a.jsxs)("div",{className:"absolute -top-2 -right-2 bg-red-600 text-white text-xs px-2 py-0.5 rounded-md shadow-lg animate-pulse z-10 font-bold",children:["+",s]}),eM(e)>0&&(0,a.jsx)("div",{className:"absolute bottom-2 left-2 right-2 bg-black/50 rounded px-2 py-1",children:(0,a.jsxs)("div",{className:"flex items-center gap-1",children:[(0,a.jsx)("div",{className:"flex-1 bg-gray-600 rounded-full h-1",children:(0,a.jsx)("div",{className:"bg-blue-500 h-1 rounded-full transition-all",style:{width:`${Math.min(eM(e),100)}%`}})}),(0,a.jsxs)("span",{className:"text-xs text-white font-medium",children:[Math.round(eM(e)),"%"]})]})})]},e.key)})}),0===ew.length&&(0,a.jsxs)("div",{className:"text-center py-12",children:[(0,a.jsx)(n.PlayCircle,{className:"w-16 h-16 text-gray-300 dark:text-gray-600 mx-auto mb-4"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400 mb-2",children:"暂无需要继续观看的内容"}),(0,a.jsx)("p",{className:"text-xs text-gray-400 dark:text-gray-500",children:ec?`观看进度在${ei}%-${en}%之间且播放时间超过2分钟的内容会显示在这里`:"播放时间超过2分钟的所有内容都会显示在这里"})]}),(0,a.jsx)("div",{className:"mt-6 pt-4 border-t border-gray-200 dark:border-gray-700",children:(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 text-center",children:"点击海报即可继续观看"})})]})})]}),eW=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:eE,onTouchMove:e=>{e.preventDefault()},onWheel:e=>{e.preventDefault()},style:{touchAction:"none"}}),(0,a.jsx)("div",{className:"fixed inset-x-4 top-1/2 transform -translate-y-1/2 max-w-4xl mx-auto bg-white dark:bg-gray-900 rounded-xl shadow-2xl border border-gray-200 dark:border-gray-700 z-1001 max-h-[80vh] overflow-y-auto",onClick:e=>e.stopPropagation(),children:(0,a.jsxs)("div",{className:"p-6",children:[(0,a.jsxs)("div",{className:"flex items-center justify-between mb-4",children:[(0,a.jsxs)("h3",{className:"text-xl font-bold text-gray-900 dark:text-white flex items-center gap-2",children:[(0,a.jsx)(d.Heart,{className:"w-6 h-6 text-red-500"}),"我的收藏"]}),(0,a.jsx)("button",{onClick:eE,className:"p-2 text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-200 transition-colors",children:(0,a.jsx)(h.X,{className:"w-5 h-5"})})]}),(0,a.jsx)("div",{className:"grid grid-cols-2 sm:grid-cols-3 md:grid-cols-4 lg:grid-cols-5 xl:grid-cols-6 gap-4",children:eI.map(e=>{let{source:r,id:t}=eU(e.key),s=e.remarks,l=!1;if(e.releaseDate){let a=new Date;a.setHours(0,0,0,0);let r=Math.ceil((new Date(e.releaseDate).getTime()-a.getTime())/864e5);if(r<0){let e=Math.abs(r);s=`已上映${e}天`,e<=7&&(l=!0)}else 0===r?(s="今日上映",l=!0):s=`${r}天后上映`}return(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsx)(I.default,{id:t,title:e.title,poster:e.cover,year:e.year,source:r,source_name:e.source_name,episodes:e.total_episodes,query:e.search_title,from:"favorite",type:e.total_episodes>1?"tv":"",remarks:s,releaseDate:e.releaseDate}),l&&(0,a.jsx)("div",{className:"absolute top-2 left-2 bg-orange-500 text-white text-xs font-bold px-3 py-1 rounded-md shadow-lg animate-pulse z-40",children:"新上映"})]},e.key)})}),0===eI.length&&(0,a.jsxs)("div",{className:"text-center py-12",children:[(0,a.jsx)(d.Heart,{className:"w-16 h-16 text-gray-300 dark:text-gray-600 mx-auto mb-4"}),(0,a.jsx)("p",{className:"text-gray-500 dark:text-gray-400 mb-2",children:"暂无æ”
1¶è—"}),(0,a.jsx)("p",{className:"text-xs text-gray-400 dark:text-gray-500",children:"在详情页点击收藏按钮即可添加收藏"})]}),(0,a.jsx)("div",{className:"mt-6 pt-4 border-t border-gray-200 dark:border-gray-700",children:(0,a.jsx)("p",{className:"text-xs text-gray-500 dark:text-gray-400 text-center",children:"点击海报即可进入详情页面"})})]})})]});return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsxs)("div",{className:"relative",children:[(0,a.jsxs)("button",{onClick:eP,className:"relative w-10 h-10 p-2 rounded-full flex items-center justify-center text-gray-600 hover:text-blue-500 dark:text-gray-300 dark:hover:text-blue-400 transition-all duration-300 hover:scale-110 hover:shadow-lg hover:shadow-blue-500/30 dark:hover:shadow-blue-400/30 group","aria-label":"User Menu",children:[(0,a.jsx)("div",{className:"absolute inset-0 rounded-full bg-linear-to-br from-blue-400/0 to-purple-600/0 group-hover:from-blue-400/20 group-hover:to-purple-600/20 dark:group-hover:from-blue-300/20 dark:group-hover:to-purple-500/20 transition-all duration-300"}),(0,a.jsx)(u.User,{className:"w-full h-full relative z-10 group-hover:scale-110 transition-transform duration-300"})]}),(ek===j.UpdateStatus.HAS_UPDATE||ee&&ea>0)&&(0,a.jsx)("div",{className:"absolute top-[2px] right-[2px] w-2 h-2 bg-yellow-500 rounded-full animate-pulse shadow-lg shadow-yellow-500/50"})]}),C&&Q&&(0,b.createPortal)(eV,document.body),R&&Q&&(0,a.jsx)(S.SettingsPanel,{isOpen:R,onClose:()=>{E(!1)}}),U&&Q&&(0,b.createPortal)(e$,document.body),B&&Q&&(0,b.createPortal)(eH,document.body),L&&Q&&(0,b.createPortal)(ez,document.body),$&&Q&&(0,b.createPortal)(eW,document.body),(0,a.jsx)(w.VersionPanel,{isOpen:D,onClose:()=>_(!1)})]})}])},426015,e=>{"use strict";var a=e.i(228219),r=e.i(826771),t=e.i(802972),s=e.i(82515),l=e.i(590782),d=e.i(420465),o=e.i(381013),i=e.i(652419),n=e.i(419573),c=e.i(312614),x=e.i(502502);let g=[{version:"6.6.5",date:"2026-10-01",added:["🚀 HLS 并发分片预取:新增 OptimizedHlsLoader,主
1加载同时预取后续 2-3 个分片,缓冲速度提升 2-4 倍;缓存上限 50MB,连续失败 3 次自动熔断,跳过 Byte-Range 分片,保留广告过滤与源站标识","🔐 统一认证模块:新增 src/lib/auth.ts,登录/注册/OIDC/Telegram 等路由统一使用密码哈希(HMAC-SHA256)校验与签名生成逻辑"],changed:["📦 依赖升级:Next.js 16.1.0→16.3.6、React/React-DOM 19.2.3→19.3.0、hls.js 1.7.1→1.7.3、@mui/material 升级至 9.4.0、@tanstack/react-virtual 升级至 3.14.13、framer-motion 升级至 13.2.0、TanStack Query 系列升级至 5.103.1;移除未使用的依赖;新增 GitHub Actions CI 配置","⚡ 播放体验优化:测速重构为固定并发 worker pool,避免源数量多时创建大量 hls 实例;Wake Lock 释放时机统一移至 video:ended 事件","📥 下载性能优化:大于 512KB 的 TS 分片先探测大小再切 4 块 Range 并发下载合并,突破源站单连接限速;不支持 Range 的源站直接复用完整响应,fMP4 BYTERANGE 场景跳过分块"],fixed:["🎬 视频代理播放修复:修复开启视频代理(Cloudflare Worker)后 m3u8 无法播放的问题——代理地址会被 ArtPlayer 误判格式而退回原生 video 播放,导致 hls.js 未启动且降级直连永不触发;现对 m3u8 及其代理地址显式指定播放类型,换集/换源时同步更新,并在 hls.js 未启动时兜底降级为直连","🛡️ 安全加固:修改密码接口增加旧密码校验和新密码合法性检查;定时任务增加 5 分钟最小执行间隔节流;图片代理增加 MIME 类型检查,防止上游返回非图片内容;HTTPS 部署时 Cookie Secure 属性动态判断;admin 与代理路由改用哈希校验替代明文比对"]},{version:"6.6.4",date:"2026-08-23",added:["🌐 CORSAPI Cloudflare Worker 代理:Bangumi 数据/图片代理、TMDB 请求均新增 Cloudflare Worker 加速选项;VideoProxyConfig 开关同时加速 m3u8/视频播放流,Emby 源跳过(需自定义鉴权头)","🎬 Bangumi 数据源新增桜色镜像站(bangumi.lol)选项","🛡️ VOD 播放容错:直连失败时自动降级到第一方 HLS 代理,形成直连 -> Worker 直连 -> 第一方代理三级 fallback"],changed:["📦 依赖升级:hls.js 1.6.16→1.7.1、TanStack Query/react-virtual 系列升级至 5.102.0/3.14.10、@mui/material 升级至 9.3.1、sonner 升级至 2.0.8、ipaddr.js 升级至 2.5.0,EdgeOne Node.js 版本调整为 22.11.0 LTS","⚡ 播放体验优化:关闭点播场景 lowLatencyMode 减少卡顿;换源后弹幕改为跟随实际切换完成触发;换源时清除旧播放记录改为异步执行,避免阻塞状态更新","🚀 性能优化:非关键组件改为动态导入减少首屏 JS 体积;响应缓存策略细化(public/private);搜索单源超时从 20s 降至 10s;登入地理位置查询改为异步执行不阻塞登录"],fixed:["🛡️ 安全加固:检测弱默认密码并跳转警告页;代理路由响应体加大小上限防止内存打爆;采集源保存新增 SSRF 校验;登录接口加暴力破解限流","🌐 EdgeOne 部署修复:修复首页未跳转 /login 及 middleware/proxy 构建冲突;修复 Next.js 16 proxy.ts 导致的 /warning 误重定向;修复 node:sqlite 导致的部署崩溃","🎬 播放修复:支持非 m3u8 URL 并修复反向代理端口问题;修复分享页链接被误判优先于真实 m3u8 链接的问题;修复 corsapi bangumi 代理路径拼接错误","📱 UI/交互修复:修复登录/注册页错误提示动画错位;修复 iOS 沉浸式状态栏未生效问题;修复分片下载失败时仍误报“下载完成”的问题","🔧 其他修复:Spider JAR md5 锁定版本并加并发去重,避免 TVBox 校验不一致"]},{version:"6.6.3",date:"2026-06-26",added:["🔍 Nyaa 搜索与下载导出:支持 Nyaa 种子站搜索及下载链接导出","🔐 PanSou 认证支持:新增盘搜身份认证,支持需要登录的私有搜索接口","🖼️ Bangumi 图片代理:新增 Bangumi 封面图片代理,支持用户自选代理方式","🏠 HomeBanner TMDB Logo:首页 HeroBanner 新增 TMDB logo 展示及撤销删除功能","📺 Bangumi 集成增强:管理员缓存管理器新增 Bangumi 独立缓存分类,移动端操作面板展示番剧详情","🌐 EdgeOne 部署支持:新增腾讯云 EdgeOne 部署方案及构建脚本","📡 TVBox 代理增强:新增 TVBox/Video 代理端点配置、detail 接口及剧集标题格式化","🎬 视频分辨率推断与筛选:自动推断视频流分辨率并支持按分辨率筛选","🌍 翻译插件检测警告:检测到浏览器翻译插件时弹出友好提示 Toast","🔑 自定义 X-Emby-Authorization 请求头:支持用户自定义 Emby 鉴权请求头","🏗️ Next.js 构建阶段环境标志:standalone 模式新增构建阶段环境变量标记"],changed:["📦 @mui/material 升级至 9.1.2","📦 @tanstack/react-virtual 升级至 3.14.4","📦 TanStack Query 升级至 5.101.0"],fixed:["🛡️ 翻译插件 DOM 崩溃防护:为页面根容器加 `translate='no'` 并用 DOMErrorBoundary 包裹内容,多层防止浏览器翻译插件修改 DOM 导致 React 崩溃;ErrorBoundary 新增 removeChild 错误自动恢复","🌐 Bangumi CN 区修复:修复中国区 API 被拦截导致首页崩溃问题,新增多层智能降级策略;修复 useState 初始值、localStorage 重置及管理面板缺少默认 cmliussss 的问题;修复服务端日历 API 返回非数组时的错误","📺 短剧数据源修复:迁移短剧 API 数据源并支持子分类,首页热门短剧返回空时自动切换至第一个非空子分类,当前分类无结果时自动跳转下一分类","🐛 豆瓣数据清理:过滤推荐 API 返回的广告及播放列表条目,过滤列表中 null/undefined 条目防止 renderItem 崩溃","⏩ 快进/快退图标方向修复:修复播放器快进快退按钮图标方向错误","🖼️ 分辨率与 TMDB Logo 修复:修复下游解析层分辨率标注问题;优化 TMD
1B logo 在深色背景的显示效果,防止溢出","🎨 播放器锁定模式:锁定模式下彻底隐藏控制栏背景","⚡ 卡片点击性能优化:优化卡片点击响应速度并加强 DOM 错误追踪","🔧 代理端口转发修复:修复代理层端口转发问题"]},{version:"6.6.2",date:"2026-05-30",added:["🎬 PlayInfoPanel Hero Banner:新增 TMDB backdrop 背景图、logo 图片、海报、评分、简介展示,支持多季徽章(共X季)","🔍 豆瓣快速信息面板:新增豆瓣 quick-info 和 suggest API,MobileActionSheet 接入豆瓣详情","🌐 豆瓣代理新增 cmliussss 统一 CDN 选项","🗄️ TMDB 服务端缓存:TMDB backdrop API 新增 db.getCache/setCache 服务端缓存(tmdb- 前缀,24小时 TTL),与管理员缓存管理集成"],changed:["🎬 PlayInfoPanel 重构:以 TMDB backdrop 为主视觉,TMDB logo/poster/评分/简介优先展示,收藏按钮移至简介下方","🔍 TMDB 搜索优化:自动清理标题中的「第X季」「Season X」「S1」「年份」等后缀;移除年份参数避免年份不一致导致搜索失败;根据 stype(movie/tv)只搜对应端点,避免电视剧搜到同名电影","🐛 TMDB 与豆瓣数据获取完全独立:移除 loadingMovieDetails 守卫,两者并行加载互不阻塞","📺 直播频道展开触发区域:缩小为仅 chevron 按钮触发展开,避免误触"],fixed:["📺 直播错误覆盖:在 artplayer ready 事件清除 unsupportedType,频道慢速连接成功后不再显示错误覆盖层","🔧 直播频道健康检查:修复 directPlaybackEnabled 未加入 useCallback 依赖导致的问题","⚡ 管理员播放统计 API:并行化每用户数据库查询,提升性能","📱 登入详情卡片:修复移动端地区徽章溢出问题,优化登入 IP/设备信息响应式布局"]},{version:"6.6.1",date:"2026-05-29",added:["📍 登入追踪增强:记录用户每次登入的客户端IP、ip-api.com 归属地(城市/省份/国家)、设备类型(手机/平板/桌面)、浏览器及操作系统,无需外部依赖或API Key,覆盖 Redis/Upstash/SQLite 三种存储后端","🗄️ SQLite 存储后端:新增 SQLite 存储实现(SqliteStorage),支持无需外部数据库的本地部署","🔑 跨源跳过配置共享:新增 identityKey 支持,允许不同视频源共享同一套跳过配置","🕐 全屏时钟:全屏播放模式下显示实时时钟覆盖层","🖼️ 进度条缩略图预览:集成 artplayer-plugin-auto-thumbnail,进度条悬停时显示视频帧预览","🔍 用户管理搜索过滤:管理员用户管理表格新增用户名搜索过滤功能","🌐 VirtualGrid 滚动位置持久化:路由切换后恢复滚动位置,支持豆瓣/搜索/短剧/Emby 四个列表页,30分钟TTL","⚡ ChunkLoadError 自动恢复:部署后旧 chunk 失效时自动触发单次硬刷新,10秒TTL防止无限循环","🛡️ 可信网络访客管理员访问拦截:可信网络自动登入的访客可选择性屏蔽 /admin 访问,密码登入的站长不受影响","🔗 Bangumi API 代理配置:管理员面板和用户设置均可配置 Bangumi API 代理(server/cmliussss/自定义),用户设置优先","📡 DNS 缓存与重试机制:新增 DNS 缓存和请求重试机制,提升视频源连接稳定性","🧪 视频源测速与状态持久化:优化视频源测速排序逻辑,source-browser 页面新增筛选条件和分类状态持久化"],changed:["🐳 Docker 基础镜像升级:从 node:20-alpine 升级至 node:22-alpine(Node 22 LTS,SQLite DatabaseSync 无需实验性标志)","📦 @tanstack/react-query 升级至 5.100.14,TrustedNetworkConfig 迁移至 TanStack Query"],fixed:["🎬 直连模式修复:修复 HLS loader 读取错误的 localStorage key,添加 isLunaProxyUrl() 守卫防止 moontv-source 参数注入外部 CDN URL,直连模式下跳过健康检查","⚡ 播放速率修复:修复切换视频源或剧集时播放速率被重置的问题","🎬 播放器锁定模式修复:移除锁定模式下的背景渐变,修复浮动快进按钮在锁定时仍显示的问题","🔄 source-browser URL 状态修复:修复 URL 参数与状态的同步循环,正确从 URL 恢复来源和分类,修复分类高亮类型比较和加载时分类参数丢失问题","🛡️ 浏览器翻译插件崩溃防护加固:在所有页面根容器加 translate='no',防止 Safari/Chrome 翻译插件修改 DOM 导致 React removeChild 崩溃(补充 layout.tsx 的 html 级防护)","🔧 DOM 节点守卫:修复 undefined 列表和过期 DOM 节点引用导致的崩溃"]},{version:"6.6.0",date:"2026-05-09",added:["🔍 外部流量监控优化:过滤无效域名(0.0.0.0、localhost、内网IP)显示","📊 动态Cron阈值:基于实际用户数动态计算查询阈值","🔐 SSRF保护绕过:为私有部署添加DISABLE_SSRF_PROTECTION环境变量","🎯 剧集选择器:速度测试后自动按速度排序","⏱️ API缓存统一:统一所有API缓存时长为2小时"],changed:["⚡ Cron性能优化:通过进程级缓存减少数据库查询94%(466→28-30查询)","🔧 Cron配置集中化:创建DEFAULT_CRON_CONFIG作为单一配置源","📉 Cron默认值优化:批处理大小降至50条,活跃窗口缩短至21天","🚀 TanStack Query迁移:YouTube和Bilibili搜索迁移到TanStack Query","📊 豆瓣/短剧页面优化:迁移到useInfiniteQuery + 虚拟滚动"],fixed:["🐛 SSR错误完全修复:修复所有服务端渲染时访问浏览器API导致的崩溃(utils.ts、download-idb.ts、stream-saver.ts、AnimatedCardGrid.tsx、HomeClient.tsx、HeroBanner.tsx)","🔄 数据迁移增强:API读取时自动升级旧版用户数据字段","🎨 UI优化:播放按钮悬停改为轮廓样式,扩大控制栏悬停区域","📝 数据导入导出:修复提醒和视频源导入导出时缺失字段","🔍 追番更新修复:修复依赖查询加载逻辑和自动刷新功能","🔄 豆瓣无限加载ä¿
1®å¤ï¼šé€šè¿‡è®°å¿†åŒ–endReached回调防止无限加载"]},{version:"6.5.3",date:"2026-05-07",added:["🛡️ SSRF保护集成:将SSRF保护集成到代理端点,增强安全性","🚀 持久化导航Shell:实现遵循Next.js最佳实践的持久化导航Shell","⚡ 路由优化:添加预取和加载状态的路由优化","🎯 请求去重和超时保护:添加请求去重和超时保护机制","🗂️ TanStack Query缓存优化:使用TanStack Query优化数据源浏览器缓存","🎨 剧集选择器增强:添加手动速度测试和状态徽章到剧集选择器"],changed:["📦 依赖更新:更新依赖到最新版本","🔄 TanStack Query迁移:将数据获取和缓存迁移到TanStack Query","⚡ 导航优化:减少导航请求风暴并优化缓存"],fixed:["🔄 追番更新功能完整还原:100%还原旧watching-updates.ts逻辑到TanStack Query实现,包括getOriginalEpisodes数据库重读、protectedTotalEpisodes保护机制、新上映检查、排序逻辑、localStorage持久化、CDN缓存绕过等所有功能","🔧 代理Tavily API使用查询:通过后端代理Tavily API使用查询以避免WAF阻止","🛡️ 改进Tavily使用API错误处理:改进WAF阻止的错误处理","🗄️ 启动时重建缺失的视频元数据:防止误删除,优先使用本地文件缓存","🎨 移动画质徽章位置:将画质徽章移到右下角,避免与当前源标签重叠","🖥️ 修复登录/注册页面全屏显示:使用fixed定位实现全屏显示,修复z-index问题","🔐 跳过认证页面的RouteWarmup:防止登录干扰","✅ 添加RouteWarmup认证检查:添加认证检查到RouteWarmup","🎬 修复路由过渡的加载回退:将CinematicLoadingFallback包装在fixed容器中","📱 添加play-stats页面底部内边距:为移动导航添加底部内边距,匹配admin页面模式"]},{version:"6.5.2",date:"2026-05-06",added:["🕐 预告片URL生命周期时间戳日志:添加详细的时间戳日志追踪预告片URL的获取、缓存和刷新过程","📊 客户端错误日志系统:实现客户端到服务端的错误日志记录功能,支持无需认证访问","💥 崩溃监控系统:添加完整的崩溃监控系统,支持移动端响应式UI","🛡️ 全局错误边界:实现全面的崩溃监控与全局错误边界","🗄️ 崩溃日志数据库存储:将崩溃日志迁移到数据库存储,支持自动过期清理","🚪 观影房解散按钮:为房主添加房间列表中的解散房间按钮","📥 下载源标准化:添加下载源标准化功能并增强代理错误处理","🎬 M3U8代理Referer/Origin转发:添加Referer和Origin头转发到M3U8代理以改善兼容性","⏱️ 服务端强制刷新冷却:添加服务端强制刷新冷却机制防止频繁请求"],changed:["🎬 使用影片ID替代视频ID作为视频缓存Key:确保同一部影片的预告片永远使用同一个缓存文件(movie_{doubanId}格式),即使豆瓣返回不同的视频ID","🗑️ 替换TTL视频缓存为LRU管理:移除12小时TTL机制,改用LRU(最近最少使用)策略管理视频缓存,最多保留10个视频文件,总大小限制2GB","🔄 移除localStorage预告片URL依赖:完全移除localStorage缓存,统一使用React Query内存缓存 + Redis全局缓存","⚡ 优化延迟加载策略:仅预加载当前和下一张幻灯片(从3张减少到2张),减少不必要的API请求","📦 移除Puppeteer依赖:移除Puppeteer依赖以减少打包体积","📦 升级@mui/material至v9.0.0:从旧版本升级到v9.0.0","🔧 升级GitHub Actions至Node.js 24:升级GitHub Actions到Node.js 24兼容版本,强制使用Node.js 24"],fixed:["🔧 使用共享db实例删除video-proxy中的Redis缓存:修复缓存删除使用错误的Redis实例导致删除失败的问题","🗑️ 视频文件缺失且URL过期时清除Redis URL缓存:当视频URL返回403且视频文件不存在时,自动清除Redis中的过期URL缓存,下次请求会获取新URL","📁 优先检查文件存在性,缺失元数据时自动重建:修复Redis重启后元数据丢失但文件存在导致的缓存未命中问题,现在会自动重建元数据","🎥 URL过期时返回缓存视频文件而非删除:当视频URL返回403时,优先检查视频文件是否存在,如果存在则返回缓存文件,避免不必要的重新下载","🔄 防止无限refresh-trailer请求:实现请求去重机制,防止同一个ID的重复请求导致API限流","🗂️ 移除生成错误douban_格式的旧缓存迁移:删除倒转迁移函数,防止将正确的movie_格式转换回错误的douban_格式","⏱️ 防止视频缓存TTL在访问时重置:移除访问时重置TTL的逻辑,避免热门视频永久占用缓存空间","🔍 强制刷新前检查视频文件缓存:在强制刷新前先检查视频文件是否存在,如果存在则跳过强制刷新,避免不必要的API请求","🎨 记忆化enableVideo防止HeroBanner重新挂载:使用useMemo优化enableVideo,防止不必要的组件重新渲染","🎬 记忆化HeroBanner items防止不必要的重新渲染:使用useMemo优化HeroBanner items,减少组件重新渲染","🔄 持久化强制刷新冷却跨组件重新挂载:修复强制刷新冷却在组件重新挂载后丢失的问题","🚫 添加全面的速率限制防止豆瓣API节流:实现多层速率限制机制防止豆瓣API限流","🔄 添加请求去重防止豆瓣API速率限制:实现请求去重机制防止重复请求","🪝 确保HomeClient中Hook调用顺序一致:修复Hook调用顺序不一致导致的React错误","🎬 添加CinematicLoadingFallback到首页Suspense边界:修复首页加载时的Suspense边界问题","🔧 ç¨
1³å®šuseHomePageQueries中的config对象引用:防止Hook计数不匹配问题","🎥 添加详细的视频错误日志并过滤非网络错误:改进视频错误日志记录和过滤","🔄 添加视频onError防抖和key优化:优化视频错误处理和组件key管理"]},{version:"6.5.1",date:"2026-05-04",added:["🗄️ Redis全局缓存预告片URL:实现基于Redis的全局缓存机制,减少对豆瓣API的请求次数,所有用户共享缓存,支持Kvrocks和Upstash,24小时TTL"],changed:[],fixed:["🐛 修复加载屏幕导致组件重复挂载问题:将CinematicLoadingFallback从替换整个页面改为overlay覆盖方式,防止HeroBanner等组件在loading时被卸载和重新挂载","🔄 修复无限trailer URL请求问题:解决因组件频繁mount/unmount导致的疯狂请求豆瓣API问题,避免IP被封","🚫 防止失败预告片无限重试:为没有预告片的视频添加NO_TRAILER标记(24小时后重试),为服务端错误添加FAILED标记(5分钟后重试),避免重复请求导致API限流","⏱️ 限制预告片请求频率:每次最多请求3个预告片,请求之间延迟2秒,防止短时间内连续请求触发豆瓣API限流","🔧 修复所有模块的mount/unmount问题:移除HeroBanner和即将上映模块的!loading条件,使用useRef保留数据避免refetch时组件卸载,彻底解决重复请求问题","🎬 优化登录注册页面体验:转换注册页面为服务端组件,消除白屏闪烁,添加渐变背景到加载状态,优化页面导航过渡效果","🎨 修复Bilibili统计显示:当数值为零时隐藏Bilibili统计信息以改善用户体验"]},{version:"6.5.0",date:"2026-05-02",added:["🎬 电影主题加载屏幕:实现电影主题加载体验,包含Bing每日壁纸背景、胶片卷轴动画、旋转趣味消息、移动端响应式设计","📺 Bilibili搜索和播放集成:添加Bilibili搜索和播放功能,支持UP主视频、视频统计、QR码登录、Cookie过期追踪","🎥 Bilibili热门视频:添加Bilibili热门视频作为默认视图,支持搜索/热门模式切换、分页加载、缓存管理","🌍 YouTube热门视频:添加YouTube热门视频功能,支持可搜索的地区选择器、按字母排序","🏠 首页模块切换:实现首页模块切换功能,管理员可控制首页显示的模块","🎛️ 控制栏透明度控制:添加控制栏遮挡度设置(10-80%),支持实时调整透明度和模糊效果以改善字幕可见性"],changed:["📦 升级@tanstack/react-query至5.100.6:从5.100.5升级到5.100.6","🎨 优化电影主题加载动画:减少视觉强度,优化动画效果","🔄 重构加载逻辑:使用isFetching替代isLoading显示加载屏幕,正确检测空数据状态","🎯 控制栏设置重命名:将设置重命名为'控制栏遮挡度'以提高清晰度"],fixed:["📱 修复移动端内容截断:为多个页面添加底部padding防止内容被底部导航栏截断(play、douban、shortdrama、tvbox、source-browser、emby、search)","🎬 修复骨架屏问题:使用isFetching和数据检查防止骨架屏显示,显示加载直到所有数据准备就绪","🖼️ 修复Bing壁纸显示:移除导致壁纸无法显示的wallpaperLoaded状态,添加平滑淡入过渡防止闪烁","🎞️ 修复加载动画闪烁:使用固定Film图标消除周期性闪烁","⚡ 优化导航速度:移除服务端预取优化已登录用户的导航速度,减少预取超时从3秒到1秒","🔄 修复客户端异常:移除导致客户端异常的重复加载检查,恢复正确位置的加载检查","📺 修复Bilibili功能:修复搜索触发、标签行为、UP主视频播放、分页重复问题、模式切换状态重置","🖼️ 修复Bilibili封面图片:使用图片代理处理Bilibili封面图片","🎨 修复全屏显示问题:使用渐变叠加避免backdrop-filter堆叠上下文问题","🔍 修复搜索历史显示:在YouTube/Bilibili搜索模式无结果时显示搜索历史","🎛️ 修复控制栏透明度:调整模糊效果和透明度以改善字幕可见性","🐛 修复服务端数据获取:修复首页、短剧、豆瓣的服务端数据预取问题","🔄 修复无限循环:从useEffect依赖中移除加载状态防止无限循环","💬 优化弹幕密度:减少全屏模式下的弹幕密度以改善控制响应性"]},{version:"6.4.0",date:"2026-04-27",added:["🎥 观影房屏幕共享功能:实现完整的屏幕共享观影室功能,支持WebRTC实时传输、画质预设选择(流畅/高清/超清)、自动成员连接处理","🎨 屏幕共享页面沉浸式设计:全屏渐变背景布局、玻璃态效果、实时çŠ
1¶æ€æŒ‡ç¤ºå™¨ï¼ˆå…±äº«æ—¶é•¿ã€è§‚看人数、连接状态)、支持明暗主题切换","⏩ 视频播放快进快退按钮:添加可自定义的快进快退按钮,支持自定义时间间隔、响应式布局、Netflix风格设计","📺 直播源导入导出功能:支持M3U/M3U8格式导入、自定义源导出、源验证和管理","☁️ 光鸭云存储支持:集成光鸭云存储服务","🎛️ 快进快退设置面板:添加快进快退按钮设置面板,支持自定义时间和布局选项"],changed:["📦 升级@tanstack/react-query至5.100.5:从5.96.1升级到5.100.5","📦 升级@tanstack/react-virtual至3.13.24:从3.13.23升级到3.13.24","📦 升级hls.js至1.6.16:改进HLS播放兼容性"],fixed:["🔧 修复邀请码禁用检查和剪贴板错误误报:解决邀请码系统的检查逻辑和剪贴板错误提示问题","🔌 添加Redis兼容适配器:支持Upstash和ioredis API兼容","🎬 保持切换视频时的播放速率:视频切换后保持用户设置的播放速率","📅 修复发布日历worker时区问题:应用时区修复到发布日历worker,修正日期格式传递","🔊 修复音量面板悬停问题:解决音量面板鼠标移动时消失的问题,添加过渡延迟和扩展点击区域,防止双重剧集跳过","🎯 修复播放页年份匹配:改进年份匹配逻辑","🎨 修复OIDC提供商编辑模态框溢出问题:解决编辑模态框内容溢出显示问题","📺 修复M3U导入模态框z-index问题:使用createPortal防止z-index层级问题","📱 改进移动端快进快退按钮:采用Netflix风格布局、垂直单侧设计、改进可见性和定位","⚡ 优化移动端快进快退按钮性能:仅在布局变化时重建,实现实时设置更新","💬 修复弹幕发射器按钮隐藏:强制隐藏弹幕发射器按钮防止初始化时闪烁","📤 修复直播源导出前验证:导出前验证自定义源有效性"]},{version:"6.3.0",date:"2026-04-03",added:["🎵 Emby多音轨支持:为Emby播放添加多音轨切换支持,自动选择浏览器兼容的音轨,支持剧集动态音轨获取","🔔 即将上映内容提醒系统:实现完整的即将上映内容关注列表和æ
1é†’系统,支持铃铛图标提醒、自动发布通知和关闭功能","🎨 UI增强:添加GlobalError自动关闭功能并增强弹幕剧集选择器","📦 TVBox功能增强:添加自定义JAR配置、增强JAR代理诊断功能并更新镜像源","🎟️ 邀请码注册系统:添加完整的邀请码注册系统,支持邀请码输入页面、历史记录和禁用功能"],changed:["📦 升级@tanstack/react-query至5.96.1:升级@tanstack/react-query从5.95.0到5.96.1","🔄 迁移到TanStack Query queryOptions模式:重构为使用TanStack Query的queryOptions模式","🔇 禁用备用API剧集计数端点:禁用备用API剧集计数端点以减少日志噪音"],fixed:["🎵 修复Emby音频和流媒体问题:修复流URL参数编码、添加音频流获取到详情API、解决无限加载问题","🔔 修复新发布通知系统:修复铃铛图标显示、提醒状态加载、无播放记录时的检查、日期计算时区问题和发布日期格式统一","🗑️ 移除失效的短剧API:移除已失效的短剧API","🌐 修复TVBox源问题:添加ghproxy.vip作为主要国内CDN、移除限速源、更新智能健康检查JAR源","💾 修复邀请码数据类型:将邀请码数据转换为字符串以兼容Redis hSet","🎬 修复ArtPlayer后台音频问题:在清理视频和HLS之前销毁ArtPlayerä
1»¥é˜²æ­¢åŽå°éŸ³é¢‘播放"]},{version:"6.2.1",date:"2026-03-21",added:["🔔 下载Toast通知:下载开始时显示即时Toast通知,提升下载体验","🎯 快速跳过预设:添加灵活的片头片尾快速跳过预设功能","🙈 隐藏短剧API配置:从管理后台隐藏短剧API配置项","🖥️ 超宽显示器视频显示模式:添加超宽显示器视频显示模式控制","🔓 Emby免密登录:支持Emby免密登录并添加认证模式切换器","🔍 搜索列表视图模式:添加带图片预览的搜索列表视图模式,支持列表项播放按钮","💾 播放速率持久化:持久化播放速率设置,增强跳过预设验证和导入导出功能"],changed:["🔄 迁移UserEmbyConfig到sonner toast库:重构UserEmbyConfig组件使用sonner toast通知库","📦 升级TanStack包:@tanstack/react-query从5.90.21升级到5.91.0,@tanstack/react-virtual从3.13.22升级到3.13.23","📚 部署文档更新:移除Zeabur,添加Vercel/Render部署指南","🎬 升级ArtPlayer至5.4.0和弹幕插件至5.3.0","🔄 重构搜索:将EventSource迁移到experimental_streamedQuery","🎯 重构跳过预设:从快速跳过按钮重新设计为片头片尾模板"],fixed:["📥 修复短剧下载系统:修复短剧下载功能、IndexedDB序列化问题和AES加密任务序列化错误,改善下载UX","🔧 修复短剧分类端点使用配置的短剧源:使用已配置的短剧源进行分类端点请求","🔑 修复EmbyClient构建流URL前确保认证:在构建流媒体URL之前确保已完成认证","🔒 修复短剧封面图SSL证书问题:代理短剧封面图片绕过过期SSL证书,证书无效时自动回退HTTP加载","🔍 修复详情获取搜索失败时回退直接ID查找:搜索方式获取详情失败时回退到直接ID查找","🎬 修复HeroBanner尊重DISABLE_HERO_TRAILER环境变量:HeroBanner正确响应禁用预告片环境变量","❤️ 修复切换视频源后收藏状态丢失:切换源后正确保持收藏状态,通过标题回退匹配并使用实际存储键切换收藏","🤖 修复AI系统多项问题:正确处理流式API响应并过滤think块,功能禁用时阻止未授权API调用,移除导致过多调用的API健康检查","🔄 集中查询缓存失效到QueryProvider:在QueryProvider中集中管理查询缓存失效","🔧 修复登录页用户名字段:通过NEXT_PUBLIC环境变量在构建时解析shouldAskUsername,消除用户名字段渲染延迟"]},{version:"6.2.0",date:"2026-03-01",added:["🔌 Emby私有库支持:集成Emby私有库支持,支持自动初始化和配置UI改进","⚙️ Emby高级选项:在配置UI中添加Emby高级选项设置","🔍 Emby搜索功能:为私有库添加实时Emby搜索功能,采用现代化UI设计,使用本地全文索引支持模糊匹配","👤 Emby用户配置:实现每用户独立的Emby配置系统,支持测试API功能","📭 Emby空状态UI:为无搜索结果添加空状态UI提示","🌐 Emby公共源:添加管理员公共源功能","💾 私有库功能增强:localStorage持久化排序偏好,手动刷新按钮,移动端显示分类总数","🎛️ EnableWebLive开关:添加EnableWebLive开关控制直播流访问","🖼️ 短剧图片缓存:实现短剧图片缓存和优先加载","♾️ 虚拟滚动无缝加载:为Emby和短剧实现虚拟滚动无缝无限加载,支持视口感知endReached阈值和自适应overscan"],changed:["🏷️ 重命名'私人影库'为'Emby':提升清晰度和用户理解,路由重命名为/emby","🔄 重构SettingsPanel组件:提取设置到独立的SettingsPanel组件,使用TanStack Query管理Emby配置","⚡ 迁移私有库到TanStack Query:使用TanStack Query重构私有库数据管理","🔐 数据库迁移:将扁平Redis键迁移到Hash结构,使用scrypt哈希密码","📦 虚拟网格重构:通过统一VirtualGrid将react-window迁移到@tanstack/react-virtual"],fixed:["🔍 修复源查找和详情API:修复指定源和ID的源查找逻辑,常规API源使用基于搜索的详情获取,统一/api/detail中的Emby源详情处理","🔄 修复播放页初始化:修复detailData空值检查和后台加载状态,优化播放页初始化以支持直接源访问","📊 修复Emby详情和路由:修复Emby详情API返回SearchResult格式,修复Emby源详情请求路由到正确的API端点","🔐 修复Emby认证系统:修复API密钥和用户名/密码双重认证支持,使用/Users/Me端点进行API密钥认证,修复getCurrentUser方法中的API密钥认证处理","💾 修复Emby配置管理:修复Emby配置时自动获取并保存UserId,用户更新配置时清除EmbyClient缓存以立
1即应用更改,在详情API中使用用户特定配置而非全局配置","⚡ 优化UserEmbyConfig性能:重写为非受控输入以消除延迟,优化表单性能,修复每用户Emby配置并添加完整UI,改进保存UX体验","🎨 修复Emby私有库UI:修复自动初始化和配置UI改进,修复导航可见性和用户特定客户端解析,改进移动端UX体验","🎵 修复Emby播放问题:在HLS转码URL中添加PlaySessionId以解决片段加载错误,使用强制音频转码的HLS解决EAC3/TrueHD播放问题","📂 修复Emby搜索和过滤:将搜索结果范围限定到选定的库文件夹,修复繁体中文搜索无法匹配简体标题的问题","🏷️ 修复私有库显示问题:传递Emby源名称以防止收藏夹中显示'即将上映'标签,同步收藏状态和搜索卡片的悬停爱心显示,修复右键触发播放问题","🔧 更新动态路由参数以兼容Next.js 15","🎬 修复常规API源和视频加载覆盖层z-index问题","✅ 移除fetchSourceDetail中的剧集验证","🎯 恢复CapsuleSwitch中心对齐,用max-w-full替换w-full","🖼️ 优化图片加载性能:实现模块级图片缓存系统,在VideoCard和useImagePreload之间共享缓存,防止虚拟滚动重新挂载时闪烁,用仅透明度过渡替换模糊/缩放过渡,用onLoad替换Next.js 15+已废弃的onLoadingComplete","🎬 修复豆瓣虚拟滚动问题:修复虚拟模式双重无限滚动触发ï¼
1Œé€šè¿‡åœ¨flushSync内释放锁消除加载更多闪烁,使用同步ref锁防止页面跳过,防止加载更多时单元格重新挂载闪烁和布局跳动","⚡ 优化虚拟滚动性能:使用统一容器偏移量提升VirtualGrid性能,增加初始页面大小以填充视口,在视口结束前800px预加载数据实现无缝滚动"]},{version:"6.1.3",date:"2026-02-23",added:["🔬 WebSR超分辨率:升级至v0.0.15,用WebSR替换Anime4K-WebGPU实现多内容类型超分辨率,添加玻璃态设计风格设置面板","💬 弹幕手动匹配:添加手动弹幕匹配功能,支持搜索番剧、选择剧集、覆盖自动匹配结果","📥 M3U8下载器增强:在UserMenu添加下载管理器入口,支持IndexedDB持久化和Storage Buckets,页面刷新后可恢复下载任务","🔍 精确搜索过滤:添加精确搜索过滤功能","📺 FLV直播CORS代理支持:为FLV直播流添加CORS代理支持"],changed:["⚡ TanStack Query全面迁移:全面用useQuery/useQueries/useMutation替换播放页、首页、HeroBanner、发布日历、搜索建议、播放统计、继续观看、UserMenu的数据获取逻辑,集成prefetching和乐观更新","⚡ 首页标签切换非阻塞优化:使用useTransition实现首页标签切换非阻塞渲染"],fixed:["🎬 修复直播播放器错误覆盖层遮挡视频画面","🎨 迁移所有已废弃的Tailwind v4 opacity工具类到斜杠语法:修复YouTube缩略图被不透明覆盖层遮挡等Tailwind v4破坏性变更导致的样式问题","🔬 修复WebSR设置面板多项问题:关闭按钮pointer-events、面板结构与弹幕面板对齐、图标显示","🔔 减少噪音错误弹窗:仅对用户主动操作失败显示错误提示","🔧 修复/api/cache 401错误、hydration错误418及CMS代理Referer/Origin头缺失问题","🔍 修复源搜索精确标题匹配优先于子字符串匹配","🔄 修复播放记录乐观更新同步到continueWatching查询键及watching updates检查死循环","💬 修复弹幕系统多项问题:加载前未清空旧数据导致重复、模态框全屏portalContainer渲染、手动匹配损坏图片URL、搜索过早过滤无集数番剧、移动端响应式和iPhone安全区域适配","📥 修复下载系统多项问题:进度显示优化、页面刷新后恢复进度和任务、恢复时不自动弹出面板","👤 修复UserMenu初始化时强制刷新问题"]},{version:"6.1.2",date:"2026-02-09",added:["📺 FLV直播流支持:集成flv.js实现FLV格式直播流播放功能","🎯 一键无效源选择:添加一键选择无效源功能,现代化按钮UI设计","🎬 播放器错误UI覆盖层:添加带重试按钮的播放器错误提示界面","📦 TVBox Vercel Blob CDN:为spider JAR添加Vercel Blob CDN支持","🎨 弹幕设置面板2026 UI/UX升级:采用2026年最佳UI/UX设计实践,支持全屏Portal渲染","💬 弹幕系统增强:错误状态显示、自动重试、加载元数据跟踪和改进的重新加载反馈","📺 Chromecast增强:元数据支持、断开连接切换和播放恢复功能","🖱️ Material UI Tabs拖拽滚动:添加拖拽滚动功能和滚动懒加载健康检查","🏥 频道健康检查系统:添加频道健康检查系统和增强的分类管理","🎭 演员作品API:添加带反爬虫保护的演员作品API和三层回退搜索机制","👥 观影房直播频道同步:为观影房添加直播频道同步功能","🎬 全屏播放信息覆盖层:全屏播放时显示标题和剧集信息"],changed:["📦 包导入优化:使用optimizePackageImports优化打包体积","🔍 豆瓣HTML解析优化:使用split替代正则表达式提升解析性能","📦 TVBox Spider JAR下载策略:通过服务器代理所有spider JAR下载请求"],fixed:["📱 移动端底部内边距和文本溢出:改进移动端底部内边距和文本溢出显示问题","📦 TVBox多项修复:改进配置API兼容性和网络可靠性、spider.jar IP访问兼容性","⚡ 性能监控系统修复:环境检查、CPU基线初始化、懒加载初始化防止模块加载错误","🗑️ 配置源数据库清理:从数据库中移除已删除的配置源","🎮 播放器全屏控制自动隐藏:进入全屏后自动隐藏播放器控制栏","💬 弹幕系统修复:修复加载问题、设置面板滑块闪烁、Portal渲染支持全屏","🖱️ Tabs拖拽滚动修复:修复滚动按钮协同、标签点击冲突问题","💬 聊天发送按钮显示:防止发送按钮被推出视图外","🎬 全屏标题层渲染修复:修复初始HTML内容和渲染时机问题","🎨 Portal隔离包装器字体:恢复portal隔离包装器的font-family设置","📊 剧集总数计算:在latestTotalEpisodes计算中包含newRecord.total_episodes"]},{version:"6.1.1",date:"2026-02-01",added:["🔍 搜索历史UX优化:清空输入时始终显示搜索历史","💾 ACG搜索数据库缓存:为ACG搜索添加数据库缓存,提升搜索体验","✏️ 视频源编辑功能:添加视频源编辑功能,改进短剧处理逻辑","📊 性能监控增强:显示CPU核心数和型号名称,添加进程级指标","🔄 首页数据缓存:实现GlobalCacheContext首页数据全局缓存","💬 弹幕系统增强:防重叠开关、实时滑块控制、自定义弹幕API支持","📦 视频缓存LRU淘汰:实现视频缓存LRU淘汰策略","🔐 信任网络模式:内网部署å
1¯è·³è¿‡ç™»å½•认证,支持IPv6白名单","⚖️ 视频源权重/优先级系统:添加源权重系统优化播放源选择","🎌 Bangumi API优先:动漫内容详情优先使用Bangumi API","🔍 智能搜索变体检测:添加智能搜索变体检测,支持并行执行","📹 短剧备用API:添加短剧推荐和列表的备用API支持","🎬 DISABLE_HERO_TRAILER环境变量:添加环境变量控制预告片播放","📚 部署文档更新:添加HF Space和EdgeOne Pages部署指南"],changed:["🔨 重构短剧源聚合:动态分类检测,改进短剧源聚合逻辑","⚡ Cron API全面优化:并发处理、超时控制、监控、重试机制、任务统计和并行化","⚡ 直播频道性能优化:添加超时控制和EPG缓存","⚡ AI推荐请求优化:仅在后台开关启用时发送AI推荐请求","⚡ Redis优化:KEYS替换为SCAN避免阻塞,Upstash减少命令使用量","⚡ 豆瓣页面智能防抖:添加智能防抖和flushSync优化","⚡ 视频缓存优化:优化清理逻辑、错误处理,增加缓存上限","⚡ 信任网络缓存优化:24小时缓存,通过cookie版本号立即刷新配置"],fixed:["🐛 修复UserMenu导航卡死:通过router优化解决导航卡死问题","🐛 修复ACG搜索按钮显示:改进动漫内容的ACG搜索按钮显示逻辑","🐛 修复短剧系统:替换失效API、解决CORS问题、验证空数据、修复字段映射、自动选择分类、隐藏零评分、防止空缓存","🐛 修复配置订阅覆盖:保留用户手动修改的配置","🐛 修复源详情提前设置:移除fetchSourceDetail中过早的setAvailableSources调用","🐛 修复筛选标签排序选择:始终显示排序选择","🐛 修复Cron性能阈值:使用宽松的性能阈值评估任务","🐛 修复播放记录传参:将douban_id和type传递到VideoCard","🐛 修复移动端响应式:Spider Jar状态溢出、TVBox安全配置、信任网络配置、管理页面底部内边距、短剧卡片徽章重叠","🐛 修复弹幕系统:过滤占位符弹幕、纠正响应验证和超时输入UX","🐛 修复三星浏览器深色模式:添加color-scheme meta标签","🐛 修复流式代理并发请求:防止并发请求,移除Content-Length头","🐛 修复Vercel预告片带宽:Vercel环境禁用首页预告片视频","🐛 修复Kvrocks持久化:禁用外部流量监控和性能监控的持久化"]},{version:"6.1.0",date:"2026-01-26",added:["🤖 短剧卡片AI聊天功能:为ShortDramaCard组件添加AI聊天功能","📱 短剧卡片右键和长按菜单:新增短剧卡片的右键和长按上下文菜单功能","📊 性能监控系统:为管理后台添加完整的性能监控仪表板,支持所有API(豆瓣、搜索、列表、详情、播放记录、收藏、跳过配置、短剧)的性能监控,带过滤支持和行业基准评级系统","📈 流量监控系统:添加真实流量监控、外部流量域名分解、请求列表显示和可折叠区域","🍪 豆瓣Cookies认证支持:为详情和评论API添加豆瓣Cookies认证支持","💾 Kvrocks持久化和监控:为cron、豆瓣搜索API和外部流量监控添加Kvrocks持久化","🔍 Cron监控和API过滤:添加cron监控、API过滤和48小时自动清理功能","⚙️ 可配置Cron任务优化:添加可配置的cron任务优化以减少出站流量","🔍 TanStack Query全局状态管理:实现TanStack Query进行全局状态管理","🛡️ 豆瓣反爬虫验证机制:添加豆瓣反爬虫验证机制","🎯 广告过滤增强:基于关键词的广告检测功能","🌸 Mikan Project集成:添加ACG搜索双源系统(ACG.RIP和Mikan Project),支持源切换、统一响应格式和完整种子元数据,改进速度测试准确性防止浏览器缓存影响","💾 视频缓存系统:实现12小时TTL的视频缓存系统并添加最低系统要求"],changed:["⚡ 优化移动端滚动性能:使用GPU加速和iOS momentum scrolling优化移动端滚动体验","⚡ 优化首页性能:使用useReducer优化状态管理,使用useMemo优化昂贵的计算操作","⚡ 优化所有定期任务:将所有定期任务优化为1小时间隔","⚡ 优化性能监控:使用真实数据收集优化性能监控,改进准确性并优化首页API请求","⚡ 优化数据加载:移除手动è
1™šæ‹Ÿæ‰¹å¤„理,使用react-window原生虚拟化","⚡ 优化Anime4K requestAnimationFrame:减少CPU使用率,提升视频超分辨率性能","🔨 重构播放页组件:提取评论区、加载屏幕、返回顶部按钮、收藏按钮、下载按钮和VideoInfoSection为独立组件,提升代码可维护性","🔨 重构弹幕逻辑:提取弹幕逻辑到useDanmu自定义Hook","🔨 重构Docker配置:移除Puppeteer/Chromium并隐藏管理UI配置","🔨 重构搜索页面:移除渐进式加载,优化虚拟滚动性能和加载指示器","🔧 更新user-agent字符串:更新到最新浏览器版本"],fixed:["🐛 修复视频缓存系统:添加调试日志和Docker目录权限,支持Range请求缓存,处理ReadableStream消费错误,使用douban_id替代URL哈希优化","🐛 修复Cron任务超时:将cron任务超时从30秒增加到5分钟","🐛 修复首页底部内边距:添加底部内边距防止内容截断","🐛 修复外部流量评级标准:调整外部流量评级标准并修复ShortDramaCard截断问题","🐛 修复Kvrocks数据管理:对所有流量显示应用formatTraffic,正确清理监控模块中的旧数据","🐛 修复统计计算与显示限制分离:将统计计算与显示限制分离","🐛 修复请求列表返回限制:返回时间范围内的所有请求而非限制为100条","🐛 修复缓存清理前创建快照:在缓存清理前创建快照以防止数据丢失","🐛 修复性能监控数据持久化:解决竞态条件问题,确保Docker重启后数据持久化和实时统计,防止数据丢失","🐛 修复性能监控CPU使用率百分比计算:纠正CPU使用率百分比计算方法","🐛 修复管理后台移动端布局:改进移动端布局并添加API性能监控,最后两个标签页现在可访问","🐛 修复数据不可用时隐藏演员和评论区:当数据不可用时隐藏演员和评论区","🐛 修复零时长显示:隐藏零时长并添加性能监控","🐛 修复bangumi日历加载问题:解决bangumi日历加载问题并为性能监控添加移动端响应式设计","🐛 修复VirtualDoubanGrid无限滚动触发问题:解决滚动加载异常","🐛 修复短剧卡片上下文菜单:添加海报和更多操作到上下文菜单","🐛 修复ShortDramaCard移动端长按冲突:使用div和router导航替代Link,防止移动端长按冲突","🐛 修复transform translateZ导致的模态框层叠上下文问题:移除导致模态框显示异常的transform属性","🐛 修复公告模态框z-index问题:解决移动端对话框不可见的问题"]},{version:"6.0.0",date:"2026-01-22",added:["✨ 用户体验增强:删除用户加载状态指示器和画质徽章自动隐藏功能","🚀 Puppeteer反爬虫系统:全面支持豆瓣反爬虫绕过(包括Docker/Vercel环境和评论API),集成反机器人检测、重试机制和页面加载稳定性增强","📱 豆瓣移动端API回退机制:添加备用数据源和详细日志追踪"],changed:["⚡ 主页加载性能优化:实施分批加载策略(7个请求分3批)、延迟加载非关键数据、Web Worker处理即将上映数据、React.memo优化组件,CPU使用从200-300%降至50-80%","⚡ 算法优化:即将上映算法复杂度从O(n²)优化到O(n),使用Map替代reduce+find","🚀 User-Agent管理重构:统一管理并恢复旧版User-Agent以兼容移动端短剧API","⬆️ 依赖升级:puppeteer-core从24.35.0升级到24.36.0","🔧 架构优化:MobileActionSheet使用独立Portal容器、内容类型检测从scraper移至AI orchestrator防止超时","⚡ 播放进度恢复:切换剧集时自动恢复播放进度"],fixed:["🐛 修复用户删除功能:完善删除流程并修正Redis方法命名错误","🐛 修复AI类型检测:改进电影/电视剧类型检测算法,防止误识别","🐛 修复分辨率检测:使用视频宽度而非高度进行检测","🐛 修复Husky hooks兼容性:更新shebang支持Windows系统","🐛 修复豆瓣API问题:处理302重定向、429限流、移动端API响应格式、电视剧剧集数据、请求头设置,防止重试循环和无效数据循环"]},{version:"5.9.3",date:"2026-01-13",added:["📱 直播长频道名点击展开功能:为移动端长频道名添加点击展开/收起功能","⚡ 下载功能增强:添加片段时长追踪、时间范围和完整视频总时长显示","🔍 繁体中文搜索支持:添加繁体中文搜索功能,提升繁体用户搜索体验","📅 2026年份筛选选项:为豆瓣内容添加2026年份筛选功能","📚 fnOS部署指南:添加飞牛NAS(fnOS)部署指南到README文档","📺 TVBox源管理增强:添加手动开关和完整源解析支持","🖼️ 百度图片代理选项:为豆瓣图片添加百度图片代理选项,提供更多代理方式"],changed:["⚡ 繁体中文搜索全面优化:采用轻量级switch-chinese库、tree-shakeable导入、单例模式、多策略搜索、限制转换范围(前3个变体)、移除冗余detect()调用","🔧 TVBox优化:User-Agent更新为okhttp/4.1.0,优化管理后台开关布局","🚀 User-Agent全面升级:更新所有User-Agent到2026年最新版本(Chrome 135, Firefox 146, Safari 26, Edge 143)","⚡ 图片代理性能优化:改进图片代理性能和缓存策略"],fixed:["🐛 修复直播移动端频道名显示:优化移动端频道名显示,添加chevron指示器用于可展开名称","🐛 修复HeroBanner标题溢出问题:移除最大宽度限制,防止标题截断和溢出容器","🐛 修复Tavily API密钥未保存提醒:添加未保存更改警告","🐛 修复EPG频道解析:支持多行XML格式的频道解析","🐛 修复时间范围显示条件运算符优先级问题:纠正时间范围显示的条件判断逻辑","🐛 修复繁简转换应用范围:将繁体转简体转换应用到所有搜索变体,确保搜索完整性","🐛 修复标签按钮可见性和移动端响应式:增强标签按钮在不同设备上的可见性和响应式布局","🐛 修复搜索分类按钮深色模式对比度:改进深色模式下搜索分类按钮的对比度和可读性","🐛 修复ScrollableRow隐藏按钮捕获指针事件:防止不可见按钮响应点击事件","🐛 修复Zeabur部署standalone模式:启用Next.js standalone模式以支持Zeabur部署","🐛 修复Firefox悬停消失问题:ä
1½¿ç”¨box-shadow替代drop-shadow解决Firefox浏览器悬停效果消失","🐛 修复TVBox配置和解析:支持加密配置(Base64)、JSON注释解析、M3U8代理源键传递、完整URL解析修复直播片段500错误","🐛 修复TVBox功能问题:AdminConfig类型定义、编辑模式开关状态更新、解析和播放模式改进","🐛 修复用户菜单百度图片代理选项:在用户菜单中添加百度图片代理选项","🐛 修复播放页面下载配置开关:确保下载配置开关在播放页面正确生效"]},{version:"5.9.2",date:"2026-01-05",added:["🎬 豆瓣预告片系统增强:添加移动API自动刷新、专用刷新端点、localStorage持久化、自动重试机制、性能日志追踪,支持电视剧内容","💾 V2用户数据备份支持:备份/迁移系统添加V2用户数据支持","🎯 动漫分类默认排序:为动漫分类页面默认使用'最近热度'排序","👥 新用户默认用户组:为新注册用户添加默认用户组功能","📚 设计和实现参考文档:添加设计和实现参考章节","📱 TVBox诊断移动端响应式优化:优化TVBox诊断页面移动端布局","🔍 管理后台用户组筛选:为管理后台用户列表添加用户组筛选功能","🔧 代理配置系统:添加TVBox和视频播放独立代理配置,支持智能URL替换、状态检测、配置指南文档","⚡ M3U8下载器升级:升级M3U8下载器并发下载速度提升6倍,添加下载设置UI和边下边存自动检测","📺 EPG系统增强:添加调试API端点、完整解析调试信息、名称回退匹配(保持tvg-id优先)、Logo提取显示和回退图标、多显示名称支持","⚡ 直播直连模式:添加带智能CORS检测的直播直连播放模式,在管理后台添加CORS统计面板"],changed:["📱 移动导航全面重设计:底部导航采用Netflix风格全宽布局(浮动胶囊→底部停靠→全宽),ModernNav重设计为全宽样式","⚡ 导航性能优化:添加prefetch={false}、浅色模式支持、基于transition的FastLink组件","⚡ 豆瓣分类选择器滚动优化:使用requestAnimationFrame优化滚动性能","⏱️ 发布日历缓存时长调整:将缓存时长从24小时减少到8小时","⚡ 版本检查双层缓存:添加双层缓存和请求去重优化","📺 EPG名称匹配优化:使用反向映射优化EPG名称匹配性能"],fixed:["🐛 修复HeroBanner多项问题:背景图始终使用高清版本、有效预告片URL渲染、音量按钮位置避免重叠、localStorage过期URL清理并重试刷新","🐛 修复移动端性能和预告片缺失:优化移动端性能并解决预告片丢失问题","🐛 修复动漫页面排序初始化:在组件挂载时初始化默认排序值","🐛 修复发布日历<dl>结构支持:爬虫添加对<dl>结构的支持","🐛 修复TVBox诊断移动端文本溢出:防止移动端文本溢出,完成所有组件移动端响应式修复,解决额外的溢出问题","🐛 修复用户组和API权限:预选用户组API、显示组合权限、处理Redis标签序列化","🐛 修复订阅源替换逻辑:替换订阅源而非合并","🐛 修复视频代理应用:将视频代理配置应用到源验证端点和源测试API,在源级别而非请求级别应用","🐛 修复短视频跳过检测:优化短视频的跳过检测逻辑","🐛 修复源切换进度保留:切换视频源时保留播放进度","🐛 修复豆瓣分页和数据:统一分页常量防止不一致、添加去重逻辑防止重复、优化图片预加载和API代理确保CORS安全","🐛 修复流式下载并发写入:解决边下边存并发写入数据丢失问题","🐛 修复EPG多项问题:节目匹配前收集所有频道标签、数据分发到所有M3U频道名称变体、处理单行programme元素内联title标签、调试函数应用反向映射优化","🐛 修复直播CORS检测:优化CORS检测处理混合内容(Mixed Content)情况","🐛 修复直播页面移动端文本显示:优化长频道名在移动端的显示,使用line-clamp-1 md:line-clamp-2响应式截断,移除不适用于移动端的hover滚动动画,添加title属性显示完整文本,确保直连/代理模式指示器始终可见"]},{version:"5.9.1",date:"2025-12-31",added:["🎨 玻璃态设计应用到控制按钮:为控制按钮应用玻璃态设计效果","🚀 CMS代理和成人内容过滤增强:添加CMS代理功能并增强成人内容过滤","⚡ 图片代理超时和CORS支持优化:优化图片代理,添加超时控制和CORS支持","🔍 ACG种子搜索集成:添加ACG种子搜索功能","🛠️ cn()工具函数:添加用于Tailwind类合并的cn()实用函数","🔐 多Provider OIDC编辑器回调URL复制按钮:为管理后台OIDC编辑器添加回调URL一键复制功能","🎯 豆瓣代理API:添加带unstable_cache的豆瓣代理API和useDoubanInfo hook","📊 豆瓣24小时缓存和增强头像提取:为豆瓣数据添加24小时缓存并增强演员头像提取","🎨 CategoryBar Material UI Tabs:为直播和播放页面添加工业风CategoryBar,使用Material UI Tabs实现可靠滚动和响应式分类选择器","🎬 Netflix风格徽章系统:统一所有徽章(剧集徽章、通知徽章、源指示器)为Netflix风格设计","📅 即将上线标签页:添加即将上线内容标签页功能","🤖 AI功能全面增强:添加流式传输、编排器、视频上下文支持,集成豆瓣和TMDB数据,支持ID缺失时自动TMDB搜索","🔔 自定义确认对话框:为清除操作和继续观看记录清除添加可选确认对话框","🤖 Tavily仅模式支持:支持无需AI API的Tavily搜索模式,提供灵活的API验证","🎬 Netflix风格HeroBanner:添加带预告片和背景图的Netflix风格横幅,支持backdrop占位符","🎥 视频代理和图片URL重定向修复:添加视频代理功能并修复图片URL重定向","🔍 调试模式控制台切换:添加带控制台切换的调试模式,
1可绕过缓存","👥 观影房源切换确认对话框:为观影房添加源切换确认功能,播放记录添加douban_id支持","⚡ Netflix风格智能速度测试:添加带智能提前停止的实时速度测试功能","📊 Tavily API使用追踪:在AI配置中添加Tavily API使用情况追踪,支持单个密钥刷新","🔍 2026年发布数据爬虫:添加首页爬虫获取2026年发布数据"],changed:["📱 播放页UI增强:移动端优先设计并重组控制器布局","🎨 LinuxDo OIDC Logo更新:使用官方设计Logo并适配UI","⚡ Tailwind v4规范类语法升级:升级到Tailwind v4规范语法","🔄 替换手动滚动为原生scrollIntoView API:使用浏览器原生API替代手动滚动实现","🔄 移除CategoryBar:恢复到之前版本,更新观影房文档为多平台Docker镜像","⚡ 搜索性能优化:优化季度搜索数字变体生成和变体搜索策略,提升搜索速度","🔄 用自定义ConfirmDialog替代原生confirm:使用自定义确认对话框组件","⚡ 首页所有ScrollableRow启用虚拟化:修复移动端卡顿问题","⚙️ HeroBanner优化:标准化缓存时长为4小时,重构性能并提取自定义hooks","🔄 提升AI权限检查到页面级别:实现一致的状态管理","🚀 升级所有爬虫和代理到2025最佳实践:全面优化爬虫和代理实现"],fixed:["🐛 修复观影房配置保存前过早获取统计信息:分离已保存配置和本地输入状态,防止过早API调用","🐛 修复OIDC用户登录时间记录:为现有和新用户立即记录登录时间,解决显示未知时间和待激活状态问题","🐛 修复旧版移动浏览器backdrop-filter兼容性:使用95%不透明度实心背景替代模糊效果,自动修复36个使用backdrop-blur类的文件,确保旧版移动系统UI完整渲染","🐛 修复缺失或无效海报图片显示:VideoCard在图片加载失败后设置fallback SVG占位符,过滤空白vod_pic字段,确保所有视频卡片显示正确占位符而非空白","🐛 修复模态框内容截断问题:修复Tailwind模态框结构、OIDC模态框、OIDC提供商模态框桌面端滚动等内容截断问题,使用正确结构和min-h-0","🐛 改进移动端响应式:优化认证页面、观影房和OIDC配置的移动端显示和布局","🐛 修复搜索结果人工限制丢弃有效匹配:移除人为设置的结果数量限制","🐛 修复直播CategoryBar滚动问题:解决对象依赖导致的滚动循环、滚动跳跃、手动/自动冲突等问题","🐛 修复返回顶部按钮:修复播放页面ACG返回顶部按钮和网盘模态框返回顶部按钮的定位和功能","🐛 简化非活跃用户清理逻辑:仅检查最后登录时间","🐛 修复Docker相关问题:解决短剧API问题、HTTPS支持、配置缓存问题等Docker部署相关多个问题","🐛 统一首页和UserMenu发布日期计算:统一跨组件的日期计算逻辑","🐛 为普通用户统计VideoCard光环效果添加悬停缩放动画:改进交互效果","🤖 AI功能修复和改进:修复推荐提取、YouTube解析、流式模式、Markdown渲染、Tavily API密钥输入、欢迎消息、聊天历史同步等多个AI功能问题","🤖 Tavily搜索模式优化:支持SSE流式传输、移除默认值回退、改进用户指导和友好提示","🤖 AI流式传输优化:立即显示聊天消息、Markdown格式欢迎消息、显示预设按钮","🤖 AI助手动态适配站点名称:使AI助手自动适应站点名称","🎨 修复粘性筛选栏问题:使用负边距技术消除间隙、修复内容穿透、使用精确响应式负top值优化不同屏幕尺寸显示","🎬 修复切换视频源时保留剧集编号:解决源切换后剧集编号丢失问题","🎬 修复HeroBanner问题:修复首次加载视频自动播放、调整横幅高度、启用视频、使用剧照作为背景、修复动漫分类","👥 修复观影房源切换问题:改进源切换检测、使用doubanId和标题加年份匹配视频、使用状态值匹配、使用router.push带reload标志、重新加载视频数据、使用React key prop强制组件重新挂载","📱 修复旧版iOS Safari认证页面崩溃:解决iOS Safari兼容性问题","🎬 修复豆瓣预告片缓存问题:解决预告片URL过期问题,调整CDN缓存和unstable_cache策略,将CDN缓存从24小时降至30分钟"]},{version:"5.9.0",date:"2025-12-27",added:["🔐 多Provider OIDC支持:添加多Provider模式,支持同时配置多个OAuth提供商","🔐 Facebook OAuth登录支持:集成Facebook OAuth认证","🔐 微信和Apple OAuth登录支持:添加微信和Apple Sign In认证","🔐 Apple JWKS URI支持:为Apple Sign In添加JWKS URI配置","🔐 OIDC认证和V2用户存储:实现OIDC认证并迁移到V2用户存储系统","👥 观影房功能:添加外部服务器集成的多人观影房功能","👥 观影房离开/解散功能:支持房间管理和hook顺序优化","👥 观影房集成到播放页:在播放页面集成观影房功能","👥 观影房同步增强:添加视频展示和智能控制","👥 观影房按钮全局布局:将观影房按钮移至全局布局","📥 M3U8客户端下载功能:添加M3U8视频客户端下载支持","📥 批量剧集下载功能:支持批量下载多个剧集","🎬 播放器缓冲优化:添加三种缓冲模式优化","🎨 Anime4K超分辨率:使用WebGPU实现视频超分辨率","🎯 自定义广告过滤代码:添加自定义广告过滤规则功能","📊 收藏API性能监控:为收藏功能添加性能监控","🔘 自定义广告过滤重置按钮:添加独立的重置和恢复默认按钮"],changed:["🔐 迁移到V2用户存储:使用SHA256加密的V2用户存储系统","👥 重构观影房全局状态管理:改进连接和状态管理","👥 优化剧集显示和用户名加载:改善观影房用户体验","📊 优化收藏同步超时:移除过多的错误提示","🍪 改进C
1ookie加载检测:使用持久轮询检测","🎯 观影房视频卡片显示:显示带海报的视频卡片"],fixed:["🔐 改进GitHub OAuth用户信息处理:添加GitHub专用API headers,支持私有邮箱获取","🔐 修复GitHub OAuth集成问题:使用正确的scope和Accept header,排除id_token验证","🔐 修复OIDC redirect_uri:支持本地开发和反向代理环境的正确重定向","🍎 添加Apple Sign In的POST处理器:支持form_post响应模式","🔐 修复Apple Sign In的OIDC发现:改进Apple OAuth配置","🔐 修复Zeabur和反向代理的OIDC redirect_uri问题:解决部署环境的重定向问题","🔐 修复OIDC Provider检测:通过issuer正确识别Provider","🔐 修复OIDC注册和用户同步:确保新用户正确创建和显示","🔐 修复admin面板包含V2用户:getAllUsers()现在包含OIDC用户","🔐 修复注册后自动登出:改进配置缓存失效机制","🔐 修复注册和登录Cookie名称不一致:统一Cookie命名","🔐 修复客户端路由注册Cookie未应用:确保Cookie正确设置","🔐 添加oidc-register到中间件排除列表:允许OIDC注册页面访问","🔐 修复用户注册和创建问题:确保新用户正确创建","🔐 恢复V1用户存储:为所有用户使用V1存储","📥 修复Windows上的M3U8下载和husky:改进Windows兼容性","🖼️ 修复图片预加载中的querySelector错误:处理格式错误的URL","👥 修复成员离开房间和播放同步问题:改进同步机制","👥 导出WatchRoomContextType并添加连接状态指示器:改进类型安全","👥 修复房间创建/加入立即更新UI状态:改善用户反馈","👥 修复stats API使用POST方法:更新API调用方式","👥 修复观影房用户名硬编码问题:动态从auth cookies获取用户名","👥 修复剧集切换同步:使用URL videoId而非detail.vod_id","👥 修复剧集切换自动跟随房主:无需确认","👥 修复剧集切换同步并适配watch-room-server权限:改进权限处理","👥 修复观影房首次访问401和访客显示问题:改进认证和显示","👥 启用剧集切换同步:读取URL index参数","👥 调整观影房按钮位置:位于返回顶部按钮上方","👥 修复跟随房主时避免退出房间:防止页面刷新","👥 修复用户名显示问题:改进视频卡片逻辑","🎯 修复SSR导致用户名默认为guest:解决服务端渲染问题","🐛 修复首次加入房间的guest名称问题:改进用户名初始化","📝 添加用户名初始化问题的详细日志:便于调试","🎨 修复自定义广告过滤保存:正确的HTTP方法和请求负载","🛡️ 为CustomAdFilterConfig添加JSON解析错误处理:增强稳定性"]},{version:"5.8.0",date:"2025-12-24",added:["🎯 AI推荐按钮:在ModernNav导航栏添加AI智能推荐按钮,全局可用","🎬 短剧自动跳集:备用API集数不可用时自动跳到下一集","⚡ 升级到Next.js 16.1 + Tailwind CSS 4.1 + React 19:享受最新框架性能提升","🎭 TMDB演员作品备用:添加TMDB作为演员作品搜索的备用数据源","💾 演员作品缓存:缓存演员作品信息2小时,减少API请求","🎬 演员作品内联显示:使用搜索API在播放页面内联显示演员作品","🎨 交互式演员作品查看器:在播放页面添加交互式演员作品浏览功能","⚙️ 弹幕综合设置:添加完整的弹幕设置面板,支持速度、透明度、字体等配置","🎨 弹幕设置集成:将弹幕配置集成到全局设置面板"],changed:["⚡ AI聊天性能优化:优化聊天弹窗性能,消除输入延迟","添加100ms防抖滚动,减少过度滚动动画","使用requestIdleCallback实现300ms防抖的异步localStorage写入","使用useCallback记忆化所有事件处理函数","创建记忆化MessageItem组件,使用useMemo缓存格式化内容","输入延迟减少85-90%,消息重渲染减少70-85%","🎨 VideoCard容器查询:为VideoCard添加Tailwind 4容器查询支持","⚡ React 19性能优化:使用useTransition优化非紧急更新,添加图片优先级","⚡ 收藏乐观更新:使用React 19的useOptimistic优化收藏功能,合并重复useEffect","🖱️ 用户菜单悬停优化:优化用户菜单悬停过渡性能","🎨 Tailwind CSS 4.1优化:优化globals.css以适配Tailwind CSS 4.1","🔧 Telegram用户自动清理:为Telegram用户添加createdAt字段以启用自动清理"],fixed:["🐛 短剧错误信息显示:在短剧播放器中显示实际的API错误信息","🔧 备用API错误处理:改进备用API字符串响应的错误处理","🎯 AI模态框居中:修复AI模态框居中问题,确保AI按钮全局可用","🖼️ TMDB API白屏修复:使用TMDB API路由替代客户端导入,解决白屏错误","🔑 演员缓存键格式:修正演员缓存键格式问题","🎮 弹幕速度设置:修复弹幕速度设置以匹配原生插件数值"]},{version:"5.7.1",date:"2025-12-13",added:["🎨 毛玻璃效果控制栏插件:为播放器添加现代化液态玻璃(liquid-glass)悬浮控制栏效果","💬 豆瓣用户评论功能:在播放页面展示豆瓣短评,提供用户真实观影评价参考","⭐ 全局收藏按钮:为所有视频卡片和短剧卡片添加收藏按钮,快速收藏喜爱内容","🔄 自动同步收藏元数据:从播放页面自动同步更新收藏内容的元数据","🔌 备用API支持:为短剧添加备用API支持,增强短剧元数据获取能力","📊 收藏过滤、排序和统计:支持按类型过滤、多种排序方式和详细统计信息","🎌 动漫分类支持:在收藏过滤中添加动漫(anime)类别"],changed:["⚡ 首屏图片加载优化:优化首屏内容的图片加载策略,提升首屏渲æ
1Ÿ“速度","🎯 可选虚拟化滚动:为ScrollableRow添加可选的虚拟化支持,提升长列表性能","⏱️ 延迟详情请求:使用requestIdleCallback延迟详情请求,优化主线程性能","🎨 VideoCard渲染优化:优化VideoCard组件渲染性能,减少不必要的重渲染","🎬 禁用卡片动画:禁用卡片动画并简化motion配置,提升整体流畅度"],fixed:["🔧 控制栏布局修复:回归官方liquid-glass实现,修复拖动进度条时控制栏漂移的问题,通过按钮自动缩小防止溢出","📺 短剧卡片集数显示:始终获取并显示短剧的真实集数","🔗 收藏内容播放修复:为收藏内容生成正确的播放URL","🐛 豆瓣源参数修复:防止豆瓣源参数导致播放页面崩溃","🎯 分类过滤修复:排除直播频道和番剧,修正电视剧type字段,改善收藏分类准确性","📊 集数徽章显示:API可用时立即显示集数,失败或仅1集时隐藏徽章","🏷️ 类型识别增强:正确识别短剧、综艺等类型,防止空字符串导致分类错误","🔄 短剧搜索竞态条件:解决清空搜索时的竞态条件问题","🔌 备用API优化:添加专用代理、HTTPS转换、数据验证等,提升短剧内容获取成功率"]},{version:"5.7.0",date:"2025-12-06",added:["🎭 演员头像和推荐影片功能:在播放页面展示演员头像和类似影片推荐","🔍 直播源标签页搜索功能:为直播源标签页添加搜索功能,快速查找直播频道"],changed:["🖼️ 默认图片代理模式改为 server:在所有组件中将默认图片代理从 direct 改为 server 模式","📅 演员信息显示优化:为演员姓名和角色添加 tooltip,防止文本截断","📦 升级依赖:升级 hls.js 到 v1.6.15"],fixed:["🖼️ 修复演员头像显示问题:","支持 `/celebrity/` 和 `/personage/` URL 格式","过滤默认占位符头像","实现图片代理自动修复(从 direct 迁移到 server 模式)","自动迁移旧版 localStorage 配置","📱 修复推荐卡片移动端导航问题:","使用捕获阶段事件监听拦截 VideoCard 内部事件","添加长按检测(500ms)以保留操作菜单功能","修复移动端点击跳转到页面顶部的问题","保留所有 VideoCard hover 效果和 UI 显示","🎯 修复推荐卡片事件冲突:","使用 `addEventListener` 的捕获模式优先拦截事件","添加 `stopImmediatePropagation` 防止事件干扰","短按跳转,长按显示菜单,完美兼容移动端和桌面端","🔧 修复日期计算不一致性:修复首页和发布日历之间的日期计算差异"]},{version:"5.6.3",date:"2025-11-17",added:["🎉 短剧多源搜索功能:为短剧内容启用多源搜索,支持从横幅和卡片触发的详情集成","🎨 虚拟滚动增强功能:添加自动滚动和图片预加载,提升浏览体验","📊 智能分布算法:为即将上映部分实现智能时间分布算法"],changed:["🔐 SessionTracker兼容性增强:同时支持auth和user_auth cookies,提升会话追踪稳定性","📈 发布日历API限制提升:从20增加到100,显示更多即将上映内容","🔍 即将上映时间范围扩展:从30天扩展到90天,提供更长期的内容预览","📅 今日发布硬性限制:防止今日发布内容在即将上映部分占主导地位","📊 即将上映时间分布算法改进:优化即将上映内容的展示分布","📺 频道名称滚动动画:为直播
1视图中的频道名称添加滚动文字动画"],fixed:["🔧 修复videoDoubanId检查时渲染0值的问题:防止豆瓣ID为0时的错误显示","🎯 智能源过滤实现:自动过滤class字段和源中的零值以及无集数的视频源","🚫 过滤无效数据:清理class字段中的零值和没有集数的源","📺 更新availableSources状态:确保源选择器仅显示有效视频源","🔝 改进全屏按钮可见性:优化小屏幕设备上全屏按钮的显示","🎪 隐藏收藏中的占位集数:避免显示短剧的99集占位符误导用户","🚫 防止短剧源错误添加:确保短剧源不被添加到非短剧内容","🎯 修复VideoCard徽章显示:支持所有发布状态类型的徽章正确显示","⏰ 解决日期比较时区问题:修复即将上映过滤中的时区导致的日期判断错误","🔗 修复HeroBanner播放链接:添加stype参数确保正确跳转","🎯 修复HeroBanner搜索匹配:使用douban_id替代标题匹配,提升搜索准确性","🎬 改进短片标题搜索:优化短片标题的模糊搜索算法准确性","🔝 修复跳过按钮z-index:防止跳过按钮覆盖导航栏","📍 修复跳过按钮定位:确保跳过按钮保持在播放器容器内的固定位置","❤️ 添加专用收藏心形按钮:为收藏面板添加专用可点击心形按钮","🎯 隐藏收藏悬停按钮:防止浮动心形按钮干扰用户操作","🗑️ 移除收藏面板重复元素:清理收藏面板中的重复心形和日期标签","🧹 清理已上映内容播放URL:确保已上映的即将上映内容可正常播放","🏷️ 智能源标签系统:支持动态状态和配色主题的源标签","🎨 动态发布徽章:根据发布状态动态显示徽章并隐藏占位集数","▶️ 启用已上映收藏播放:智能检测即将上映内容是否已上映并启用播放","🔄 智能去重和动态状态:优化即将上映内容的去重和状态更新逻辑","🎯 增强M3U8广告过滤:添加SCTE-35检测提升广告过滤效果","🔧 修复带副标题的去重逻辑:改进标题重复检测算法","📊 修复卡片z-index冲突:防止所有卡片组件覆盖导航栏","📱 修复VideoCard悬停z-index:解决VideoCard悬停/点击时覆盖导航栏的问题","🎯 修复工具提示z-index冲突:确保VideoCard工具提示不与导航栏冲突","🔧 修复短剧源显示问题:确保短剧源正确显示在源选择器中"]},{version:"5.6.2",date:"2025-11-06",added:["🎬 英雄横幅全品类内容支持:为所有内容类型(电影、剧集、综艺、短剧、番剧)添加详情描述到英雄横幅","📅 即将上映日历功能:新增即将上映section,展示未来30天内的电影和电视剧上映信息","🖼️ 发布日历海报图片提取:实现从manmankan网站抓取即将上映内容的封面图片(支持懒加载data-original)","🎨 Aurora网格渐变背景:为发布日历页面实现Aurora Mesh Gradient背景,增加动画blob效果","📱 移动端横幅滑动卡片布局:实现移动端友好的可滑动卡片式横幅布局,支持触摸手势导航","🔖 即将上映类型徽章:为即将上映卡片添加电影/电视剧类型标识徽章(左上角)","⭐ 即将上映收藏功能:支持收藏即将上映内容,上映后自动变为可播放状态","🔄 收藏集数自动更新:播放页面自动更新收藏的占位符集数(99集)为真实集数","📺 直播流DVR后加载检测:","播放器加载后使用video.seekable API检测DVR/时移支持","检测到可seek范围超过60秒时显示通知横幅","添加启用进度条按钮以DVR模式重新加载播放器(isLive: false)","显示可seek时间范围(分钟)供用户参考","仅在未启用DVR模式时检测,避免冗余检查"],changed:["🎨 发布日历页面UI美化:优化发布日历页面视觉效果,添加渐变背景和现代化设计","📱 大屏幕响应式布局优化:改进大屏幕设备上的响应式布局效果","🎯 即将上映内容去重:基于标题对即将上映数据进行去重,保留最早上映日期","🚫 即将上映内容禁用播放:未上映内容显示敬请期待而非播放按钮,防止用户困惑","👁️ 隐藏即将上映集数徽章:不显示即将上映内容的占位符集数,避免误导用户","⚡ 播放进度保存频率优化:增加播放进度保存间隔以减少网络开销","🔍 新集数检测优化:跳过播放期间的冗余fetch请求,优化性能","📊 播放记录请求优化:减少播放记录API请求频率,降低网络负担"],fixed:["🖼️ manmankan图片代理支持:添加manmankan.com的Referer支持到图片代理,绕过防盗链","🔧 豆瓣详情剧情摘要提取修复:修复从豆瓣详情中提取完整剧情摘要的问题","🗑️ 豆瓣详情缓存失效处理:当plot_summary缺失时自动失效缓存,确保数据完整性","🔗 短剧横幅更多按钮链接修复:修正短剧类别在英雄横幅中的更多按钮跳转链接","🔝 播放页返回顶部按钮位置修复:调整返回顶部按钮在移动端的响应式位置,防止与更多菜单重叠","📐 搜索页z-index修复:防止底部导航被返回顶部按钮遮挡","🎬 横幅内容截断修
1复:防止描述过长时英雄横幅内容被截断","🎮 视频播放器z-index修复:修复移动端底部菜单被视频播放器遮挡的问题","🔍 移动端短剧搜索参数修复:使用正确的query参数进行移动端短剧搜索","🐛 isUpcoming变量声明顺序修复:移动isUpcoming声明到useEffect之前,解决编译错误","📦 getAllFavorites导入修复:使用正确的静态导入替代动态import,修复TypeScript编译错误","🎯 异步详情获取修复:修正所有英雄横幅项目的异步详情获取逻辑"]},{version:"5.6.1",date:"2025-11-01",added:["🎨 英雄横幅和现代化导航UI:添加自动轮播的英雄横幅和渐变背景,重新设计导航(桌面端水平顶部栏+移动端Liquid Glass底部导航)","🎯 TVBox智能搜索代理:添加TVBox智能搜索代理功能,支持成人内容过滤和UI控制","📋 快速复制TVBox配置模式按钮:新增TVBox配置模式的快速复制按钮,简化配置流程","🔧 成人内容路径前缀支持:为成人内容过滤添加路径前缀支持功能","📤 视频源导出格式选择:新增导出格式选择,支持数组和配置文件格式","⏱️ 批量成人内容标记成功提示自动关闭:为批量成人内容标记成功提示添加自动关闭计时器"],changed:["📱 修复移动端页面过度间距问题:减少移动端头部高度并应用更紧凑的布局,修复所有页面的过度间距","🎨 优化短剧页面加载指示器:改进短剧页面在浅色模式下的加载指示器显示效果"],fixed:["🔧 修复卡片和徽章的z-index层级问题:纠正卡片和徽章的z-index层级,防止出现叠加显示问题","🎭 降低剧集徽章z-index:降低剧集徽章的z-index值,防止遮挡模态框","📱 增加移动端PageLayout底部内边距:增加移动设备上PageLayout的底部内边距,改善布局","🔝 提高AI推荐模态框z-index:提高AI推荐模态框的z-index值,防止徽章重叠","🖼️ 修复豆瓣海报图片403错误:通过代理路由豆瓣海报图片,防止出现403禁止访问错误","🎬 移除短剧页面白色背景框:移除短剧页面的白色背景框,优化视觉效果","🔄 还原短剧加载指示器样式改进:还原对短剧加载指示器在浅色模式下的样式改进","🐛 修复Webkit光标和iPadOS进度条问题:修复Webkit浏览器的光标显示和iPadOS设备的进度条交互问题"]},{version:"5.6.0",date:"2025-10-27",added:["🔐 Telegram Magic Link身份验证:实现基于Telegram的Magic Link认证功能,提供更安全便捷的登录方式","🤖 自动设置Telegram Webhook:生成Magic Link时自动配置Telegram webhook,简化部署流程","🔍 资源搜索端点权限验证:为/api/search/resources端点新增用户身份验证检查,提升API安全性","🎯 源浏览器完整功能集成:新增源浏览器和测试模块到管理后台,支持源站测试和管理","🎨 源浏览器增强UI设计:优化源浏览器和测试模块UI界面,提升用户体验"],changed:["📱 源浏览器移动端布局优化:改进移动端搜索控制和响应式布局,适配各种屏幕尺寸","🎯 侧抽屉替代居中弹窗:用侧边抽屉替代源测试结果的居中弹窗显示,优化空间利用","📐 抽屉卡片布局优化:优化抽屉模式下的卡片布局和间距"],fixed:["🔧 防止Upstash用户自动删除:修复Upstash环境下用户被自动删除的问题,并清理登录统计数据","🎭 抽屉z-index层级修复:增加抽屉z-index防止移动端导航栏覆盖问题","🔄 防止源站跳转问题:修复源浏览器中的源站意外跳转问题","🚪 Portal渲染修复视口定位:使用Portal渲染抽屉以修复视口定位问题","📱 预览弹窗z-index修复:修复源浏览器预览弹窗z-index防止被头部覆盖","🔒 移动端底部导航遮挡问题:防止移动端底部导航栏遮挡预览弹窗内容","✨ 移除短剧分类按钮闪烁效果:移除短剧分类按钮的闪烁动画效果,优化视觉体验"]},{version:"5.5.8",date:"2025-10-16",added:["🎬 新增视频源导入/导出功能:支持批量管理视频源配置,便于备份和迁移"],changed:["🎨 优化VideoCard徽章布局和定位:改进视频卡片徽章的视觉效果和位置","📱 优化返回顶部按钮位置:调整按钮位置更贴近底部,提升移动端体验","⚡ 优化短剧分页分类UI闪烁问题:通过智能加载状态管理,切换分类时保持旧内容显示直到新内容加载完成,大幅减少UI闪烁"],fixed:["🔧 修复片尾自动播放导致跳跃2集的问题:","添加冷却机制防止双集跳过","在SkipController添加episodeIndex prop修复剧集切换时的自动跳过","防止视频结束时保存播放进度以避免不正确的恢复位置","重置lastProcessedSegmentRef状态防止重复处理片段","添加详细调试日志协助排查匹配失败","优化剧集切换后的自动跳过重置机制","🎯 修复VideoCard装饰元素的悬停缩放和z-index同步问题","🔄 改进视频卡片装饰覆盖层的悬停效果同步","📐 优化视频卡片徽章和装饰覆盖层的z-index层级","🖱️ 修复VideoCard工具提示定位和布局问题","🔨 修复返回顶部按钮的定位和可见性问题","🎭 修复加载旋转器边框和工具提示显示问题","🐛 修复Docker工作流自动构建版本标签功能","🔍 修复merge job中版本检测总是变化的问题","🛠️ 为merge job版本检查添加调试输出"]},{version:"5.5.7",date:"2025-10-11",added:["🎨 玻璃态渐变UI全面升级:为首页、侧边栏、视频卡片、播放页、短剧页面等应用玻璃态设计、渐变主题和流畅动画效果","🔐 TVBox用户专属Token系统:新增每个用户独立的TVBox token和视频源访问限制功能","📊 Docker自动版本标签:为CI/CD流水线添加自动版本检测功能,实现Docker镜像自动打标签"],changed:["🎯 剧集选择器和视频源切换器UI增强:优化剧集选择器和视频源切换器的视觉效果,添加渐变和动画","🎬 播放页UI优化:为移动端和桌面端播放页面增强UI体验,添加渐变效果","📱 豆瓣页面筛选面板美化:优化豆瓣页面筛选面板和分页状态的视觉设计","🎭 短剧页面UI美化:为短剧页面应用渐变设计和动画效果","🛠️ 管理后台加载和空状态美化:优化管理页面的加载和空状态显示效果","📏 播放页返回顶部按钮位置调整:将返回顶部按钮移至右下角位置","🎯 VirtualDoubanGrid完成消息优化:改进Bangumi模式下的完成提示消息"],fixed:["🔥 彻底修
1复片尾自动播放双集跳跃问题:通过多层防护机制完全解决片尾自动播放时跳2集的bug","添加`lastProcessedSegmentRef`防重复触发机制,确保同一片段只处理一次","添加`videoEndedHandledRef`防止同一video:ended事件被多个监听器重复处理","移除SkipController中的1秒延迟,避免延迟期间触发video:ended事件","延迟重置`isSkipControllerTriggeredRef`标志至2秒,适配短剧异步URL解析","🎭 剧集选择器标签页文字不可见问题:修复剧集选择器中标签页文本隐形的问题","🔄 跳过配置段落长度未定义错误:修复SkipController中segments.length未定义导致的错误","⚙️ 跳过设置对话框UX优化:新增多种关闭选项提升用户体验","🎯 切换集数时自动跳过设置重置问题:修复切换集数时跳过设置被重置的问题,确保用户设置持久化","📝 跨组件自动跳过设置同步:修复所有UI组件之间的自动跳过设置同步问题","🔁 用户设置跨集数和跨进度保持:修复用户跳过设置在seek和切换集数时的持久化问题","📊 番剧模式继续观看卡片集数显示:修复继续观看卡片的集数显示与播放统计页面保持一致"]},{version:"5.5.6",date:"2025-10-08",added:["🎯 片头片尾跳过实时标记按钮:新增实时标记片头片尾时间点的交互按钮,方便用户快速配置跳过设置","🎮 可拖拽跳过配置悬浮窗:新增可拖拽的跳过配置悬浮窗组件,支持触摸操作和位置持久化存储","📱 移动端跳过设置按钮显示:修复移动端设备上跳过设置按钮的显示问题","🎬 片尾剩余时间模式跨集数支持:实现片尾跳过配置的剩余时间模式在切换集数时的正确处理","📊 继续观看卡片完结徽章:为所有继续观看部分添加已完结系列徽章显示","🔍 TVBox深度JAR诊断系统:新增JAR文件头验证的深度诊断系统和智能健康检查"],changed:["📐 可拖拽跳过配置悬浮窗边界限制:优化悬浮窗拖拽边界限制和位置持久化机制","🎨 Zeabur部署指南简化:简化Zeabur部署指南为仅Docker镜像方式,移除复杂的GitHub集成部署","📝 Zeabur部署指南KVRocks配置更正:修正KVRocks持久化卷路径说明,从`/data`改为正确的`/var/lib/kvrocks/db`","🌐 Zeabur一键部署模板链接更新:更新README中的Zeabur一键部署模板链接","🏠 Zeabur部署完成后域名设置提醒:添加部署完成后需要设置访问域名的重要提示","📚 README锚点链接修复:修复设置访问域名部分的锚点链接"],fixed:["🔧 original_episodes损坏和无限API请求防护:防止original_episodes数据损坏导致的无限API请求问题","🛡️ 剧集检测时自动original_episodes更新防护:防止剧集检测过程中original_episodes被自动更新","📝 剧集更新检测时original_episodes覆盖防护:防止剧集更新检测时original_episodes字段被意外覆盖","🎬 片尾跳过剩余时间模式跨集数修复:修复片尾跳过配置在剩余时间模式下切换集数时的处理逻辑(多次优化)","🔄 KVRocks跳过配置首次加载问题:修复KVRocks环境下跳过配置首次加载不生效的问题","📊 跳过配置架构重构:采用新的跳过配置架构设计,实现更稳定可靠的片头片尾跳过功能","🎯 观看更新卡片闪烁优化:通过排序updatedSeries防止继续观看卡片闪烁","🌐 Zeabur部署指南和演示站点更新:更新Zeabur部署指南内容并添加最新演示站点链接"]},{version:"5.5.5",date:"2025-10-06",added:["🎯 TVBox诊断增强:新增完整诊断详情展示到用户页面和管理后台,包括基本信息、Spider状态、配置字段等","🔍 Spider管理系统:实现Spider探测、缓存、降级代理机制,支持多个Spider JAR备份源(gaotianliuyun作为第三备份源)","📊 管理统计卡片增强:新增新剧集卡片和继续观看卡片到管理员统计页面,优化布局显示","🎬 已完结系列徽章:基于vod_remarks添加已完结系列徽章功能,支持搜索API和详情API的remarks检测","📝 双语README和完整文档:新增CC BY-NC-SA 4.0协议声明、Vercel部署指南、Selene移动应用说明、重要声明章节","🔄 Spider状态API:新增Spider状态查询端点,增强TVBox诊断UI显示"],changed:["⚡ Spider JAR优化:优先使用GitHub raw源以减少失败尝试,实现快速模式和本地代理降级","🔄 缓存机制优化:Kvrocks/Upstash使用内存缓存以解决慢加载问题,防止localStorage写入","🎯 原始集数逻辑改进:信任客户端提供的original_episodes,使用recordKey精确匹配source+id而非标题匹配","📊 搜索API优先级:优先使用搜索API的remarks而非详情API来判断完结状态","🌐 TVBox站点名称动态化:使用动态站点名称替代硬编码的LunaTV","📦 react-window升级至v2.2.0:升级虚拟滚动组件至最新版本","🎨 README优化:修复目录锚点链接ï¼
1Œæ›´æ–°Docker配置说明,添加Selene移动应用章节"],fixed:["🔧 original_episodes更新逻辑完善:自动修正无效的original_episodes值(大于total_episodes时),当用户观看新剧集时更新,保留原始值不被覆盖","💾 缓存更新时序修复:在数据库更新成功后清除缓存而非之前,确保数据一致性","🔄 播放记录缓存刷新:当original_episodes更新时强制刷新播放记录和watching-updates缓存","📱 QuotaExceededError修复:watching-updates使用内存缓存解决localStorage配额超限问题","⚙️ ESLint规范修复:将siteExt改为const以修复prefer-const警告","🎯 实时数据同步:为Kvrocks存储模式确保实时数据同步,优化播放记录和watching-updates同步机制","🔍 强制刷新参数:为checkWatchingUpdates和UserMenu添加forceRefresh参数以绕过缓存","🗄️ 数据库original_episodes获取:总是从数据库获取新鲜的original_episodes数据,确保更新检测准确","🎭 TVBox配置问题:修复yingshicang模式下的硬编码spider jar问题,修复长URL溢出显示,优化TVBox页面布局","🔐 localStorage写入限制:防止saveUserCache在使用Kvrocks/Upstash时写入localStorage","📝 UserMenu存储类型初始化:优化存储类型初始化以防止冗余渲染"]},{version:"5.5.4",date:"2025-10-03",added:["🔐 TVBox普通用户访问支持:新增/api/tvbox-config端点,允许所有登录用户访问TVBox配置","🎨 登录注册界面现代化:升级登录/注册页面,添加动态随机壁纸和现代化UI设计","💾 日历缓存数据库迁移:将日历缓存从localStorage迁移至数据库,支持跨设备同步"],changed:["🎯 登录注册链接卡片化:将登录/注册链接升级为渐变按钮卡片样式","📊 前端数据库缓存优化:实现前端数据库缓存优化,提供即时加载体验","📦 react-window升级至v2.2.0:升级虚拟滚动组件至最新版本"],fixed:["🔄 原始集数更新逻辑修复:修复新剧集追踪的original_episodes更新逻辑","🔁 重复播放记录问题:解决重复播放记录和错误original_episodes值的问题","🗄️ Upstash对象反序列化支持:修复日历缓存的Upstash对象反序列化问题","📝 自动更新检测original_episodes保留:防止auto-update检测时覆盖original_episodes字段","🔐 用户注册后Upstash主从同步等待:修复Upstash主从同步延迟问题","🚫 Next.js动态路由警告消除:为动态API路由添加force-dynamic声明,清理控制台警告"]},{version:"5.5.3",date:"2025-09-30",added:["🎯 用户等级系统:新增用户等级系统取代大数字登录次数显示,提供更友好的用户体验","📅 登录时间追踪:实现登录时间跟踪功能,增强管理员用户清理配置和分析能力"],changed:["🏷️ 用户等级显示逻辑:用户等级从首次登录时开始显示,避免0登录边界情况","📝 管理员页面文案:更新管理页面文本以反映基于登录的用户删除逻辑"],fixed:["🔄 播放记录原始集数修复:自动修复历史播放记录中缺失的original_episodes字段,消除数据警告","📺 继续观看卡片去重:修复重复的继续观看卡片问题,确保传递正确的数据源名称","🎮 用户等级系统边界处理:修复用户等级系统显示问题和0登录边界情况的处理逻辑","🛡️ TVBox IP白名单解析优化:修复x-forwarded-for头部解析问题,提升TVBox配置在代理环境下的访问准确性"]},{version:"5.5.2",date:"2025-09-27",added:["⚡ react-window升级至2.1.2版本:升级虚拟滚动库至最新版本,利用ResizeObserver优化提升性能","🎨 虚拟滚动开关界面美化:为虚拟滚动和聚合开关添加渐变样式、图标和动画效果,提升用户界面体验","🏠 首页继续观看新剧集徽章:为首页继续观看部分添加新剧集提醒徽章"],changed:["🎯 虚拟滚动网格尺寸优化:添加明确的高度和宽度设置,避免不必要的ResizeObserver调用,改善滚动体验","📊 overscanCount参数优化:将overscan数量从1调整为3(官方默认值),减少滚动时的视觉闪烁","🔔 继续观看组件主动更新检测:优化继续观看组件的主动更新检测机制","👤 用户菜单即时更新检测:修复用户菜单组件的即时更新检测逻辑","📅 TMDB排序优化:修复TMDB排序逻辑,使用正确的日期顺序(最新优先)","🎯 用户菜单实时更新增强:为用户菜单各组件添加全面的实时更新功能","🔍 继续观看进度过滤定制化:添加可定制的进度过滤器,移除95%上限限制"],fixed:["🔄 跨设备同步原始集数追踪:修复跨设备original_episodes同步问题,确保新剧集检测的准确性","📺 发布日历网格视图去重:为发布日历网格视图添加去
1重逻辑,避免重复条目显示","🐛 react-window 2.1.2加载和滚动问题:基于源码分析修复升级后的加载停滞和滚动异常问题","🖤 虚拟滚动黑色背景伪影:消除虚拟滚动过程中出现的黑色背景区域","📱 Grid滚动截断问题:修复Grid内滚动时最后一行被截断的显示问题,优化高度计算和边距设置","🔄 重复播放记录问题:修复更新剧集数量时产生重复播放记录的问题","📊 播放记录剧集数量同步:确保播放记录的剧集数量与新剧集检测保持同步"]},{version:"5.5.1",date:"2025-09-25",added:[],changed:[],fixed:["🔧 Bangumi推荐接口错误处理增强:修复bangumi API返回null数据时导致首页崩溃的问题,使用Promise.allSettled防止单个API失败影响整个首页","🛡️ Bangumi数据结构类型安全修复:更新BangumiCalendarData接口定义,将所有可能缺失的字段标记为可选属性,确保类型安全","🖼️ Bangumi图片数据空值安全检查:添加可选链操作符处理anime.images可能为null的情况,提供默认占位图片作为fallback","🎯 首页推荐数据健壮性提升:为所有推荐API(电影、剧集、综艺、短剧、bangumi)添加错误处理和默认值,确保页面在部分API失败时仍能正常显示","🔄 继续观看功能更新提醒优化:从用户菜单更新提醒中移除继续观看功能,避免功能重复和用户困惑","📱 跨设备原始集数追踪机制:添加跨设备原始集数追踪功能,防止API缓存问题导致的错误更新提醒","🎪 观看更新检测逻辑完善:修复观看更新检测逻辑,确保更新通知的准确性和可靠性"]},{version:"5.5.0",date:"2025-09-24",added:["🎭 TMDB演员搜索系统:实现完整的演员搜索功能,支持过滤和缓存机制","📊 发布日历和即将上线系统:为用户提供即将发布的影视内容预览和跟踪功能","🔝 发布日历返回顶部按钮:为发布日历页面添加快捷返回顶部功能,提升浏览体验","🎯 非活跃用户自动清理功能:实现智能的非活跃账户自动清理机制,包含详细配置和日志记录","🔔 用户菜单更新提醒功能:新增更新提醒按钮,支持实时通知剧集更新和继续观看","▶️ 用户菜单继续观看功能:新增继续观看快捷入口,展示播放进度和待续看内容","❤️ 用户菜单我的收藏功能:新增收藏快捷入口,便捷访问收藏的影视内容","🔗 移除GitHub链接:清理登录和注册页面的GitHub相关链接,简化界面设计","📱 移动端弹幕配置优化:将外部弹幕默认设置为禁用状态,优化移动设备的弹幕配置和悬停稳定性","🎬 视频播放增强:升级HLS.js到v1.6.13版本,改进错误处理和播放稳定性"],changed:["🔄 管理员环境变量使用标准化:统一管理员相关的环境变量使用规范","⚙️ 音量控制悬停区域优化:减少音量控制的悬停触发区域,防止意外激活并优化检测精度","🎛️ 弹幕配置面板交互改进:通过延迟机制改进弹幕配置面板的悬停稳定性和精确控制","📅 发布日历视图数据显示改进:解决日历视图数据展示问题并增加地区信息显示","🎨 TMDB卡片界面简化:简化TMDB卡片设计并增强日历视图交互体验","🐛 TMDB虚拟滚动点击播放优化:修复虚拟滚动环境下的点击播放功能问题"],fixed:["🔧 TMDB缓存管理和搜索限制修复:解决TMDB缓存操作问题并移除搜索限制","📊 即将上线发布部分首次API失败修复:解决发布日历初次加载时的API调用失败问题","🎯 播放统计强制缓存清除修复:解决记录删除时的缓存清除问题,确保UI实时更新","📱 继续观看卡片实时更新修复:改进播放统计的数据刷新和实时更新机制","🔍 英语搜索匹配算法重构:使用基于词汇的算法改进英语搜索匹配准确性","🌐 语言感知搜索过滤实现:实现语言相关的搜索过滤以提高搜索结果相关性","🚫 搜索变体无意义词汇过滤:过滤搜索变体中的无意义词汇以防止不相关匹配","📺 播放页面搜索功能修复:移除数字变体并改进中文电影标题的模糊搜索","⚡ 搜索性能优化:移除早期退出策略,优化搜索相关性评分和同步播放页面逻辑","🎵 中文电影标题模糊搜索改进:改进带标点符号和数字变体的中文标题模糊搜索","🎯 智能模糊搜索相关性评分:实现带相关性评分的智能模糊搜索系统","🔢 数字后缀标题匹配优先级修复:修复搜索优先级以匹配带数字后缀的标题","🔄 观看更新检测逻辑优化:引入原始集数保护机制,防止API缓存问题导致的错误更新提醒","📈 观看更新算法完善:改进新集数检测和继续观看提醒的判断逻辑,确保更新通知准确性"]},{version:"5.4.4",date:"2025-09-22",added:["🎬 播放统计页面VideoCard观看更新显示系统:使用VideoCard组件显示观看更新,提供更直观的用户体验","📊 播放统计页面双重提醒系统:新增新剧集和继续观看独立分类,红色主题显示新剧集更新,蓝色主题显示继续观看提醒","🎨 播放统计页面视觉效果增强:为观看更新卡片添加红/蓝光环效果、渐变徽章和动画,提升界面美观度","📈 播放统计页面用户活动分析增强:新增登录天数计算,基于firstWatchDate逻辑补充现有注册天数数据","🛠️ 播放统计页面调试功能完善:为缓存读写操作添加详细日志记录,增强调试能力和故障排查","📋 管理员个人统计选项卡:为管理员统计页面添加选项卡切换功能,支持全局统计和个人统计视图","🆔 播放统计页面API端点安全性:新增/api/sources端点,安全地向客户端暴露可用数据源"],changed:["🔄 播放统计页面移除弹窗式更新:完全移除基于弹窗的观看更新显示方式,改用VideoCard直接展示","🔧 播放统计页面移除测试按钮:移除弹窗显示调试的测试按钮,简化界面","📋 播放统计页面WatchingUpdate接口扩展:为接口添加cover属性和continueWatchingCount字段,增强数据结构","🎯 播放统计页面更新检测逻辑优化:简化shouldShowUpdate条件,移除复杂的userWatchedLatest检查逻辑","🔧 播放统计页面参数修正:修复VideoCard的source/id参数使用正确的sourceKey和videoId值","⚡ 播放统计页面数据刷新机制优化:增强刷新数据按钮功能,支持清除缓存并强制重新检查更新","📊 播放统计页面统计计算标准化:统一管理员和个人统计页面的注册天数计算逻辑,使用PROJECT_START_DATE作为fallback","🌐 播放统计页面API源映射策略:从响应式改为主动式源名称到API密钥映射,预防API调用错误"],fixed:["🔢 修复播放统计页面继续观看计数错误:纠正继续观看数量计算逻辑,显示正确的统计值","📅 修复播放统计页面注册天数计算不一致:解决管理员统计显示7天而个人统计显示1天的差异问题","⚙️ 修复播放统计页面新用户创建时间戳:为自注册和管理员创建的新用户正确设置createdAt字段","🌐 修复播放统计页面API源映射问题:实现主动源名称到API密钥映射,避免400错误并修复Upstash环境变量错误","🔗 修复播放统计页面数据源映射逻辑:改进源名称与API配置的智能匹配,处理显示名称与内部API密钥差异","🚫 修复播放统计页面ESLint合规性:移除空箭头函数以符合ESLint规范要求","🏠 修复播放统计页面owner用户统计API:确保个人统计API使用实际用户createdAt而非当前时间","🔄 修复播放统计页面更新检测逻辑:确保只要latestEpisodes > record.total_episodes即显示更新,支持多剧集更新检测"]},{version:"5.4.3",date:"2025-09-20",added:["🎯 扩展Bangumi ID支持范围:从仅支持6位数字扩展至支持3-6位数字,兼容更多Bangumi主题ID"],changed:[],fixed:["🔧 修复弹幕菜单长时间播放后悬停失效问题:恢复原ç”
1ŸArtPlayer悬停机制处理弹幕控制","🖱️ 解决pointer-events阻挡导致的悬停检测失败:添加周期性状态重置防止长期DOM污染","🎮 实现精确进度条冲突解决方案:确保悬停功能在普通和全屏模式下均正常工作","⚡ 升级react-window至v2.1.1:采用单行网格优化改善布局处理","🔄 确保单行网格高度约束:当rowCount === 1时利用react-window 2.1.1修复","📺 修复剧集切换播放时间不重置问题:添加剧集变更检测标志","🎯 区分剧集和源切换逻辑:剧集使用switchUrl()重置至0,源使用switchQuality()保持时间","🧹 完善标志清理机制:确保所有路径下的状态标志正确清理"]},{version:"5.4.2",date:"2025-09-19",added:["🎯 网盘搜索结果标题展开收起功能增强:支持移动端30字符、桌面端80字符响应式展开","📱 网盘搜索结果移动端显示优化:长标题自动截断并提供展开按钮功能"],changed:["🎨 网盘搜索结果标题按钮样式升级:采用蓝色胶囊按钮设计,支持悬停效果和旋转动画图标","📱 移动端视频控制器断点优化:从768px调整至1024px,更好支持现代手机屏幕","🔄 移动端控制器跨方向响应性改进:移除方向限制,在所有方向下都应用移动端优化","⚡ 弹幕性能优化:源切换时的批量处理和去重优化"],fixed:["🔧 修复弹幕清理序列防止重复:正确使用弹幕插件清理流程","🎮 修复ArtPlayer弹幕插件API调用:移除无效调用并使用正确的API方法","🎵 解决视频源切换时弹幕重复和延迟:添加源切换标志位防止重复加载,优化状态管理","📺 修复首集切换时弹幕不更新:重置弹幕加载状态,清理旧数据防止竞态条件","📱 简化视频控制器媒体查询防止按钮溢出:移除悬停和指针限制,确保一致的UI行为","🖥️ 修复桌面浏览器窗口缩小时的控制按钮溢出问题:在1024px以下隐藏特定控件"]},{version:"5.4.1",date:"2025-09-17",added:["🚀 弹幕性能激进优化:智能分段加载系统,按5分钟分段管理弹幕数据","🎯 设备性能自动检测:根据硬件性能自动调整弹幕渲染策略","💡 动态弹幕密度控制:实时监控屏幕弹幕数量,自动丢弃过量弹幕保持流畅","🔧 用户组权限系统:为AI助手和YouTube功能添加用户组权限控制"],changed:["🎮 TVBox配置移动:从导航栏移至用户菜单,优化界面布局","⚡ 弹幕数量限制移除:取消10000条硬编码限制,支持处理大量弹幕数据","🎯 弹幕过滤策略升级:更严格的质量过滤,智能采样保持时间分布均匀","🔄 短剧缓存系统增强:自动清理机制和HTTP缓存优化"],fixed:["🐛 TVBox API路由兼容性:修复动态分类获取和配置字段兼容问题","📱 短剧移动端缓存:解决缓存刷新问题,提升移动端体验","🎬 YouTube流量说明:修复管理面板中的流量解释显示","🎛️ 播放统计导航:修复activePath属性,确保导航高亮正确","⚡ 进度跳转卡顿:通过硬件加速和批é‡
1å¤„理大幅改善拖拽性能","🔄 集数切换优化:防抖处理和状态管理,减少切换时的延迟"]},{version:"5.4.0",date:"2025-09-14",added:["🎬 短剧完整功能集成:全面集成短剧搜索、播放、详情展示功能","📱 短剧移动端API代理路由:为移动端提供专用的短剧API代理,解决跨域问题","💾 短剧缓存系统:集成短剧缓存到管理员系统,提供完整的缓存管理功能","🎯 短剧专用详情页面布局:避免与豆瓣详情冲突,提供专门的短剧展示界面","📊 播放统计系统:完整的播放数据统计和分析功能","🎮 弹幕面板移动端优化:基于ArtPlayer挂载逻辑的精确定位"],changed:["🔄 短剧内容过滤优化:防止短剧显示豆瓣/Bangumi数据,确保数据源纯净","📐 移动端弹幕面板定位逻辑:改进CSS定位算法,提升移动端体验","🎵 移动端弹幕面板操作:简化为点击切换机制,避免复杂手势冲突","🔍 内容筛选功能优化:移除所有内容类型(电影、剧集、综艺、动漫)的快捷筛选功能,避免与普通筛选冲突","🎛️ 侧边栏高亮修复:改进导航状态同步机制"],fixed:["🔧 短剧API路由缓存问题:添加HTTP缓存控制头,解决移动端缓存不刷新问题","📱 移动端API代理循环依赖:解决短剧功能的循环依赖问题","🎯 短剧详情显示优化:防止显示0集数,添加双重保护机制","⭐ 短剧评分显示:隐藏零评分内容,优化用户体验","🎮 播放统计Redis错误:修复KVRocks JSON解析错误","📐 移动端弹幕面板定位:修复音量控制悬停状态的定位问题","🔊 音量控制交互优化:修复移动端音量按钮hover状态异常问题","🔄 视频播放器问题:修复动漫筛选和视频播放相关bug"]},{version:"5.3.2",date:"2025-09-13",added:["🎯 弹幕设置菜单交互优化:添加桌面端hover延迟交互机制(300ms显示,500ms隐藏)","⚡ 弹幕菜单性能大幅优化:实现防抖机制,解决开启弹幕时调节字幕大小卡顿问题","🔄 事件监听器全面优化:为位置调整、方向变化、DOM观察器添加防抖处理,提升整体性能","🎮 AI推荐系统令牌优化:默认最大令牌数从1000提升至3000,改善AI响应质量"],changed:["🛠️ 基于ArtPlayer原生拖拽逻辑实现精确弹幕菜单修复","🔍 DOM观察器优化:减少监听范围,仅观察必要的class变化","⏱️ 增强定时器清理机制:防止内存泄漏,确保所有定时器正确释放","📐 弹幕面板位置算法重构:使用CSS默认定位替代复杂的手动计算"],fixed:["🔧 修复弹幕配置菜单全屏模式定位问题:改进CSS定位算法,确保各种屏幕模式下正确显示","🖱️ 解决进度条拖拽与弹幕菜单冲突:基于ArtPlayer原生拖拽逻辑实现精确修复","📱 修复移动端弹幕菜单定位算法:纠正位置计算逻辑,适配不同设备屏幕","🎯 弹幕面板点击事件冲击修复:解决弹幕面板阻挡进度条点击的核心问题","🧹 AI聊天历史自动清理机制修复:优化历史记录管理和清理逻辑","🔄 移除播放器设置中的重复弹幕切换选项:简化用户界面","💡 弹幕菜单CSS hover冲突解决:精确控制hover状态与进度条拖拽的交互","📋 完善弹幕菜单hover行为:统一移动端和桌面端交互逻辑,提供一致用户体验"]},{version:"5.3.1",date:"2025-09-11",added:["🎥 AI推荐系统YouTube视频链接解析:支持直接解析YouTube视频链接并获取视频信息","🔍 AI推荐卡片三种类型支持:影视推荐卡片、YouTube视频卡片、视频链接解析卡片","🚀 升级react-window到v2.1.0:性能优化提升虚拟滚动效率","📺 升级hls.js到v1.6.12:改进视频播放稳定性和兼容性","🎬 YouTube搜索功能增强:支持时间筛选和排序选项","🔄 直播源自动刷新功能:支持localStorage持久化配置","🎯 电影快速筛选按钮:新增类型快速访问功能","📱 TV节目和综艺节目筛选扩展:完善筛选功能覆盖","🎮 YouTube直播播放器优化:实时视频信息获取功能"],changed:[],fixed:["🔧 修复AI聊天列表项空格过多问题:优化markdown格式处理逻辑","📝 解决AI响应中项目符号间距过大
1问题:移除多余的margin-bottom样式","🎵 修复外部弹幕拖拽进度条后显示异常问题:改进弹幕同步机制","🔍 修复YouTube搜索缓存键和内容类型筛选问题:优化缓存管理策略","📺 修复TV节目和综艺节目MultiLevelSelector缺失initialValues属性问题","🛠️ 解决DoubanSelector中的TypeScript编译错误","🎯 修复平台筛选状态同步问题:改进TV节目筛选器状态管理","🔗 使用YouTube无cookie域名:减少机器人验证问题","📊 修复搜索历史显示问题:优化历史记录展示逻辑","🔝 修复播放页面返回顶部按钮显示问题"]},{version:"5.3.0",date:"2025-09-10",added:["🎥 YouTube集成: 完整的YouTube搜索和直播播放功能","集成YouTube Data API v3搜索功能","支持iframe直接播放YouTube视频","管理后台YouTube API配置面板","YouTube缓存管理系统(参考网盘实现)","YouTube搜索结果缓存统计和管理","🔧 AI推荐系统: 增强的AI内容推荐功能","动态提示词和模型管理优化","支持GPT-5/o系列模型的max_completion_tokens","改进推荐UI和卡片显示计数器","优化推理模型空响应处理","📱 TVBox安全配置: 全面的TVBox集成","通过管理后台完整配置TVBox安全设置","API优化和安全性增强","配置面板移动端UI优化","🎬 iPad/iOS视频播放优化: 全面的移动端播放改进","基于ArtPlayer兼容性模式的智能设备检测","iOS特定自动播放策略(静音启动+音量恢复)","基于官方源码优化的HLS.js配置","多重尝试自动播放重试机制,提升成功率","移动设备内存管理优化"],changed:["🚀 搜索性能: 智能搜索优化和状态管理","切换搜索类型时清除网盘搜索状态","功能切换时的缓存绕过改进","防止功能禁用时的无限重试循环","🎯 移动端UI: 响应式设计改进","TVBox配置移动端显示优化(token复制/重新生成按钮)","配置面板移动端布局改进","💾 缓存管理: 统一缓存系统增强","管理员端点缺失的配置缓存清理","YouTube集成到完整缓存管理基础设施","所有搜索类型的数据库缓存统计(YouTube、网盘、豆瓣、弹幕)","🏗️ HLS.js优化: 基于官方源码的移动设备流媒体改进","缓冲策略:iOS13+ 8秒,iOS 10秒,桌面30秒","内存管理:iOS13+ 20MB,iOS 30MB缓冲大小","加载策略:移动端优化的超时和重试策略","ABR优化:移动设备更快的码率切换","🔧 代码质量: 增强的TypeScript支持和错误处理","EventListener API兼容性改进","复杂函数中的变量作用域管理优化","改进错误边界和回退机制","📦 架构: 遵循现有模式的模块化YouTube集成","与其他搜索功能一致的API端点结构","跨所有搜索类型的统一缓存管理","遵循既定模式的配置管理"],fixed:["🔄 修复功能禁用时网盘搜索卡死问题","🛠️ 解决功能禁用场景下的无限重试循环","🔧 修复TVBox安全配置移动端UI截断问题","📱 修正AI推荐卡片显示并防止无效链接点击","🎵 修复GPT-5/推理模型因token限制导致的空响应","🔨 解决EventListenerOptions的TypeScript编译错误","📊 修复管理面板中YouTube缓存统计显示问题","🎭 改进配置缓存管理的错误处理"]},{version:"5.2.1",date:"2025-09-08",added:[],changed:[],fixed:["🔧 修复 ArtPlayer 5.3.0 SSR 兼容性问题:通过动态导入解决服务端渲染时的 window 对象访问错误","📱 修复直播页面 ArtPlayer SSR 问题:实现相同的动态导入策略,避免 Cannot read properties of undefined 错误","🛠️ 修复 TypeScript 编译错误:为 onSwitch 函数参数添加正确的类型注解","🔍 修复 searchFromApi 函数作用域问题:解决 apiBaseUrl 变量访问范围导致的编译错误","💾 修复 Docker 构建缓存问题:添加无缓存标志和依赖验证,确保新版本依赖正确应用","🎬 修复 ArtPlayer 5.3.0 销毁序列错误:优化播放器实例清理流程,防止运行时错误","🚫 移除不必要的视频元素存在性检查:简化销毁流程,提高稳定性","🎯 实现智能搜索优化:新增搜索查询变体生成器,自动尝试多种搜索模式提高命中率","🔄 优化豆瓣/bangumi 点击搜索:解决手动搜索能找到但点击找不到的标题空格匹配问题","⚡ 智能搜索变体支持:自动生成去空格、关键词组合等搜索变体,支持中餐厅 第九季→中餐厅第九季等转换","🎬 播放页面搜索增强:在播放页面集成智能搜索变体,提升豆瓣内容的片源搜索成功率","💬 弹幕插件 v5.2.0 优化:","启用 useWorker: true 实现基于 Web Worker 的弹幕位置计算","减少 lockTime: 2 降低拖拽延迟,提升交互响应性","实现基于设备性能的智能配置:","高性能设备:启用完整功能,包含防重叠算法 + Worker","中等性能设备:选择性防重叠 + Worker","低性能设备:禁用防重叠但保持同步 + Worker,减
1少 maxLength 至 30","保持 synchronousPlayback: true 确保所有设备的一致用户体验","优化拖拽/窗口变化事件处理,改进防抖机制","🏗️ ArtPlayer 动态导入架构:重构播放器初始化流程,支持客户端只加载,完全兼容 Next.js SSR","🔨 代码质量优化:修复 ESLint 导入排序警告,优化变量声明规范","📦 依赖版本同步:确保 package.json 和 pnpm-lock.yaml 版本一致性","🏗️ 改进 Docker 构建流程:优化缓存策略,确保依赖更新的可靠性","🔄 播放器实例管理优化:改进多实例冲突处理和 DOM 清理逻辑"]},{version:"5.2.0",date:"2025-09-07",added:["🎬 升级播放器核心:将 Artplayer 从 5.2.5 升级到 5.3.0,提升播放稳定性和性能","💬 升级弹幕插件:将 artplayer-plugin-danmuku 从 5.1.8 升级到 5.2.0,优化弹幕显示效果","📱 移动端底部导航增强:TVBox 设置集成到移动端底部导航,提升移动端管理便利性","🔍 PanSou 网盘搜索集成:集成高级筛选和用户体验优化的网盘搜索功能","🗂️ 网盘搜索优化:优化搜索算法和缓存管理,提升搜索响应速度和准确性","🎥 视频详情页网盘搜索:在播放/详情页面直接集成网盘搜索功能,一站式观影体验","🔄 Upstash Redis 缓存集成:完整集成 Upstash Redis 缓存系统,提升数据访问性能","⚡ KVRocks 缓存兼容:新增 KVRocks 存储类型特定处理,完善缓存兼容性支持"],changed:[],fixed:["🔧 修复 TVB
1ox 配置生成错误:解决 undefined API 导致的配置生成失败问题","💾 修复存储类型处理:完善 Upstash 和 KVRocks 缓存兼容性处理逻辑"]},{version:"5.1.0",date:"2025-09-05",added:["🚀 新增豆瓣弹幕API反IP封锁优化:智能延迟策略防止频繁请求被封","🔍 新增IPTV频道当前源内搜索功能:支持在当前直播源中快速搜索频道","📱 新增豆瓣页面虚拟滚动支持:提升大量内容加载性能和用户体验","🎵 新增EXT-X-MEDIA URI处理:防止HLS音轨加载错误导致播放失败","🎌 新增Bangumi API集成:实现动漫内容智能检测和信息获取","💾 新增Bangumi API缓存机制:提升动漫信息获取速度,减少重复请求","🏪 迁移到统一存储缓存:设置直连代理为默认选项,优化网络性能","📦 新增TVBox完整API兼容支持:实现完整的TVBox功能接口","📺 实现直播源聚合功能:解决多源限制问题,提升直播体验","🔧 更新视频解析器接口:新增健康检查机制,提升解析稳定性"],changed:["⚡ 优化豆瓣API请求智能延迟策略:根据请求频率动态调整延迟时间","🛡️ 改进HLS错误处理:防止keyLoadError导致页面冻结,提升播放稳定性","⚙️ 默认禁用源优化和速度测试:减少不必要的网络请求,提升启动速度","🚫 禁用TVBox API缓存:排除中间件认证,优化TVBox兼容性"],fixed:["🔗 修复聚合搜索结果传递douban_id参数到播放页面的问题","📱 修复移动端操作面板在虚拟滚动模式下的截断问题"]},{version:"5.0.0",date:"2025-08-30",added:["🌟 全新豆瓣详情增强显示:播放页面新增丰富的豆瓣电影/剧集信息展示","⭐ 豆瓣评分显示:带星级图标的直观评分展示","🎭 完整演职人员信息:导演、编剧、主演等详细信息","📅 首播/上映日期:智能区分电影和剧集显示格式","⏱️ 时长信息:支持电影总片长和剧集单集时长显示","🌍 制作信息:国家/地区、语言、集数等标签展示","🔧 豆瓣API解析引擎完全重构:基于真实HTML结构精确解析","📺 剧集支持:完美解析中国电视剧信息(如《生万物》)","🎥 电影支持:准确提取国际电影数据(如《坏蛋联盟2》)","🎨 动漫支持:全面兼容日本动画作品(如《怪兽8号》)","👥 多演员处理:正确解析多导演、多编剧、大型演员阵容","🌐 多语言适配:支持中文、英文、日文等不同语言内容"],changed:[],fixed:["🐛 修复豆瓣详情API解析失败问题:重新设计HTML结构匹配算法","🔄 解决首播日期重复显示问题:优化日期提取逻辑,避免'首播:首播:'格式错误","✨ 修复演职人员信息缺失:使用精确的CSS选择器匹配豆瓣页面真实结构","🎯 优化豆瓣评分显示:新增星级图标和颜色区分,提升视觉体验","🚨 主版本升级至5.0.0:豆瓣详情系统重大改进,API响应格式优化","📊 豆瓣详情数据结构调整:新增多个字段,删除重复内容显示"]},{version:"4.3.7",date:"2025-08-30",added:["🚀 高性能弹幕系统优化:实现基于设备性能的智能弹幕渲染策略,自动检测CPU核心数、内存容量和设备类型","🎯 设备性能分级渲染:高性能设备启用完整功能,中等性能设备适度优化,低性能设备激进优化,确保流畅播放","💻 Web端专用弹幕输入按钮:新增简洁的弹字按钮,支持一键快速发送弹幕,仅在Web浏览器显示,避免移动端UI拥挤","⚡ CSS硬件加速优化:为低性能设备启用GPU硬件加速,使用transform和will-change属性优化弹幕动画性能","🧠 智能弹幕过滤器:保持完整弹幕数量的同时,只过滤可能影响性能的超长弹幕和特殊字符弹幕","🎨 自适应弹幕配置:根据设备性能自动调整防重叠算法、同步播放等计算密集型功能的启用策略"],changed:["🎛️ 弹幕渲染策略重构:从减少弹幕数量改为优化渲染性能,确保用户体验不受影响","🖥️ 响应式UI设计:弹幕输入功能仅在Web端启用,移动端专注于播放体验,避免UI元素冲突","⚙️ 设备检测算法:基于硬件并发数、内存限制和设备类型计算综合性能评分,实现精准的性能分级","🛠️ TypeScript类型安全:修复弹幕插件类型定义兼容性问题,使用const assertion确保类型正确性","🔧 代ç 
1æž¶æž„优化:重构弹幕性能检测逻辑,采用工厂模式根据设备性能生成最优配置","📊 性能监控增强:添加详细的性能等级日志输出,便于调试和性能分析"],fixed:[]},{version:"4.3.6",date:"2025-08-30",added:["🚀 新增虚拟滑动功能:搜索结果支持虚拟化渲染,显著提升大量结果的加载性能","📱 智能响应式网格:根据屏幕尺寸自动调整列数(2-8列),完美适配手机到桌面端","⚡ 渐进式加载:搜索结果分批加载(初始12项,滚动时自动加载更多),优化首屏体验","🎛️ 虚拟滑动开关:用户可在搜索页面自由切换虚拟滑动和传统网格显示模式","🔧 智能容器尺寸检测:采用ResizeObserver监听容器变化,确保布局始终准确"],changed:["🎨 优化搜索结果渲染性能:使用react-window 2.0.0进行DOM节点虚拟化,减少内存占用","📐 改进响应式布局算法:基于实际容器宽度动态计算最优列数和项目尺寸","🔄 升级加载状态显示:新增容器尺寸初始化进度提示,提升用户体验"],fixed:["🐛 修复首次搜索时虚拟滑动布局偏移问题:解决容器尺寸计算时序导致的初始布局错误","⏱️ 修复容器引用挂载时机问题:优化useLayoutEffect执行顺序,确保DOM元素正确绑定","🔧 修复react-window 2.0.0 API兼容性:适配新版本的cellComponent和cellProps参数结构"]},{version:"4.3.5",date:"2025-08-29",added:["新增Chromecast投屏功能:支持将视频内容投射到Chromecast设备","Chromecast智能浏览器检测:仅在真正的Chrome浏览器中显示Chromecast按钮","排除厂商浏览器显示Chromecast:自动识别并排除OPPO、小米、华为、三星等厂商浏览器"],changed:["优化弹幕控制按钮显示策略:只显示配置按钮,隐藏切换按钮和发射器以节省空间"],fixed:["修复小屏幕设备控制栏按钮被推出画面的问题:优化弹幕插件控制按钮占用空间","修复移动端弹幕配置按钮不显示的问题:调整width参数确保移动端正确显示","修复OPPO等厂商浏览器错误显示Chromecast按钮的问题:增加OppoBrowser和HeyTapBrowser识别"]},{version:"4.3.4",date:"2025-08-28",added:["新增弹幕数据智能缓存机制:支持localStorage持久化存储,30分钟缓存有效期","缓存支持页面刷新保持:重新打开页面时自动复用缓存数据,避免重复请求","智能缓存键生成:基于影片标题、年份、豆瓣ID、集数生成唯一缓存标识","智能过期清理机制:每次缓存更新时自动清理过期数据,保持localStorage整洁"],changed:["优化切换集数时的弹幕加载逻辑:统一使用缓存优先策略,提升切换速度","改进弹幕API调用性能:相同集数重复访问时直接使用缓存,减少服务器压力","增强状态同步机制:弹幕缓存键使用最新state值而非ref值,确保数据一致性"],fixed:["修复切换集数时弹幕数据未清空的问题:现在使用正确的load()方法清空弹幕","修复页面刷新后缓存失效的问题:改用localStorage替代内存缓存","修复缓存键生成时机过早导致的缓存未命中问题","修复ESLint编译错误:规范变量声明和Map迭代语法"]},{version:"4.3.3",date:"2025-08-28",added:["新增弹幕字号动态调整:支持小号(18px)、默认(25px)、大号(32px)、特大(40px)四种规格","新增弹幕显示区域控制:支持1/4屏幕、1/2屏幕、3/4屏幕、全屏四种显示范围,避免遮挡重要画面","新增弹幕速度调节:支持极慢(10秒)到极快(1秒)五档速度,满足不同观看习惯","新增弹幕透明度设置:从完全透明(10%)到完全不透明(100%)五档透明度选择","新增按类型蒙蔽功能:支持选择性隐藏滚动、顶部、底部弹幕,用户可根据喜好过滤弹幕类型","新增弹幕防重叠开关:可开启/关闭弹幕重叠防护,优化密集弹幕显示效果","新增完善的弹幕配置错误处理机制,防止设置调整时播放器崩溃","优化外部弹幕开关性能:使用Promise.resolve()替代setTimeout()实现更好的异步处理","改进弹幕显示区域配置:使用百分比值替代固定像素值,提升不同屏幕尺
1寸适配性","增强状态同步机制:防止React状态更新和ArtPlayer插件状态不一致导致的显示问题","所有弹幕设置均支持实时调整,无需刷新页面即可看到效果"],changed:[],fixed:["修复外部弹幕开关按钮点击延迟和无响应问题,现在切换更加流畅","修复关闭外部弹幕后仍显示弹幕的问题,现在会完全清空弹幕数据","修复快速切换外部弹幕开关时的竞态条件问题,避免状态不一致","修复弹幕显示区域调整无效的问题,现在可以正确控制弹幕显示范围","恢复弹幕加载提示功能,现在会显示'已加载 X 条弹幕'或'暂无弹幕数据'"]},{version:"4.3.2",date:"2025-08-27",added:["集成第三方弹幕API功能,支持从多个视频平台获取弹幕数据","新增caiji.cyou API集成,支持搜索真实视频内容而非预告片","支持腾讯视频、爱奇艺、优酷、B站等主流平台弹幕获取","智能内容匹配,自动过滤解说、预告等不相关内容","支持多平台弹幕数据合并和时间排序"],changed:["优化弹幕API超时机制,爱奇艺30秒、优酷25秒、其他平台20秒","改进弹幕数据格式转换,确保与ArtPlayer兼容","移除不合适的测试弹幕fallback逻辑"],fixed:["修复弹幕API集数参数传递问题,现在切换集数时能正确获取对应集数的弹幕","改进集数匹配逻辑,支持多种URL格式","修复豆瓣链接解析只获取到预告片的问题","添加定时任务用户处理调试信息,便于排查删除用户仍出现的问题"]},{version:"4.3.1",date:"2025-08-27",added:["新增用户自行注册功能","注册页面支持用户名、密码验证","管理员可配置是否允许用户注册","注册成功后自动登录"],changed:["登录页面在数据库模式下显示注册链接","增强用户名格式验证(3-20位字母数字下划线)","密码长度要求至少6位"],fixed:[]},{version:"4.3.0",date:"2025-08-26",added:["支持将 IPTV 频道添加到收藏中"],changed:["禁用 flv 直播,仅支持 m3u8 直播","降低代理 ts 分片的内存占用"],fixed:[]},{version:"4.2.1",date:"2025-08-26",added:[],changed:[],fixed:["修复直播源加载失败或离开页面后依然无限加载的问题"]},{version:"4.2.0",date:"2025-08-26",added:["支持 flv 直播和直播地址解析到 mp4 的处理","增加直播台标的 proxy 以防止 cors","支持播放页选集分组的滚动翻页"],changed:["管理后台页面的按钮增加加载中的 UI"],fixed:["/api/proxy/m3u8 仅对 m3u8 内容反序列化,降低内存和 CPU 消耗"]},{version:"4.1.1",date:"2025-08-25",added:[],changed:["增加对 url-tvg 和多 epg url 的支持"],fixed:["修复 epg 数据清洗中去重叠逻辑未考虑日期导致的问题"]},{version:"4.1.0",date:"2025-08-24",added:["解析 m3u 自带的 epg 和自定义 epg,增加今日节目单"],changed:["直播源数据刷新改为并发刷新"],fixed:[]},{version:"4.0.0",date:"2025-08-24",added:["增加 iptv 订阅和播放功能"],changed:["搜索页面视频卡片移动端/右键菜单添加豆瓣链接","搜索建议遵循色情过滤"],fixed:[]},{version:"3.2.1",date:"2025-08-22",added:[],changed:["新增色色过滤分类","调整搜索建议框层级"],fixed:[]},{version:"3.2.0",date:"2025-08-22",added:["视频源管理支持批量启用、禁用、删除","用户管理支持批量设置用户组","视频卡片右键/长按菜单新增新标签页播放"],changed:["视频卡片移动端 hover 时仅保留播放按钮","微调管理页面 UI 和视频卡片右键/长按菜单中的收藏样式"],fixed:["修复了搜索栏 enter 键自动选中第一个建议项的问题"]},{version:"3.1.2",date:"2025-08-22",added:[],changed:[],fixed:["修复移动端卡片无法点击的问题"]},{version:"3.1.1",date:"2025-08-21",added:[],changed:[],fixed:["修复了视频卡片 hover 的非播放按钮点击后进入播放页的问题"]},{version:"3.1.0",date:"2025-08-21",added:["增加用户组管理和用户组播放源限制","增加管理面板视频源有效性检查","搜索栏增加一键删除按钮"],changed:["放宽授权心跳对于网络问题的判断标准","统一管理面板弹窗使用 createPortal","VideoCard 允许移动端响应 hover 事件","移动端布局 header 常驻,搜索按钮移动到 header 右侧","调大搜索接口超时时间"],fixed:["修复 bangumi 返回的整数评分无小数导致 UI 不对齐的问题"]},{version:"3.0.2",date:"2025-08-20",added:[],changed:["优化机器码生成逻辑"],fixed:["修复 redis url 不支持 rediss 协议的问题"]},{version:"3.0.1",date:"2025-08-20",added:[],changed:[],fixed:["修复授权初始化错误"]},{version:"3.0.0",date:"2025-08-20",added:["防盗卖加固","支持自定义用户可用视频源"],changed:["右键视频卡片可弹出操作菜单"],fixed:["过滤掉集数为 0 的搜索结果"]},{version:"2.7.1",date:"2025-08-17",added:[],changed:[],fixed:["修复 iOS 下版本面板可穿透滚动èƒ
1Œæ™¯çš„问题"]},{version:"2.7.0",date:"2025-08-17",added:["视频卡片新增移动端操作面板,优化触控屏操作体验"],changed:["优化集数标题的匹配和展示逻辑"],fixed:["修复设置面板和修改密码面板背景可被拖动的问题"]},{version:"2.6.0",date:"2025-08-17",added:["新增搜索流式输出接口,并设置流式搜索为默认搜索接口,优化搜索体验","新增源站搜索结果内存缓存,粒度为源站+关键词+页数,缓存 10 分钟","新增豆瓣 CDN provided by @JohnsonRan"],changed:["搜索结果默认为无排序状态,不再默认按照年份排序","常规搜索接口无结果时,不再设置响应的缓存头","移除豆瓣数据源中的 cors-anywhere 方式"],fixed:["数据导出时导出站长密码,保证迁移到新账户时原站长用户可正常登录","聚合卡片优化移动端源信息展示"]},{version:"2.4.1",date:"2025-08-15",added:[],changed:[],fixed:["对导入和 db 读取的配置文件做自检,防止 USERNAME 修改导致用户状态异常"]},{version:"2.4.0",date:"2025-08-15",added:["支持 kvrocks 存储(持久化 kv 存储)"],changed:[],fixed:["修复搜索结果排序不稳定的问题","导入数据时同时更新内存缓存的管理员配置"]},{version:"2.3.0",date:"2025-08-15",added:["支持站长导入导出整站数据"],changed:["仅允许站长操作配置文件","微调搜索结果过滤面板的移动端样式"],fixed:[]},{version:"2.2.1",date:"2025-08-14",added:[],changed:[],fixed:["修复了筛选 panel 打开时滚动页面 panel 不跟随的问题"]},{version:"2.2.0",date:"2025-08-14",added:["搜索结果支持按播放源、标题和年份筛选,支持按年份排序","搜索界面视频卡片展示年份信息,聚合卡片展示播放源"],changed:[],fixed:["修复 /api/search/resources 返回空的问题","修复 upstash 实例无法编辑自定义分类的问题"]},{version:"2.1.0",date:"2025-08-13",added:["支持通过订阅获取配置文件"],changed:["微调部分文案和 UI","删除部分无用代码"],fixed:[]},{version:"2.0.1",date:"2025-08-13",added:[],changed:["版本检查和变更日志请求 Github"],fixed:["微调管理面板样式"]},{version:"2.0.0",date:"2025-08-13",added:["支持配置文件在线配置和编辑","搜索页搜索框实时联想","去除对 localstorage 模式的支持"],changed:["播放记录删除按钮改为垃圾桶图标以消除歧义"],fixed:["限制设置面板的最大长度,防止超出视口"]},{version:"1.1.1",date:"2025-08-12",added:[],changed:["修正 zwei 提供的 cors proxy 地址","移除废弃代码"],fixed:["[运维] docker workflow release 日期使用东八区日期"]},{version:"1.1.0",date:"2025-08-12",added:["每日新番放送功能,展示每日新番放送的番剧"],changed:[],fixed:["修复远程 CHANGELOG 无法提取变更内容的问题"]},{version:"1.0.5",date:"2025-08-12",added:[],changed:["实现基于 Git 标签的自动 Release 工作流"],fixed:[]},{version:"1.0.4",date:"2025-08-11",added:["优化版本管理工作流,实现单点修改"],changed:["版本号现在从 CHANGELOG 自动提取,无需手动维护 VERSION.txt"],fixed:[]},{version:"1.0.3",date:"2025-08-11",added:[],changed:["升级播放器 Artplayer 至版本 5.2.5"],fixed:[]},{version:"1.0.2",date:"2025-08-11",added:[],changed:["版本号比较机制恢复为数字比较,仅当最新版本大于本地版本时才认为有更新","[运维] 自动替换 version.ts 中的版本号为 VERSION.txt 中的版本号"],fixed:[]},{version:"1.0.1",date:"2025-08-11",added:[],changed:[],fixed:["修复版本检查功能,只要与最新版本号不一致即认为有更新"]},{version:"1.0.0",date:"2025-08-10",added:["基于 Semantic Versioning 的版本号机制","版本信息面板,展示本地变更日志和远程更新日志"],changed:[],fixed:[]}];var u=e.i(810239),m=e.i(974412);e.s(["VersionPanel",0,({isOpen:e,onClose:h})=>{let[y,p]=(0,c.useState)(!1),[b,f]=(0,c.useState)([]),[v,k]=(0,c.useState)(!1),[j,N]=(0,c.useState)(""),[w,I]=(0,c.useState)(!1);(0,c.useEffect)(()=>(p(!0),()=>p(!1)),[]),(0,c.useEffect)(()=>
1{if(e){let e=document.body,a=document.documentElement,r=e.style.overflow,t=a.style.overflow;return e.style.overflow="hidden",a.style.overflow="hidden",()=>{e.style.overflow=r,a.style.overflow=t}}},[e]),(0,c.useEffect)(()=>{e&&S()},[e]);let S=async()=>{try{let e=Date.now(),a=await fetch(`https://raw.githubusercontent.com/SzeMeng76/LunaTV/refs/heads/main/CHANGELOG?_t=${e}`);if(a.ok){let e=await a.text(),r=P(e);if(f(r),r.length>0){let e=r[0];N(e.version),k((0,m.compareVersions)(e.version)===m.UpdateStatus.HAS_UPDATE)}}else console.error("获取远程变更日志失败:",a.status,a.statusText)}catch(e){console.error("获取远程变更日志失败:",e)}},P=e=>{let a=e.split("\n"),r=[],t=null,s=null,l=!1;for(let e of a){let a=e.trim(),d=a.match(/^## \[([\d.]+)\] - (\d{4}-\d{2}-\d{2})$/);if(d){t&&r.push(t),t={version:d[1],date:d[2],added:[],changed:[],fixed:[]},s=null,l=!0;continue}if(l&&t){if("### Added"===a){s="added";continue}if("### Changed"===a){s="changed";continue}if("### Fixed"===a){s="fixed";continue}if(a.startsWith("- ")&&s){let e=a.substring(2);"added"===s?t.added.push(e):"changed"===s?t.changed.push(e):"fixed"===s&&t.fixed.push(e)}}}return t&&r.push(t),r},A=(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)("div",{className:"fixed inset-0 bg-black/50 backdrop-blur-sm z-1000",onClick:h,onTouchMove:e=>{e.preventDefault()},onWheel:e=>{e.preventDefault()},style:{touchAction:"none"}}),(0,a.jsxs)("div",{className:"fixed top-1/2 left-1/2 -translate-x-1/2 -translate-y-1/2 w-full max-w-xl max-h-[90vh] bg-white dark:bg-gray-900 rounded-xl shadow-xl z-1001 overflow-hidden",onTouchMove:e=>{e.stopPropagation()},style:{touchAction:"auto"},children:[(0,a.jsxs)("div",{className:"flex items-center justify-between p-3 sm:p-6 border-b border-gray-200 dark:border-gray-700",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 sm:gap-3",children:[(0,a.jsx)("h3",{className:"text-lg sm:text-xl font-bold text-gray-800 dark:text-gray-200",children:"版本信息"}),(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-1 sm:gap-2",children:[(0,a.jsxs)("span",{className:"px-2 sm:px-3 py-1 text-xs sm:text-sm font-medium bg-green-100 text-green-800 dark:bg-green-900/30 dark:text-green-300 rounded-full",children:["v",u.CURRENT_VERSION]}),v&&(0,a.jsxs)("span",{className:"px-2 sm:px-3 py-1 text-xs sm:text-sm font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300 rounded-full flex items-center gap-1",children:[(0,a.jsx)(d.Download,{className:"w-3 h-3 sm:w-4 sm:h-4"}),(0,a.jsx)("span",{className:"hidden sm:inline",children:"有新版本可用"}),(0,a.jsx)("span",{className:"sm:hidden",children:"可更新"})]})]})]}),(0,a.jsx)("button",{onClick:h,className:"w-6 h-6 sm:w-8 sm:h-8 p-1 rounded-full flex items-center justify-center text-gray-500 hover:bg-gray-100 dark:hover:bg-gray-800 transition-colors","aria-label":"关闭",children:(0,a.jsx)(n.X,{className:"w-full h-full"})})]}),(0,a.jsx)("div",{className:"p-3 sm:p-6 overflow-y-auto max-h-[calc(95vh-140px)] sm:max-h-[calc(90vh-120px)]",children:(0,a.jsxs)("div",{className:"space-y-3 sm:space-y-6",children:[v&&(0,a.jsx)("div",{className:"bg-linear-to-r from-yellow-50 to-amber-50 dark:from-yellow-900/20 dark:to-amber-900/20 border border-yellow-200 dark:border-yellow-800 rounded-lg p-3 sm:p-4",children:(0,a.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 sm:gap-3",children:[(0,a.jsx)("div",{className:"w-8 h-8 sm:w-10 sm:h-10 bg-yellow-100 dark:bg-yellow-800/40 rounded-full flex items-center justify-center shrink-0",children:(0,a.jsx)(d.Download,{className:"w-4 h-4 sm:w-5 sm:h-5 text-yellow-600 dark:text-yellow-400"})}),(0,a.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,a.jsx)("h4",{className:"text-sm sm:text-base font-semibold text-yellow-800 dark:text-yellow-200",children:"发现新版本"}),(0,a.jsxs)("p",{className:"text-xs sm:text-sm text-yellow-700 dark:text-yellow-300 break-all",children:["v",u.CURRENT_VERSION," → v",j]})]})]}),(0,a.jsxs)("a",{href:"https://github.com/SzeMeng76/LunaTV",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center justify-center gap-2 px-3 py-2 bg-yellow-600 hover:bg-yellow-700 text-white text-xs sm:text-sm rounded-lg transition-colors shadow-sm w-full",children:[(0,a.jsx)(d.Download,{className:"w-3 h-3 sm:w-4 sm:h-4"}),"前往仓库"]})]})}),!v&&(0,a.jsx)("div",{className:"bg-linear-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 border border-green-200 dark:border-green-800 rounded-lg p-3 sm:p-4",children:(0,a.jsxs)("div",{className:"flex flex-col gap-3",children:[(0,a.jsxs)("div",{className:"flex items-center gap-2 sm:gap-3",children:[(0,a.jsx)("div",{className:"w-8 h-8 sm:w-10 sm:h-10 bg-green-100 dark:bg-green-800/40 rounded-full flex items-center justify-center shrink-0",children:(0,a.jsx)(t.CheckCircle,{className:"w-4 h-4 sm:w-5 sm:h-5 text-green-600 dark:text-green-400"})}),(0,a.jsxs)("div",{className:"min-w-0 flex-1",children:[(0,a.jsx)("h4",{className:"text-sm sm:text-base font-semibold text-green-800 dark:text-green-200",children:"当前为最新版本"}),(0,a.jsxs)("p",{className:"text-xs sm:text-sm text-green-700 dark:text-green-300 break-all",children:["已是最新版本 v",u.CURRENT_VERSION]})]})]}),(0,a.jsxs)("a",{href:"https://github.com/SzeMeng76/LunaTV",target:"_blank",rel:"noopener noreferrer",className:"inline-flex items-center justify-center gap-2 px-3 py-2 bg-green-600 hover:bg-green-700 text-white text-xs sm:text-sm rounded-lg transition-colors shadow-sm w-full",children:[(0,a.jsx)(t.CheckCircle,{className:"w-3 h-3 sm:w-4 sm:h-4"}),"前往仓库"]})]})}),v&&(0,a.jsxs)("div",{className:"space-y-4",children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-3",children:[(0,a.jsxs)("h4",{className:"text-lg font-semibold text-gray-800 dark:text-gray-200 flex items-center gap-2",children:[(0,a.jsx)(d.Download,{className:"w-5 h-5 text-yellow-500"}),"远程更新内容"]}),(0,a.jsx)("button",{onClick:()=>I(!w),className:"inline-flex items-center justify-center gap-2 px-3 py-1.5 bg-yellow-100 hover:bg-yellow-200 text-yellow-800 dark:bg-yellow-800/30 dark:hover:bg-yellow-800/50 dark:text-yellow-200 rounded-lg transition-colors text-sm w-full sm:w-auto",children:w?(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(l.ChevronUp,{className:"w-4 h-4"}),"收起"]}):(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(s.ChevronDown,{className:"w-4 h-4"}),"查看更新内容"]})})]}),w&&b.length>0&&(0,a.jsx)("div",{className:"space-y-4",children:b.filter(e=>!g.map(e=>e.version).includes(e.version)).map((e,t)=>(0,a.jsxs)("div",{className:`p-4 rounded-lg border ${e.version===j?"bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800":"bg-gray-50 dark:bg-gray-800/60 border-gray-200 dark:border-gray-700"}`,children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-3",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,a.jsxs)("h4",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100",children:["v",e.version]}),e.version===j&&(0,a.jsx)("span",{className:"px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300 rounded-full flex items-center gap-1",children:"远程最新"})]}),(0,a.jsx)("div",{className:"flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:e.date})]}),e.added&&e.added.length>0&&(0,a.jsxs)("div",{className:"mb-3",children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-green-600 dark:text-green-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(o.Plus,{className:"w-4 h-4"}),"新增功能"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.added.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-green-400 rounded-full mt-2 shrink-0"}),e]},r))})]}),e.changed&&e.changed.length>0&&(0,a.jsxs)("div",{className:"mb-3",children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-blue-600 dar
1k:text-blue-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(i.RefreshCw,{className:"w-4 h-4"}),"功能改进"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.changed.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-blue-400 rounded-full mt-2 shrink-0"}),e]},r))})]}),e.fixed&&e.fixed.length>0&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-purple-700 dark:text-purple-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(r.Bug,{className:"w-4 h-4"}),"问题修复"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.fixed.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-purple-500 rounded-full mt-2 shrink-0"}),e]},r))})]})]},t))})]}),(0,a.jsxs)("div",{className:"border-b border-gray-200 dark:border-gray-700 pb-4",children:[(0,a.jsx)("h4",{className:"text-lg font-semibold text-gray-800 dark:text-gray-200 pb-3 sm:pb-4",children:"变更日志"}),(0,a.jsx)("div",{className:"space-y-4",children:g.map(e=>((e,t=!1,s=!1)=>{let l=s&&v&&e.version===j;return(0,a.jsxs)("div",{className:`p-4 rounded-lg border ${t?"bg-blue-50 dark:bg-blue-900/20 border-blue-200 dark:border-blue-800":l?"bg-yellow-50 dark:bg-yellow-900/20 border-yellow-200 dark:border-yellow-800":"bg-gray-50 dark:bg-gray-800/60 border-gray-200 dark:border-gray-700"}`,children:[(0,a.jsxs)("div",{className:"flex flex-col sm:flex-row sm:items-center justify-between gap-2 mb-3",children:[(0,a.jsxs)("div",{className:"flex flex-wrap items-center gap-2",children:[(0,a.jsxs)("h4",{className:"text-lg font-semibold text-gray-900 dark:text-gray-100",children:["v",e.version]}),t&&(0,a.jsx)("span",{className:"px-2 py-1 text-xs font-medium bg-blue-100 text-blue-800 dark:bg-blue-900/30 dark:text-blue-300 rounded-full",children:"当前版本"}),l&&(0,a.jsxs)("span",{className:"px-2 py-1 text-xs font-medium bg-yellow-100 text-yellow-800 dark:bg-yellow-900/30 dark:text-yellow-300 rounded-full flex items-center gap-1",children:[(0,a.jsx)(d.Download,{className:"w-3 h-3"}),"可更新"]})]}),(0,a.jsx)("div",{className:"flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400",children:e.date})]}),(0,a.jsxs)("div",{className:"space-y-3",children:[e.added.length>0&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-green-700 dark:text-green-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(o.Plus,{className:"w-4 h-4"}),"新增功能"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.added.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-green-500 rounded-full mt-2 shrink-0"}),e]},r))})]}),e.changed.length>0&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-blue-700 dark:text-blue-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(i.RefreshCw,{className:"w-4 h-4"}),"功能改进"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.changed.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-blue-500 rounded-full mt-2 shrink-0"}),e]},r))})]}),e.fixed.length>0&&(0,a.jsxs)("div",{children:[(0,a.jsxs)("h5",{className:"text-sm font-medium text-purple-700 dark:text-purple-400 mb-2 flex items-center gap-1",children:[(0,a.jsx)(r.Bug,{className:"w-4 h-4"}),"问题修复"]}),(0,a.jsx)("ul",{className:"space-y-1",children:e.fixed.map((e,r)=>(0,a.jsxs)("li",{className:"text-sm text-gray-700 dark:text-gray-300 flex items-start gap-2",children:[(0,a.jsx)("span",{className:"w-1.5 h-1.5 bg-purple-500 rounded-full mt-2 shrink-0"}),e]},r))})]})]})]},e.version)})(e,e.version===u.CURRENT_VERSION,!1))})]})]})})]})]});return y&&e?(0,x.createPortal)(A,document.body):null}],426015)},734918,e=>{"use strict";var a=e.i(402458),r=e.i(475529);let t="moontv_watching_updates";async function s(e,a,r){console.log(`🔍 getOriginalEpisodes 调试信息 - ${e.title}:`,{"record.original_episodes":e.original_episodes,"record.total_episodes":e.total_episodes,类型检查:typeof e.original_episodes,完整记录:e});try{console.log(`🔍 从数据库读取最新的原始集数: ${e.title}`);let a=await fetch("/api/playrecords");if(a.ok){let t=(await a.json())[r];if(t?.original_episodes&&t.original_episodes>0)return console.log(`📚 从数据库读取到最新原始集数: ${e.title} = ${t.original_episodes}集 (当前播放记录: ${e.total_episodes}集)`),t.original_episodes}}catch(a){console.warn(`⚠️ 从数据库读取原始集数失败: ${e.title},使用内存值`,a)}return e.original_episodes&&e.original_episodes>0?(console.log(`📚 使用内存中的原始集数: ${e.title} = ${e.original_episodes}集 (当前播放记录: ${e.total_episodes}
1集)`),e.original_episodes):((void 0===e.original_episodes||null===e.original_episodes)&&e.total_episodes>0?console.log(`⚠️ ${e.title} 缺少原始集数,使用当前值 ${e.total_episodes}集(不写入数据库)`):console.log(`⚠️ 该剧集未找到原始集数记录,使用当前播放记录集数: ${e.title} = ${e.total_episodes}集`),e.total_episodes)}async function l(e,a,r){try{let t=6e5*Math.floor(Date.now()/6e5),l=`/api/detail?source=${r}&id=${a}&_t=${t}`;console.log(`🔍 [追番更新] ${e.title} 调用API:`,l);let d=await fetch(l,{cache:"no-store"});if(!d.ok)return console.warn(`❌ [追番更新] 获取${e.title}详情失败:`,d.status),{hasUpdate:!1,hasNewEpisode:!1,hasContinueWatching:!1,hasNewRelease:!1,newEpisodes:0,remainingEpisodes:0,latestEpisodes:e.total_episodes};let o=await d.json(),i=o.episodes?o.episodes.length:0;console.log(`📊 [追番更新] ${e.title} API检查详情:`,{API返回集数:i,当前观看到:e.index,播放记录集数:e.total_episodes});let n=e.key,c=await s(e,a,n);console.log(`📊 [追番更新] ${e.title} 集数对比:`,{原始集数:c,当前播放记录集数:e.total_episodes,API返回集数:i});let x=i>c,g=x?i-c:0,u=Math.max(i,c,e.total_episodes),m=e.index<u,h=m?u-e.index:0;return i<c&&console.warn(`⚠️ [追番更新] ${e.title} API返回集数(${i})少于原始记录(${c}),可能是API缓存问题`),x&&(console.log(`✨ [追番更新] ${e.title} 发现新集数: ${c} -> ${i} 集,新增${g}集`),i>e.total_episodes&&(console.log(`📊 [追番更新] 检测到集数差异: ${e.title} 播放记录${e.total_episodes}集 < API最新${i}集`),console.log("✅ [追番更新] 已记录新集数信息,等待用户实际观看时自动同步"))),m&&console.log(`📺 [追番更新] ${e.title} 继续观看提醒: 当前第${e.index}集,共${u}集,还有${h}集未看`),console.log(`✓ [追番更新] ${e.title} 最终检测结果:`,{hasUpdate:x,hasContinueWatching:m,newEpisodes:g,remainingEpisodes:h,原始集数:c,当前播放记录集数:e.total_episodes,API返回集数:i,保护后集数:u,当前观看到:e.index}),{hasUpdate:x,hasNewEpisode:x,hasContinueWatching:m,hasNewRelease:c<=1&&i>1,newEpisodes:g,remainingEpisodes:h,latestEpisodes:u}}catch(a){return console.error(`❌ [追番更新] 检查${e.title}更新失败:`,a),{hasUpdate:!1,hasNewEpisode:!1,hasContinueWatching:!1,hasNewRelease:!1,newEpisodes:0,remainingEpisodes:0,latestEpisodes:e.total_episodes}}}e.s(["useRefreshWatchingUpdates",0,function(){let e=(0,r.useQueryClient)();return()=>{e.invalidateQueries({queryKey:["playRecords"],refetchType:"all"}),e.invalidateQueries({queryKey:["reminders"],refetchType:"all"}),e.invalidateQueries({queryKey:["watchingUpdates"],refetchType:"all"})}},"useWatchingUpdatesQuery",0,function(e){let s=(0,r.useQueryClient)();return(0,a.useQuery)({queryKey:["watchingUpdates",e?.forceRefresh?Date.now():"cached"],queryFn:async()=>{console.log("🔄 [追番更新] 开始检查追番更新...");let e=await s.ensureQueryData({queryKey:["playRecords","array"],queryFn:async()=>{let e=await fetch("/api/playrecords");if(!e.ok)throw Error("Failed to fetch play records");return Object.entries(await e.json()).map(([e,a])=>({...a,key:e})).sort((e,a)=>(a.save_time||0)-(e.save_time||0))}}),a=await s.ensureQueryData({queryKey:["sources","map"],queryFn:async()=>{let e=await fetch("/api/sources");if(!e.ok)throw Error("Failed to fetch sources");let a=await e.json(),r=new Map;return a.forEach(e=>{e.name&&e.key&&r.set(e.name,e.key)}),r}}),r=await s.ensureQueryData({queryKey:["reminders"],queryFn:async()=>{let e=await fetch("/api/reminders");if(!e.ok)throw Error("Failed to fetch reminders");return await e.json()}}),d=0,o=0,i=0,n=[];if(e&&0!==e.length){console.log(`📋 [追番更新] 找到 ${e.length} 条播放记录`);let r=e.filter(e=>e.total_episodes>1);if(console.log(`🎯 [追番更新] 找到 ${r.length} 个可能有更新的剧集`),r.length>0&&console.log("[追番更新] 候选记录详情:",r.map(e=>({title:e.title,index:e.index,total:e.total_episodes}))),r.length>0){let e=r.map(async e=>{try{let[r,t]=e.key.split("+"),s=r;if(a){let e=a.get(r);e&&(s=e,console.log(`[追番更新] 映射数据源: ${r} -> ${s}`))}
1let c=await l(e,t,s),x=c.latestEpisodes,g={title:e.title,source_name:e.source_name,year:e.year,cover:e.cover,sourceKey:s,videoId:t,currentEpisode:e.index,totalEpisodes:x,hasNewEpisode:c.hasNewEpisode,hasContinueWatching:c.hasContinueWatching,hasNewRelease:c.hasNewRelease,newEpisodes:c.newEpisodes,remainingEpisodes:c.remainingEpisodes,latestEpisodes:c.latestEpisodes,remarks:e.remarks};return n.push(g),c.hasNewEpisode&&d++,c.hasContinueWatching&&(o++,console.log(`[追番更新] ${e.title} 计入继续观看计数,当前总数: ${o}`)),c.hasNewRelease&&i++,console.log(`[追番更新] ${e.title} 检查结果: hasUpdate=${c.hasUpdate}, hasContinueWatching=${c.hasContinueWatching}`),g}catch(d){console.error(`[追番更新] 检查${e.title}更新失败:`,d);let[r,t]=e.key.split("+"),s=r;if(a){let e=a.get(r);e&&(s=e)}let l={title:e.title,source_name:e.source_name,year:e.year,cover:e.cover,sourceKey:s,videoId:t,currentEpisode:e.index,totalEpisodes:e.total_episodes,hasNewEpisode:!1,hasContinueWatching:!1,hasNewRelease:!1,newEpisodes:0,remainingEpisodes:0,latestEpisodes:e.total_episodes,remarks:e.remarks};return n.push(l),l}});await Promise.all(e)}}else console.log("⚠️ [追番更新] 无播放记录,跳过播放记录更新检查");console.log("🎬 开始检查想看中的新上映内容...");try{if(r){let a=new Date().toLocaleDateString("zh-CN",{timeZone:"Asia/Shanghai",year:"numeric",month:"2-digit",day:"2-digit"}).replace(/\//g,"-"),t=Object.entries(r).filter(([r,t])=>!!t.releaseDate&&!(t.releaseDate>a)&&!(e&&e.some(e=>e.title===t.title&&e.year===t.year))).map(([e,r])=>{let[t,s]=e.split("+"),l="已上映";if(r.releaseDate){let e=r.releaseDate;if(e<a){let r=e.split("-").map(Number),t=a.split("-").map(Number),s=new Date(r[0],r[1]-1,r[2]).getTime(),d=new Date(t[0],t[1]-1,t[2]).getTime(),o=Math.floor((d-s)/864e5);l=`已上映${o}天`}else e===a&&(l="今日上映")}return{title:r.title,source_name:r.source_name,year:r.year,cover:r.cover,sourceKey:t||"unknown",videoId:s||"unknown",currentEpisode:0,totalEpisodes:r.total_episodes||0,hasNewEpisode:!1,hasContinueWatching:!1,hasNewRelease:!0,newEpisodes:0,remainingEpisodes:0,latestEpisodes:r.total_episodes||0,remarks:l,releaseDate:r.releaseDate}});t.length>0?(console.log(`🎬 [追番更新] 发现 ${t.length} 部新上映的想看内容`),n.push(...t),i=t.length):console.log("🎬 [追番更新] 没有新上映的想看内容")}}catch(e){console.error("[追番更新] 检查新上映内容失败:",e)}n.sort((e,a)=>e.hasNewRelease!==a.hasNewRelease?e.hasNewRelease?-1:1:e.hasNewEpisode!==a.hasNewEpisode?e.hasNewEpisode?-1:1:e.hasContinueWatching!==a.hasContinueWatching?e.hasContinueWatching?-1:1:e.title.localeCompare(a.title,"zh-CN"));let c=d>0||o>0||i>0;console.log(`✅ [追番更新] 检查完成: ${c?`发现${i}部新上映,${d}部剧集有新集数更新,${o}部剧集需要继续观看`:"暂无更新"}`);let x={hasUpdates:c,timestamp:Date.now(),updatedCount:d,continueWatchingCount:o,newReleasesCount:i,updatedSeries:n};try{localStorage&&(localStorage.setItem(t,JSON.stringify(x)),console.log("[追番更新] 结果已保存到 localStorage"))}catch(e){console.warn("[追番更新] 保存到 localStorage 失败:",e)}return x},staleTime:18e5,gcTime:36e5,refetchInterval:18e5,refetchIntervalInBackground:!1,initialData:()=>{try{if(localStorage){let e=localStorage.getItem(t);if(e){let a=JSON.parse(e);return console.log("[追番更新] 从 localStorage 加载缓存数据"),a}}}catch(e){console.warn("[追番更新] 从 localStorage 读取失败:",e)}},enabled:e?.enabled!==!1,retry:!1})}])}]);

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.