@serifpersia/dango 3.3.4 → 3.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -1
- package/client/dist/assets/AnimeCard-OKU7LaSN.js +1 -0
- package/client/dist/assets/{AnimeInfo-0huPAq0O.js → AnimeInfo-BCyLw0yz.js} +1 -1
- package/client/dist/assets/{AnimeInfoPage-Dqr5QH6R.js → AnimeInfoPage-BZWl-TJY.js} +2 -2
- package/client/dist/assets/{Asmr-B6ZiqkmU.js → Asmr-4S6uoevp.js} +1 -1
- package/client/dist/assets/{AsmrResetProgressModal-Cqsoo3XC.js → AsmrResetProgressModal-C8i6weqW.js} +1 -1
- package/client/dist/assets/{AvSyncCalibrator-C1_iBSyL.css → AvSyncCalibrator-BPa6KaGC.css} +1 -1
- package/client/dist/assets/AvSyncCalibrator-oK6LlG61.js +10 -0
- package/client/dist/assets/Home-CQ4Ikeja.js +1 -0
- package/client/dist/assets/{Insights-ZlgPrzGD.js → Insights-DiAo0UAc.js} +1 -1
- package/client/dist/assets/{LibraryListPage-CCiee-Ot.js → LibraryListPage-B0MDTnEc.js} +1 -1
- package/client/dist/assets/{ListeningList-ctAz_6Zi.js → ListeningList-Dxkhy6E2.js} +1 -1
- package/client/dist/assets/{Manga-BI9WMTx5.js → Manga-pJEpcUpo.js} +1 -1
- package/client/dist/assets/{MangaInfoPage-DcrEr7Sk.js → MangaInfoPage-BEQsjTHH.js} +1 -1
- package/client/dist/assets/{MangaReadPage-SYg63m48.js → MangaReadPage-C0WAtK-1.js} +1 -1
- package/client/dist/assets/{MangaResetProgressModal-DX-1PS4h.js → MangaResetProgressModal-WjKH_G_f.js} +1 -1
- package/client/dist/assets/{Mature-Dqh_9SA3.js → Mature-Ckx99wFj.js} +1 -1
- package/client/dist/assets/{MediaCard-Be1ST9oj.js → MediaCard-DszKDA4s.js} +1 -1
- package/client/dist/assets/{Music-zsPwT8_5.js → Music-CU6TBHF5.js} +1 -1
- package/client/dist/assets/{OptionListMenu-Drc_vybW.js → OptionListMenu-CkK2BvEz.js} +1 -1
- package/client/dist/assets/Player-C3yWQkXb.js +56 -0
- package/client/dist/assets/{PlayerSettings-Cwoji-P7.js → PlayerSettings-CBdTzo0E.js} +1 -1
- package/client/dist/assets/{QueueOptionsButton-B6BMq66e.js → QueueOptionsButton-DKWi-9kd.js} +1 -1
- package/client/dist/assets/{QueueRail-VxpUDBSm.js → QueueRail-DAcIex5B.js} +1 -1
- package/client/dist/assets/{Radio-B2Q_Egj7.js → Radio-BhTsgGGd.js} +1 -1
- package/client/dist/assets/{ReadingList-O0QPwXu7.js → ReadingList-BLnkwB--.js} +1 -1
- package/client/dist/assets/{ResetProgressModal-CR_ovLAu.js → ResetProgressModal-8mcLXaAb.js} +1 -1
- package/client/dist/assets/{Search-C8e2nlDD.js → Search-DxX021dj.js} +1 -1
- package/client/dist/assets/{Settings-BgPWBl2V.js → Settings-bSA7BG7h.js} +1 -1
- package/client/dist/assets/{SkeletonGrid-CtHKKMLj.js → SkeletonGrid-Du10CNfq.js} +1 -1
- package/client/dist/assets/{Trackers-Bfoiyuzy.js → Trackers-BXSONaRD.js} +1 -1
- package/client/dist/assets/Tv-C2SWcVzN.css +1 -0
- package/client/dist/assets/Tv-DJTbg4VW.js +4 -0
- package/client/dist/assets/{TvInfo-D_scgw_h.js → TvInfo-Z0c1Wh3i.js} +1 -1
- package/client/dist/assets/{TvPopup-YTI7dEbJ.js → TvPopup-CP41CncZ.js} +1 -1
- package/client/dist/assets/{TvSearch-CxU33UOf.js → TvSearch-BlqTQYJa.js} +1 -1
- package/client/dist/assets/TvWatchlist-COCWPkgh.js +1 -0
- package/client/dist/assets/{Watchlist-P6YMZUdF.js → Watchlist-BHLshSPX.js} +1 -1
- package/client/dist/assets/{hls-C4cG9wQw.js → hls-B_yo8-yR.js} +1 -1
- package/client/dist/assets/index-lo-bz7f2.js +178 -0
- package/client/dist/assets/{useAnimeInfoData-DeuwDSnI.js → useAnimeInfoData-CbNnHRj8.js} +1 -1
- package/client/dist/assets/{useAsmr-CbMVRjmV.js → useAsmr-BEcgHwxg.js} +1 -1
- package/client/dist/assets/{useAsmrPopup-D91Q3CBg.js → useAsmrPopup-BXD3y2m1.js} +1 -1
- package/client/dist/assets/{useMangaLibrary-BPvFb1lU.js → useMangaLibrary-BXhgN-dl.js} +1 -1
- package/client/dist/assets/{useMangaPopup-BOL2mQJs.js → useMangaPopup-BvgtZ53s.js} +1 -1
- package/client/dist/assets/{useProviders-BsRGONMA.js → useProviders-xlftutIo.js} +1 -1
- package/client/dist/assets/{useTv-D37MfTHA.js → useTv-DTqrJEWp.js} +1 -1
- package/client/dist/assets/{useTvLibrary-Cwxgy_Bg.js → useTvLibrary-BHeWSd1F.js} +1 -1
- package/client/dist/index.html +1 -1
- package/package.json +2 -2
- package/server/dist/controllers/tv-library.controller.js +9 -5
- package/server/dist/repositories/tv.repository.js +10 -8
- package/server/dist/sync.js +19 -1
- package/server/package.json +1 -1
- package/client/dist/assets/AnimeCard-B5A20jAI.js +0 -1
- package/client/dist/assets/AvSyncCalibrator-C8ZoIwMY.js +0 -10
- package/client/dist/assets/Home-thJhPfs1.js +0 -1
- package/client/dist/assets/Player-BEtAYps2.js +0 -56
- package/client/dist/assets/Tv-Ca0fCdko.js +0 -3
- package/client/dist/assets/Tv-CuEl3Iol.css +0 -1
- package/client/dist/assets/TvWatchlist-B4X1fWEH.js +0 -1
- package/client/dist/assets/index-IZgh1beL.js +0 -178
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as L}from"./vendor-core-8R2fFbyN.js";import{b as d,u as c,a as y,e as Q}from"./vendor-query-BXRECSI6.js";import{q as n,z as o}from"./index-
|
|
1
|
+
import{T as L}from"./vendor-core-8R2fFbyN.js";import{b as d,u as c,a as y,e as Q}from"./vendor-query-BXRECSI6.js";import{q as n,z as o}from"./index-lo-bz7f2.js";function P(e){return String(e||"").trim().toUpperCase()}function B(e){return P(e.id||e._id||"")}function I(e){return!!e.isAdult}const U=["Listening","Completed","On-Hold","Dropped","Planned"],T=e=>P(e),J=(e="All",s=1,r=24)=>d({queryKey:["asmr-library",e,s,r],queryFn:()=>{const t=new URLSearchParams;return t.set("status",e),t.set("page",String(s)),t.set("limit",String(r)),n(`/api/asmr/library?${t.toString()}`)}}),O=()=>d({queryKey:["asmr-library-ids"],queryFn:()=>n("/api/asmr/library/ids"),staleTime:1e3*60}),M=e=>d({queryKey:["asmr-library-check",e],queryFn:()=>n(`/api/asmr/library/check/${encodeURIComponent(e||"")}`),enabled:!!e,staleTime:1e3*60}),D=(e=24)=>d({queryKey:["asmr-continue-listening",e],queryFn:()=>n(`/api/asmr/continue-listening?limit=${e}`)}),G=e=>d({queryKey:["asmr-progress",e],queryFn:()=>n(`/api/asmr/progress/${encodeURIComponent(e||"")}`),enabled:!!e}),$=()=>{const e=c();return y({mutationFn:async s=>{const{silent:r,...t}=s;return n("/api/asmr/library/add",{method:"POST",body:JSON.stringify(t)})},onSuccess:(s,r)=>{r.silent||o.success("Added to listening list"),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-library-ids"]}),e.invalidateQueries({queryKey:["asmr-library-check",T(r.rjCode)]})},onError:s=>{o.error(`Failed to add: ${s.message}`)}})},k=()=>{const e=c();return y({mutationFn:async s=>{await n("/api/asmr/library/remove",{method:"POST",body:JSON.stringify({id:s})})},onSuccess:(s,r)=>{o.success("Removed from listening list"),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-library-ids"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]}),e.invalidateQueries({queryKey:["asmr-library-check",r]})},onError:s=>{o.error(`Failed to remove: ${s.message}`)}})},H=()=>{const e=c();return y({mutationFn:async({id:s,status:r})=>{await n("/api/asmr/library/status",{method:"POST",body:JSON.stringify({id:s,status:r})})},onSuccess:()=>{o.success("Status updated"),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]})},onError:s=>{o.error(`Failed to update status: ${s.message}`)}})},x=()=>{const e=c();return y({mutationFn:async s=>{await n("/api/asmr/progress",{method:"POST",body:JSON.stringify(s)})},onSuccess:(s,r)=>{e.invalidateQueries({queryKey:["asmr-progress",r.workId]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]}),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-library-ids"]})}})},W=()=>{const e=c();return y({mutationFn:async({workId:s,trackIndex:r})=>{await n("/api/asmr/progress/remove",{method:"POST",body:JSON.stringify({workId:s,trackIndex:r})})},onSuccess:()=>{o.success("Progress reset"),e.invalidateQueries({queryKey:["asmr-progress"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]}),e.invalidateQueries({queryKey:["asmr-library"]})},onError:s=>{o.error(`Failed to reset progress: ${s.message}`)}})},z=()=>{const e=c();return y({mutationFn:async({ids:s,status:r})=>n("/api/asmr/library/batch-status",{method:"POST",body:JSON.stringify({ids:s,status:r})}),onSuccess:s=>{o.success(`Status updated for ${s.updated??0} items`),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]})},onError:s=>{o.error(`Failed to update statuses: ${s.message}`)}})},j=()=>{const e=c();return y({mutationFn:async s=>n("/api/asmr/library/remove-many",{method:"POST",body:JSON.stringify({ids:s})}),onSuccess:s=>{const r=s.removed??0;o.success(`Removed ${r} ${r===1?"item":"items"} from listening list`),e.invalidateQueries({queryKey:["asmr-library"]}),e.invalidateQueries({queryKey:["asmr-library-ids"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]})},onError:s=>{o.error(`Failed to remove: ${s.message}`)}})},Y=()=>{const e=c();return y({mutationFn:async s=>n("/api/asmr/progress/remove-many",{method:"POST",body:JSON.stringify({ids:s})}),onSuccess:s=>{const r=s.removed??0;o.success(`Reset progress for ${r} ${r===1?"item":"items"}`),e.invalidateQueries({queryKey:["asmr-progress"]}),e.invalidateQueries({queryKey:["asmr-continue-listening"]}),e.invalidateQueries({queryKey:["asmr-library"]})},onError:s=>{o.error(`Failed to reset progress: ${s.message}`)}})},V=()=>{const e=$(),s=k(),{data:r}=O(),t=L(()=>new Set(r?.ids||[]),[r]);return{toggle:a=>{const u=T(a.rjCode);t.has(u)?s.mutate(u):e.mutate({...a,thumbnail:a.thumbnail||""})},bookmarkedIds:t,pending:e.isPending||s.isPending}},q=300*1e3,K=15,X=(e,s,r,t)=>{const l=s+1,a=Q({queries:Array.from({length:l},(m,p)=>{const w=p+1;return{queryKey:["asmrBrowse",e,w,r,t],queryFn:()=>{const S=new URLSearchParams;return e.trim()&&S.set("q",e.trim()),S.set("page",w.toString()),r&&r!=="latest"&&S.set("sort",r),t&&S.set("rating",t),n(`/api/asmr/browse?${S.toString()}`)},staleTime:q}})}),u=a.flatMap(m=>m.data?.shows??[]),b=u.slice((s-1)*K,s*K),g=a[a.length-1]?.data,f=!!(g&&(g.hasNext||u.length>s*K)),v=a.some(m=>m.isLoading),i=a.some(m=>m.isFetching),A=a.some(m=>m.isError);return{data:{shows:b,hasNext:f},isLoading:v,isError:A,isFetching:i}},Z=e=>d({queryKey:["asmrWork",e],queryFn:()=>n(`/api/asmr/work/${e}`),enabled:!!e,staleTime:q,refetchOnMount:"always"}),E=15,h=6;function _(e){if(e.isAdult||!e.thumbnail)return!1;const s=(e.rating||"").toLowerCase();return s===""||s==="sfw"}function F(e,s){const r=new Set,t=[];for(const l of e)for(const a of l){if(t.length>=s)return t;const u=a.id||a._id;!u||r.has(u)||(r.add(u),_(a)&&t.push(a))}return t}const ee=(e=!0)=>{const s=Q({queries:Array.from({length:E},(i,A)=>{const m=A+1;return{queryKey:["asmrBrowse","",m,"popular_month",""],queryFn:()=>{const p=new URLSearchParams;return p.set("page",String(m)),p.set("sort","popular_month"),n(`/api/asmr/browse?${p.toString()}`)},staleTime:q,enabled:e,retry:1}})}),r=s.map(i=>i.data?.shows??[]),t=F(r,h),l=s.every(i=>i.isFetched),a=e&&l&&t.length<h,u=d({queryKey:["asmrBrowse","",1,"popular","sfw"],queryFn:()=>{const i=new URLSearchParams;return i.set("page","1"),i.set("sort","popular"),i.set("rating","sfw"),n(`/api/asmr/browse?${i.toString()}`)},staleTime:q,enabled:a,retry:1}),b=u.data?.shows??[],g=t.length>=h?t.slice(0,h):F([t,b],h),f=e&&(s.some(i=>i.isLoading)||a&&u.isLoading),v=e&&l&&g.length===0&&s.some(i=>i.isError);return{data:g,isLoading:f,isError:v}};export{U as A,B as a,ee as b,Z as c,M as d,V as e,G as f,P as g,x as h,$ as i,X as j,T as k,I as l,J as m,k as n,H as o,z as p,j as q,Y as r,W as s,D as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as e,S as y,L as g,d as k,A as L,q as r}from"./vendor-core-8R2fFbyN.js";import{I as a}from"./vendor-icons-CDMuNDeL.js";import{c as P}from"./useAsmr-
|
|
1
|
+
import{u as e,S as y,L as g,d as k,A as L,q as r}from"./vendor-core-8R2fFbyN.js";import{I as a}from"./vendor-icons-CDMuNDeL.js";import{c as P}from"./useAsmr-BEcgHwxg.js";import{p as s,a as f}from"./MediaCard-DszKDA4s.js";import{a as A}from"./Asmr.module-ChUXDZKx.js";const B=({data:n,anchorRect:l,bookmarked:i,onToggleBookmark:c,onMouseEnter:o,onMouseLeave:m,onRequestClose:p})=>{const{data:t,isLoading:d}=P(n.rjCode||null),u=t?.tracks.length??0,N=u>0,h=!d;return e(f,{anchorRect:l,onMouseEnter:o,onMouseLeave:m,onRequestClose:p,children:[e("div",{className:s.header,children:[n.thumbnail&&e("img",{src:n.thumbnail,alt:n.title,loading:"lazy",decoding:"async",className:A.popupCover}),e("div",{className:s.title,children:n.title}),e("div",{className:s.synopsis,children:n.rjCode})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[e("div",{className:s.metaItem,children:[e(a,{name:"headphones",size:14}),e("span",{children:h?N?e(y,{children:[u," track",u===1?"":"s"]}):"No tracks":"Loading tracks…"})]}),n.rating&&e("div",{className:s.metaItem,children:e("span",{children:n.rating.toUpperCase()})}),n.isAdult&&e("div",{className:s.metaItem,children:e("span",{children:"18+"})}),n.progressLabel&&e("div",{className:s.metaItem,children:[e(a,{name:"bookmark",size:12}),e("span",{children:n.progressLabel})]})]}),e("div",{className:s.synopsis,children:!h&&!t?.description?"Loading description…":t?.description??"No description available."})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:N?e(g,{to:n.listenTarget,className:s.watchBtn,children:[e(a,{name:"play",size:14}),"Listen now"]}):e("span",{className:s.watchBtn,"aria-disabled":"true",style:{opacity:.5,pointerEvents:"none"},children:[e(a,{name:"play",size:14}),h?"No tracks":"Loading…"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${i?s.active:""}`,onClick:v=>{v.preventDefault(),v.stopPropagation(),c()},children:[i?e(a,{name:"check",size:12}):e(a,{name:"plus",size:12}),e("span",{children:i?"Remove":"Bookmark"})]}),e(g,{to:n.listenTarget,className:s.detailsBtn,children:"Details"})]})]})]})},C=300;function D(){const[n,l]=k(null),i=L(null),c=r(()=>{i.current&&(clearTimeout(i.current),i.current=null)},[]),o=r((t,d)=>{c(),l({data:d,rect:t})},[c]),m=r(()=>{c(),i.current=setTimeout(()=>{i.current=null,l(null)},C)},[c]),p=r(()=>{c(),l(null)},[c]);return{popup:n,openPopup:o,scheduleClose:m,cancelClose:c,closePopup:p}}export{B as A,D as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{b as y,c as b,u as m,a as d}from"./vendor-query-BXRECSI6.js";import{q as s,z as o}from"./index-
|
|
1
|
+
import{b as y,c as b,u as m,a as d}from"./vendor-query-BXRECSI6.js";import{q as s,z as o}from"./index-lo-bz7f2.js";import{T as S}from"./vendor-core-8R2fFbyN.js";const q=300*1e3,f={mangadex:"https://mangadex.org/",mangapill:"https://www.mangapill.com/"},K=(e,a)=>`/api/proxy?url=${encodeURIComponent(a)}&referer=${encodeURIComponent(f[e])}`,M=(e,a)=>a&&(e==="mangapill"?K(e,a):a),$=(e,a=!0)=>{const{provider:n,query:t,page:u,sort:i,status:g,type:c,rating:l,mature:p}=e;return y({queryKey:["mangaBrowse",n,t,u,i,g,c,l,p],queryFn:()=>{const r=new URLSearchParams;return r.set("provider",n),t.trim()&&r.set("q",t.trim()),r.set("page",String(u)),i&&r.set("sort",i),g&&r.set("status",g),c&&r.set("type",c),l&&r.set("rating",l),p&&r.set("mature","1"),s(`/api/manga/search?${r.toString()}`)},staleTime:q,enabled:a&&!!n})},k=(e,a=14)=>{const{provider:n,query:t,sort:u,status:i,type:g,rating:c,mature:l}=e;return b({queryKey:["mangaBrowseInfinite",n,t,u,i,g,c,l,a],queryFn:({pageParam:p=1})=>{const r=new URLSearchParams;return r.set("provider",n),t.trim()&&r.set("q",t.trim()),r.set("page",String(p)),r.set("limit",String(a)),u&&r.set("sort",u),i&&r.set("status",i),g&&r.set("type",g),c&&r.set("rating",c),l&&r.set("mature","1"),s(`/api/manga/search?${r.toString()}`)},initialPageParam:1,getNextPageParam:(p,r)=>p.hasNext?r.length+1:void 0,staleTime:q,enabled:!!n})},C=(e,a,n="safe",t=!1)=>y({queryKey:["mangaDetail",e,a,n,t],queryFn:()=>{const u=new URLSearchParams;return u.set("provider",e||""),u.set("id",a||""),n&&u.set("rating",n),t&&u.set("mature","1"),s(`/api/manga/info?${u.toString()}`)},enabled:!!e&&!!a,staleTime:q}),w=(e,a,n)=>y({queryKey:["mangaPages",e,a],queryFn:()=>s(`/api/manga/pages?provider=${e}&id=${encodeURIComponent(a||"")}`),enabled:!!e&&!!a,staleTime:1800*1e3}),O=()=>y({queryKey:["mangaTrending"],queryFn:()=>s("/api/manga/trending"),staleTime:600*1e3}),N=e=>e.contentRating==="erotica"||e.contentRating==="pornographic"||e.type==="doujinshi";function I(e,a){const n=e.titles??{};return a==="englishName"?n.en||e.title:a==="nativeName"&&(n.native||n.romaji||e.altTitle)||e.title}function B(e){return{englishName:e.titles?.en??e.title,nativeName:e.titles?.native??e.titles?.romaji??e.altTitle??void 0}}const E=["Reading","Completed","On-Hold","Dropped","Planned"],v=(e,a)=>`${e.toLowerCase()}:${a}`,U=(e="All",a=1,n=24)=>y({queryKey:["manga-library",e,a,n],queryFn:()=>{const t=new URLSearchParams;return t.set("status",e),t.set("page",String(a)),t.set("limit",String(n)),s(`/api/manga/library?${t.toString()}`)}}),h=()=>y({queryKey:["manga-library-ids"],queryFn:()=>s("/api/manga/library/ids"),staleTime:1e3*60}),L=e=>y({queryKey:["manga-library-check",e],queryFn:()=>s(`/api/manga/library/check/${encodeURIComponent(e||"")}`),enabled:!!e,staleTime:1e3*60}),A=(e=24)=>y({queryKey:["manga-continue-reading",e],queryFn:()=>s(`/api/manga/continue-reading?limit=${e}`)}),_=e=>y({queryKey:["manga-progress",e],queryFn:()=>s(`/api/manga/progress/${encodeURIComponent(e||"")}`),enabled:!!e}),P=()=>{const e=m();return d({mutationFn:async a=>{const{silent:n,...t}=a;return s("/api/manga/library/add",{method:"POST",body:JSON.stringify(t)})},onSuccess:(a,n)=>{n.silent||o.success("Bookmarked"),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-library-ids"]}),e.invalidateQueries({queryKey:["manga-library-check",v(n.provider,n.mangaId)]})},onError:a=>{o.error(`Failed to bookmark: ${a.message}`)}})},R=()=>{const e=m();return d({mutationFn:async a=>{await s("/api/manga/library/remove",{method:"POST",body:JSON.stringify({id:a})})},onSuccess:(a,n)=>{o.success("Bookmark removed"),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-library-ids"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]}),e.invalidateQueries({queryKey:["manga-library-check",n]})},onError:a=>{o.error(`Failed to remove: ${a.message}`)}})},J=()=>{const e=m();return d({mutationFn:async({id:a,status:n})=>{await s("/api/manga/library/status",{method:"POST",body:JSON.stringify({id:a,status:n})})},onSuccess:()=>{o.success("Status updated"),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:a=>{o.error(`Failed to update status: ${a.message}`)}})},x=()=>{const e=m();return d({mutationFn:async a=>{await s("/api/manga/progress",{method:"POST",body:JSON.stringify(a)})},onSuccess:(a,n)=>{e.invalidateQueries({queryKey:["manga-progress",n.mangaId]}),e.invalidateQueries({queryKey:["manga-continue-reading"]}),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-library-ids"]})}})},D=()=>{const e=m();return d({mutationFn:async({mangaId:a,chapterId:n})=>{await s("/api/manga/progress/remove",{method:"POST",body:JSON.stringify({mangaId:a,chapterId:n})})},onSuccess:()=>{o.success("Progress reset"),e.invalidateQueries({queryKey:["manga-progress"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]}),e.invalidateQueries({queryKey:["manga-library"]})},onError:a=>{o.error(`Failed to reset progress: ${a.message}`)}})},j=()=>{const e=m();return d({mutationFn:async({ids:a,status:n})=>s("/api/manga/library/batch-status",{method:"POST",body:JSON.stringify({ids:a,status:n})}),onSuccess:a=>{o.success(`Status updated for ${a.updated??0} items`),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:a=>{o.error(`Failed to update statuses: ${a.message}`)}})},V=()=>{const e=m();return d({mutationFn:async a=>s("/api/manga/library/remove-many",{method:"POST",body:JSON.stringify({ids:a})}),onSuccess:a=>{const n=a.removed??0;o.success(`Removed ${n} ${n===1?"item":"items"} from reading list`),e.invalidateQueries({queryKey:["manga-library"]}),e.invalidateQueries({queryKey:["manga-library-ids"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]})},onError:a=>{o.error(`Failed to remove: ${a.message}`)}})},z=()=>{const e=m();return d({mutationFn:async a=>s("/api/manga/progress/remove-many",{method:"POST",body:JSON.stringify({ids:a})}),onSuccess:a=>{const n=a.removed??0;o.success(`Reset progress for ${n} ${n===1?"item":"items"}`),e.invalidateQueries({queryKey:["manga-progress"]}),e.invalidateQueries({queryKey:["manga-continue-reading"]}),e.invalidateQueries({queryKey:["manga-library"]})},onError:a=>{o.error(`Failed to reset progress: ${a.message}`)}})},G=()=>{const e=P(),a=R(),{data:n}=h(),t=S(()=>new Set(n?.ids||[]),[n]);return{toggle:i=>{const g=v(i.provider,i.id);t.has(g)?a.mutate(g):e.mutate({provider:i.provider,mangaId:i.id,title:i.title,cover:i.cover,altTitle:i.altTitle,contentRating:i.contentRating})},bookmarkedIds:t,pending:e.isPending||a.isPending}};export{E as M,k as a,M as b,B as c,A as d,O as e,$ as f,C as g,L as h,N as i,_ as j,P as k,R as l,v as m,J as n,w as o,K as p,x as q,I as r,U as s,j as t,G as u,V as v,z as w,D as x};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{u as e,S as T,L as N,d as P,A as y,q as o}from"./vendor-core-8R2fFbyN.js";import{I as c}from"./vendor-icons-CDMuNDeL.js";import{g as I,r as A}from"./useMangaLibrary-
|
|
1
|
+
import{u as e,S as T,L as N,d as P,A as y,q as o}from"./vendor-core-8R2fFbyN.js";import{I as c}from"./vendor-icons-CDMuNDeL.js";import{g as I,r as A}from"./useMangaLibrary-BXhgN-dl.js";import{d as L}from"./index-lo-bz7f2.js";import{p as s,a as M}from"./MediaCard-DszKDA4s.js";const S=({data:l,anchorRect:t,bookmarked:a,onToggleBookmark:i,onMouseEnter:d,onMouseLeave:m,onRequestClose:p})=>{const{data:n,isLoading:h}=I(l.provider,l.mangaId,l.rating||"safe",l.mature||!1),{titlePreference:f}=L(),u=n?.chapters.length??0,v=[n?.status,n?.type].filter(Boolean).join(" · "),g=A({title:l.title,altTitle:n?.altTitle??l.altTitle},f);return e(M,{anchorRect:t,onMouseEnter:d,onMouseLeave:m,onRequestClose:p,children:h?e("div",{className:s.loading,children:[e("div",{className:s.spinner}),e("span",{children:"Fetching details..."})]}):e(T,{children:[e("div",{className:s.header,children:[e("div",{className:s.title,children:g}),n?.altTitle&&n.altTitle!==g&&e("div",{className:s.synopsis,children:["Also known as: ",n.altTitle]})]}),e("div",{className:s.body,children:[e("div",{className:s.metaRow,children:[v&&e("div",{className:s.metaItem,children:[e(c,{name:"book",size:14}),e("span",{children:v})]}),u>0&&e("div",{className:s.metaItem,children:e("span",{children:[u," chapter",u===1?"":"s"]})}),l.progressLabel&&e("div",{className:s.metaItem,children:[e(c,{name:"bookmark",size:12}),e("span",{children:l.progressLabel})]})]}),e("div",{className:s.synopsis,children:n?.description?n.description:"No synopsis available."}),Array.isArray(n?.genres)&&(n?.genres?.length??0)>0&&e("div",{className:s.details,children:e("div",{className:s.genres,children:n.genres.filter(Boolean).slice(0,4).map(r=>e("span",{className:s.genre,children:r},r))})})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:e(N,{to:l.readTarget,className:s.watchBtn,children:[e(c,{name:"book",size:14}),"Read now"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${a?s.active:""}`,onClick:r=>{r.preventDefault(),r.stopPropagation(),i()},children:[a?e(c,{name:"check",size:12}):e(c,{name:"plus",size:12}),e("span",{children:a?"Remove":"Bookmark"})]}),e(N,{to:`/manga/${l.provider}/${encodeURIComponent(l.mangaId)}`,className:s.detailsBtn,children:"Read more"})]})]})]})})},b=300;function $(){const[l,t]=P(null),a=y(null),i=o(()=>{a.current&&(clearTimeout(a.current),a.current=null)},[]),d=o((n,h)=>{i(),t({data:h,rect:n})},[i]),m=o(()=>{i(),a.current=setTimeout(()=>{a.current=null,t(null)},b)},[i]),p=o(()=>{i(),t(null)},[i]);return{popup:l,openPopup:d,scheduleClose:m,cancelClose:i,closePopup:p}}export{S as M,$ as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as o}from"./vendor-core-8R2fFbyN.js";import{b as a}from"./vendor-query-BXRECSI6.js";import{q as i}from"./index-
|
|
1
|
+
import{T as o}from"./vendor-core-8R2fFbyN.js";import{b as a}from"./vendor-query-BXRECSI6.js";import{q as i}from"./index-lo-bz7f2.js";const n=300*1e3;function u(r){return{value:r.id,label:r.label,mature:r.mature,kind:r.kind,sub:r.sub,tier:r.tier,browse:r.browse,facets:r.facets,servers:r.servers}}const d=()=>{const r=a({queryKey:["providers"],queryFn:()=>i("/api/providers"),staleTime:n,retry:1}),e=Array.isArray(r.data)?r.data:null,t=o(()=>e&&e.length>0?e.filter(s=>s.loaded).map(u):[],[e]);return{...r,options:t,isFallback:!e||e.length===0}};export{d as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{N as d,u as o,S as v}from"./vendor-core-8R2fFbyN.js";import{I as g}from"./vendor-icons-CDMuNDeL.js";import{M as f}from"./MediaCard-
|
|
1
|
+
import{N as d,u as o,S as v}from"./vendor-core-8R2fFbyN.js";import{I as g}from"./vendor-icons-CDMuNDeL.js";import{M as f}from"./MediaCard-DszKDA4s.js";import{T as m}from"./TvPopup-CP41CncZ.js";import{c as T,i as h}from"./useTvLibrary-BHeWSd1F.js";import{b as u}from"./vendor-query-BXRECSI6.js";import{q as y}from"./index-lo-bz7f2.js";const b=d(({item:e})=>{const r=e.type==="tv"||e.type==="tvSeries"||e.type==="tvMiniSeries",t=T(e.type,e.id);return o(f,{item:{id:String(e.id),title:e.title,thumbnail:e.image,typeBadge:r?"TV":"Movie",isAdult:h(e)},linkTo:t,hoverIcon:"info",showInfoButton:!0,metaRow:o(v,{children:[e.year&&o("span",{style:{opacity:.75},children:e.year}),e.vote_average!=null&&o("span",{style:{display:"inline-flex",alignItems:"center",gap:3},children:[o(g,{name:"star",size:10}),Number(e.vote_average).toFixed(1)]})]}),renderPopup:(n,a)=>o(m,{item:e,anchorRect:n,onMouseEnter:a.onMouseEnter,onMouseLeave:a.onMouseLeave,onRequestClose:a.close})})}),c=1e3*60*5,w=e=>{const{query:r,type:t,genre:n,year:a,sort_by:i,page:l}=e,s=new URLSearchParams;r?.trim()&&s.set("q",r.trim()),t&&t!=="multi"&&s.set("type",t),n&&s.set("genre",n),a&&a!=="ALL"&&s.set("year",a),i&&i!=="popularity.desc"&&s.set("sort_by",i),s.set("page",String(l||1));const p=s.toString();return u({queryKey:["tv-search-paginated",p],queryFn:()=>y(`/api/tv/search?${p}`),staleTime:c,retry:1})},A=(e="all",r="week",t=1,n=!0)=>u({queryKey:["tv-trending",e,r,t],queryFn:()=>y(`/api/tv/trending?media_type=${e}&time_window=${r}&page=${t}`),enabled:n,staleTime:c,retry:1});export{b as T,w as a,A as u};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{T as m}from"./vendor-core-8R2fFbyN.js";import{b as y,u as o,a as u}from"./vendor-query-BXRECSI6.js";import{q as i,z as a}from"./index-
|
|
1
|
+
import{T as m}from"./vendor-core-8R2fFbyN.js";import{b as y,u as o,a as u}from"./vendor-query-BXRECSI6.js";import{q as i,z as a}from"./index-lo-bz7f2.js";const d=e=>String(e).toLowerCase()==="movie"?"movie":"tv",g=(e,t)=>`${d(e)}:${t}`,K=(e,t)=>{const r=d(e);return`/tv/${t}?type=${r}`},Q=(e,t,r,s)=>{const n=new URLSearchParams;return n.set("type",d(e)),r!==void 0&&n.set("s",String(r)),s!==void 0&&n.set("e",String(s)),`/tv/${t}/watch?${n.toString()}`},$=e=>e.adult===!0||e.adult===1,f=["Watching","Completed","On-Hold","Dropped","Planned"],l=(e,t)=>g(e,t),w=(e="All",t=1,r=24)=>y({queryKey:["tv-library",e,t,r],queryFn:()=>{const s=new URLSearchParams;return s.set("status",e),s.set("page",String(t)),s.set("limit",String(r)),i(`/api/tv/library?${s.toString()}`)}}),p=()=>y({queryKey:["tv-library-ids"],queryFn:()=>i("/api/tv/library/ids"),staleTime:1e3*60}),P=e=>y({queryKey:["tv-library-check",e],queryFn:()=>i(`/api/tv/library/check/${encodeURIComponent(e||"")}`),enabled:!!e,staleTime:1e3*60}),F=(e=24)=>y({queryKey:["tv-continue-watching",e],queryFn:()=>i(`/api/tv/continue-watching?limit=${e}`)}),O=e=>y({queryKey:["tv-progress",e],queryFn:()=>i(`/api/tv/progress/${encodeURIComponent(e||"")}`),enabled:!!e}),C=(e,t,r)=>y({queryKey:["tv-progress-latest",e,t,r],queryFn:()=>{const s=new URLSearchParams;t!==void 0&&s.set("season",String(t)),r!==void 0&&s.set("episode",String(r));const n=s.toString();return i(`/api/tv/progress/${encodeURIComponent(e||"")}/latest${n?`?${n}`:""}`)},enabled:!!e,staleTime:0}),q=()=>{const e=o();return u({mutationFn:async t=>{const{silent:r,...s}=t;return i("/api/tv/library/add",{method:"POST",body:JSON.stringify(s)})},onSuccess:(t,r)=>{r.silent||a.success("Added to TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-library-ids"]}),e.invalidateQueries({queryKey:["tv-library-check",l(r.mediaType,r.tmdbId)]})},onError:t=>{a.error(`Failed to add: ${t.message}`)}})},b=()=>{const e=o();return u({mutationFn:async t=>{await i("/api/tv/library/remove",{method:"POST",body:JSON.stringify({id:t})})},onSuccess:(t,r)=>{a.success("Removed from TV watchlist"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-library-ids"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library-check",r]})},onError:t=>{a.error(`Failed to remove: ${t.message}`)}})},R=()=>{const e=o();return u({mutationFn:async({id:t,status:r})=>{await i("/api/tv/library/status",{method:"POST",body:JSON.stringify({id:t,status:r})})},onSuccess:()=>{a.success("Status updated"),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]})},onError:t=>{a.error(`Failed to update status: ${t.message}`)}})},k=()=>{const e=o();return u({mutationFn:async t=>{await i("/api/tv/progress",{method:"POST",body:JSON.stringify(t)})},onSuccess:(t,r)=>{e.invalidateQueries({queryKey:["tv-progress",r.mediaId]}),e.invalidateQueries({queryKey:["tv-progress-latest",r.mediaId]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-library-ids"]})}})},L=()=>{const e=o();return u({mutationFn:async({mediaId:t,season:r,episode:s})=>{await i("/api/tv/progress/remove",{method:"POST",body:JSON.stringify({mediaId:t,season:r,episode:s})})},onSuccess:()=>{a.success("Progress reset"),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]})},onError:t=>{a.error(`Failed to reset progress: ${t.message}`)}})},I=()=>{const e=o();return u({mutationFn:async({ids:t,status:r})=>i("/api/tv/library/batch-status",{method:"POST",body:JSON.stringify({ids:t,status:r})}),onSuccess:t=>{a.success(`Status updated for ${t.updated??0} items`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]})},onError:t=>{a.error(`Failed to update statuses: ${t.message}`)}})},U=()=>{const e=o();return u({mutationFn:async t=>i("/api/tv/library/remove-many",{method:"POST",body:JSON.stringify({ids:t})}),onSuccess:t=>{const r=t.removed??0;a.success(`Removed ${r} ${r===1?"item":"items"} from TV watchlist`),e.invalidateQueries({queryKey:["tv-library"]}),e.invalidateQueries({queryKey:["tv-library-ids"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]})},onError:t=>{a.error(`Failed to remove: ${t.message}`)}})},E=()=>{const e=o();return u({mutationFn:async t=>i("/api/tv/progress/remove-many",{method:"POST",body:JSON.stringify({ids:t})}),onSuccess:t=>{const r=t.removed??0;a.success(`Reset progress for ${r} ${r===1?"item":"items"}`),e.invalidateQueries({queryKey:["tv-progress"]}),e.invalidateQueries({queryKey:["tv-continue-watching"]}),e.invalidateQueries({queryKey:["tv-library"]})},onError:t=>{a.error(`Failed to reset progress: ${t.message}`)}})},J=()=>{const e=q(),t=b(),{data:r}=p(),s=m(()=>new Set(r?.ids||[]),[r]);return{toggle:c=>{const v=l(c.mediaType,c.tmdbId);s.has(v)?t.mutate(v):e.mutate({...c,poster:c.poster||""})},bookmarkedIds:s,pending:e.isPending||t.isPending}};export{f as T,b as a,L as b,K as c,g as d,P as e,J as f,k as g,R as h,$ as i,C as j,O as k,w as l,I as m,d as n,U as o,E as p,Q as t,F as u};
|
package/client/dist/index.html
CHANGED
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
background-color: #0c0d12;
|
|
34
34
|
}
|
|
35
35
|
</style>
|
|
36
|
-
<script type="module" crossorigin src="/assets/index-
|
|
36
|
+
<script type="module" crossorigin src="/assets/index-lo-bz7f2.js"></script>
|
|
37
37
|
<link rel="modulepreload" crossorigin href="/assets/vendor-core-8R2fFbyN.js">
|
|
38
38
|
<link rel="modulepreload" crossorigin href="/assets/vendor-query-BXRECSI6.js">
|
|
39
39
|
<link rel="modulepreload" crossorigin href="/assets/vendor-icons-CDMuNDeL.js">
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@serifpersia/dango",
|
|
3
|
-
"version": "3.3.
|
|
3
|
+
"version": "3.3.6",
|
|
4
4
|
"description": "A web application for watching anime.",
|
|
5
5
|
"main": "orchestrator.js",
|
|
6
6
|
"repository": {
|
|
@@ -81,5 +81,5 @@
|
|
|
81
81
|
"allowScripts": {
|
|
82
82
|
"esbuild@0.28.2": true
|
|
83
83
|
},
|
|
84
|
-
"versionDate": "2026-09-
|
|
84
|
+
"versionDate": "2026-09-25T11:33:57.632Z"
|
|
85
85
|
}
|
|
@@ -127,18 +127,18 @@ export class TvLibraryController {
|
|
|
127
127
|
const episode = parseInt(req.query.episode, 10);
|
|
128
128
|
if (Number.isFinite(season) && Number.isFinite(episode)) {
|
|
129
129
|
const row = TvProgressRepository.getEpisode(db, mediaId, season, episode);
|
|
130
|
-
res.json(row || { currentTime: 0, duration: 0 });
|
|
130
|
+
res.json(row || { currentTime: 0, duration: 0, completed: 0 });
|
|
131
131
|
return;
|
|
132
132
|
}
|
|
133
133
|
const row = TvProgressRepository.getLatest(db, mediaId);
|
|
134
|
-
res.json(row || { currentTime: 0, duration: 0 });
|
|
134
|
+
res.json(row || { currentTime: 0, duration: 0, completed: 0 });
|
|
135
135
|
}
|
|
136
136
|
catch {
|
|
137
|
-
res.json({ currentTime: 0, duration: 0 });
|
|
137
|
+
res.json({ currentTime: 0, duration: 0, completed: 0 });
|
|
138
138
|
}
|
|
139
139
|
};
|
|
140
140
|
saveProgress = async (req, res) => {
|
|
141
|
-
const { mediaId: mediaIdRaw, season, episode, currentTime, duration, title, poster, backdrop, year, overview, tmdbId, mediaType, adult, } = req.body ?? {};
|
|
141
|
+
const { mediaId: mediaIdRaw, season, episode, currentTime, duration, completed, title, poster, backdrop, year, overview, tmdbId, mediaType, adult, } = req.body ?? {};
|
|
142
142
|
const mediaId = normalizeTvMediaId(mediaIdRaw);
|
|
143
143
|
if (!mediaId) {
|
|
144
144
|
return res.status(400).json({ error: 'mediaId is required' });
|
|
@@ -147,14 +147,18 @@ export class TvLibraryController {
|
|
|
147
147
|
const episodeNum = Math.max(Number(episode) || 1, 1);
|
|
148
148
|
const timeNum = Math.max(Number(currentTime) || 0, 0);
|
|
149
149
|
const durationNum = Math.max(Number(duration) || 0, 0);
|
|
150
|
+
const clampedTime = durationNum > 0 ? Math.min(timeNum, durationNum) : timeNum;
|
|
151
|
+
const storedTime = durationNum > 0 && clampedTime >= durationNum * 0.8 ? durationNum : clampedTime;
|
|
152
|
+
const completedNow = Number(completed) === 1 || (durationNum > 0 && storedTime >= durationNum * 0.8) ? 1 : 0;
|
|
150
153
|
try {
|
|
151
154
|
await performTvWriteTransaction(tvDb(req), (tx) => {
|
|
152
155
|
TvProgressRepository.upsert(tx, {
|
|
153
156
|
mediaId: String(mediaId),
|
|
154
157
|
season: Math.round(seasonNum),
|
|
155
158
|
episode: Math.round(episodeNum),
|
|
156
|
-
currentTime:
|
|
159
|
+
currentTime: storedTime,
|
|
157
160
|
duration: durationNum,
|
|
161
|
+
completed: completedNow,
|
|
158
162
|
title: title ?? null,
|
|
159
163
|
poster: poster ?? null,
|
|
160
164
|
backdrop: backdrop ?? null,
|
|
@@ -86,14 +86,15 @@ export const TvLibraryRepository = {
|
|
|
86
86
|
},
|
|
87
87
|
};
|
|
88
88
|
export const TvProgressRepository = {
|
|
89
|
-
getByMedia: (db, mediaId) => dbAll(db, 'SELECT mediaId, season, episode, currentTime, duration, updatedAt FROM tv_progress WHERE mediaId = ? ORDER BY updatedAt DESC', [mediaId]),
|
|
90
|
-
getEpisode: (db, mediaId, season, episode) => dbGet(db, 'SELECT mediaId, season, episode, currentTime, duration, updatedAt FROM tv_progress WHERE mediaId = ? AND season = ? AND episode = ?', [mediaId, season, episode]),
|
|
91
|
-
getLatest: (db, mediaId) => dbGet(db, 'SELECT mediaId, season, episode, currentTime, duration, updatedAt FROM tv_progress WHERE mediaId = ? ORDER BY updatedAt DESC LIMIT 1', [mediaId]),
|
|
92
|
-
upsert: (db, data) => dbRun(db, `INSERT INTO tv_progress (mediaId, season, episode, currentTime, duration, title, poster, backdrop, year, overview, tmdbId, mediaType, adult, updatedAt)
|
|
93
|
-
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s', 'now'))
|
|
89
|
+
getByMedia: (db, mediaId) => dbAll(db, 'SELECT mediaId, season, episode, currentTime, duration, completed, updatedAt FROM tv_progress WHERE mediaId = ? ORDER BY updatedAt DESC, rowid DESC', [mediaId]),
|
|
90
|
+
getEpisode: (db, mediaId, season, episode) => dbGet(db, 'SELECT mediaId, season, episode, currentTime, duration, completed, updatedAt FROM tv_progress WHERE mediaId = ? AND season = ? AND episode = ?', [mediaId, season, episode]),
|
|
91
|
+
getLatest: (db, mediaId) => dbGet(db, 'SELECT mediaId, season, episode, currentTime, duration, completed, updatedAt FROM tv_progress WHERE mediaId = ? ORDER BY updatedAt DESC, rowid DESC LIMIT 1', [mediaId]),
|
|
92
|
+
upsert: (db, data) => dbRun(db, `INSERT INTO tv_progress (mediaId, season, episode, currentTime, duration, completed, title, poster, backdrop, year, overview, tmdbId, mediaType, adult, updatedAt)
|
|
93
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, strftime('%s', 'now'))
|
|
94
94
|
ON CONFLICT(mediaId, season, episode) DO UPDATE SET
|
|
95
95
|
currentTime = EXCLUDED.currentTime,
|
|
96
96
|
duration = EXCLUDED.duration,
|
|
97
|
+
completed = CASE WHEN tv_progress.completed = 1 OR EXCLUDED.completed = 1 THEN 1 ELSE 0 END,
|
|
97
98
|
title = COALESCE(EXCLUDED.title, tv_progress.title),
|
|
98
99
|
poster = COALESCE(EXCLUDED.poster, tv_progress.poster),
|
|
99
100
|
backdrop = COALESCE(EXCLUDED.backdrop, tv_progress.backdrop),
|
|
@@ -108,6 +109,7 @@ export const TvProgressRepository = {
|
|
|
108
109
|
data.episode,
|
|
109
110
|
data.currentTime,
|
|
110
111
|
data.duration,
|
|
112
|
+
data.completed,
|
|
111
113
|
data.title ?? null,
|
|
112
114
|
data.poster ?? null,
|
|
113
115
|
data.backdrop ?? null,
|
|
@@ -137,15 +139,15 @@ export const TvProgressRepository = {
|
|
|
137
139
|
COALESCE(l.title, p.title) as title, COALESCE(l.poster, p.poster) as poster, COALESCE(l.backdrop, p.backdrop) as backdrop,
|
|
138
140
|
COALESCE(l.year, p.year) as year, COALESCE(l.overview, p.overview) as overview,
|
|
139
141
|
l.status as watchlistStatus, COALESCE(l.adult, p.adult) as adult,
|
|
140
|
-
p.season, p.episode, p.currentTime, p.duration, p.updatedAt as progressAt
|
|
142
|
+
p.season, p.episode, p.currentTime, p.duration, p.completed, p.updatedAt as progressAt
|
|
141
143
|
FROM (
|
|
142
|
-
SELECT *, ROW_NUMBER() OVER (PARTITION BY mediaId ORDER BY updatedAt DESC) as rn
|
|
144
|
+
SELECT *, rowid AS progressRowid, ROW_NUMBER() OVER (PARTITION BY mediaId ORDER BY updatedAt DESC, rowid DESC) as rn
|
|
143
145
|
FROM tv_progress
|
|
144
146
|
) p
|
|
145
147
|
LEFT JOIN tv_library l ON p.mediaId = l.id
|
|
146
148
|
WHERE p.rn = 1
|
|
147
149
|
AND (l.status IS NULL OR l.status = 'Watching')
|
|
148
|
-
ORDER BY p.updatedAt DESC
|
|
150
|
+
ORDER BY p.updatedAt DESC, p.progressRowid DESC
|
|
149
151
|
${limitClause}`);
|
|
150
152
|
},
|
|
151
153
|
};
|
package/server/dist/sync.js
CHANGED
|
@@ -974,7 +974,7 @@ export async function initializeTvDatabase(dbPath) {
|
|
|
974
974
|
db.run('PRAGMA mmap_size = 268435456;');
|
|
975
975
|
db.run('PRAGMA foreign_keys = ON;');
|
|
976
976
|
db.run(`CREATE TABLE IF NOT EXISTS tv_library (id TEXT PRIMARY KEY, tmdbId INTEGER NOT NULL, mediaType TEXT NOT NULL, title TEXT, poster TEXT, backdrop TEXT, year TEXT, overview TEXT, status TEXT DEFAULT 'Watching', adult INTEGER DEFAULT 0, lastSeason INTEGER, lastEpisode INTEGER, updatedAt INTEGER)`);
|
|
977
|
-
db.run(`CREATE TABLE IF NOT EXISTS tv_progress (mediaId TEXT NOT NULL, season INTEGER NOT NULL, episode INTEGER NOT NULL, currentTime REAL DEFAULT 0, duration REAL DEFAULT 0, updatedAt INTEGER, PRIMARY KEY (mediaId, season, episode))`);
|
|
977
|
+
db.run(`CREATE TABLE IF NOT EXISTS tv_progress (mediaId TEXT NOT NULL, season INTEGER NOT NULL, episode INTEGER NOT NULL, currentTime REAL DEFAULT 0, duration REAL DEFAULT 0, completed INTEGER NOT NULL DEFAULT 0, updatedAt INTEGER, PRIMARY KEY (mediaId, season, episode))`);
|
|
978
978
|
db.run(`CREATE TABLE IF NOT EXISTS sync_metadata (key TEXT PRIMARY KEY, value INTEGER)`);
|
|
979
979
|
db.run(`INSERT OR IGNORE INTO sync_metadata (key, value) VALUES ('db_version', 1)`);
|
|
980
980
|
db.run(`CREATE INDEX IF NOT EXISTS idx_tv_library_status ON tv_library(status)`);
|
|
@@ -1005,6 +1005,24 @@ export async function initializeTvDatabase(dbPath) {
|
|
|
1005
1005
|
if (!tvProgressColumns.some((c) => c.name === 'adult')) {
|
|
1006
1006
|
db.run(`ALTER TABLE tv_progress ADD COLUMN adult INTEGER`);
|
|
1007
1007
|
}
|
|
1008
|
+
if (!tvProgressColumns.some((c) => c.name === 'completed')) {
|
|
1009
|
+
db.run(`ALTER TABLE tv_progress ADD COLUMN completed INTEGER NOT NULL DEFAULT 0`);
|
|
1010
|
+
}
|
|
1011
|
+
db.run(`UPDATE tv_progress SET completed = 1 WHERE completed = 0 AND duration > 0 AND currentTime >= duration * 0.8`);
|
|
1012
|
+
db.run(`CREATE TRIGGER IF NOT EXISTS trg_tv_progress_completed_insert
|
|
1013
|
+
AFTER INSERT ON tv_progress
|
|
1014
|
+
WHEN NEW.duration > 0 AND NEW.currentTime >= NEW.duration * 0.8
|
|
1015
|
+
BEGIN
|
|
1016
|
+
UPDATE tv_progress SET completed = 1
|
|
1017
|
+
WHERE mediaId = NEW.mediaId AND season = NEW.season AND episode = NEW.episode;
|
|
1018
|
+
END`);
|
|
1019
|
+
db.run(`CREATE TRIGGER IF NOT EXISTS trg_tv_progress_completed_update
|
|
1020
|
+
AFTER UPDATE OF currentTime, duration ON tv_progress
|
|
1021
|
+
WHEN OLD.completed = 1 OR (NEW.duration > 0 AND NEW.currentTime >= NEW.duration * 0.8)
|
|
1022
|
+
BEGIN
|
|
1023
|
+
UPDATE tv_progress SET completed = 1
|
|
1024
|
+
WHERE mediaId = NEW.mediaId AND season = NEW.season AND episode = NEW.episode;
|
|
1025
|
+
END`);
|
|
1008
1026
|
db.run(`UPDATE OR IGNORE tv_progress SET mediaId = REPLACE(mediaId, '-', ':') WHERE mediaId LIKE 'tv-%' OR mediaId LIKE 'movie-%'`);
|
|
1009
1027
|
db.run(`DELETE FROM tv_progress WHERE mediaId LIKE 'tv-%' OR mediaId LIKE 'movie-%'`);
|
|
1010
1028
|
return db;
|
package/server/package.json
CHANGED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{T as P,d as I,A as T,u as s,S as B,L as M,N as C}from"./vendor-core-8R2fFbyN.js";import{I as o}from"./vendor-icons-CDMuNDeL.js";import{u as D}from"./useAnimeInfoData-DeuwDSnI.js";import{d as z,s as R,e as A}from"./index-IZgh1beL.js";import{Q as x}from"./QueueOptionsButton-B6BMq66e.js";import{p as t,a as _,m as $,M as L}from"./MediaCard-Be1ST9oj.js";const k=({showId:e,anchorRect:l,onMouseEnter:m,onMouseLeave:h,onRequestClose:N})=>{const{showMeta:a,loadingMeta:r,inWatchlist:u,toggleWatchlist:f}=D(e),{titlePreference:n}=z(),d=P(()=>a?.name?n==="name"?a.name:n==="nativeName"?a.names?.native||a.name:n==="englishName"&&a.names?.english||a.name:"",[a,n]),[g,b]=I(!1),p=T(!1),y=()=>{p.current=!0,m()},w=()=>{p.current=!1,!g&&h()},c=i=>{b(i),!i&&!p.current&&h()};return s(_,{anchorRect:l,onMouseEnter:y,onMouseLeave:w,onRequestClose:N,children:r?s("div",{className:t.loading,children:[s("div",{className:t.spinner}),s("span",{children:"Fetching details..."})]}):a?s(B,{children:[s("div",{className:t.header,children:s("div",{className:t.title,children:d})}),s("div",{className:t.body,children:[s("div",{className:t.metaRow,children:[a.score&&s("div",{className:t.metaItem,children:[s(o,{name:"star",className:t.scoreIcon,size:14}),s("span",{children:a.score})]}),a.status&&s("div",{className:t.metaItem,children:[s(o,{name:"tv",size:14}),s("span",{children:a.status})]})]}),s("div",{className:t.synopsis,children:a.description?R(a.description):"No synopsis available."}),s("div",{className:t.details,children:[a.nextEpisodeAirDate&&s("div",{className:t.detailItem,children:[s("strong",{children:"Aired:"})," ",a.nextEpisodeAirDate]}),Array.isArray(a.genres)&&a.genres.length>0&&s("div",{className:t.genres,children:a.genres.filter(Boolean).slice(0,4).map(i=>{const E=typeof i=="string"?i:i?.name;return s("span",{className:t.genre,children:E},E)})})]})]}),s("div",{className:t.footer,children:[s("div",{className:t.primaryAction,children:s(M,{to:`/watch/${a?.id||e}`,className:t.watchBtn,children:[s(o,{name:"play",size:14}),"Watch now"]})}),s("div",{className:t.secondaryActions,children:[s("button",{className:`${t.watchlistBtn} ${u?t.active:""}`,onClick:i=>{i.preventDefault(),i.stopPropagation(),f()},children:[u?s(o,{name:"check",size:12}):s(o,{name:"plus",size:12}),s("span",{children:u?"Remove":"Watchlist"})]}),s(x,{showId:e,showName:a.name||a.names?.romaji,showThumbnail:a.thumbnail,nativeName:a.names?.native,englishName:a.names?.english,showType:a.type,className:t.watchlistBtn,activeClassName:t.active,align:"left",onMenuOpenChange:c}),s(M,{to:`/anime/${a?.id||e}`,className:t.detailsBtn,children:"Read more"})]})]})]}):s("div",{className:t.loading,children:"Failed to load info."})})},q=C(({anime:e,continueWatching:l=!1,onRemove:m,config:h,layout:N="vertical"})=>{const a=e.currentTime||0,r=e.duration||0,u=a>5&&r>5&&a<r*.95,f=a>0&&(r<=5||a>=r*.95),n=e.episodeNumber,d=l?{pathname:n?`/watch/${e._id}/${n}`:`/watch/${e._id}`,state:{name:e.name,thumbnail:e.thumbnail,nativeName:e.nativeName,englishName:e.englishName,type:e.type}}:n?`/watch/${e._id}/${n}`:`/anime/${e._id}`,g=(()=>{if(typeof d=="string")return d.startsWith("/watch/");const c=d.pathname;return typeof c=="string"&&c.startsWith("/watch/")})(),b=l&&n?`EP ${n}`:e.watchedCount!==void 0&&e.watchedCount>0?`EP ${e.watchedCount}`:null,p=[e.airTime,e.aired===!1&&e.nextEpisodeAirDate?`· ${e.nextEpisodeAirDate.split(",")[0]}`:""].filter(Boolean).join(" "),y=e.isAdult||e.rating==="R+"||e.rating==="Rx"||e.rating?.includes("17+"),w=s(B,{children:[(e.availableEpisodesDetail?.sub||e.availableEpisodes?.sub)&&s("div",{className:$.metaItem,children:[s(o,{name:"closed-captioning",size:10}),e.availableEpisodesDetail?.sub?.length??e.availableEpisodes?.sub]}),(e.availableEpisodesDetail?.dub||e.availableEpisodes?.dub)&&s("div",{className:$.metaItem,children:[s(o,{name:"microphone",size:10}),e.availableEpisodesDetail?.dub?.length??e.availableEpisodes?.dub]})]});return s(L,{item:{id:e.id||e.showId||e._id,title:e.name,nativeName:e.nativeName,englishName:e.englishName,thumbnail:e.thumbnail,typeBadge:e.type||"TV",chapterBadge:b,airMeta:p||void 0,isAdult:y,notAired:e.aired===!1},linkTo:d,hoverIcon:g?"play":"info",progress:u?{percent:a/r*100,label:`${A(a)} / ${A(r)}`}:f?{percent:100,label:"Watched"}:void 0,showProgress:l,metaRow:w,display:h,layout:N,onRemove:m,showRemoveButton:h?.elements?.poster?.removeButton??(l&&!!m),showInfoButton:!l,enrichedId:e._id,renderPopup:(c,v)=>s(k,{showId:e._id,anchorRect:c,onMouseEnter:v.onMouseEnter,onMouseLeave:v.onMouseLeave,onRequestClose:v.close})})});export{q as A};
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import{u as t,A as g,d as w,h as I,q as N,T as re,$ as St}from"./vendor-core-8R2fFbyN.js";import{I as U}from"./vendor-icons-CDMuNDeL.js";import{S as fe,q as ve,e as kt,B as te}from"./index-IZgh1beL.js";import{u as Bt}from"./vendor-query-BXRECSI6.js";const xt="_controls_13898_1",Tt="_titleContainer_13898_9",Lt="_scheduleInfo_13898_15",Et="_status_13898_23",Nt="_nextEpisode_13898_35",It="_watchlistBtn_13898_45",Pt="_inList_13898_72",$t="_queueBtn_13898_83",Mt="_queueActive_13898_95",Ft="_modeToggleBtn_13898_101",At="_modeToggleActive_13898_108",Rt="_nativeToggleBtn_13898_119",Ot="_nativeToggleActive_13898_132",Dt="_markWatchedBtn_13898_153",qt="_markWatchedDone_13898_167",Ht="_completeSeriesBtn_13898_178",zt="_providerAndEpisodeRow_13898_192",Wt="_episodeActions_13898_199",Vt="_desktopEpisodeActions_13898_206",Ut="_mobileEpisodeActions_13898_213",Kt="_episodeNavBtn_13898_217",Gt="_primary_13898_247",Jt="_secondary_13898_257",Qt="_episodePickerBtn_13898_261",Xt="_queueCountdown_13898_265",jt="_speedBoostBadge_13898_280",Yt="_videoContainer_13898_311",Zt="_loadingOverlay_13898_324",en="_loadingDots_13898_338",tn="_dot_13898_343",nn="_bounce_13898_1",rn="_bufferingOverlay_13898_372",on="_bufferingSpinner_13898_381",sn="_spin_13898_920",cn="_videoIframe_13898_396",an="_videoElementHidden_13898_419",ln="_upscalerCanvas_13898_424",un="_upscalerActive_13898_437",dn="_upscalerStatusBadge_13898_441",pn="_subtitleOverlay_13898_456",fn="_controlsOverlay_13898_468",_n="_hidden_13898_498",mn="_centerPlayPause_13898_504",hn="_bottomControls_13898_536",gn="_progressBarContainer_13898_553",yn="_progressBar_13898_553",vn="_scrubbing_13898_576",bn="_watchedBar_13898_581",wn="_bufferedBar_13898_582",Cn="_thumb_13898_604",Sn="_timeBubble_13898_625",kn="_skipSegment_13898_647",Bn="_op_13898_661",xn="_ed_13898_665",Tn="_recap_13898_669",Ln="_bottomControlsRow_13898_673",En="_controlBtn_13898_681",Nn="_timeDisplay_13898_705",In="_leftControls_13898_714",Pn="_rightControls_13898_715",$n="_middleControls_13898_716",Mn="_skipControls_13898_722",Fn="_skipBtn_13898_728",An="_volumeContainer_13898_752",Rn="_volumeSlider_13898_759",On="_settingsMenu_13898_837",Dn="_slideUp_13898_1",qn="_qualityListInMenu_13898_876",Hn="_ccOptionsContainer_13898_877",zn="_qualityItemInMenu_13898_885",Wn="_ccItem_13898_886",Vn="_active_13898_907",Un="_sourceLoader_13898_914",Kn="_spinner_13898_920",Gn="_skipBubble_13898_971",Jn="_skipIcon_13898_975",Qn="_skipText_13898_978",Xn="_watchBtn_13898_990",jn="_errorOverlay_13898_1036",Yn="_retryButton_13898_1046",Zn="_skipIndicatorContainer_13898_1073",er="_leftSkip_13898_1073",tr="_rightSkip_13898_1076",nr="_sourceSelectionContainer_13898_1081",rr="_slideUpIn_13898_1",or="_providerSelectContainer_13898_1096",sr="_providerSelect_13898_1096",ir="_sourceSelect_13898_1081",cr="_sourceButtons_13898_1152",ar="_sourceButton_13898_1152",lr="_detailsBox_13898_1184",ur="_detailsToggleBtn_13898_1197",dr="_detailsGridContainer_13898_1221",pr="_fadeIn_13898_1",fr="_detailItem_13898_1233",_r="_animeStatus_13898_1253",mr="_genresList_13898_1266",hr="_genreTag_13898_1273",gr="_loadingDetails_13898_1291",yr="_descriptionSection_13898_1298",vr="_description_13898_1298",br="_epJumpControls_13898_1334",wr="_epRangeButtons_13898_1345",Cr="_metaTags_13898_1351",Sr="_epRangeBtn_13898_1358",kr="_epJumpInputGroup_13898_1373",Br="_fullscreenActive_13898_1405",xr="_skipRipple_13898_1",Tr="_errorSubtext_13898_1511",ss={controls:xt,titleContainer:Tt,scheduleInfo:Lt,status:Et,nextEpisode:Nt,watchlistBtn:It,inList:Pt,queueBtn:$t,queueActive:Mt,modeToggleBtn:Ft,modeToggleActive:At,nativeToggleBtn:Rt,nativeToggleActive:Ot,markWatchedBtn:Dt,markWatchedDone:qt,completeSeriesBtn:Ht,providerAndEpisodeRow:zt,episodeActions:Wt,desktopEpisodeActions:Vt,mobileEpisodeActions:Ut,episodeNavBtn:Kt,primary:Gt,secondary:Jt,episodePickerBtn:Qt,queueCountdown:Xt,speedBoostBadge:jt,videoContainer:Yt,loadingOverlay:Zt,loadingDots:en,dot:tn,bounce:nn,bufferingOverlay:rn,bufferingSpinner:on,spin:sn,videoIframe:cn,videoElementHidden:an,upscalerCanvas:ln,upscalerActive:un,upscalerStatusBadge:dn,subtitleOverlay:pn,controlsOverlay:fn,hidden:_n,centerPlayPause:mn,bottomControls:hn,progressBarContainer:gn,progressBar:yn,scrubbing:vn,watchedBar:bn,bufferedBar:wn,thumb:Cn,timeBubble:Sn,skipSegment:kn,op:Bn,ed:xn,recap:Tn,bottomControlsRow:Ln,controlBtn:En,timeDisplay:Nn,leftControls:In,rightControls:Pn,middleControls:$n,skipControls:Mn,skipBtn:Fn,volumeContainer:An,volumeSlider:Rn,settingsMenu:On,slideUp:Dn,qualityListInMenu:qn,ccOptionsContainer:Hn,qualityItemInMenu:zn,ccItem:Wn,active:Vn,sourceLoader:Un,spinner:Kn,skipBubble:Gn,skipIcon:Jn,skipText:Qn,watchBtn:Xn,errorOverlay:jn,retryButton:Yn,skipIndicatorContainer:Zn,leftSkip:er,rightSkip:tr,sourceSelectionContainer:nr,slideUpIn:rr,providerSelectContainer:or,providerSelect:sr,sourceSelect:ir,sourceButtons:cr,sourceButton:ar,detailsBox:lr,detailsToggleBtn:ur,detailsGridContainer:dr,fadeIn:pr,detailItem:fr,animeStatus:_r,genresList:mr,genreTag:hr,loadingDetails:gr,descriptionSection:yr,description:vr,epJumpControls:br,epRangeButtons:wr,metaTags:Cr,epRangeBtn:Sr,epJumpInputGroup:kr,fullscreenActive:Br,skipRipple:xr,errorSubtext:Tr},Lr="_playerPageLayout_xfhzl_1",Er="_episodeSidebar_xfhzl_15",Nr="_playerMain_xfhzl_28",Ir="_videoPlayerWrapper_xfhzl_36",Pr="_playerInfoHeader_xfhzl_52",$r="_playerAnimeCard_xfhzl_58",Mr="_playerInfoContainer_xfhzl_70",Fr="_videoTitleSection_xfhzl_94",Ar="_theaterMode_xfhzl_276",is={playerPageLayout:Lr,episodeSidebar:Er,playerMain:Nr,videoPlayerWrapper:Ir,playerInfoHeader:Pr,playerAnimeCard:$r,playerInfoContainer:Mr,videoTitleSection:Fr,theaterMode:Ar},Rr="_shell_41rxp_1",Or="_stage_41rxp_37",Dr="_shellFill_41rxp_85",qr="_shellFullscreen_41rxp_93",Hr="_uiLayer_41rxp_107",zr="_volumeWrap_41rxp_118",Wr="_volumeSlider_41rxp_124",j={shell:Rr,stage:Or,shellFill:Dr,shellFullscreen:qr,uiLayer:Hr,volumeWrap:zr,volumeSlider:Wr},Vr=e=>(e.language??e.lang??"").toLowerCase(),Ur=e=>(e.label??"").toLowerCase(),Kr=e=>`${e.language??e.lang??""}|||${e.label??""}`,Gr=e=>Vr(e).startsWith("en")||Ur(e).includes("english");function cs(e,r){if(e.length===0||r?.enabled===!1)return-1;const n=r?.lastKey??null;if(n){const o=e.findIndex(u=>Kr(u)===n);if(o>=0)return o}const s=e.findIndex(Gr);return s>=0?s:0}const K={fontSize:1.8,position:0,bgOpacity:.5,bgColor:"#000000",textColor:"#ffffff",edge:"shadow",bold:!1},Se=(e,r,n)=>Math.max(r,Math.min(n,e)),ke=e=>typeof e=="string"&&/^#[0-9a-fA-F]{6}$/.test(e),be=(e,r,n,s)=>{try{const o=localStorage.getItem(e);if(o===null)return r;const u=parseFloat(o);return Number.isFinite(u)?Se(u,n,s):r}catch{return r}};function Jr(){let e=K.edge,r=K.bgColor,n=K.textColor,s=K.bold;try{const o=localStorage.getItem("subtitleEdge");(o==="shadow"||o==="outline"||o==="none")&&(e=o);const u=localStorage.getItem("subtitleBgColor");ke(u)&&(r=u);const h=localStorage.getItem("subtitleTextColor");ke(h)&&(n=h);const i=localStorage.getItem("subtitleBold");i!==null&&(s=i==="true")}catch{}return{fontSize:be("subtitleFontSize",K.fontSize,.5,10),position:be("subtitlePosition",K.position,0,100),bgOpacity:be("subtitleBgOpacity",K.bgOpacity,0,1),bgColor:r,textColor:n,edge:e,bold:s}}function He(e,r){const n=`rgba(0, 0, 0, ${Se(r,0,1)})`;if(!ke(e))return n;const s=parseInt(e.slice(1,3),16),o=parseInt(e.slice(3,5),16),u=parseInt(e.slice(5,7),16);return`rgba(${s}, ${o}, ${u}, ${Se(r,0,1)})`}function ze(e,r){return e==="none"?r<=0?"0 1px 3px rgba(0, 0, 0, 0.9)":"none":e==="outline"?["-1px 0 0 black","1px 0 0 black","0 -1px 0 black","0 1px 0 black","-1px -1px 0 black","1px -1px 0 black","-1px 1px 0 black","1px 1px 0 black","0 0 6px rgba(0, 0, 0, 0.9)"].join(", "):"0 0 4px black, 0 1px 2px rgba(0, 0, 0, 0.8)"}function as(e){return`
|
|
2
|
-
video::cue {
|
|
3
|
-
font-size: ${e.fontSize}rem !important;
|
|
4
|
-
color: ${e.textColor} !important;
|
|
5
|
-
background-color: ${He(e.bgColor,e.bgOpacity)} !important;
|
|
6
|
-
font-weight: ${e.bold?"bold":"normal"} !important;
|
|
7
|
-
text-shadow: ${ze(e.edge,e.bgOpacity)} !important;
|
|
8
|
-
}
|
|
9
|
-
`}function ls(e){return[`font-size: ${e.fontSize}rem`,`color: ${e.textColor}`,`background-color: ${He(e.bgColor,e.bgOpacity)}`,`font-weight: ${e.bold?"700":"400"}`,`text-shadow: ${ze(e.edge,e.bgOpacity)}`,"padding: 0.2em 0.5em","border-radius: 0.25em","text-align: center","position: absolute","left: 50%","transform: translateX(-50%)","max-width: 92%","white-space: pre-wrap","overflow-wrap: break-word","line-height: 1.4"].join(`;
|
|
10
|
-
`)+";"}const Qr=new Set(["b","i","u","strong","em"]);function us(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/<(\/?)([a-zA-Z]+)>/g,(n,s,o)=>Qr.has(o.toLowerCase())?`<${s}${o.toLowerCase()}>`:n)}function ds(e){return e.replace(/<[^>]*>/g,"")}const ps=["#ffffff","#ffff00","#7CFC00","#00e5ff","#ff9ff3","#ffa502"],fs=["#000000","#1e272e","#2f3542","#3d0c02","#0c3d2e","#ffffff"];function _s(e,r){const n=Number.isFinite(e)?e*16:K.fontSize*16;return!Number.isFinite(r)||r<=0?n/16:Math.min(n,Math.max(13,r*.07))/16}function ms(e,r){const n=e.clientWidth||0,s=e.clientHeight||0,o=e.videoWidth>0&&e.videoHeight>0?e.videoWidth/e.videoHeight:0;let u=s;o>0&&n>0&&s>0&&(u=n/s>o?s:n/o);const h=Math.max(0,(s-u)/2),i=Math.max(0,Math.min(100,Number(r)||0))/100*u;return h+i}const Xr="_centerControls_61n7k_1",jr="_centerSkipBtn_61n7k_15",Yr="_centerPlayPause_61n7k_40",Zr="_playIconOffset_61n7k_71",ne={centerControls:Xr,centerSkipBtn:jr,centerPlayPause:Yr,playIconOffset:Zr},hs=({isPlaying:e,onTogglePlay:r,onSkipBack:n,onSkipForward:s,skipSeconds:o=10})=>t("div",{className:ne.centerControls,onClick:u=>u.stopPropagation(),children:[t("button",{className:ne.centerSkipBtn,onClick:n,title:`Skip back ${o}s`,"aria-label":`Skip back ${o} seconds`,children:t(U,{name:"replay-10"})}),t("button",{className:ne.centerPlayPause,"data-speed-boost-ignore":"true",onClick:r,"aria-label":e?"Pause":"Play",children:e?t(U,{name:"pause"}):t(U,{name:"play",className:ne.playIconOffset})}),t("button",{className:ne.centerSkipBtn,onClick:s,title:`Skip forward ${o}s`,"aria-label":`Skip forward ${o} seconds`,children:t(U,{name:"forward-10"})})]}),gs=({classes:e,videoRef:r,duration:n,formatTime:s,isScrubbing:o,buffered:u="auto",onSeek:h,onScrubStart:i,onScrubMove:S,onScrubEnd:b,timeLabelRef:a,children:E})=>{const _=g(null),T=g(null),f=g(null),p=g(null),[y,l]=w({time:0,position:null});I(()=>{const d=r.current;if(!d)return;const x=M=>{const m=M/n*100||0;T.current&&(T.current.style.width=`${m}%`),f.current&&(f.current.style.left=`${m}%`),a?.current&&(a.current.innerText=`${s(M)} / ${s(n)}`)},$=()=>{o||x(d.currentTime)},O=()=>{if(u==="auto"&&d.buffered.length>0){const m=d.buffered.end(d.buffered.length-1)/n*100||0;p.current&&(p.current.style.width=`${m}%`)}};return x(d.currentTime),O(),d.addEventListener("timeupdate",$),d.addEventListener("progress",O),()=>{d.removeEventListener("timeupdate",$),d.removeEventListener("progress",O)}},[r,n,o,u,s,a]),I(()=>{if(!o)return;const d=O=>{if(!_.current||!n)return;const M=_.current.getBoundingClientRect(),m=Math.min(1,Math.max(0,(O.clientX-M.left)/M.width));S(m),$(m)},x=()=>b();return document.addEventListener("mousemove",d),document.addEventListener("mouseup",x),()=>{document.removeEventListener("mousemove",d),document.removeEventListener("mouseup",x)};function $(O){const M=O*n,m=M/n*100||0;T.current&&(T.current.style.width=`${m}%`),f.current&&(f.current.style.left=`${m}%`),a?.current&&(a.current.innerText=`${s(M)} / ${s(n)}`);const F=_.current?.getBoundingClientRect();l({time:M,position:F?O*F.width:null})}},[o,n,S,b,s,a]);const C=d=>{if(!_.current)return 0;const x=_.current.getBoundingClientRect();return Math.min(1,Math.max(0,(d-x.left)/x.width))};return t("div",{className:`${e.container} ${o&&e.scrubbing?e.scrubbing:""}`,ref:_,onClick:d=>{!r.current||isNaN(n)||n===0||h(C(d.clientX))},onMouseMove:d=>{if(!n)return;const x=C(d.clientX);l({time:x*n,position:d.clientX-(_.current?.getBoundingClientRect().left??0)})},onMouseLeave:()=>{o||l({time:0,position:null})},children:[y.position!==null&&t("div",{className:e.timeBubble,style:{left:y.position},children:s(y.time)}),t("div",{className:e.bar,children:[t("div",{className:e.buffered,ref:p,style:u==="full"?{width:"100%"}:void 0}),t("div",{className:e.watched,ref:T}),t("div",{className:e.thumb,ref:f,onMouseDown:d=>{d.preventDefault(),r.current&&i()}}),E]})]})};function we(){try{if(typeof window>"u")return!1;const e=window.matchMedia?.("(pointer: coarse)").matches??!1,n=(navigator.maxTouchPoints??0)>0||"ontouchstart"in window;return e||n}catch{return!1}}function We(){const[e,r]=w(we);return I(()=>{r(we());let n=null;const s=()=>r(we());try{n=window.matchMedia("(pointer: coarse)"),n.addEventListener?n.addEventListener("change",s):n.addListener(s)}catch{}return window.addEventListener("touchstart",s,{passive:!0,once:!0}),()=>{try{n&&(n.removeEventListener?n.removeEventListener("change",s):n.removeListener(s))}catch{}window.removeEventListener("touchstart",s)}},[]),e}const qe=280;function eo(e){return e?!!e.closest('button, input, select, textarea, a, [role="button"], [data-player-ui="true"]'):!1}const ys=({player:e,topBar:r,centerControls:n,bottomBar:s,settingsPanel:o,overlays:u,isInteracting:h=!1,className:i,chromeDisabled:S=!1,children:b})=>{const{state:a,refs:E,actions:_}=e,T=E.playerContainerRef,p=We()?5e3:3e3,y=g(0),l=g(null),C=g(h);C.current=h;const d=N(()=>{const m=_.inactivityTimer.current;m&&(window.clearTimeout(m),_.inactivityTimer.current=null)},[_]),x=N(()=>{d(),a.isPlaying&&(C.current||a.useNativeControls||(_.inactivityTimer.current=window.setTimeout(()=>{if(C.current)return;_.setShowControls(!1);const m=T.current;m&&a.isFullscreen&&(m.style.cursor="none")},p)))},[_,d,T,p,a.isFullscreen,a.isPlaying,a.useNativeControls]),$=N(()=>{const m=T.current;m&&(m.style.cursor="default"),!a.showControls&&!a.useNativeControls&&_.setShowControls(!0),x()},[_,T,x,a.showControls,a.useNativeControls]);I(()=>{if(a.showControls){if(!a.isPlaying){d();return}if(h||a.isScrubbing||a.showSettings||a.showVolumeSlider){_.setShowControls(!0),d();return}x()}},[_,d,h,x,a.isPlaying,a.isScrubbing,a.showControls,a.showSettings,a.showVolumeSlider]),I(()=>()=>d(),[d]);const O=N(m=>{const F=m.target;if(eo(F))return;const J=Date.now(),H=J-y.current<qe;if(y.current=J,H){l.current&&(window.clearTimeout(l.current),l.current=null),_.toggleFullscreen();return}l.current&&window.clearTimeout(l.current),l.current=window.setTimeout(()=>{l.current=null,_.setShowControls(!a.showControls),a.showControls?x():$()},qe)},[_,x,a.showControls,$]);I(()=>()=>{l.current&&window.clearTimeout(l.current)},[]);const M=a.showControls||a.isScrubbing||a.showSettings||a.showVolumeSlider;return t("div",{ref:T,className:`${j.shell} ${a.isFullscreen?j.shellFullscreen:""} ${i??""}`,onContextMenu:m=>m.preventDefault(),onPointerMove:m=>{m.pointerType==="mouse"&&$()},onMouseLeave:()=>{window.matchMedia?.("(hover: hover) and (pointer: fine)").matches&&a.isPlaying&&!C.current&&_.setShowControls(!1)},children:[t("div",{className:j.stage,onClick:O,onContextMenu:m=>m.preventDefault(),children:b}),u,!S&&!a.useNativeControls&&t("div",{className:j.uiLayer,onContextMenu:m=>m.preventDefault(),children:[t("div",{"data-player-ui":"true",children:r}),M&&n&&t("div",{"data-player-ui":"true",children:n}),t("div",{"data-player-ui":"true",children:s}),o&&t("div",{"data-player-ui":"true",children:o})]})]})},to=450,vs=({muted:e,volume:r,volumeIcon:n,buttonClassName:s,sliderClassName:o,onToggleMute:u,onVolumeChange:h,onExpandedChange:i})=>{const S=We(),[b,a]=w(!1),E=g(null),_=g(!1),T=g(null),f=N(d=>{a(d),i?.(d)},[i]);I(()=>()=>{E.current&&window.clearTimeout(E.current)},[]),I(()=>{if(!b)return;const d=x=>{T.current&&!T.current.contains(x.target)&&f(!1)};return document.addEventListener("pointerdown",d),()=>document.removeEventListener("pointerdown",d)},[b,f]);const p=e?0:r,y=()=>{_.current=!1,E.current&&window.clearTimeout(E.current),E.current=window.setTimeout(()=>{_.current=!0,f(!0)},to)},l=()=>{E.current&&(window.clearTimeout(E.current),E.current=null)},C=d=>{if(d.stopPropagation(),_.current){_.current=!1;return}if(S){b?u():f(!0);return}u()};return t("div",{ref:T,className:j.volumeWrap,"data-expanded":b?"true":"false",onContextMenu:d=>d.preventDefault(),children:[t("button",{type:"button",className:s,onClick:C,onPointerDown:y,onPointerUp:l,onPointerLeave:l,onContextMenu:d=>d.preventDefault(),"aria-label":e?"Unmute":"Mute","aria-expanded":b,children:n}),t("input",{type:"range",min:"0",max:"1",step:"0.05",value:p,onChange:d=>h(parseFloat(d.target.value)),onClick:d=>d.stopPropagation(),onPointerDown:d=>d.stopPropagation(),onContextMenu:d=>d.preventDefault(),className:`${j.volumeSlider} ${o??""}`,style:{"--volume-percent":`${p*100}%`},"aria-label":"Volume"})]})},no="_statusArea_1xccu_1",ro="_toggleBtn_1xccu_20",oo="_shortcuts_1xccu_46",so="_shortcutGroup_1xccu_56",io="_shortcut_1xccu_46",co="_key_1xccu_70",ao="_label_1xccu_91",B={statusArea:no,toggleBtn:ro,shortcuts:oo,shortcutGroup:so,shortcut:io,key:co,label:ao},bs=({showTheater:e=!0})=>{const[r,n]=w(!1);return t("div",{className:B.statusArea,children:[t("button",{type:"button",className:B.toggleBtn,onClick:()=>n(s=>!s),"aria-expanded":r,"aria-controls":"player-shortcuts",children:[t(U,{name:"keyboard",size:14}),t("span",{children:"Keyboard Shortcuts"}),r?t(U,{name:"chevron-up",size:12}):t(U,{name:"chevron-down",size:12})]}),r&&t("div",{id:"player-shortcuts",className:B.shortcuts,children:[t("div",{className:B.shortcutGroup,children:[t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"↑"}),t("span",{className:B.key,children:"↓"}),t("span",{className:B.label,children:"Volume"})]}),t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"←"}),t("span",{className:B.key,children:"→"}),t("span",{className:B.label,children:"Seek"})]})]}),t("div",{className:B.shortcutGroup,children:[t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"Space"}),t("span",{className:B.label,children:"Play/Pause"})]}),t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"F"}),t("span",{className:B.label,children:"Fullscreen"})]}),t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"M"}),t("span",{className:B.label,children:"Mute"})]}),e&&t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"T"}),t("span",{className:B.label,children:"Theater"})]}),t("div",{className:B.shortcut,children:[t("span",{className:B.key,children:"N"}),t("span",{className:B.label,children:"Next"})]})]})]})]})},lo="_episodeListContainer_9y3pr_1",uo="_drawerContainer_9y3pr_9",po="_episodeListHeader_9y3pr_14",fo="_drawerHeader_9y3pr_20",_o="_episodeListTitle_9y3pr_28",mo="_rangeSelector_9y3pr_40",ho="_rangeButton_9y3pr_46",go="_active_9y3pr_69",yo="_episodeList_9y3pr_1",vo="_drawerList_9y3pr_88",bo="_episodeItem_9y3pr_117",wo="_watched_9y3pr_144",Co="_episodeThumb_9y3pr_166",So="_episodeText_9y3pr_175",ko="_episodeLabel_9y3pr_183",Bo="_episodeSub_9y3pr_188",L={episodeListContainer:lo,drawerContainer:uo,episodeListHeader:po,drawerHeader:fo,episodeListTitle:_o,rangeSelector:mo,rangeButton:ho,active:go,episodeList:yo,drawerList:vo,episodeItem:bo,watched:wo,episodeThumb:Co,episodeText:So,episodeLabel:ko,episodeSub:Bo},xo=({episodes:e,currentEpisode:r,watchedEpisodes:n=[],onEpisodeClick:s,variant:o="sidebar",title:u="Episodes",header:h})=>{const[i,S]=w(0),b=g(null),a=re(()=>e.map(f=>typeof f=="string"?{id:f,label:`Episode ${f}`}:f),[e]),E=re(()=>new Set(n),[n]);I(()=>{const f=b.current;if(!f)return;let p=f.parentElement;for(;p;){const C=window.getComputedStyle(p);if((C.overflowY==="auto"||C.overflowY==="scroll")&&p.scrollHeight>p.clientHeight)break;p=p.parentElement}if(!p)return;const y=p.getBoundingClientRect(),l=f.getBoundingClientRect();p.scrollTop+=l.top+l.height/2-(y.top+p.clientHeight/2)},[r,i]);const _=re(()=>{if(a.length<=100)return[];const f=[];for(let p=0;p<a.length;p+=100){const y=p+1,l=Math.min(p+100,a.length);f.push(`${y}-${l}`)}return f},[a]),T=re(()=>{if(_.length===0)return a;const f=_[i];if(!f)return a;const[p,y]=f.split("-"),l=parseInt(p,10),C=parseInt(y,10);return a.slice(l-1,C)},[a,_,i]);return t("div",{className:`${L.episodeListContainer} ${o==="drawer"?L.drawerContainer:""}`,children:[t("div",{className:`${L.episodeListHeader} ${o==="drawer"?L.drawerHeader:""}`,children:[h,t("h3",{className:L.episodeListTitle,children:u}),_.length>0&&t("div",{className:L.rangeSelector,children:_.map((f,p)=>t("button",{className:`${L.rangeButton} ${i===p?L.active:""}`,onClick:()=>S(p),children:f},f))})]}),t("div",{className:`${L.episodeList} ${o==="drawer"?L.drawerList:""}`,children:T.map(f=>{const p=f.id===r,y=E.has(f.id)||f.watched===!0;return t("div",{ref:p?b:void 0,className:`${L.episodeItem} ${y?L.watched:""} ${p?L.active:""}`,onClick:()=>s(f.id),children:[f.thumbnail&&t("img",{src:f.thumbnail,alt:"",loading:"lazy",decoding:"async",className:L.episodeThumb}),t("span",{className:L.episodeText,children:[t("span",{className:L.episodeLabel,children:f.label??`Episode ${f.id}`}),f.sublabel&&t("span",{className:L.episodeSub,children:f.sublabel})]})]},f.id)})})]})},ws=({variant:e="sidebar",count:r=12})=>t("div",{className:`${L.episodeListContainer} ${e==="drawer"?L.drawerContainer:""}`,children:[t("div",{className:`${L.episodeListHeader} ${e==="drawer"?L.drawerHeader:""}`,children:[t("h3",{className:L.episodeListTitle,children:"Episodes"}),t("div",{className:L.rangeSelector,children:[t(fe,{width:"60px",height:"28px",variant:"rectangular"}),t(fe,{width:"60px",height:"28px",variant:"rectangular"}),t(fe,{width:"60px",height:"28px",variant:"rectangular"})]})]}),t("div",{className:`${L.episodeList} ${e==="drawer"?L.drawerList:""}`,children:Array.from({length:r}).map((n,s)=>t("div",{className:L.episodeItem,style:{border:"none",background:"transparent"},children:t(fe,{width:"120px",height:"1.2rem",variant:"text"})},s))})]}),To="_shell_cys6s_1",Lo="_overlay_cys6s_10",Eo="_drawer_cys6s_21",No="_handle_cys6s_56",Io="_header_cys6s_64",Po="_headerCopy_cys6s_73",$o="_kicker_cys6s_79",Mo="_title_cys6s_87",Fo="_closeBtn_cys6s_94",Ao="_body_cys6s_116",W={shell:To,overlay:Lo,drawer:Eo,handle:No,header:Io,headerCopy:Po,kicker:$o,title:Mo,closeBtn:Fo,body:Ao};function Cs({isOpen:e,onClose:r,episodes:n,currentEpisode:s,watchedEpisodes:o=[],onEpisodeClick:u,title:h,header:i}){return I(()=>{if(!e)return;const S=a=>{a.key==="Escape"&&r()},b=document.body.style.overflow;return document.body.style.overflow="hidden",document.addEventListener("keydown",S),()=>{document.body.style.overflow=b,document.removeEventListener("keydown",S)}},[e,r]),e?St(t("div",{className:W.shell,role:"dialog","aria-modal":"true","aria-label":"Episode picker",children:[t("button",{className:W.overlay,type:"button",onClick:r,"aria-label":"Close episodes"}),t("aside",{className:W.drawer,children:[t("div",{className:W.handle}),t("div",{className:W.header,children:[t("div",{className:W.headerCopy,children:[t("span",{className:W.kicker,children:"Episode picker"}),t("h3",{className:W.title,children:"Choose an episode"})]}),t("button",{className:W.closeBtn,type:"button",onClick:r,"aria-label":"Close",children:t(U,{name:"times"})})]}),t("div",{className:W.body,children:t(xo,{episodes:n,currentEpisode:s,watchedEpisodes:o,onEpisodeClick:u,variant:"drawer",title:h,header:i})})]})]}),document.body):null}function xe(){return document}function Ve(e){const r=xe();if(document.fullscreenElement)return document.fullscreenElement;if(r.webkitFullscreenElement)return r.webkitFullscreenElement;const n=e;return n?.webkitDisplayingFullscreen?n:null}function oe(e){return Ve(e)!==null}async function Ro(e,r){if(Ve(r))return;const n=e;try{if(typeof e.requestFullscreen=="function"){await e.requestFullscreen();return}if(typeof n.webkitRequestFullscreen=="function"){await n.webkitRequestFullscreen();return}if(typeof n.webkitRequestFullScreen=="function"){await n.webkitRequestFullScreen();return}}catch{}const s=r;if(s&&typeof s.webkitEnterFullscreen=="function"){if(s.webkitSupportsFullscreen===!1)return;try{await s.webkitEnterFullscreen()}catch{}}}async function Oo(e){const r=xe();try{if(document.fullscreenElement&&typeof document.exitFullscreen=="function"){await document.exitFullscreen();return}if(r.webkitFullscreenElement&&typeof r.webkitExitFullscreen=="function"){await r.webkitExitFullscreen();return}}catch{}const n=e;if(n?.webkitDisplayingFullscreen&&typeof n.webkitExitFullscreen=="function"){try{n.webkitExitFullscreen()}catch{}return}try{typeof r.webkitCancelFullScreen=="function"?r.webkitCancelFullScreen():!document.fullscreenElement&&typeof document.exitFullscreen=="function"&&(document.fullscreenElement??r.webkitFullscreenElement)&&await document.exitFullscreen()}catch{}}async function Do(e,r){!e&&!r||(oe(r)?await Oo(r):e&&await Ro(e,r))}function qo(e,r){const n=()=>{try{r(oe(e()))}catch{}},s=xe(),o=n;s.addEventListener("fullscreenchange",n),s.addEventListener("webkitfullscreenchange",o),s.addEventListener("webkitbeginfullscreen",o,!0),s.addEventListener("webkitendfullscreen",o,!0);const u=e();return u?.addEventListener("webkitbeginfullscreen",o),u?.addEventListener("webkitendfullscreen",o),()=>{s.removeEventListener("fullscreenchange",n),s.removeEventListener("webkitfullscreenchange",o),s.removeEventListener("webkitbeginfullscreen",o,!0),s.removeEventListener("webkitendfullscreen",o,!0),u?.removeEventListener("webkitbeginfullscreen",o),u?.removeEventListener("webkitendfullscreen",o)}}const Ss=({skipIntervals:e,showId:r,episodeNumber:n,episodeCount:s,sourceType:o,showMeta:u})=>{const h=Bt(),i=g(null),S=g(null),b=g(null),a=g(null),E=g(!1),_=g(null),T=g(0),f=g(1),p=g({mouse:!1,keyboard:!1}),y=g(null),l=g(null),C=g(!1),d=g(Math.random().toString(36).substring(2)),[x,$]=w(!1),[O,M]=w(()=>{try{return localStorage.getItem("playerMuted")==="true"}catch{return!1}}),[m,F]=w(()=>{try{const c=parseFloat(localStorage.getItem("playerVolume")||"");return isNaN(c)?1:Math.max(0,Math.min(1,c))}catch{return 1}}),[J,H]=w(!1),[D,se]=w(0),[Ue,z]=w(!0),[ie,Te]=w(!1),[Ke,Le]=w({time:0,position:null}),[me,Ge]=w(localStorage.getItem("autoSkipEnabled")==="true"),[Je,he]=w(null),[Qe,Xe]=w(!1),[G]=w(Jr),[je,Ye]=w(G.fontSize),[Ze,et]=w(G.position),[tt,nt]=w(G.bgOpacity),[rt,ot]=w(G.bgColor),[st,it]=w(G.textColor),[ct,at]=w(G.edge),[lt,ut]=w(G.bold),[dt,pt]=w([]),[ft,_t]=w(null),[mt,ht]=w(!1),[gt,yt]=w(!1),[vt,ge]=w(!1),[bt,ce]=w(!1),[wt,Ee]=w(()=>{try{return localStorage.getItem("playerUseNativeControls")==="true"}catch{return!1}}),Y=g(!1),ye=g(-1),ae=N(()=>{const c=i.current;return!r||!n||!u?.name?null:{showId:r,episodeNumber:n,episodeCount:s,currentTime:c?c.currentTime:0,duration:c?c.duration:0,showName:u.name,showThumbnail:u.thumbnail,nativeName:u.names?.native,englishName:u.names?.english,genres:Array.isArray(u.genres)?u.genres.map(v=>typeof v=="string"?v:v?.name).filter(Boolean):void 0,popularityScore:u.score,type:u.type,isPlaying:c?!c.paused:!0,sessionId:d.current,isAdult:u.isAdult}},[r,n,s,u]),A=N((c=!1,v=!1)=>{if(Y.current)return!1;const k=ae();if(!k)return!1;const P=i.current;if(!P&&o!=="iframe")return!1;const R=P?P.currentTime>=P.duration*.8:!1;let V=P?P.currentTime:0;if(c&&R&&(V=P?P.duration:0),!v){if(V===0&&!R)return!1;const ee=P?Math.abs(V-ye.current):0;if(!c&&P&&V!==P.duration&&ee<5)return!1}return k.currentTime=V,ye.current=V,c?(async()=>{try{await ve("/api/update-progress",{method:"POST",body:JSON.stringify(k)}),h.invalidateQueries({queryKey:["video-sources",r,n]}),h.invalidateQueries({queryKey:["allContinueWatching"]}),h.invalidateQueries({queryKey:["thisWeekSchedule"]})}catch(ee){console.error("Failed to update progress:",ee)}})():ve("/api/update-progress",{method:"POST",body:JSON.stringify(k),keepalive:!0}).catch(ee=>console.error("Failed to update progress:",ee)),!0},[ae,o,h,r,n]);I(()=>{const c=i.current;c&&(c.volume=m,c.muted=O)},[i,m,O]),I(()=>{const c=()=>{Y.current||A(!0)};window.addEventListener("beforeunload",c);const v=_,k=a;return()=>{window.removeEventListener("beforeunload",c),Y.current||A(!0),v.current&&clearTimeout(v.current),k.current&&clearTimeout(k.current)}},[A]);const le=N(()=>{const c=S.current;c&&Do(c,i.current).catch(v=>{console.error(`Error attempting to toggle full-screen mode: ${v?.message} (${v?.name})`)})},[]),ue=N(()=>{i.current&&(i.current.paused?i.current.play().catch(()=>console.warn("Autoplay was prevented.")):(i.current.pause(),z(!0)))},[z]),Q=N(()=>{const c=i.current;if(!c)return;const v=p.current.mouse||p.current.keyboard;c.playbackRate=v?2:f.current},[]),de=N(c=>{p.current.mouse!==c&&(p.current.mouse=c,ce(c||p.current.keyboard),Q())},[Q]),X=N(c=>{p.current.keyboard!==c&&(p.current.keyboard=c,ce(p.current.mouse||c),Q())},[Q]),Z=N(c=>{i.current&&(i.current.currentTime+=c,_.current&&clearTimeout(_.current),_.current=setTimeout(()=>{A(!1,!0)},1500),z(!0))},[A,z]),pe=N(()=>{if(!i.current)return;const c=!i.current.muted;i.current.muted=c,M(c),localStorage.setItem("playerMuted",String(c)),!c&&i.current.volume===0&&(i.current.volume=.5,F(.5),localStorage.setItem("playerVolume",String(.5))),z(!0)},[z]);I(()=>{const c=()=>i.current,v=qo(c,k=>{H(k),k&&z(!0)});return H(oe(c())),v},[z]),I(()=>{const c=k=>{if(!k.target.closest('input, textarea, button, select, a, [role="button"], [contenteditable="true"]')){if(k.code==="Space"){if(k.preventDefault(),C.current)return;C.current=!0,l.current&&clearTimeout(l.current),l.current=window.setTimeout(()=>{l.current=null,C.current&&X(!0)},180);return}switch(k.key.toLowerCase()){case"f":le();break;case"m":pe();break;case"arrowright":Z(10);break;case"arrowleft":Z(-10);break;case"arrowup":if(k.preventDefault(),i.current){const R=Math.min(1,i.current.volume+.1);i.current.volume=R,F(R)}break;case"arrowdown":if(k.preventDefault(),i.current){const R=Math.max(0,i.current.volume-.1);i.current.volume=R,F(R)}break}}},v=k=>{if(k.code==="Space"){if(k.preventDefault(),C.current=!1,p.current.keyboard){X(!1);return}l.current&&(clearTimeout(l.current),l.current=null,ue())}};return document.addEventListener("keydown",c),document.addEventListener("keyup",v),()=>{document.removeEventListener("keydown",c),document.removeEventListener("keyup",v),l.current&&(clearTimeout(l.current),l.current=null),C.current=!1,X(!1),ce(!1)}},[X,ue,le,pe,Z]),I(()=>{const c=P=>{if(P.button!==0)return;const R=P.target;if(!R||R.closest('[data-speed-boost-ignore="true"]'))return;const V=S.current;!V||!V.contains(R)||(y.current&&clearTimeout(y.current),y.current=window.setTimeout(()=>{y.current=null,de(!0)},180))},v=()=>{y.current&&(clearTimeout(y.current),y.current=null),de(!1)},k=()=>{y.current&&(clearTimeout(y.current),y.current=null),C.current=!1,l.current&&(clearTimeout(l.current),l.current=null),X(!1),de(!1),ce(!1)};return document.addEventListener("mousedown",c),document.addEventListener("mouseup",v),window.addEventListener("blur",k),()=>{document.removeEventListener("mousedown",c),document.removeEventListener("mouseup",v),window.removeEventListener("blur",k),y.current&&(clearTimeout(y.current),y.current=null)}},[X,de]);const Ne=N(()=>{$(!0),ge(!1),setTimeout(()=>A(!1,!0),50)},[A]),Ie=N(()=>{ge(!1)},[]),Pe=N(()=>{ge(!0)},[]),$e=N(()=>{$(!1),z(!0),setTimeout(()=>A(!1,!0),50)},[A]);I(()=>{Y.current=!1,ye.current=-1,T.current=0,d.current=Math.random().toString(36).substring(2)},[r,n]),I(()=>{const c=d.current;return()=>{const v=JSON.stringify({sessionId:c}),k=new Blob([v],{type:"application/json"});navigator.sendBeacon("/api/discord/clear",k)}},[r,n]),I(()=>{if(o!=="iframe")return;A(!1,!0);const c=setInterval(()=>{A(!1,!0)},6e4);return()=>clearInterval(c)},[o,A]);const Me=N(()=>{se(i.current?.duration||0),Q()},[Q]),Fe=N(()=>{if(i.current){const c=i.current.muted,v=i.current.volume;M(c),F(v),localStorage.setItem("playerMuted",String(c)),localStorage.setItem("playerVolume",String(v))}},[]),Ae=N(()=>{},[]),Re=N(()=>{const c=i.current;if(!c)return;const v=c.currentTime||0,k=Date.now();k-T.current>6e4&&A()&&(T.current=k);const P=e.find(R=>v>=R.start_time&&v<R.end_time)||null;he(R=>R?.skip_id!==P?.skip_id?P:R),me&&P&&!c.paused&&(c.currentTime=P.end_time,he(null))},[e,me,A]),Oe=N(()=>{const c=ae();c&&(c.currentTime=c.duration,ve("/api/update-progress",{method:"POST",body:JSON.stringify(c)}).then(()=>{h.invalidateQueries({queryKey:["video-sources",r,n]}),h.invalidateQueries({queryKey:["allContinueWatching"]})}).catch(v=>console.error("Failed to send final progress:",v)))},[ae,h,r,n]),De=N(()=>{Y.current=!0,Oe()},[Oe]);I(()=>{const c=()=>{ie&&(Te(!1),Le({time:0,position:null}),E.current&&i.current?.play(),A(!1,!0))};return ie&&document.addEventListener("mouseup",c),()=>{document.removeEventListener("mouseup",c)}},[ie,A]);const Ct=re(()=>({togglePlay:ue,seek:Z,toggleMute:pe,toggleFullscreen:le,onPlay:Ne,onPause:$e,onLoadedMetadata:Me,formatTime:kt,onVolumeChange:Fe,onProgress:Ae,onTimeUpdate:Re,onEnded:De,setShowControls:z,setIsScrubbing:Te,setHoverTime:Le,setIsAutoSkipEnabled:Ge,setCurrentSkipInterval:he,setShowCCMenu:Xe,setSubtitleFontSize:Ye,setSubtitlePosition:et,setSubtitleBgOpacity:nt,setSubtitleBgColor:ot,setSubtitleTextColor:it,setSubtitleEdge:at,setSubtitleBold:ut,setAvailableSubtitles:pt,setActiveSubtitleTrack:_t,setShowSettings:ht,setShowVolumeSlider:yt,wasPlayingBeforeScrub:E,inactivityTimer:a,setIsFullscreen:H,onWaiting:Pe,onPlaying:Ie,sendProgressUpdate:A,setUseNativeControls:Ee}),[ue,Z,pe,le,Ne,$e,Me,Fe,Ae,Re,De,H,Pe,Ie,A,Ee]);return{refs:{videoRef:i,playerContainerRef:S,progressBarRef:b},state:{isPlaying:x,isMuted:O,volume:m,isFullscreen:J,duration:D,showControls:Ue,isScrubbing:ie,hoverTime:Ke,isAutoSkipEnabled:me,currentSkipInterval:Je,showCCMenu:Qe,subtitleFontSize:je,subtitlePosition:Ze,subtitleBgOpacity:tt,subtitleBgColor:rt,subtitleTextColor:st,subtitleEdge:ct,subtitleBold:lt,availableSubtitles:dt,activeSubtitleTrack:ft,showSettings:mt,showVolumeSlider:gt,isBuffering:vt,isSpeedBoostActive:bt,useNativeControls:wt},actions:Ct}};function Ho(){try{return typeof navigator<"u"&&/android/i.test(navigator.userAgent)}catch{return!1}}function ks(e,r){const{state:n,refs:s,actions:o}=e,u=g(r);u.current=r;const h=g(!1);I(()=>{if(!Ho())return;let i=null;const S=()=>i?i.matches:window.innerWidth>window.innerHeight,b=()=>{const a=s.playerContainerRef.current;if(S()){if(!u.current||!a||oe(s.videoRef.current))return;h.current=!0,o.toggleFullscreen()}else h.current&&(h.current=!1,oe(s.videoRef.current)&&o.toggleFullscreen())};try{i=window.matchMedia("(orientation: landscape)"),i.addEventListener?i.addEventListener("change",b):i.addListener(b)}catch{}return b(),()=>{try{i&&(i.removeEventListener?i.removeEventListener("change",b):i.removeListener(b))}catch{}}},[o,s.playerContainerRef,s.videoRef,r]),I(()=>{n.isFullscreen||(h.current=!1)},[n.isFullscreen])}const zo=e=>Math.max(8,Math.min(40,Math.ceil(e/16.7)+4));function Bs({videoRef:e,canvasRef:r,delayMs:n,enabled:s}){const o=g(n);o.current=n;const u=g([]),h=g(-1),i=g(-1),S=g(!1),b=g(0),a=g(null);I(()=>{const E=l=>{if(l)try{l.close()}catch{}},_=()=>{for(const l of u.current)E(l.bitmap);u.current=[]};if(!s){_(),h.current=-1,i.current=-1,S.current=!1,b.current=0;return}let T=!1;const f=()=>{a.current!==null&&(cancelAnimationFrame(a.current),a.current=null)},p=()=>{T||(f(),a.current=requestAnimationFrame(()=>{y()}))};async function y(){if(T)return;const l=e.current,C=r.current;if(!l||!C||l.videoWidth===0){p();return}if(l.paused||l.ended||document.hidden||l.readyState<HTMLMediaElement.HAVE_CURRENT_DATA){p();return}const d=l.getVideoPlaybackQuality().totalVideoFrames;if(d===h.current){p();return}(l.seeking||i.current>=0&&Math.abs(l.currentTime-i.current)>.5)&&(_(),S.current=!1,b.current=0,h.current=-1),i.current=l.currentTime,(C.width!==l.videoWidth||C.height!==l.videoHeight)&&(C.width=l.videoWidth,C.height=l.videoHeight);const x=Math.max(0,o.current||0);x>b.current&&(S.current=!1);try{const $=await createImageBitmap(l);if(T){E($);return}h.current=d;const O=performance.now(),M=C.getContext("2d"),m=D=>{M&&M.drawImage(D,0,0,C.width,C.height)};if(x<=0){_(),S.current=!1,b.current=0,m($),E($),p();return}const F=u.current;F.push({bitmap:$,capture:O});const J=zo(x);for(;F.length>J;)E(F.shift()?.bitmap);let H=-1;for(let D=F.length-1;D>=0;D--)if(O-F[D].capture>=x){H=D;break}if(H!==-1){for(let se=0;se<H;se++)E(F.shift()?.bitmap);const D=F.shift();D?(m(D.bitmap),E(D.bitmap),S.current=!0,b.current=x):m($)}else if(!S.current)m($);else{const D=F.shift();D?(m(D.bitmap),E(D.bitmap)):m($)}}catch{}p()}return p(),()=>{T=!0,f();for(const l of u.current)try{l.bitmap.close()}catch{}u.current=[]}},[s,e,r])}const Wo="_row_1fq55_1",Vo="_rowHeader_1fq55_9",Uo="_rowLabel_1fq55_17",Ko="_rowValue_1fq55_28",Go="_slider_1fq55_36",Jo="_swatches_1fq55_99",Qo="_swatch_1fq55_99",Xo="_swatchPicked_1fq55_114",jo="_colorInput_1fq55_120",Yo="_segmented_1fq55_131",q={row:Wo,rowHeader:Vo,rowLabel:Uo,rowValue:Ko,slider:Go,swatches:Jo,swatch:Qo,swatchPicked:Xo,colorInput:jo,segmented:Yo},Zo=({label:e,display:r,min:n,max:s,step:o,value:u,percent:h,onChange:i,onCommit:S})=>t("div",{className:q.row,children:[t("div",{className:q.rowHeader,children:[t("span",{className:q.rowLabel,children:e}),t("span",{className:q.rowValue,children:r})]}),t("input",{type:"range",className:q.slider,min:n,max:s,step:o,value:u,"aria-label":e,onInput:b=>i(Number(b.target.value)),onPointerUp:S,onTouchEnd:S,onKeyUp:S,onBlur:S,style:{"--slider-percent":`${h}%`}})]}),xs=({label:e,colors:r,value:n,onChange:s})=>t("div",{className:q.row,children:[t("div",{className:q.rowHeader,children:t("span",{className:q.rowLabel,children:e})}),t("div",{className:q.swatches,children:[r.map(o=>t("button",{type:"button","aria-label":`${e} ${o}`,"aria-pressed":n.toLowerCase()===o.toLowerCase(),onClick:()=>s(o),className:`${q.swatch} ${n.toLowerCase()===o.toLowerCase()?q.swatchPicked:""}`,style:{backgroundColor:o}},o)),t("input",{type:"color","aria-label":`Custom ${e.toLowerCase()}`,className:q.colorInput,value:n,onInput:o=>s(o.target.value)})]})]});function Ts({label:e,options:r,value:n,onChange:s}){return t("div",{className:q.row,children:[t("div",{className:q.rowHeader,children:t("span",{className:q.rowLabel,children:e})}),t("div",{className:q.segmented,role:"group","aria-label":e,children:r.map(o=>t("button",{type:"button","aria-pressed":n===o,onClick:()=>s(o),children:[t("span",{children:o}),n===o&&t(U,{name:"check",size:10})]},o))})]})}const _e=10,Be=500,Ce=e=>Math.max(0,Math.min(Be,Math.round(e))),Ls=({isOpen:e,ms:r,onChange:n,onApply:s,onClose:o,testClipActive:u,onTestClip:h})=>e?t("div",{role:"dialog","aria-label":"Calibrate audio video sync","data-speed-boost-ignore":"true",onClick:i=>i.stopPropagation(),style:{position:"absolute",right:8,bottom:112,width:"min(260px, calc(100% - 16px))",maxHeight:"calc(100% - 124px)",overflowY:"auto",overflowX:"hidden",zIndex:60,display:"flex",flexDirection:"column",alignItems:"center",gap:8,padding:12,borderRadius:"var(--radius-lg)",border:"1px solid var(--glass-border)",background:"rgba(18, 18, 22, 0.95)",boxShadow:"var(--glass-shadow)",backdropFilter:"blur(14px)",WebkitBackdropFilter:"blur(14px)",boxSizing:"border-box"},children:[t("div",{style:{fontSize:"0.8rem",fontWeight:800,color:"var(--text-primary)"},children:"A/V sync"}),t("div",{children:t(te,{size:"sm",variant:"secondary",onClick:h,children:u?"Back to video":"Preview test clip"})}),t("div",{style:{display:"flex",alignItems:"center",justifyContent:"center",gap:6,flexWrap:"wrap"},children:[t(te,{size:"sm",onClick:()=>n(Ce(r-_e)),"aria-label":"Decrease delay by 10 milliseconds",children:["− ",_e,"ms"]}),t("div",{style:{fontSize:"1.1rem",fontWeight:800,minWidth:64,textAlign:"center"},children:[r,"ms"]}),t(te,{size:"sm",onClick:()=>n(Ce(r+_e)),"aria-label":"Increase delay by 10 milliseconds",children:["+ ",_e,"ms"]})]}),t(Zo,{label:"Video delay",display:`${r}ms`,min:0,max:Be,step:5,value:r,percent:r/Be*100,onChange:i=>n(Ce(i))}),t("div",{style:{display:"flex",gap:8,justifyContent:"center",flexWrap:"wrap"},children:[t(te,{size:"sm",variant:"secondary",onClick:o,children:"Cancel"}),t(te,{size:"sm",onClick:s,children:["Apply ",r,"ms"]})]})]}):null;export{Ls as A,fs as B,hs as C,K as D,ws as E,Zo as M,bs as P,gs as S,ps as T,vs as U,ys as a,Bs as b,ks as c,as as d,ls as e,_s as f,ms as g,ds as h,xo as i,ss as j,j as k,is as l,Cs as m,xs as n,Ts as o,cs as p,us as r,Kr as s,Ss as u};
|