@serifpersia/dango 3.6.7 → 3.6.9
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-C3P9zWi9.js → AnimeCard-DKDJK8Mp.js} +1 -1
- package/client/dist/assets/{AnimeInfo-Et6687Tl.js → AnimeInfo-CTcvfjva.js} +1 -1
- package/client/dist/assets/{AnimeInfoPage-DX4eNnlH.js → AnimeInfoPage-B_UiacIN.js} +2 -2
- package/client/dist/assets/{Asmr-CCdEWrFi.js → Asmr-DMSN2vxl.js} +2 -2
- package/client/dist/assets/{AsmrResetProgressModal-DgEWBJOw.js → AsmrResetProgressModal-CRwfOatX.js} +1 -1
- package/client/dist/assets/{AvSyncCalibrator-CQ2fjf2E.js → AvSyncCalibrator-CRJsi-vz.js} +1 -1
- package/client/dist/assets/{Home-DUkUTTTy.js → Home-pwmK9_Eh.js} +1 -1
- package/client/dist/assets/{Insights-QCh4xW12.js → Insights-m7kFzg2A.js} +1 -1
- package/client/dist/assets/{LibraryListPage-BoTxRqHz.js → LibraryListPage-C1wpPvu6.js} +1 -1
- package/client/dist/assets/ListeningList-OzfEI1Ga.js +1 -0
- package/client/dist/assets/{Manga-HydR-L7o.js → Manga-ChRCExhK.js} +1 -1
- package/client/dist/assets/{MangaInfoPage-CBakEI9a.js → MangaInfoPage-DSHJPo2A.js} +1 -1
- package/client/dist/assets/{MangaReadPage-DwAR3iPy.js → MangaReadPage-CzOVY1wA.js} +1 -1
- package/client/dist/assets/{MangaResetProgressModal-DGzl8vsO.js → MangaResetProgressModal-CJfzdUBb.js} +1 -1
- package/client/dist/assets/{Mature-Pi0TxKuF.js → Mature-CifQMfhs.js} +1 -1
- package/client/dist/assets/{MediaCard--cuFxOCS.js → MediaCard-CM10yB9V.js} +1 -1
- package/client/dist/assets/{OptionListMenu-B3D39dGS.js → OptionListMenu-6Kovbsqw.js} +1 -1
- package/client/dist/assets/{Player-CsH4x_I_.js → Player-CK0hT-u4.js} +2 -2
- package/client/dist/assets/{PlayerSettings-DGxBsi3F.js → PlayerSettings-Bb66uqT9.js} +1 -1
- package/client/dist/assets/{QueueOptionsButton-Djq4Cpex.js → QueueOptionsButton-C_nTj8_q.js} +1 -1
- package/client/dist/assets/{QueueRail-DOrYgNVX.js → QueueRail-DUK7URAE.js} +1 -1
- package/client/dist/assets/{ReadingList-DwYoBrNk.js → ReadingList-Ck9LJThU.js} +1 -1
- package/client/dist/assets/{ResetProgressModal-CMF86mX6.js → ResetProgressModal-BUphIv0k.js} +1 -1
- package/client/dist/assets/{Search-DFkhuk-x.js → Search-zJyP15h6.js} +1 -1
- package/client/dist/assets/{Settings-DBB2r0VQ.js → Settings-BYdoSEUh.js} +1 -1
- package/client/dist/assets/{SkeletonGrid-DJelJgAv.js → SkeletonGrid-CqgbOhjX.js} +1 -1
- package/client/dist/assets/{Trackers-DGYXFhYZ.js → Trackers-BVjyv6CM.js} +1 -1
- package/client/dist/assets/{Tv-C5MDGD2Z.js → Tv-L13ylswR.js} +1 -1
- package/client/dist/assets/{TvInfo-DrKuK13u.js → TvInfo-Cvcm5U2D.js} +1 -1
- package/client/dist/assets/{TvPopup-DtHilRDT.js → TvPopup-DhxfKvYm.js} +1 -1
- package/client/dist/assets/{TvSearch-CzNxdu_w.js → TvSearch-P8bFE6_X.js} +1 -1
- package/client/dist/assets/{TvWatchlist-D7p4br6S.js → TvWatchlist-D5gVPjtb.js} +1 -1
- package/client/dist/assets/{Watchlist-DrOzswl2.js → Watchlist-Cjq8l3rU.js} +1 -1
- package/client/dist/assets/{hls-BGCX7mJy.js → hls-BkzuANAg.js} +1 -1
- package/client/dist/assets/{index-CnfZwsds.js → index-CLVgzKLk.js} +19 -19
- package/client/dist/assets/{useAnimeInfoData-DYXWBPF-.js → useAnimeInfoData-DZJZu-so.js} +1 -1
- package/client/dist/assets/{useAsmr-BbhQ59bk.js → useAsmr-CvrMGHuo.js} +1 -1
- package/client/dist/assets/useAsmrPopup-Bimy8Ouw.js +1 -0
- package/client/dist/assets/{useMangaLibrary-DuesWQaE.js → useMangaLibrary--MiN11uR.js} +1 -1
- package/client/dist/assets/{useMangaPopup-D57OVGUr.js → useMangaPopup-CR5XhKKS.js} +1 -1
- package/client/dist/assets/{useProviders-mpQb_dix.js → useProviders-DqdT4fA5.js} +1 -1
- package/client/dist/assets/{useTv-DGflCsSI.js → useTv-BL0HMDyP.js} +1 -1
- package/client/dist/assets/{useTvLibrary-BqeSmyc4.js → useTvLibrary-D4U4iqN8.js} +1 -1
- package/client/dist/index.html +1 -1
- package/package.json +3 -5
- package/server/dist/config.js +1 -174
- package/server/dist/server.js +1068 -289
- package/server/dist/shipped-defaults.js +1 -6
- package/server/package.json +4 -5
- package/client/dist/assets/Asmr.module-CdWlioTY.js +0 -1
- package/client/dist/assets/ListeningList-DguKjI_t.js +0 -1
- package/client/dist/assets/Music-BGH_0voi.css +0 -1
- package/client/dist/assets/Music-CQpyXTLH.js +0 -1
- package/client/dist/assets/Radio-CCHNFN7R.css +0 -1
- package/client/dist/assets/Radio-DF6g6odd.js +0 -1
- package/client/dist/assets/Radio.module-DGSZLpKM.js +0 -1
- package/client/dist/assets/useAsmrPopup-SymV1J-b.js +0 -1
- package/server/dist/app-auth.js +0 -157
- package/server/dist/app-hono.js +0 -598
- package/server/dist/db/drizzle.js +0 -16
- package/server/dist/db/schema-anime.js +0 -61
- package/server/dist/db/schema-asmr.js +0 -13
- package/server/dist/db/schema-manga.js +0 -31
- package/server/dist/db/schema-tv.js +0 -18
- package/server/dist/db.js +0 -217
- package/server/dist/discord-gateway.js +0 -385
- package/server/dist/discord-rpc.js +0 -413
- package/server/dist/github-sync.js +0 -508
- package/server/dist/google.js +0 -741
- package/server/dist/hono/asmr.js +0 -10
- package/server/dist/hono/auth.js +0 -49
- package/server/dist/hono/music.js +0 -209
- package/server/dist/hono/proxy.js +0 -827
- package/server/dist/hono/tv.js +0 -200
- package/server/dist/hono/watchlist.js +0 -341
- package/server/dist/lib/anilist.js +0 -1583
- package/server/dist/lib/anischedule.js +0 -191
- package/server/dist/lib/insights.js +0 -185
- package/server/dist/lib/ipc.js +0 -23
- package/server/dist/lib/kitsu.js +0 -517
- package/server/dist/lib/mal-import.js +0 -291
- package/server/dist/lib/mal.js +0 -957
- package/server/dist/lib/migration.js +0 -310
- package/server/dist/lib/offline-db.js +0 -395
- package/server/dist/lib/potoken.js +0 -135
- package/server/dist/lib/recommendations.service.js +0 -216
- package/server/dist/lib/temp-ids.js +0 -3
- package/server/dist/lib/tmdb.js +0 -72
- package/server/dist/lib/tracker/anilist-tracker.js +0 -308
- package/server/dist/lib/tracker/manga-sync.service.js +0 -773
- package/server/dist/lib/tracker/sync-state.js +0 -21
- package/server/dist/lib/tracker/sync.service.js +0 -476
- package/server/dist/lib/translate.js +0 -79
- package/server/dist/lib/ump.js +0 -106
- package/server/dist/lib/ytmusic.js +0 -162
- package/server/dist/logger.js +0 -16
- package/server/dist/providers/manga/manga.types.js +0 -1
- package/server/dist/providers/provider.interface.js +0 -1
- package/server/dist/providers/remote-loader.js +0 -614
- package/server/dist/providers/remote-types.js +0 -159
- package/server/dist/providers/title-matching.js +0 -226
- package/server/dist/providers/tv.types.js +0 -1
- package/server/dist/rclone.js +0 -120
- package/server/dist/repositories/asmr.repository.js +0 -77
- package/server/dist/repositories/insights.repository.js +0 -106
- package/server/dist/repositories/library.repository.js +0 -94
- package/server/dist/repositories/mal-cache.repository.js +0 -52
- package/server/dist/repositories/manga.repository.js +0 -95
- package/server/dist/repositories/notifications.repository.js +0 -60
- package/server/dist/repositories/queue.repository.js +0 -72
- package/server/dist/repositories/settings.repository.js +0 -30
- package/server/dist/repositories/shows-meta.repository.js +0 -58
- package/server/dist/repositories/temp-show-ids.repository.js +0 -63
- package/server/dist/repositories/tv.repository.js +0 -93
- package/server/dist/repositories/watched-episodes.repository.js +0 -82
- package/server/dist/repositories/watchlist.repository.js +0 -60
- package/server/dist/scripts/backfill-episode-duration.js +0 -42
- package/server/dist/sync-payload.js +0 -91
- package/server/dist/sync.js +0 -657
- package/server/dist/trpc/context.js +0 -7
- package/server/dist/trpc/errors.js +0 -15
- package/server/dist/trpc/index.js +0 -18
- package/server/dist/trpc/router.js +0 -49
- package/server/dist/trpc/routers/asmr-library.js +0 -112
- package/server/dist/trpc/routers/asmr-progress.js +0 -121
- package/server/dist/trpc/routers/asmr.js +0 -87
- package/server/dist/trpc/routers/auth.js +0 -194
- package/server/dist/trpc/routers/continue-watching.js +0 -81
- package/server/dist/trpc/routers/data.js +0 -1026
- package/server/dist/trpc/routers/discord.js +0 -285
- package/server/dist/trpc/routers/discovery.js +0 -11
- package/server/dist/trpc/routers/insights.js +0 -14
- package/server/dist/trpc/routers/manga-library.js +0 -263
- package/server/dist/trpc/routers/manga-progress.js +0 -169
- package/server/dist/trpc/routers/manga.js +0 -201
- package/server/dist/trpc/routers/music.js +0 -655
- package/server/dist/trpc/routers/notifications.js +0 -80
- package/server/dist/trpc/routers/progress.js +0 -109
- package/server/dist/trpc/routers/queue.js +0 -93
- package/server/dist/trpc/routers/radio.js +0 -145
- package/server/dist/trpc/routers/settings.js +0 -96
- package/server/dist/trpc/routers/tracker.js +0 -213
- package/server/dist/trpc/routers/tv-library.js +0 -135
- package/server/dist/trpc/routers/tv-progress.js +0 -159
- package/server/dist/trpc/routers/tv.js +0 -551
- package/server/dist/trpc/routers/watchlist.js +0 -550
- package/server/dist/trpc/validation.js +0 -258
- package/server/dist/utils/cache.utils.js +0 -25
- package/server/dist/utils/cookie.utils.js +0 -13
- package/server/dist/utils/db-utils.js +0 -17
- package/server/dist/utils/env.utils.js +0 -77
- package/server/dist/utils/http.utils.js +0 -82
- package/server/dist/utils/request-context.js +0 -2
- package/server/dist/utils/security.utils.js +0 -76
- /package/client/dist/assets/{Asmr-D1KuQwQy.css → useAsmrPopup-D1KuQwQy.css} +0 -0
|
@@ -1,6 +1 @@
|
|
|
1
|
-
export
|
|
2
|
-
"GITHUB_CLIENT_ID": "Ov23liT1ZtPk7XtN9PZk",
|
|
3
|
-
"GOOGLE_AUTH_WORKER_URL": "https://google-auth-client.ramiserifpersia.workers.dev",
|
|
4
|
-
"DISCORD_CLIENT_ID": "1512253778022367426",
|
|
5
|
-
"PROVIDER_REPO_URL": "https://raw.githubusercontent.com/serifpersia/dango-providers/main/registry.json"
|
|
6
|
-
};
|
|
1
|
+
const t={GITHUB_CLIENT_ID:"Ov23liT1ZtPk7XtN9PZk",GOOGLE_AUTH_WORKER_URL:"https://google-auth-client.ramiserifpersia.workers.dev",DISCORD_CLIENT_ID:"1512253778022367426",PROVIDER_REPO_URL:"https://raw.githubusercontent.com/serifpersia/dango-providers/main/registry.json"};export{t as SHIPPED_DEFAULTS};
|
package/server/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "dango-server",
|
|
3
3
|
"private": true,
|
|
4
|
-
"version": "3.6.
|
|
4
|
+
"version": "3.6.9",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
7
7
|
"node": ">=22.12.0"
|
|
@@ -9,7 +9,7 @@
|
|
|
9
9
|
"scripts": {
|
|
10
10
|
"start": "node --max-old-space-size=256 dist/server.js",
|
|
11
11
|
"dev": "tsx watch src/server.ts --dev",
|
|
12
|
-
"build": "tsc",
|
|
12
|
+
"build": "tsc --noEmit && node build.mjs",
|
|
13
13
|
"format": "prettier --write .",
|
|
14
14
|
"lint": "eslint ."
|
|
15
15
|
},
|
|
@@ -19,7 +19,6 @@
|
|
|
19
19
|
"@octokit/rest": "^22.0.1",
|
|
20
20
|
"@trpc/server": "11.19.0",
|
|
21
21
|
"@xhayper/discord-rpc": "^1.3.4",
|
|
22
|
-
"bgutils-js": "^4.0.3",
|
|
23
22
|
"cheerio": "^1.2.0",
|
|
24
23
|
"dotenv": "^17.4.2",
|
|
25
24
|
"drizzle-orm": "1.0.0-rc.4",
|
|
@@ -29,13 +28,13 @@
|
|
|
29
28
|
"jsdom": "^30.1.0",
|
|
30
29
|
"lru-cache": "^11.5.2",
|
|
31
30
|
"pino": "^10.3.1",
|
|
32
|
-
"ws": "^8.18.0"
|
|
33
|
-
"youtubei.js": "^18.1.0"
|
|
31
|
+
"ws": "^8.18.0"
|
|
34
32
|
},
|
|
35
33
|
"devDependencies": {
|
|
36
34
|
"@types/jsdom": "^30.0.0",
|
|
37
35
|
"@types/node": "^22.5.0",
|
|
38
36
|
"@types/ws": "^8.5.10",
|
|
37
|
+
"esbuild": "0.28.2",
|
|
39
38
|
"pino-pretty": "^13.1.1",
|
|
40
39
|
"tsx": "^4.23.13"
|
|
41
40
|
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const o="_sortSelect_16zfo_1",e="_grid_16zfo_11",t="_fetching_16zfo_18",a="_thumbPlaceholder_16zfo_57",_="_asmrCardWrap_16zfo_93",n="_bookmarkBtn_16zfo_98",r="_bookmarked_16zfo_122",l="_popupCover_16zfo_139",s="_statusMsg_16zfo_162",c="_skeletonCard_16zfo_170",p="_skeletonThumb_16zfo_175",i="_skeletonLine_16zfo_181",f="_shimmer_16zfo_188",d="_pagination_16zfo_202",z="_pageBtn_16zfo_210",k="_pageIndicator_16zfo_224",g="_matureToggleWrap_16zfo_229",y="_matureLabel_16zfo_236",m="_translateToggleWrap_16zfo_242",B="_filterTogglesGroup_16zfo_249",h="_filterBar_16zfo_261",T="_filterLabel_16zfo_268",b="_detailOverlay_16zfo_273",u="_detailModal_16zfo_285",w="_detailClose_16zfo_297",L="_detailHeader_16zfo_313",C="_detailCover_16zfo_319",R="_detailInfo_16zfo_328",v="_detailTitle_16zfo_332",A="_detailRj_16zfo_339",I="_metaRow_16zfo_345",S="_metaLabel_16zfo_351",H="_tagChips_16zfo_357",O="_tagChip_16zfo_357",W="_npOverlay_16zfo_373",D="_playerBarDocked_16zfo_388",M="_playerBarDockedHidden_16zfo_402",P="_npOverlayControlsHidden_16zfo_413",j="_npArrow_16zfo_413",G="_npImageCount_16zfo_414",V="_npStage_16zfo_423",x="_sliderViewport_16zfo_439",q="_slide_16zfo_439",E="_slideImg_16zfo_441",F="_npStageBlank_16zfo_460",J="_sliderTrack_16zfo_479",K="_slideImgLoaded_16zfo_512",N="_slideSpinner_16zfo_517",Q="_npArrowLeft_16zfo_567",U="_npArrowRight_16zfo_571",X="_chapterPanel_16zfo_588",Y="_chapterRow_16zfo_603",Z="_chapterRowActive_16zfo_622",$="_chapterRowTime_16zfo_626",oo="_chapterRowLabel_16zfo_637",eo="_npBackdrop_16zfo_643",to="_playerBtn_16zfo_649",ao="_playerBtnActive_16zfo_649",_o="_tracksSection_16zfo_655",no="_tracksHeading_16zfo_659",ro="_trackList_16zfo_665",lo="_trackRow_16zfo_674",so="_trackIcon_16zfo_692",co="_trackLabel_16zfo_697",po="_trackType_16zfo_702",io="_noTracks_16zfo_707",fo="_playAllBtn_16zfo_712",zo="_detailActions_16zfo_725",ko="_playerBar_16zfo_388",go="_playerActions_16zfo_748",yo="_playerInfo_16zfo_754",mo="_playerTitle_16zfo_759",Bo="_playerTrack_16zfo_768",ho="_playerControls_16zfo_774",To="_seekRow_16zfo_781",bo="_playerButtons_16zfo_789",uo="_seekBtn_16zfo_824",wo="_seekBtnLabel_16zfo_829",Lo="_playBtn_16zfo_834",Co="_seekBar_16zfo_881",Ro="_volumeBar_16zfo_882",vo="_timeLabel_16zfo_974",Ao="_playerRight_16zfo_980",Io="_volumeIcon_16zfo_986",So="_playerToggle_16zfo_1030",Ho={sortSelect:o,grid:e,fetching:t,thumbPlaceholder:a,asmrCardWrap:_,bookmarkBtn:n,bookmarked:r,popupCover:l,statusMsg:s,skeletonCard:c,skeletonThumb:p,skeletonLine:i,shimmer:f,pagination:d,pageBtn:z,pageIndicator:k,matureToggleWrap:g,matureLabel:y,translateToggleWrap:m,filterTogglesGroup:B,filterBar:h,filterLabel:T,detailOverlay:b,detailModal:u,detailClose:w,detailHeader:L,detailCover:C,detailInfo:R,detailTitle:v,detailRj:A,metaRow:I,metaLabel:S,tagChips:H,tagChip:O,npOverlay:W,playerBarDocked:D,playerBarDockedHidden:M,npOverlayControlsHidden:P,npArrow:j,npImageCount:G,npStage:V,sliderViewport:x,slide:q,slideImg:E,npStageBlank:F,sliderTrack:J,slideImgLoaded:K,slideSpinner:N,npArrowLeft:Q,npArrowRight:U,chapterPanel:X,chapterRow:Y,chapterRowActive:Z,chapterRowTime:$,chapterRowLabel:oo,npBackdrop:eo,playerBtn:to,playerBtnActive:ao,tracksSection:_o,tracksHeading:no,trackList:ro,trackRow:lo,trackIcon:so,trackLabel:co,trackType:po,noTracks:io,playAllBtn:fo,detailActions:zo,playerBar:ko,playerActions:go,playerInfo:yo,playerTitle:mo,playerTrack:Bo,playerControls:ho,seekRow:To,playerButtons:bo,seekBtn:uo,seekBtnLabel:wo,playBtn:Lo,seekBar:Co,volumeBar:Ro,timeLabel:vo,playerRight:Ao,volumeIcon:Io,playerToggle:So};export{Ho as a};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{o as U,d as k,h as L,T as E,u,S as y}from"./vendor-core-DfaOB3Rn.js";import{M as F}from"./MediaCard--cuFxOCS.js";import{L as N}from"./LibraryListPage-BoTxRqHz.js";import{u as _,A as q}from"./useAsmrPopup-SymV1J-b.js";import{A as z}from"./AsmrResetProgressModal-DgEWBJOw.js";import{g as h}from"./index-CnfZwsds.js";import{m as O,u as Q,n as Y,o as D,e as G,p as H,q as K,r as Z,A as T,k as J}from"./useAsmr-BbhQ59bk.js";import"./vendor-ui-3qrARCPr.js";import"./useIsMobile-Dvx1uJ82.js";import"./vendor-icons-DrybRNxP.js";import"./SkeletonGrid-DJelJgAv.js";import"./ErrorMessage-DAxegITP.js";import"./Watchlist.module-XGtVQr1d.js";import"./Asmr.module-CdWlioTY.js";import"./usePopup-DS9jMzp6.js";import"./ResetProgressModal-CMF86mX6.js";import"./vendor-query-BBT5_sHx.js";const V=["All","Continue Listening",...T],A=24;function W(a){const d=a.currentTime??0,i=a.duration??0,r=(a.trackIndex??0)+1;return i>0?`Track ${r} · ${h(d)} / ${h(i)}`:`Track ${r}`}function kt(){const{filter:a="All"}=U(),[d,i]=k(1),[r,m]=k(null);L(()=>{document.title="Listening List - dango"},[]),L(()=>{i(1)},[a]);const o=a==="Continue Listening",n=O(o?"All":a,d,A),l=Q(100),f=Y(),C=D(),{toggle:v,bookmarkedIds:R}=G(),{popup:s,openPopup:I,scheduleClose:c,cancelClose:p,closePopup:B}=_(),P=H(),S=K(),j=Z(),M=E(()=>o?(l.data?.data??[]).map(t=>{const e=t.currentTime??0,g=t.duration??0,b=t.rjCode||t.id;return{key:t.id,libId:t.id,rjCode:b,title:t.title,thumbnail:t.thumbnail||"",status:t.status,isAdult:!!t.isAdult,trackLabel:`Track ${(t.trackIndex??0)+1}`,progressPercent:g>0?Math.min(100,e/g*100):0,progressLabel:W(t),detailTarget:`/asmr/${encodeURIComponent(b)}`}}):(n.data?.data??[]).map(t=>{const e=t.rjCode||t.id;return{key:t.id,libId:t.id,rjCode:e,title:t.title,thumbnail:t.thumbnail||"",status:t.status,isAdult:!!t.isAdult,trackLabel:t.lastTrackIndex!==null&&t.lastTrackIndex!==void 0?`Track ${t.lastTrackIndex+1}`:void 0,progressPercent:void 0,progressLabel:void 0,detailTarget:`/asmr/${encodeURIComponent(e)}`}}),[o,l.data,n.data]),w=o?l.data?.total??0:n.data?.total??0,x=o?l.isLoading:n.isLoading,$=o?l.error:n.error;return u(N,{headerTitle:"My Listening List",headerSubtitle:"Track and manage your ASMR collection",filters:V,filterBy:a,filterBasePath:"/listening-list",continueFilter:"Continue Listening",statusOptions:[...T],entries:M,total:w,isLoading:x,error:$,page:d,pageSize:A,onPageChange:i,emptyTitle:"Your listening list is looking a bit lonely",emptyFilteredText:"No works match this filter.",emptyAllText:"Let's find something to listen to!",browseLabel:"Browse ASMR",browseTarget:"/asmr",removeListLabel:"Remove from Listening List",listNoun:"listening list",skipConfirmKey:"asmrSkipRemoveConfirmation",onBulkStatus:(t,e)=>P.mutate({ids:t,status:e}),onBulkRemove:t=>{o?j.mutate({ids:t}):S.mutate({ids:t})},onStatusChange:(t,e)=>C.mutate({id:t,status:e}),onRemoveItem:t=>f.mutate({id:t}),renderCard:t=>u(F,{item:{id:t.libId,title:t.title,thumbnail:t.thumbnail,typeBadge:t.rjCode||void 0,chapterBadge:t.trackLabel??null,isAdult:t.isAdult},linkTo:t.detailTarget,hoverIcon:"info",layout:"horizontal",showInfoButton:!o,progress:t.progressPercent!==void 0&&t.progressLabel?{percent:t.progressPercent,label:t.progressLabel}:void 0,showProgress:o,display:{elements:{poster:{typeBadge:!0,chapterBadge:!0,adultBadge:!0},info:{title:!0,mobileBadges:!0,progress:!0,meta:!1}}},onRemove:o?()=>m(t):void 0,onOpenDetails:o?void 0:e=>I(e,{rjCode:t.rjCode,title:t.title,thumbnail:t.thumbnail,isAdult:t.isAdult,listenTarget:t.detailTarget,progressLabel:t.progressLabel}),onPopupHoverIntent:e=>e?p():c(),rawThumbnail:!0}),modals:u(y,{children:[u(z,{workId:r?r.libId:null,title:r?.title,onClose:()=>m(null)}),s&&u(q,{data:s.data,anchorRect:s.rect,bookmarked:R.has(J(s.data.rjCode)),onToggleBookmark:()=>v({rjCode:s.data.rjCode,title:s.data.title,thumbnail:s.data.thumbnail||"",isAdult:s.data.isAdult}),onMouseEnter:p,onMouseLeave:c,onRequestClose:B})]})})}export{kt as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
._authRow_10tvv_1{display:flex;gap:8px;align-items:center;flex-wrap:wrap;margin-bottom:16px}._btn_10tvv_9{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 20px;border:none;border-radius:var(--radius-full);background:var(--accent);color:var(--accent-text);font-size:var(--font-size-sm);font-weight:600;cursor:pointer;transition:background var(--transition-fast),transform var(--transition-quick),opacity var(--transition-fast)}._btn_10tvv_9:hover:not(:disabled){background:var(--accent-light);box-shadow:0 0 12px var(--accent-glow)}._btn_10tvv_9:active:not(:disabled){transform:scale(.96)}._btn_10tvv_9:disabled{opacity:.5;cursor:not-allowed}._btnGhost_10tvv_42{display:inline-flex;align-items:center;justify-content:center;gap:8px;padding:10px 20px;border:1px solid var(--border-primary);border-radius:var(--radius-full);background:#ffffff0a;color:var(--text-primary);font-size:var(--font-size-sm);font-weight:600;cursor:pointer;transition:background var(--transition-fast),transform var(--transition-quick),opacity var(--transition-fast)}._btnGhost_10tvv_42:hover:not(:disabled){background:#ffffff14}._btnGhost_10tvv_42:active:not(:disabled){transform:scale(.96)}._btnGhost_10tvv_42:disabled{opacity:.5;cursor:not-allowed}._cookieForm_10tvv_74{display:flex;gap:8px;flex-wrap:wrap;align-items:center;flex:1;min-width:280px}._cookieInput_10tvv_83{flex:1;min-width:200px;padding:10px 16px;border:1px solid var(--border-primary);border-radius:var(--radius-full);background:var(--bg-secondary);color:var(--text-primary);font-size:var(--font-size-sm);outline:none}._cookieInput_10tvv_83:focus{border-color:var(--accent)}._link_10tvv_99{color:var(--accent);text-decoration:underline;font-weight:600}._link_10tvv_99:hover{opacity:.85}._contentLayout_10tvv_109{display:grid;grid-template-columns:minmax(0,1fr) 340px;gap:24px;align-items:start}._mainCol_10tvv_116{min-width:0}._upnextAside_10tvv_120{position:sticky;top:16px;max-height:calc(100vh - 140px);overflow-y:auto;background:#ffffff08;border:1px solid var(--border-primary);border-radius:12px;padding:12px}._upnextHeader_10tvv_131{display:flex;align-items:center;justify-content:space-between;gap:8px;margin-bottom:8px}._upnextTitle_10tvv_139{font-size:var(--font-size-sm);font-weight:700;opacity:.9;display:flex;align-items:center;gap:6px;min-width:0}._upnextActions_10tvv_149{display:flex;gap:8px;margin-bottom:12px;flex-wrap:wrap}._nowPlayingLabel_10tvv_156{font-size:11px;font-weight:700;text-transform:uppercase;letter-spacing:.6px;opacity:.55;margin:4px 0 8px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._nowPlayingWrap_10tvv_168{margin-bottom:12px}._likeBtn_10tvv_172{display:inline-flex;align-items:center;justify-content:center;padding:8px;border:0;background:transparent;color:inherit;opacity:.55;cursor:pointer;flex-shrink:0;border-radius:50%}._likeBtn_10tvv_172:hover:not(:disabled){opacity:1;background:#ffffff14}._likeBtn_10tvv_172:disabled{opacity:.3;cursor:not-allowed}._likeActive_10tvv_196{opacity:1;color:var(--accent-light)}@media(max-width:900px){._contentLayout_10tvv_109{grid-template-columns:minmax(0,1fr)}._upnextAside_10tvv_120{position:static;max-height:none;order:-1}}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as y,h as A,u as e,A as R,g as Pe,S,$ as tt,p as nt,T as j}from"./vendor-core-DfaOB3Rn.js";import{t as Ie,P as it,h as H,z as $}from"./index-CnfZwsds.js";import{I as f}from"./vendor-icons-DrybRNxP.js";import{r as p}from"./Radio.module-DGSZLpKM.js";import{a}from"./Asmr.module-CdWlioTY.js";import{b as ne,u as Ae,a as Ee}from"./vendor-query-BBT5_sHx.js";import{p as te}from"./page.module-C1MlZzf3.js";const pe=new Set,ue=new Map,qe=n=>`/api/image-proxy?url=${encodeURIComponent(n)}&strict=1`,ze=n=>/googleusercontent\.com/.test(n)?n.replace(/=w\d+-h\d+(?:-l\d+)?(?:-rj)?$/,"=w544-h544-l90-rj"):n,Ye=/^[A-Za-z0-9_-]{11}$/;function st(n,s){const l=[],b=n?ue.get(n):void 0;b&&!pe.has(b)&&l.push(b);for(const x of s??[]){if(!x?.url)continue;const w=qe(ze(x.url));pe.has(w)||l.includes(w)||l.push(w)}if(n&&Ye.test(n)){const x=qe(`https://i.ytimg.com/vi/${n}/hqdefault.jpg`);!pe.has(x)&&!l.includes(x)&&l.push(x)}return l}function at(n,s){const l=s?.[0]?.url;return l?ze(l):n&&Ye.test(n)?`https://i.ytimg.com/vi/${n}/hqdefault.jpg`:""}function rt(n,s){!n||pe.has(s)||(ue.set(n,s),ue.size>500&&ue.clear())}function ot(n){pe.add(n);for(const[s,l]of ue)l===n&&ue.delete(s)}function $e({id:n,thumbnails:s}){const[l,b]=y(0),[x,w]=y(!1);A(()=>{b(0),w(!1)},[n]);const _=st(n,s),E=_[l];return x||!E?e("span",{className:p.stationThumbPlaceholder,children:e(f,{name:"headphones"})}):e("img",{src:E,alt:"",className:p.stationThumb,loading:"lazy",decoding:"async",onLoad:()=>rt(n,E),onError:()=>{ot(E),l+1<_.length?b(l+1):w(!0)}})}function Ue(n){if(!Number.isFinite(n)||n<0)return"0:00";const s=Math.floor(n/60),l=Math.floor(n%60);return`${s}:${String(l).padStart(2,"0")}`}const ct=({track:n,shuffle:s,onToggleShuffle:l,onTrackStep:b,onTrackFailed:x,onClose:w,liked:_,likeVisible:E,likePending:de,onToggleLike:ie})=>{const O=R(null),me=R(!1),[T,se]=y(!1),[h,v]=y(!0),[V,B]=y(!1),[F,ae]=y(0),[Z,J]=y(0),[N,re]=y(()=>{const r=parseFloat(localStorage.getItem("musicVolume")||"");return Number.isFinite(r)?r:1}),[z,oe]=y(()=>localStorage.getItem("musicAutoplay")!=="false"),L=R(N);L.current=N;const k=R(z);k.current=z;const W=R(0),D=R(0),Y=R(null),G=R("");G.current||(G.current=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`music-${Date.now()}-${Math.random().toString(36).slice(2)}`);const fe=`/api/music/audio?videoId=${encodeURIComponent(n.id)}`,q=Pe.useCallback(()=>{Y.current&&(window.clearTimeout(Y.current),Y.current=null)},[]),ce=Pe.useCallback(r=>{const c=O.current;if(!c)return;q(),v(!0),B(!1);const P=()=>{if(c.removeEventListener("loadedmetadata",P),r>5&&Number.isFinite(c.duration)&&r<c.duration-5)try{c.currentTime=r}catch{}};c.addEventListener("loadedmetadata",P),c.src=fe,c.load(),c.volume=L.current,c.play().catch(()=>{})},[fe,q]),ye=()=>{v(!1),B(!0),x?.(n),k.current&&b(1)},be=()=>{if(!Y.current){if(D.current>=3){ye();return}D.current+=1,Y.current=window.setTimeout(()=>{Y.current=null,ce(W.current)},5e3)}},Q=()=>{D.current=0,ce(W.current)};A(()=>{W.current=0,D.current=0,se(!1),ae(0),J(0);const r=O.current;return ce(W.current),()=>{q(),r&&r.removeAttribute("src")}},[ce,q]),A(()=>{const r=O.current;r&&(r.volume=N)},[N]),A(()=>(document.body.classList.add("asmr-player-open"),()=>document.body.classList.remove("asmr-player-open")),[]);const ve=at(n.id,n.thumbnails),K=Pe.useCallback(r=>{const c=O.current;Ie.discord.musicPresence.mutate({title:n.title,artistLabel:n.artists,isPlaying:r,thumbnail:ve||"",currentTime:c?.currentTime??0,duration:Number.isFinite(c?.duration??NaN)?c?.duration:0,sessionId:G.current}).catch(()=>{}),Ie.discord.heartbeat.mutate({sessionId:G.current}).catch(()=>{})},[n,ve]);A(()=>{K(T)},[K,T,n.id]),A(()=>{if(!T)return;const r=window.setInterval(()=>K(!0),15e3);return()=>window.clearInterval(r)},[T,K]),A(()=>{const r=G.current,c=()=>it(r),P=()=>c(),U=()=>{document.visibilityState==="hidden"&&c()};return window.addEventListener("pagehide",P),window.addEventListener("beforeunload",P),document.addEventListener("visibilitychange",U),()=>{window.removeEventListener("pagehide",P),window.removeEventListener("beforeunload",P),document.removeEventListener("visibilitychange",U),c()}},[]);const Se=()=>{const r=O.current;r&&(r.paused?r.play().catch(()=>{}):r.pause())},ke=`${n.title} — ${n.artists}`,Ne=e(S,{children:[e("div",{className:a.playerButtons,children:[e("button",{className:a.playerBtn,onClick:()=>b(-1),"aria-label":"Previous track",children:e(f,{name:"step-backward"})}),e("button",{className:`${a.playerBtn} ${a.playBtn}`,onClick:Se,"aria-label":T?"Pause":"Play",children:T?e(f,{name:"pause"}):e(f,{name:"play"})}),e("button",{className:a.playerBtn,onClick:()=>b(1),"aria-label":"Next track",children:e(f,{name:"step-forward"})}),V&&e("button",{className:a.playerBtn,onClick:Q,title:"Retry playback","aria-label":"Retry playback",children:e(f,{name:"redo"})})]}),e("div",{className:a.seekRow,children:[e("span",{className:a.timeLabel,children:Ue(F)}),e("input",{className:a.seekBar,type:"range",min:0,max:Z||0,step:.1,value:Math.min(F,Z||0),onChange:r=>{const c=O.current;!c||!Number.isFinite(c.duration)||(c.currentTime=parseFloat(r.target.value),ae(c.currentTime))},onPointerDown:()=>{me.current=!0},onPointerUp:()=>{me.current=!1},style:{"--played-percent":`${Z>0?F/Z*100:0}%`},"aria-label":"Seek"}),e("span",{className:a.timeLabel,children:Ue(Z)}),h&&!V&&e("span",{className:a.timeLabel,children:"loading…"})]})]}),xe=e(S,{children:[e($e,{id:n.id,thumbnails:n.thumbnails}),e("div",{className:a.playerInfo,children:[e("p",{className:a.playerTitle,title:ke,children:ke}),e("p",{className:a.playerTrack,children:n.artists})]}),e("div",{className:a.playerControls,children:Ne}),e("div",{className:a.playerRight,children:[N===0?e(f,{name:"volume-mute",className:a.volumeIcon}):N<.5?e(f,{name:"volume-down",className:a.volumeIcon}):e(f,{name:"volume-up",className:a.volumeIcon}),e("input",{className:a.volumeBar,type:"range",min:0,max:1,step:.01,value:N,onChange:r=>{const c=parseFloat(r.target.value);re(c),localStorage.setItem("musicVolume",String(c))},style:{"--volume-percent":`${N*100}%`},"aria-label":"Volume"})]}),e("div",{className:a.playerActions,children:[E&&ie&&e("button",{className:`${a.playerBtn} ${_?a.playerBtnActive:""}`,onClick:ie,disabled:de,title:_?"Remove from Liked Music":"Add to Liked Music","aria-label":_?"Remove from Liked Music":"Add to Liked Music","aria-pressed":!!_,children:e(f,{name:"heart"})}),e("button",{className:`${a.playerBtn} ${s?a.playerBtnActive:""}`,onClick:l,title:s?"Shuffle on":"Shuffle off","aria-label":"Toggle shuffle","aria-pressed":s,children:e(f,{name:"shuffle"})}),e("button",{className:`${a.playerBtn} ${z?a.playerBtnActive:""}`,onClick:()=>{oe(r=>(localStorage.setItem("musicAutoplay",String(!r)),!r))},title:z?"Autoplay on: next track plays automatically":"Autoplay off","aria-label":"Toggle autoplay","aria-pressed":z,children:e(f,{name:"forward"})}),e("a",{href:`https://music.youtube.com/watch?v=${encodeURIComponent(n.id)}`,target:"_blank",rel:"noreferrer",title:"Open in YouTube Music","aria-label":"Open in YouTube Music",className:a.playerBtn,style:{display:"inline-flex",alignItems:"center"},children:e(f,{name:"external-link-alt"})}),e("button",{className:a.playerBtn,onClick:w,"aria-label":"Close player",children:e(f,{name:"times"})})]})]});return tt(e(S,{children:[e("audio",{ref:O,preload:"none",onPlay:()=>{se(!0),v(!1),B(!1),D.current=0,q()},onPause:()=>se(!1),onWaiting:()=>{V||v(!0)},onPlaying:()=>{v(!1),D.current=0,q()},onTimeUpdate:r=>{const c=r.target.currentTime;W.current=c,q(),me.current||ae(c)},onStalled:()=>{be()},onLoadedMetadata:r=>{const c=r.target.duration;Number.isFinite(c)&&J(c)},onDurationChange:r=>{const c=r.target.duration;Number.isFinite(c)&&J(c)},onError:()=>{be()},onEnded:()=>{k.current&&b(1)}}),e("div",{className:a.playerBar,children:xe})]}),document.body)},lt=()=>e("div",{style:{marginTop:"0.9rem",paddingTop:"0.9rem",borderTop:"1px dashed var(--border-color)"},children:[e("h4",{style:{margin:"0 0 0.35rem",fontSize:"0.95rem"},children:"Where to get the cookie"}),e("p",{style:{margin:"0 0 0.6rem",fontSize:"0.85rem",color:"var(--text-secondary)"},children:"Google marks its login cookies unreadable to page scripts, so this has to come from DevTools — it takes about 20 seconds:"}),e("ol",{style:{margin:"0 0 0.75rem",paddingLeft:"1.25rem",fontSize:"0.85rem",color:"var(--text-secondary)",display:"grid",gap:"0.3rem"},children:[e("li",{children:["Open"," ",e("a",{href:"https://music.youtube.com/",target:"_blank",rel:"noopener noreferrer",children:"music.youtube.com"})," ","and make sure you are logged in."]}),e("li",{children:["Press ",e("kbd",{children:"F12"}),", go to the ",e("strong",{children:"Network"})," tab, and type ",e("kbd",{children:"browse"})," ","in the filter box."]}),e("li",{children:["Click any ",e("kbd",{children:"POST"})," browse entry, then scroll to Request Headers."]}),e("li",{children:[e("strong",{children:"Right-click"})," the ",e("kbd",{children:"Cookie"})," value and choose"," ",e("strong",{children:"Copy value"})," — right-click copies the full unwrapped value, selecting the text by hand truncates it."]}),e("li",{children:"Paste it into the sign-in box above and press Sign in."})]})]}),ge=300*1e3,ut=()=>{const n=H();return ne({...n.music.authStatus.queryOptions(),staleTime:30*1e3,refetchInterval:s=>s.state.data?.authenticated?!1:3e3,retry:1})},dt=()=>{const n=H(),s=Ae();return Ee(n.music.authStart.mutationOptions({onSuccess:(l,b)=>{localStorage.setItem("ytmusic_cookie",b.cookie??""),s.invalidateQueries(n.music.pathFilter())}}))},mt=()=>{const n=H(),s=Ae();return Ee(n.music.signOut.mutationOptions({onSuccess:()=>{s.invalidateQueries(n.music.pathFilter())}}))},ht=n=>{const s=H();return ne({...s.music.search.queryOptions({q:n}),enabled:n.trim().length>0,staleTime:ge,retry:1})},pt=n=>{const s=H();return ne({...s.music.library.queryOptions(),enabled:n,staleTime:ge,retry:1})},gt=n=>{const s=H();return ne({...s.music.track.queryOptions({id:n||void 0}),enabled:!!n,staleTime:ge,retry:1})},ft=n=>{const s=H();return ne({...s.music.playlist.queryOptions({id:n||void 0}),enabled:!!n,staleTime:ge,retry:1})},yt=n=>{const s=H();return ne({...s.music.upnext.queryOptions({id:n||void 0}),enabled:!!n,staleTime:ge,retry:1})},bt=n=>{const s=H();return ne({...s.music.likes.queryOptions(),enabled:n,staleTime:120*1e3,retry:1})},vt=()=>{const n=H(),s=Ae();return Ee(n.music.like.mutationOptions({onSuccess:()=>{s.invalidateQueries(n.music.pathFilter())}}))},kt="_authRow_10tvv_1",Nt="_btn_10tvv_9",wt="_btnGhost_10tvv_42",St="_cookieForm_10tvv_74",xt="_cookieInput_10tvv_83",Tt="_link_10tvv_99",Lt="_contentLayout_10tvv_109",Mt="_mainCol_10tvv_116",_t="_upnextAside_10tvv_120",Ct="_upnextHeader_10tvv_131",Rt="_upnextTitle_10tvv_139",Pt="_upnextActions_10tvv_149",It="_nowPlayingLabel_10tvv_156",$t="_nowPlayingWrap_10tvv_168",At="_likeBtn_10tvv_172",Et="_likeActive_10tvv_196",g={authRow:kt,btn:Nt,btnGhost:wt,cookieForm:St,cookieInput:xt,link:Tt,contentLayout:Lt,mainCol:Mt,upnextAside:_t,upnextHeader:Ct,upnextTitle:Rt,upnextActions:Pt,nowPlayingLabel:It,nowPlayingWrap:$t,likeBtn:At,likeActive:Et};function He(n){const s=n.trim();if(!s)return null;const l=s.match(/[?&]v=([A-Za-z0-9_-]{11})/)?.[1]??s.match(/youtu\.be\/([A-Za-z0-9_-]{11})/)?.[1]??null;return l||(/^[A-Za-z0-9_-]{11}$/.test(s)?s:null)}const Ot="https://github.com/serifpersia/dango/releases/latest/download/dango-extension.zip",Yt=()=>{const[n,s]=nt(),l=He(n.get("v")??""),[b,x]=y(()=>n.get("q")??""),w=n.get("q")??"";A(()=>{x(w)},[w]);const[_,E]=y(()=>{try{return localStorage.getItem("ytmusic_cookie")??""}catch{return""}}),[de,ie]=y(!1),[O,me]=y(()=>localStorage.getItem("musicShuffle")==="true"),[T,se]=y(()=>localStorage.getItem("musicRadio")!=="false"),[h,v]=y(null),[V,B]=y([]),[F,ae]=y(null),[Z,J]=y({}),N=R([]);N.current=V;const re=R(null);re.current=h;const z=R(!1),oe=R(new Set),{data:L}=ut(),k=dt(),W=mt(),D=typeof navigator<"u"?navigator.userAgent:"",Y=/android/i.test(D),G=/firefox|fxios/i.test(D)&&!Y,fe=!G&&!Y&&/chrome|chromium|edg|brave/i.test(D),q=G||fe,ce=()=>{if(de)return;ie(!0);const t=`${Date.now().toString(36)}-${Math.random().toString(36).slice(2)}`,i=window.setTimeout(()=>{window.removeEventListener("dango:ytmusic-cookie",o),ie(!1),$.error("Helper not detected — install the Dango Helper extension first.")},3e3),o=d=>{let m;try{m=JSON.parse(d.detail)}catch{return}if(!(!m||m.requestId!==t))if(window.clearTimeout(i),window.removeEventListener("dango:ytmusic-cookie",o),ie(!1),m?.ok&&m.cookie){const u=m.cookie.replace(/^cookie\s*:\s*/i,"").replace(/^["']+|["']+$/g,"").trim();if(u.includes("…")||u.includes("...")){$.error(`Helper returned a truncated cookie (${u.length} chars) — reload music.youtube.com and Extract again.`);return}E(u),$.success("Cookie extracted from helper — signing in…"),k.mutate({cookie:u})}else m?.error==="NO_COOKIE"?$.error("Helper found no YouTube login — log in on a music.youtube.com tab first."):$.error("Helper request failed — try again.")};window.addEventListener("dango:ytmusic-cookie",o),window.dispatchEvent(new CustomEvent("dango:get-ytmusic-cookie",{detail:{requestId:t}}))},{data:ye,isLoading:be}=ht(w),{data:Q,isLoading:ve,isFetching:K,error:Se,refetch:ke}=pt(L?.authenticated===!0),{data:Ne,isLoading:xe}=ft(F?.id??null),{data:Te,isLoading:r}=yt(h?.id??null),{data:c}=bt(L?.authenticated===!0),P=vt(),U=j(()=>ye?.tracks||[],[ye]),Le=j(()=>Q?.playlists||[],[Q]),I=j(()=>Q?.tracks||[],[Q]),X=j(()=>Ne?.tracks||[],[Ne]),M=j(()=>{const t=Te?.tracks||[];return h?t.filter(i=>i.id!==h.id):t},[Te,h]),Ge=j(()=>new Set(c?.likedIds||[]),[c]),Me=t=>Z[t.id]??(Ge.has(t.id)||t.liked===!0);A(()=>{L?.authenticated!==!0&&J({})},[L?.authenticated]);const Qe=j(()=>[...U,...X,...I,...M],[U,X,I,M]),Ve=l&&h?.id!==l&&!Qe.some(t=>t.id===l)?l:null,{data:Oe}=gt(Ve),_e=h?.id;A(()=>{document.title=h?`${h.title} - dango`:"Music - dango"},[h]),A(()=>{if(!l){_e&&v(null);return}if(_e===l)return;const t=d=>{const m=d.find(u=>u.id===l);return m?(v(m),B(u=>u.some(le=>le.id===l)?u:d.length>0?d:[m]),!0):!1};if(t(U)||t(X)||t(I))return;const i=M.find(d=>d.id===l);if(i){v(i),B(d=>d.some(m=>m.id===i.id)?d:[i]);return}const o=Oe?.track;o&&o.id===l&&(v(o),B(d=>d.some(m=>m.id===o.id)?d:[o]))},[l,_e,U,X,I,M,Oe]);const ee=t=>{s(i=>{const o=new URLSearchParams(i);return t?o.set("v",t):o.delete("v"),o})},Ce=(t,i)=>{oe.current.delete(t.id),v(t),B(i.length>0?i:[t]),ee(t.id)},We=t=>{oe.current.add(t.id),$.error(`Couldn't play “${t.title}” — skipped.`)},je=async()=>{if(z.current)return;const t=N.current,i=t[t.length-1]??re.current;if(i){z.current=!0;try{const o=await Ie.music.upnext.query({id:i.id}),d=new Set(t.map(u=>u.id)),m=(o.tracks||[]).filter(u=>!d.has(u.id)&&!oe.current.has(u.id));if(m.length===0){const u=N.current[0];u&&(v(u),ee(u.id));return}B([...N.current,...m]),v(m[0]),ee(m[0].id)}catch{const o=N.current[0];o&&(v(o),ee(o.id))}finally{z.current=!1}}},Ze=t=>{const i=N.current,o=re.current;if(!o||i.length===0)return;const d=i.findIndex(C=>C.id===o.id);if(t>0&&T&&(d<0||d===i.length-1)){je();return}const m=C=>oe.current.has(C.id),u=i.length;let le;if(O&&u>1){let C=Math.floor(Math.random()*u);for(let Re=0;Re<u&&(C===d||m(i[C]));Re++)C=Math.floor(Math.random()*u);le=i[C]}else{const C=t>0?1:-1;let we=(((d<0?C>0?-1:0:d)+C)%u+u)%u;for(let De=1;De<u&&m(i[we]);De++)we=((we+C)%u+u)%u;le=i[we]}v(le),ee(le.id)},Je=()=>{if(T){se(!1),localStorage.setItem("musicRadio","false");return}const t=re.current;if(!t)return;if(M.length===0){$.error("No radio suggestions for this song yet.");return}const i=new Set,o=[];for(const d of[t,...M])i.has(d.id)||(i.add(d.id),o.push(d));se(!0),localStorage.setItem("musicRadio","true"),B(o),$.success(`Radio started — ${M.length} songs queued.`)},Be=t=>{if(L?.authenticated!==!0){$.error("Sign in to like songs.");return}const i=!Me(t);J(o=>({...o,[t.id]:i})),P.mutate({id:t.id,like:i},{onError:()=>{J(o=>{const d={...o};return delete d[t.id],d}),$.error("Like action failed — try again.")}})},Ke=()=>{me(t=>(localStorage.setItem("musicShuffle",String(!t)),!t))},Xe=t=>e("button",{className:p.stationRow,onClick:()=>ae(t),"aria-label":`Open ${t.title}`,children:[e($e,{id:t.id,thumbnails:t.thumbnails}),e("span",{className:p.stationMeta,children:[e("span",{className:p.stationName,children:t.title}),t.subtitle&&e("span",{className:p.stationSub,children:t.subtitle})]})]},t.id),he=(t,i,o)=>{const d=h?.id===t.id,m=Me(t),u=[t.album,t.duration].filter(Boolean).join(" · ");return e("div",{className:`${p.stationRow} ${d?p.stationRowActive:""}`,style:{cursor:"default"},children:[e("button",{onClick:()=>o?o(t):Ce(t,i),className:p.stationRow,style:{flex:1,minWidth:0,background:"transparent",border:0,padding:0},"aria-label":`Play ${t.title}`,children:[e($e,{id:t.id,thumbnails:t.thumbnails}),e("span",{className:p.stationMeta,children:[e("span",{className:p.stationName,children:t.title}),e("span",{className:p.stationSub,children:[t.artists,u?` · ${u}`:""]})]})]}),L?.authenticated===!0&&e("button",{className:`${g.likeBtn} ${m?g.likeActive:""}`,onClick:()=>Be(t),disabled:P.isPending,title:m?"Remove from Liked Music":"Add to Liked Music","aria-label":m?`Remove ${t.title} from Liked Music`:`Add ${t.title} to Liked Music`,"aria-pressed":m,children:e(f,{name:"heart"})}),e("a",{href:`https://music.youtube.com/watch?v=${encodeURIComponent(t.id)}`,target:"_blank",rel:"noreferrer",title:"Open in YouTube Music","aria-label":`Open ${t.title} in YouTube Music`,style:{padding:8,color:"inherit",opacity:.7,flexShrink:0},children:e(f,{name:"external-link-alt"})})]},t.id)},Fe=j(()=>{if(!h)return M;const t=new Set,i=[];for(const o of[h,...M])t.has(o.id)||(t.add(o.id),i.push(o));return i},[h,M]),et=t=>{Ce(t,Fe)};return e("div",{className:`${te.page} ${h?te.pageWithPlayer:""}`,children:[e("div",{className:te.header,children:[e("h1",{className:te.pageTitle,children:[e(f,{name:"headphones"})," Music"]}),e("form",{className:te.searchForm,onSubmit:t=>{t.preventDefault();const i=He(b);if(i)ee(i);else{const o=b.trim();s(d=>{const m=new URLSearchParams(d);return o?m.set("q",o):m.delete("q"),m})}},children:[e("input",{className:te.searchInput,value:b,onChange:t=>x(t.target.value),placeholder:"Search YouTube Music…","aria-label":"Search music"}),e("button",{className:te.searchBtn,type:"submit","aria-label":"Search",children:e(f,{name:"search"})})]})]}),e("div",{className:g.authRow,children:[L?.authenticated?e(S,{children:[e("span",{className:a.statusMsg,children:["Signed in to YouTube Music",Q&&` — ${Q.tracks.length} songs, ${Q.playlists.length} playlists`]}),e("button",{className:g.btnGhost,onClick:()=>W.mutate(),disabled:W.isPending,children:"Sign out"})]}):e(S,{children:[e("form",{onSubmit:t=>{t.preventDefault();const i=_.replace(/^cookie\s*:\s*/i,"").replace(/^["']+|["']+$/g,"").trim();if(i){if(i.includes("…")||i.includes("...")){$.error("That cookie is truncated (contains …). Right-click the Cookie header → Copy value, not the wrapped preview.");return}i!==_&&E(i),k.mutate({cookie:i})}},className:g.cookieForm,children:[e("input",{className:g.cookieInput,value:_,onChange:t=>E(t.target.value),placeholder:"Paste music.youtube.com Cookie header…","aria-label":"YouTube Music cookie",type:"password"}),e("button",{className:g.btn,type:"submit",disabled:k.isPending||!_.trim(),children:k.isPending?"Checking…":"Sign in"}),q&&e("button",{className:g.btnGhost,type:"button",onClick:ce,disabled:de||k.isPending,title:"Read the YouTube Music cookie via the Dango Helper extension (same zip as AnimePahe/JapaneseASMR)",children:de?"Extracting…":"Extract from helper"})]}),q&&e("p",{className:a.statusMsg,children:["Two ways to sign in: paste the Cookie header manually (steps below), or download"," ",e("a",{href:Ot,target:"_blank",rel:"noreferrer",className:g.link,children:"dango-extension.zip"})," ","then"," ",G?e(S,{children:[e("code",{children:"about:debugging"})," → ",e("strong",{children:"This Firefox"})," →"," ",e("strong",{children:"Load Temporary Add-on"})," →"," ",e("code",{children:"dango-extension/firefox/manifest.json"})]}):e(S,{children:[e("code",{children:"chrome://extensions"})," → ",e("strong",{children:"Developer mode"})," →"," ",e("strong",{children:"Load unpacked"})," → ",e("code",{children:"dango-extension/chrome"})]}),", log in on a music.youtube.com tab, and click Extract."]}),e(lt,{})]}),k.isSuccess&&e("p",{className:a.statusMsg,children:["Signed in — found ",k.data.tracks," songs and ",k.data.playlists," ","playlists."]}),k.isError&&e("p",{className:a.statusMsg,children:k.error?.message||"Sign-in failed. Paste a fresh Cookie header from music.youtube.com."}),!L?.authenticated&&!k.isError&&!k.isSuccess&&e("p",{className:a.statusMsg,children:"Sign in with your YouTube Music cookie to see your library. Search and playback work without sign-in."})]}),e("div",{className:h?g.contentLayout:void 0,children:[e("div",{className:g.mainCol,children:w?e(S,{children:[e("h2",{className:p.sectionTitle,children:["Results for “",w,"”"]}),be?e("p",{className:a.statusMsg,children:"Searching…"}):U.length===0?e("p",{className:a.statusMsg,children:"No tracks found."}):e("div",{className:p.stationList,children:U.map(t=>he(t,U))})]}):L?.authenticated?e(S,{children:[e("h2",{className:p.sectionTitle,children:"Your library"}),ve?e("p",{className:a.statusMsg,children:"Loading library…"}):Le.length===0&&I.length===0&&!F?e(S,{children:[e("p",{className:a.statusMsg,children:Se?"Library failed to load.":"Your library came back empty — YouTube sometimes drops the saved session."}),e("div",{style:{marginBottom:8},children:e("button",{className:g.btnGhost,onClick:()=>{ke()},disabled:K,"aria-label":"Retry loading library",children:K?"Retrying…":"Retry"})}),e("p",{className:a.statusMsg,children:"If it keeps happening, sign out and paste a fresh cookie."})]}):e(S,{children:[Le.length>0&&!F&&e(S,{children:[e("h3",{className:p.sectionTitle,children:"Playlists"}),e("div",{className:p.stationList,children:Le.map(t=>Xe(t))})]}),I.length>0&&!F&&e(S,{children:[e("h3",{className:p.sectionTitle,children:["Liked songs (",I.length,")"]}),e("div",{style:{marginBottom:8},children:e("button",{className:g.btnGhost,onClick:()=>Ce(I[0],I),"aria-label":"Play all liked songs",children:[e(f,{name:"play"})," Play all"]})}),e("div",{className:p.stationList,children:I.map(t=>he(t,I))})]}),F?e(S,{children:[e("button",{className:g.btnGhost,onClick:()=>ae(null),style:{marginBottom:8},children:"← Back to library"}),e("h3",{className:p.sectionTitle,children:F.title}),xe?e("p",{className:a.statusMsg,children:"Loading playlist…"}):X.length===0?e("p",{className:a.statusMsg,children:"No tracks in this playlist."}):e("div",{className:p.stationList,children:X.map(t=>he(t,X))})]}):null]})]}):e("p",{className:a.statusMsg,children:"Search above, or sign in to see your library."})}),h&&e("aside",{className:g.upnextAside,"aria-label":"Up next",children:[e("div",{className:g.upnextHeader,children:e("span",{className:g.upnextTitle,children:[e(f,{name:"list-ul"})," Up Next"]})}),e("div",{className:g.nowPlayingWrap,children:[e("p",{className:g.nowPlayingLabel,children:"Now playing"}),he(h,V.length>0?V:[h])]}),e("div",{className:g.upnextActions,children:e("button",{className:g.btnGhost,onClick:Je,disabled:!T&&(r||M.length===0),"aria-pressed":T,title:T?"Stop the radio — the queue will loop instead of fetching more songs":"Queue these suggestions after the current song and keep the mix going",children:T?"Stop radio":"Start radio"})}),r?e("p",{className:a.statusMsg,children:"Loading suggestions…"}):M.length===0?e("p",{className:a.statusMsg,children:"No suggestions for this song."}):e("div",{className:p.stationList,children:M.map(t=>he(t,Fe,et))})]})]}),h&&e(ct,{track:h,queue:V,shuffle:O,onToggleShuffle:Ke,onTrackStep:Ze,onTrackFailed:We,onClose:()=>{v(null),ee(null)},liked:h?Me(h):!1,likeVisible:L?.authenticated===!0,likePending:P.isPending,onToggleLike:()=>Be(h)})]})};export{Yt as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
._liveBadge_lkioe_1{display:inline-flex;align-items:center;gap:4px;background:var(--accent-dark);color:#fff;font-size:11px;font-weight:700;letter-spacing:.5px;border-radius:4px;padding:2px 8px;white-space:nowrap}._stationList_lkioe_15{display:flex;flex-direction:column;gap:8px}._stationRow_lkioe_21{display:flex;align-items:center;gap:12px;width:100%;text-align:left;background:#ffffff0a;border:1px solid transparent;border-radius:10px;padding:10px 12px;cursor:pointer;color:inherit}._stationRow_lkioe_21:hover{background:#ffffff14}._stationRowActive_lkioe_39{border-color:var(--accent);background:hsla(var(--accent-h),var(--accent-s),var(--accent-l),.12)}._stationThumb_lkioe_44{width:44px;height:44px;border-radius:8px;object-fit:cover;flex-shrink:0;background:#ffffff0f}._stationThumbPlaceholder_lkioe_53{width:44px;height:44px;border-radius:8px;flex-shrink:0;display:flex;align-items:center;justify-content:center;background:#ffffff0f;color:#fff9}._stationMeta_lkioe_65{flex:1;min-width:0}._stationName_lkioe_70{display:block;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._stationSub_lkioe_78{display:block;font-size:12px;opacity:.65;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}._stationNowPlaying_lkioe_87{font-size:12px;color:var(--accent-light);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:40%;text-align:right}._coverWrap_lkioe_97{display:flex;align-items:center;justify-content:center;width:100%;height:100%}._cover_lkioe_97{max-width:min(60vw,420px);max-height:60vh;border-radius:12px;box-shadow:0 8px 40px #00000080}._sectionTitle_lkioe_112{margin:20px 0 10px;font-size:15px;font-weight:700;opacity:.9}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{d as h,A as F,h as y,g as se,u as e,S as P,$ as J,T as K}from"./vendor-core-DfaOB3Rn.js";import{I as o}from"./vendor-icons-DrybRNxP.js";import{b as Z}from"./vendor-query-BBT5_sHx.js";import{h as x,t as G,P as re}from"./index-CnfZwsds.js";import{a}from"./Asmr.module-CdWlioTY.js";import{r as i}from"./Radio.module-DGSZLpKM.js";import{p as L}from"./page.module-C1MlZzf3.js";const ee=300*1e3,le="https://cdn.listen.moe/covers/";function z(n){return n?n.startsWith("http")?n:`${le}${n}`:null}function oe(n){return n?z(n.albums[0]?.image)||z(n.artists[0]?.image)||z(n.sources[0]?.image):null}function U(n){return n?n.artists.map(s=>s.nameRomaji||s.name).join(", "):""}const ie=()=>{const n=x();return Z({...n.radio.stations.queryOptions(),staleTime:ee})},ce=n=>{const s=x();return Z({...s.radio.search.queryOptions({q:n}),enabled:n.trim().length>0,staleTime:ee})},X={song:null,lastPlayed:[],listeners:0,startTime:null},de=n=>{const[s,p]=h(X),[l,c]=h(!1),d=F(null);return y(()=>{if(p(X),c(!1),!n)return;let u=null,f=!1;try{u=new WebSocket(n)}catch{return}return u.onopen=()=>{f||c(!0)},u.onmessage=v=>{try{const m=JSON.parse(v.data);if(m.op===0){const N=m.d?.heartbeat||35e3;d.current&&window.clearInterval(d.current),d.current=window.setInterval(()=>{u&&u.readyState===WebSocket.OPEN&&u.send(JSON.stringify({op:9}))},N)}else m.op===1&&p({song:m.d?.song||null,lastPlayed:m.d?.lastPlayed||[],listeners:m.d?.listeners||0,startTime:m.d?.startTime||null})}catch{}},u.onclose=()=>{f||c(!1)},()=>{f=!0,d.current&&window.clearInterval(d.current),d.current=null,u&&u.close()}},[n]),{nowPlaying:s,connected:l}};function Y(n){if(!n)return"";const s=Math.max(0,Math.floor((Date.now()-new Date(n).getTime())/1e3)),p=Math.floor(s/60),l=s%60;return`${p}:${String(l).padStart(2,"0")}`}const me=({station:n,nowPlaying:s,connected:p,expanded:l,onStationStep:c,onExpandedChange:d,onClose:u})=>{const f=F(null),[v,m]=h(!1),[N,V]=h(!0),[S,I]=h(!1),[T,k]=h(!0),[A,E]=h(""),[b,D]=h(()=>{const t=parseFloat(localStorage.getItem("radioVolume")||"");return Number.isFinite(t)?t:1}),r=F(""),g=F(b);g.current=b,r.current||(r.current=typeof crypto<"u"&&"randomUUID"in crypto?crypto.randomUUID():`radio-${Date.now()}-${Math.random().toString(36).slice(2)}`);const w=s.song,C=oe(w)||n.favicon||null,[B,W]=h(!1);y(()=>{W(!1)},[C]);const M=B?null:C,q=!!M,R=w?`${U(w)} — ${w.title}`:n.name;y(()=>{const t=f.current;if(t)return m(!1),t.src=n.streamUrl,t.load(),t.volume=g.current,t.play().catch(()=>m(!1)),()=>{t.removeAttribute("src")}},[n.id,n.streamUrl]),y(()=>{const t=f.current;t&&(t.volume=b)},[b]),y(()=>{if(l)return document.body.classList.add("asmr-player-open"),()=>document.body.classList.remove("asmr-player-open")},[l]),y(()=>{l&&k(!0)},[l]);const te=t=>t?Math.max(0,Math.floor((Date.now()-new Date(t).getTime())/1e3)):0,H=se.useCallback(t=>{n&&(G.discord.radioPresence.mutate({title:R,stationLabel:n.name,isPlaying:t,thumbnail:M||"",currentTime:te(s.startTime),sessionId:r.current}).catch(()=>{}),G.discord.heartbeat.mutate({sessionId:r.current}).catch(()=>{}))},[n,R,M,s.startTime]);y(()=>{H(v)},[H,v,n.id,R,l]),y(()=>{if(!v)return;const t=window.setInterval(()=>H(!0),15e3);return()=>window.clearInterval(t)},[v,H]),y(()=>{const t=r.current,$=()=>re(t),O=()=>$(),_=()=>{document.visibilityState==="hidden"&&$()};return window.addEventListener("pagehide",O),window.addEventListener("beforeunload",O),document.addEventListener("visibilitychange",_),()=>{window.removeEventListener("pagehide",O),window.removeEventListener("beforeunload",O),document.removeEventListener("visibilitychange",_),$()}},[]),y(()=>{if(!s.startTime){E("");return}E(Y(s.startTime));const t=window.setInterval(()=>E(Y(s.startTime)),1e3);return()=>window.clearInterval(t)},[s.startTime,s.song?.id]),y(()=>{if(!l)return;const t=$=>{$.key==="Escape"&&(S?I(!1):d(!1))};return window.addEventListener("keydown",t),()=>window.removeEventListener("keydown",t)},[l,S,d]);const ae=()=>{const t=f.current;t&&(t.paused?(t.load(),t.play().catch(()=>{})):t.pause())},ne=e(P,{children:[e("div",{className:a.playerButtons,children:[e("button",{className:a.playerBtn,onClick:()=>c(-1),"aria-label":"Previous station",children:e(o,{name:"step-backward"})}),e("button",{className:`${a.playerBtn} ${a.playBtn}`,onClick:ae,"aria-label":v?"Pause":"Play",children:v?e(o,{name:"pause"}):e(o,{name:"play"})}),e("button",{className:a.playerBtn,onClick:()=>c(1),"aria-label":"Next station",children:e(o,{name:"step-forward"})})]}),e("div",{className:a.seekRow,children:[e("span",{className:i.liveBadge,children:[e(o,{name:"broadcast-tower",size:10})," LIVE"]}),A&&e("span",{className:a.timeLabel,children:A}),p&&s.listeners>0&&e("span",{className:a.timeLabel,children:[s.listeners," listening"]}),!p&&n.source==="listen.moe"&&e("span",{className:a.timeLabel,children:"connecting…"})]})]}),j=e(P,{children:[e("button",{className:`${a.playerBtn} ${a.playerToggle}`,onClick:()=>d(!l),"aria-label":l?"Minimize player":"Expand player",title:l?"Minimize to browse":"Expand",children:l?e(o,{name:"chevron-down"}):e(o,{name:"chevron-up"})}),e("div",{className:a.playerInfo,children:[e("p",{className:a.playerTitle,title:R,children:R}),e("p",{className:a.playerTrack,children:n.name})]}),e("div",{className:a.playerControls,children:ne}),e("div",{className:a.playerRight,children:[b===0?e(o,{name:"volume-mute",className:a.volumeIcon}):b<.5?e(o,{name:"volume-down",className:a.volumeIcon}):e(o,{name:"volume-up",className:a.volumeIcon}),e("input",{className:a.volumeBar,type:"range",min:0,max:1,step:.01,value:b,onChange:t=>{const $=parseFloat(t.target.value);D($),localStorage.setItem("radioVolume",String($))},style:{"--volume-percent":`${b*100}%`},"aria-label":"Volume"})]}),e("div",{className:a.playerActions,children:[l&&q&&e("button",{className:a.playerBtn,onClick:()=>V(t=>!t),"aria-label":N?"Hide art":"Show art",title:N?"Hide art":"Show art",children:N?e(o,{name:"eye-slash"}):e(o,{name:"image"})}),l&&s.lastPlayed.length>0&&e("button",{className:`${a.playerBtn} ${S?a.playerBtnActive:""}`,onClick:()=>I(t=>!t),"aria-label":S?"Hide history":"Show history",title:"Recently played",children:e(o,{name:"list-ol"})}),e("button",{className:a.playerBtn,onClick:u,"aria-label":"Close player",children:e(o,{name:"times"})})]})]}),Q=e("audio",{ref:f,preload:"none",onPlay:()=>m(!0),onPause:()=>m(!1)});return l?J(e(P,{children:[Q,e("div",{className:`${a.npOverlay} ${T?"":a.npOverlayControlsHidden}`,children:[e("div",{className:`${a.npStage} ${!N||!q?a.npStageBlank:""}`,onClick:()=>k(t=>!t),children:N&&q&&M&&e("div",{className:i.coverWrap,children:e("img",{src:M,alt:R,loading:"lazy",decoding:"async",draggable:!1,className:i.cover,onError:()=>W(!0)})})}),e("div",{className:`${a.playerBar} ${a.playerBarDocked} ${T?"":a.playerBarDockedHidden}`,onClick:t=>t.stopPropagation(),children:[j,S&&e(P,{children:[e("div",{className:a.npBackdrop,onClick:()=>I(!1)}),e("div",{className:a.chapterPanel,children:s.lastPlayed.map(t=>e("div",{className:a.chapterRow,children:e("span",{className:a.chapterRowLabel,title:`${U(t)} — ${t.title}`,children:[U(t)," — ",t.title]})},t.id))})]})]})]})]}),document.body):J(e(P,{children:[Q,e("div",{className:a.playerBar,children:j})]}),document.body)},Ne=()=>{y(()=>{document.title="Radio - dango"},[]);const[n,s]=h(""),[p,l]=h(""),[c,d]=h(null),[u,f]=h(!0),{data:v,isLoading:m}=ie(),{data:N,isLoading:V}=ce(p),S=K(()=>v?.stations||[],[v]),I=K(()=>N?.stations||[],[N]),T=p?I:S,{nowPlaying:k,connected:A}=de(c?.gateway),E=r=>{d(r),f(!0)},b=r=>{const g=T.length>0?T:S;if(g.length===0||!c)return;const w=g.findIndex(B=>B.id===c.id),C=g[(w<0?0:w+r+g.length)%g.length];d(C)},D=r=>{const g=c?.id===r.id,w=g&&k.song?`${U(k.song)} — ${k.song.title}`:null,C=[r.codec,r.bitrate?`${r.bitrate}k`:"",r.tags].filter(Boolean).join(" · ");return e("button",{className:`${i.stationRow} ${g?i.stationRowActive:""}`,onClick:()=>E(r),children:[r.favicon?e("img",{src:r.favicon,alt:"",className:i.stationThumb,loading:"lazy",decoding:"async",onError:B=>{B.target.style.display="none"}}):e("span",{className:i.stationThumbPlaceholder,children:e(o,{name:"broadcast-tower"})}),e("span",{className:i.stationMeta,children:[e("span",{className:i.stationName,children:r.name}),C&&e("span",{className:i.stationSub,children:C})]}),w&&e("span",{className:i.stationNowPlaying,children:w})]},r.id)};return e("div",{className:`${L.page} ${c?L.pageWithPlayer:""}`,children:[e("div",{className:L.header,children:[e("h1",{className:L.pageTitle,children:[e(o,{name:"broadcast-tower"})," Radio"]}),e("form",{className:L.searchForm,onSubmit:r=>{r.preventDefault(),l(n)},children:[e("input",{className:L.searchInput,value:n,onChange:r=>s(r.target.value),placeholder:"Search stations (anime, j-pop, k-pop…)","aria-label":"Search radio stations"}),e("button",{className:L.searchBtn,type:"submit","aria-label":"Search",children:e(o,{name:"search"})})]})]}),p?e(P,{children:[e("h2",{className:i.sectionTitle,children:["Results for “",p,"”"]}),V?e("p",{className:a.statusMsg,children:"Searching…"}):I.length===0?e("p",{className:a.statusMsg,children:"No stations found."}):e("div",{className:i.stationList,children:I.map(D)})]}):e(P,{children:[e("h2",{className:i.sectionTitle,children:"Featured"}),m?e("p",{className:a.statusMsg,children:"Loading…"}):e("div",{className:i.stationList,children:S.map(D)})]}),c&&e(me,{station:c,nowPlaying:k,connected:A,expanded:u,onStationStep:b,onExpandedChange:f,onClose:()=>d(null)})]})};export{Ne as default};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
const t="_liveBadge_lkioe_1",o="_stationList_lkioe_15",i="_stationRow_lkioe_21",s="_stationRowActive_lkioe_39",e="_stationThumb_lkioe_44",a="_stationThumbPlaceholder_lkioe_53",n="_stationMeta_lkioe_65",_="_stationName_lkioe_70",c="_stationSub_lkioe_78",l="_stationNowPlaying_lkioe_87",r="_coverWrap_lkioe_97",k="_cover_lkioe_97",v="_sectionTitle_lkioe_112",b={liveBadge:t,stationList:o,stationRow:i,stationRowActive:s,stationThumb:e,stationThumbPlaceholder:a,stationMeta:n,stationName:_,stationSub:c,stationNowPlaying:l,coverWrap:r,cover:k,sectionTitle:v};export{b as r};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{u as e,S as g,L as m}from"./vendor-core-DfaOB3Rn.js";import{I as a}from"./vendor-icons-DrybRNxP.js";import{c as y}from"./useAsmr-BbhQ59bk.js";import{p as s,a as k}from"./MediaCard--cuFxOCS.js";import{a as L}from"./Asmr.module-CdWlioTY.js";import{u as f}from"./usePopup-DS9jMzp6.js";const P=({data:i,anchorRect:d,bookmarked:n,onToggleBookmark:p,onMouseEnter:h,onMouseLeave:u,onRequestClose:N})=>{const{data:c,isLoading:v}=y(i.rjCode||null),r=c?.tracks.length??0,l=r>0,t=!v;return e(k,{anchorRect:d,onMouseEnter:h,onMouseLeave:u,onRequestClose:N,children:[e("div",{className:s.header,children:[i.thumbnail&&e("img",{src:i.thumbnail,alt:i.title,loading:"lazy",decoding:"async",className:L.popupCover}),e("div",{className:s.title,children:i.title}),e("div",{className:s.synopsis,children:i.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:t?l?e(g,{children:[r," track",r===1?"":"s"]}):"No tracks":"Loading tracks…"})]}),i.rating&&e("div",{className:s.metaItem,children:e("span",{children:i.rating.toUpperCase()})}),i.isAdult&&e("div",{className:s.metaItem,children:e("span",{children:"18+"})}),i.progressLabel&&e("div",{className:s.metaItem,children:[e(a,{name:"bookmark",size:12}),e("span",{children:i.progressLabel})]})]}),e("div",{className:s.synopsis,children:!t&&!c?.description?"Loading description…":c?.description??"No description available."})]}),e("div",{className:s.footer,children:[e("div",{className:s.primaryAction,children:l?e(m,{to:i.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}),t?"No tracks":"Loading…"]})}),e("div",{className:s.secondaryActions,children:[e("button",{className:`${s.watchlistBtn} ${n?s.active:""}`,onClick:o=>{o.preventDefault(),o.stopPropagation(),p()},children:[n?e(a,{name:"check",size:12}):e(a,{name:"plus",size:12}),e("span",{children:n?"Remove":"Bookmark"})]}),e(m,{to:i.listenTarget,className:s.detailsBtn,children:"Details"})]})]})]})},S=()=>f();export{P as A,S as u};
|
package/server/dist/app-auth.js
DELETED
|
@@ -1,157 +0,0 @@
|
|
|
1
|
-
import crypto from 'crypto';
|
|
2
|
-
import fs from 'fs';
|
|
3
|
-
import path from 'path';
|
|
4
|
-
import { CONFIG } from './config.js';
|
|
5
|
-
export const LAN_AUTH_COOKIE = 'dango_lan_auth';
|
|
6
|
-
const SESSION_TTL_MS = 30 * 24 * 60 * 60 * 1000;
|
|
7
|
-
function sessionsFile() {
|
|
8
|
-
return path.join(CONFIG.ROOT, 'lan_sessions.json');
|
|
9
|
-
}
|
|
10
|
-
function loadSessions() {
|
|
11
|
-
try {
|
|
12
|
-
if (!fs.existsSync(sessionsFile()))
|
|
13
|
-
return {};
|
|
14
|
-
const raw = fs.readFileSync(sessionsFile(), 'utf8');
|
|
15
|
-
const parsed = JSON.parse(raw);
|
|
16
|
-
const now = Date.now();
|
|
17
|
-
let dirty = false;
|
|
18
|
-
for (const [token, expiry] of Object.entries(parsed)) {
|
|
19
|
-
if (typeof expiry !== 'number' || expiry < now) {
|
|
20
|
-
delete parsed[token];
|
|
21
|
-
dirty = true;
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (dirty)
|
|
25
|
-
saveSessions(parsed);
|
|
26
|
-
return parsed;
|
|
27
|
-
}
|
|
28
|
-
catch {
|
|
29
|
-
return {};
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
function saveSessions(sessions) {
|
|
33
|
-
try {
|
|
34
|
-
fs.mkdirSync(CONFIG.ROOT, { recursive: true });
|
|
35
|
-
fs.writeFileSync(sessionsFile(), JSON.stringify(sessions));
|
|
36
|
-
}
|
|
37
|
-
catch {
|
|
38
|
-
// ignore
|
|
39
|
-
}
|
|
40
|
-
}
|
|
41
|
-
export function getAppPasswordHash() {
|
|
42
|
-
return process.env.APP_PASSWORD_HASH || CONFIG.APP_PASSWORD_HASH || '';
|
|
43
|
-
}
|
|
44
|
-
export function hasAppPassword() {
|
|
45
|
-
return !!getAppPasswordHash();
|
|
46
|
-
}
|
|
47
|
-
export function hashAppPassword(password) {
|
|
48
|
-
const salt = crypto.randomBytes(16).toString('hex');
|
|
49
|
-
const hash = crypto.scryptSync(password, salt, 32).toString('hex');
|
|
50
|
-
return `scrypt:${salt}:${hash}`;
|
|
51
|
-
}
|
|
52
|
-
export function verifyAppPassword(password) {
|
|
53
|
-
const stored = getAppPasswordHash();
|
|
54
|
-
if (!stored)
|
|
55
|
-
return false;
|
|
56
|
-
const parts = stored.split(':');
|
|
57
|
-
if (parts.length !== 3 || parts[0] !== 'scrypt')
|
|
58
|
-
return false;
|
|
59
|
-
const [, salt, expectedHex] = parts;
|
|
60
|
-
try {
|
|
61
|
-
const derived = crypto.scryptSync(password, salt, 32);
|
|
62
|
-
const expected = Buffer.from(expectedHex, 'hex');
|
|
63
|
-
if (derived.length !== expected.length)
|
|
64
|
-
return false;
|
|
65
|
-
return crypto.timingSafeEqual(derived, expected);
|
|
66
|
-
}
|
|
67
|
-
catch {
|
|
68
|
-
return false;
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
export async function setAppPassword(password) {
|
|
72
|
-
const { updateEnvFile } = await import('./utils/env.utils.js');
|
|
73
|
-
if (!password) {
|
|
74
|
-
await updateEnvFile({ APP_PASSWORD_HASH: '' });
|
|
75
|
-
CONFIG.APP_PASSWORD_HASH = '';
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
const hash = hashAppPassword(password);
|
|
79
|
-
await updateEnvFile({ APP_PASSWORD_HASH: hash });
|
|
80
|
-
CONFIG.APP_PASSWORD_HASH = hash;
|
|
81
|
-
}
|
|
82
|
-
export function createLanSession() {
|
|
83
|
-
const token = crypto.randomBytes(32).toString('hex');
|
|
84
|
-
const expiry = Date.now() + SESSION_TTL_MS;
|
|
85
|
-
const sessions = loadSessions();
|
|
86
|
-
sessions[token] = expiry;
|
|
87
|
-
saveSessions(sessions);
|
|
88
|
-
return { token, expiry };
|
|
89
|
-
}
|
|
90
|
-
export function validateLanSession(token) {
|
|
91
|
-
if (!token)
|
|
92
|
-
return false;
|
|
93
|
-
const sessions = loadSessions();
|
|
94
|
-
const expiry = sessions[token];
|
|
95
|
-
if (!expiry)
|
|
96
|
-
return false;
|
|
97
|
-
if (expiry < Date.now()) {
|
|
98
|
-
delete sessions[token];
|
|
99
|
-
saveSessions(sessions);
|
|
100
|
-
return false;
|
|
101
|
-
}
|
|
102
|
-
return true;
|
|
103
|
-
}
|
|
104
|
-
export function revokeLanSession(token) {
|
|
105
|
-
if (!token)
|
|
106
|
-
return;
|
|
107
|
-
const sessions = loadSessions();
|
|
108
|
-
if (sessions[token]) {
|
|
109
|
-
delete sessions[token];
|
|
110
|
-
saveSessions(sessions);
|
|
111
|
-
}
|
|
112
|
-
}
|
|
113
|
-
export function clearAllLanSessions() {
|
|
114
|
-
saveSessions({});
|
|
115
|
-
}
|
|
116
|
-
export function normalizeClientIp(ip) {
|
|
117
|
-
if (!ip)
|
|
118
|
-
return '';
|
|
119
|
-
if (ip.startsWith('::ffff:'))
|
|
120
|
-
return ip.slice('::ffff:'.length);
|
|
121
|
-
return ip;
|
|
122
|
-
}
|
|
123
|
-
export function isLoopbackIp(ip) {
|
|
124
|
-
const normalized = normalizeClientIp(ip);
|
|
125
|
-
return normalized === '127.0.0.1' || normalized === '::1';
|
|
126
|
-
}
|
|
127
|
-
export function getTokenFromHeaders(authorization, cookieHeader) {
|
|
128
|
-
if (authorization && authorization.toLowerCase().startsWith('bearer ')) {
|
|
129
|
-
return authorization.slice(7).trim() || null;
|
|
130
|
-
}
|
|
131
|
-
if (cookieHeader) {
|
|
132
|
-
const parts = cookieHeader.split(';');
|
|
133
|
-
for (const part of parts) {
|
|
134
|
-
const idx = part.indexOf('=');
|
|
135
|
-
if (idx === -1)
|
|
136
|
-
continue;
|
|
137
|
-
const name = part.slice(0, idx).trim();
|
|
138
|
-
if (name === LAN_AUTH_COOKIE) {
|
|
139
|
-
return decodeURIComponent(part.slice(idx + 1).trim()) || null;
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
return null;
|
|
144
|
-
}
|
|
145
|
-
export const LAN_AUTH_PUBLIC_PATHS = new Set([
|
|
146
|
-
'/api/auth/app-status',
|
|
147
|
-
'/api/auth/app-login',
|
|
148
|
-
'/api/auth/app-logout',
|
|
149
|
-
'/api/internal/shutdown',
|
|
150
|
-
]);
|
|
151
|
-
export function buildLanCookie(token, expiry) {
|
|
152
|
-
const maxAge = Math.max(1, Math.floor((expiry - Date.now()) / 1000));
|
|
153
|
-
return `${LAN_AUTH_COOKIE}=${encodeURIComponent(token)}; HttpOnly; Path=/; Max-Age=${maxAge}; SameSite=Lax`;
|
|
154
|
-
}
|
|
155
|
-
export function clearLanCookie() {
|
|
156
|
-
return `${LAN_AUTH_COOKIE}=; HttpOnly; Path=/; Max-Age=0; SameSite=Lax`;
|
|
157
|
-
}
|