mirror of
https://github.com/jeffvli/feishin.git
synced 2026-05-08 13:00:13 +02:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| e49e488b4c | |||
| 5d4547080d | |||
| cc8910cfd6 | |||
| 9fb241dca2 | |||
| e3a0879301 | |||
| 953494e9d0 | |||
| f190626c8c | |||
| 324936e0c8 | |||
| 868ec15b16 | |||
| 775c4e68fa | |||
| 34e0c4bd4a | |||
| 323130a877 | |||
| 3b2aab74ac |
@@ -409,7 +409,8 @@
|
|||||||
"input_skipDuplicates": "salta't els duplicats",
|
"input_skipDuplicates": "salta't els duplicats",
|
||||||
"success": "s'ha afegit $t(entity.trackWithCount, {\"count\": {{message}} }) a $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })",
|
"success": "s'ha afegit $t(entity.trackWithCount, {\"count\": {{message}} }) a $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })",
|
||||||
"create": "crea $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "crea $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "cerca $t(entity.playlist, {\"count\": 2}) o escriu per crear-ne una de nova"
|
"searchOrCreate": "cerca $t(entity.playlist, {\"count\": 2}) o escriu per crear-ne una de nova",
|
||||||
|
"noneAdded": "no s'han afegit pistes a la $t(entity.playlist, {\"count\": 1}) '{{playlist}}'"
|
||||||
},
|
},
|
||||||
"createPlaylist": {
|
"createPlaylist": {
|
||||||
"input_description": "$t(common.description)",
|
"input_description": "$t(common.description)",
|
||||||
@@ -935,7 +936,9 @@
|
|||||||
"sidePlayQueueLayout_optionHorizontal": "horitzontal",
|
"sidePlayQueueLayout_optionHorizontal": "horitzontal",
|
||||||
"sidePlayQueueLayout_optionVertical": "vertical",
|
"sidePlayQueueLayout_optionVertical": "vertical",
|
||||||
"waveformLoadingDelay": "demora de càrrega de la forma d'ona",
|
"waveformLoadingDelay": "demora de càrrega de la forma d'ona",
|
||||||
"waveformLoadingDelay_description": "demora en segons abans de carregar la forma d'ona. incrementeu aquest valor si patiu interrupcions en fer servir el reproductor web."
|
"waveformLoadingDelay_description": "demora en segons abans de carregar la forma d'ona. incrementeu aquest valor si patiu interrupcions en fer servir el reproductor web.",
|
||||||
|
"preventSuspendOnPlayback_description": "evita que l'aplicació quedi suspesa mentre es reprodueix música",
|
||||||
|
"preventSuspendOnPlayback": "evita la suspensió durant la reproducció"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"column": {
|
"column": {
|
||||||
|
|||||||
@@ -427,7 +427,9 @@
|
|||||||
"waveformLoadingDelay": "zpoždění načítání vlnové křivky",
|
"waveformLoadingDelay": "zpoždění načítání vlnové křivky",
|
||||||
"waveformLoadingDelay_description": "zpoždění v sekundách před načtením vlnové křivky. zvyšte, pokud jste během používání webového přehrávače zaznamenali záseky.",
|
"waveformLoadingDelay_description": "zpoždění v sekundách před načtením vlnové křivky. zvyšte, pokud jste během používání webového přehrávače zaznamenali záseky.",
|
||||||
"playerbarWaveformStretch": "natáhnutí vlnové křivky",
|
"playerbarWaveformStretch": "natáhnutí vlnové křivky",
|
||||||
"playerbarWaveformStretch_description": "natáhně vlnovou křivku tak, aby vyplnila dostupný prostor"
|
"playerbarWaveformStretch_description": "natáhně vlnovou křivku tak, aby vyplnila dostupný prostor",
|
||||||
|
"preventSuspendOnPlayback_description": "zabránit aplikaci v uspání během přehrávání hudby",
|
||||||
|
"preventSuspendOnPlayback": "zabránit uspání při přehrávání"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"editPlaylist": "upravit $t(entity.playlist, {\"count\": 1})",
|
"editPlaylist": "upravit $t(entity.playlist, {\"count\": 1})",
|
||||||
@@ -1045,7 +1047,8 @@
|
|||||||
"input_skipDuplicates": "přeskočit duplicity",
|
"input_skipDuplicates": "přeskočit duplicity",
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
"create": "vytvořit $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "vytvořit $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "vyhledejte $t(entity.playlist, {\"count\": 2}) nebo pište pro vytvoření nového"
|
"searchOrCreate": "vyhledejte $t(entity.playlist, {\"count\": 2}) nebo pište pro vytvoření nového",
|
||||||
|
"noneAdded": "do $t(entity.playlist, {\"count\": 1}) '{{playlist}}' nebyly přidány žádné skladby"
|
||||||
},
|
},
|
||||||
"updateServer": {
|
"updateServer": {
|
||||||
"title": "upravit server",
|
"title": "upravit server",
|
||||||
|
|||||||
@@ -1008,6 +1008,8 @@
|
|||||||
"audioFadeOnStatusChange_description": "enables fade out and fade in when play/pause status changes",
|
"audioFadeOnStatusChange_description": "enables fade out and fade in when play/pause status changes",
|
||||||
"preventSleepOnPlayback_description": "prevent the display from sleeping while music is playing",
|
"preventSleepOnPlayback_description": "prevent the display from sleeping while music is playing",
|
||||||
"preventSleepOnPlayback": "prevent sleep on playback",
|
"preventSleepOnPlayback": "prevent sleep on playback",
|
||||||
|
"preventSuspendOnPlayback_description": "prevent the application from suspending while music is playing",
|
||||||
|
"preventSuspendOnPlayback": "prevent suspend on playback",
|
||||||
"remotePassword_description": "sets the password for the remote control server. These credentials are by default transferred insecurely, so you should use a unique password that you do not care about",
|
"remotePassword_description": "sets the password for the remote control server. These credentials are by default transferred insecurely, so you should use a unique password that you do not care about",
|
||||||
"remotePassword": "remote control server password",
|
"remotePassword": "remote control server password",
|
||||||
"remotePort_description": "sets the port for the remote control server",
|
"remotePort_description": "sets the port for the remote control server",
|
||||||
|
|||||||
@@ -427,7 +427,9 @@
|
|||||||
"waveformLoadingDelay": "Retraso de carga de la forma de onda",
|
"waveformLoadingDelay": "Retraso de carga de la forma de onda",
|
||||||
"waveformLoadingDelay_description": "Retraso en segundos antes de cargar la forma de onda. Incrementa este valor si estás experimentando tartamudeos al usar el reproductor web.",
|
"waveformLoadingDelay_description": "Retraso en segundos antes de cargar la forma de onda. Incrementa este valor si estás experimentando tartamudeos al usar el reproductor web.",
|
||||||
"playerbarWaveformStretch": "Estiramiento de la forma de onda",
|
"playerbarWaveformStretch": "Estiramiento de la forma de onda",
|
||||||
"playerbarWaveformStretch_description": "Estira la forma de onda para rellenar el espacio disponible"
|
"playerbarWaveformStretch_description": "Estira la forma de onda para rellenar el espacio disponible",
|
||||||
|
"preventSuspendOnPlayback": "Evitar la suspensión durante la reproducción",
|
||||||
|
"preventSuspendOnPlayback_description": "Evita que la aplicación se suspenda mientras se reproduce música"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"editPlaylist": "editar $t(entity.playlist, {\"count\": 1})",
|
"editPlaylist": "editar $t(entity.playlist, {\"count\": 1})",
|
||||||
@@ -936,7 +938,8 @@
|
|||||||
"input_skipDuplicates": "saltar duplicados",
|
"input_skipDuplicates": "saltar duplicados",
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
"create": "Crear $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "Crear $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "Buscar $t(entity.playlist, {\"count\": 2}) o escribir para crear uno nuevo"
|
"searchOrCreate": "Buscar $t(entity.playlist, {\"count\": 2}) o escribir para crear uno nuevo",
|
||||||
|
"noneAdded": "Ninguna pista fue añadida a $t(entity.playlist, {\"count\": 1}) '{{playlist}}'"
|
||||||
},
|
},
|
||||||
"updateServer": {
|
"updateServer": {
|
||||||
"title": "actualizar servidor",
|
"title": "actualizar servidor",
|
||||||
|
|||||||
@@ -157,7 +157,8 @@
|
|||||||
"doNotShowAgain": "ez erakutsi hau berriro",
|
"doNotShowAgain": "ez erakutsi hau berriro",
|
||||||
"numberOfResults": "{{numberOfResults}} emaitza",
|
"numberOfResults": "{{numberOfResults}} emaitza",
|
||||||
"rename": "berrizendatu",
|
"rename": "berrizendatu",
|
||||||
"newVersionAvailable": "bertsio berri bat eskuragarri dago"
|
"newVersionAvailable": "bertsio berri bat eskuragarri dago",
|
||||||
|
"gridRows": "sareta-errenkadak"
|
||||||
},
|
},
|
||||||
"player": {
|
"player": {
|
||||||
"repeat": "errepikatu",
|
"repeat": "errepikatu",
|
||||||
@@ -409,7 +410,8 @@
|
|||||||
"fromYear": "urtetik aurrera",
|
"fromYear": "urtetik aurrera",
|
||||||
"explicitStatus": "$t(common.explicitStatus)",
|
"explicitStatus": "$t(common.explicitStatus)",
|
||||||
"matchAnd": "eta",
|
"matchAnd": "eta",
|
||||||
"matchOr": "edo"
|
"matchOr": "edo",
|
||||||
|
"sortName": "izenaren arabera ordenatu"
|
||||||
},
|
},
|
||||||
"setting": {
|
"setting": {
|
||||||
"hotkey_playbackPause": "pausatu",
|
"hotkey_playbackPause": "pausatu",
|
||||||
@@ -643,7 +645,7 @@
|
|||||||
"passwordStore_description": "zein pasahitz/sekretu biltegi erabili. aldatu hau pasahitzak gordetzeko arazoak badituzu",
|
"passwordStore_description": "zein pasahitz/sekretu biltegi erabili. aldatu hau pasahitzak gordetzeko arazoak badituzu",
|
||||||
"playerFilters": "Iragazi ilarako abestiak",
|
"playerFilters": "Iragazi ilarako abestiak",
|
||||||
"sidePlayQueueStyle_description": "alboko erreprodukzio-ilararen estiloa ezartzen du",
|
"sidePlayQueueStyle_description": "alboko erreprodukzio-ilararen estiloa ezartzen du",
|
||||||
"mediaSession_description": "Windows Media Session integrazioa gaitzen du, multimedia kontrolak eta metadatuak sistemaren bolumenaren gainjartzean eta blokeo pantailan bistaratuz (Windows bakarrik)",
|
"mediaSession_description": "Media Session integrazioa gaitzen du, multimedia kontrolak eta metadatuak sistemaren bolumenaren gainjartzean eta blokeo pantailan bistaratuz",
|
||||||
"sidePlayQueueStyle": "alboko erreprodukzio-ilarako estiloa",
|
"sidePlayQueueStyle": "alboko erreprodukzio-ilarako estiloa",
|
||||||
"skipPlaylistPage": "saltatu erreprodukzio-zerrenda orria",
|
"skipPlaylistPage": "saltatu erreprodukzio-zerrenda orria",
|
||||||
"startMinimized_description": "abiarazi aplikazioa sistemaren erretiluan",
|
"startMinimized_description": "abiarazi aplikazioa sistemaren erretiluan",
|
||||||
@@ -714,7 +716,19 @@
|
|||||||
"preservePitch": "mantendu tonua",
|
"preservePitch": "mantendu tonua",
|
||||||
"preventSleepOnPlayback": "erreprodukzioan loa saihestu",
|
"preventSleepOnPlayback": "erreprodukzioan loa saihestu",
|
||||||
"replayGainClipping_description": "Saihestu {{ReplayGain}}-k eragindako mozketa irabazpena automatikoki jaitsiz",
|
"replayGainClipping_description": "Saihestu {{ReplayGain}}-k eragindako mozketa irabazpena automatikoki jaitsiz",
|
||||||
"replayGainMode_description": "doitu bolumenaren irabazia fitxategiaren metadatuetan gordetako {{ReplayGain}} balioen arabera"
|
"replayGainMode_description": "doitu bolumenaren irabazia fitxategiaren metadatuetan gordetako {{ReplayGain}} balioen arabera",
|
||||||
|
"listenbrainz": "erakutsi ListenBrainz estekak",
|
||||||
|
"sidebarPlaylistSorting": "alboko barrako erreprodukzio-zerrenda ordenatzea",
|
||||||
|
"sidebarPlaylistListFilterRegex_description": "ezkutatu alboko barran adierazpen erregular honekin bat datozen erreprodukzio-zerrendak",
|
||||||
|
"sidebarPlaylistListFilterRegex_placeholder": "adib. ^Eguneroko Nahasketa.*",
|
||||||
|
"sidebarPlaylistListFilterRegex": "erreprodukzio-zerrenda iragazteko adierazpen erregularra",
|
||||||
|
"sidePlayQueueLayout": "alboko erreprodukzio-ilararen diseinua",
|
||||||
|
"sidePlayQueueLayout_description": "erantsitako alboko erreprodukzio-ilararen diseinua ezartzen du",
|
||||||
|
"sidePlayQueueLayout_optionHorizontal": "horizontala",
|
||||||
|
"sidePlayQueueLayout_optionVertical": "bertikala",
|
||||||
|
"skipDuration_description": "erreproduzitzailearen barran saltatzeko botoiak erabiltzean saltatzeko iraupena ezartzen du",
|
||||||
|
"skipPlaylistPage_description": "erreprodukzio-zerrenda batera nabigatzean, joan erreprodukzio-zerrendako abestien zerrendara lehenetsitako orrialdera joan beharrean",
|
||||||
|
"translationApiKey_description": "itzulpenerako api gakoa (zerbitzu globalaren amaiera-puntua soilik)"
|
||||||
},
|
},
|
||||||
"form": {
|
"form": {
|
||||||
"addServer": {
|
"addServer": {
|
||||||
@@ -731,7 +745,9 @@
|
|||||||
"success": "zerbitzaria behar bezala gehitu da",
|
"success": "zerbitzaria behar bezala gehitu da",
|
||||||
"input_preferInstantMix": "nahiago izan berehalako nahasketa",
|
"input_preferInstantMix": "nahiago izan berehalako nahasketa",
|
||||||
"input_preferInstantMixDescription": "erabili berehalako nahasketa soilik antzeko abestiak lortzeko. erabilgarria portaera hau aldatzen duten pluginak badituzu",
|
"input_preferInstantMixDescription": "erabili berehalako nahasketa soilik antzeko abestiak lortzeko. erabilgarria portaera hau aldatzen duten pluginak badituzu",
|
||||||
"input_remoteUrl": "URL publikoa"
|
"input_remoteUrl": "URL publikoa",
|
||||||
|
"input_preferRemoteUrl": "url publikoa nahiago izan",
|
||||||
|
"input_remoteUrlPlaceholder": "aukerakoa: kanpoko funtzioetarako url publikoa"
|
||||||
},
|
},
|
||||||
"addToPlaylist": {
|
"addToPlaylist": {
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
@@ -739,7 +755,8 @@
|
|||||||
"input_skipDuplicates": "saltatu bikoiztuak",
|
"input_skipDuplicates": "saltatu bikoiztuak",
|
||||||
"title": "gehitu $t(entity.playlist, {\"count\": 1})-(a)ri",
|
"title": "gehitu $t(entity.playlist, {\"count\": 1})-(a)ri",
|
||||||
"create": "sortu $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "sortu $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "bilatu $t(entity.playlist, {\"count\": 2}) edo idatzi berri bat sortzeko"
|
"searchOrCreate": "bilatu $t(entity.playlist, {\"count\": 2}) edo idatzi berri bat sortzeko",
|
||||||
|
"noneAdded": "ez da pistarik gehitu honi $t(entity.playlist, {\"count\": 1}) '{{playlist}}'"
|
||||||
},
|
},
|
||||||
"createPlaylist": {
|
"createPlaylist": {
|
||||||
"input_description": "$t(common.description)",
|
"input_description": "$t(common.description)",
|
||||||
@@ -760,7 +777,9 @@
|
|||||||
"success": "partekatzeko esteka arbelera kopiatu da (edo egin klik hemen irekitzeko)",
|
"success": "partekatzeko esteka arbelera kopiatu da (edo egin klik hemen irekitzeko)",
|
||||||
"expireInvalid": "iraungitze-data etorkizunean izan behar da",
|
"expireInvalid": "iraungitze-data etorkizunean izan behar da",
|
||||||
"allowDownloading": "baimendu deskargatzea",
|
"allowDownloading": "baimendu deskargatzea",
|
||||||
"createFailed": "partekatzea sortzeak huts egin du (partekatzea gaituta al dago?)"
|
"createFailed": "partekatzea sortzeak huts egin du (partekatzea gaituta al dago?)",
|
||||||
|
"copyToClipboard": "Kopiatu arbelean: Ctrl+C, Enter",
|
||||||
|
"successMustClick": "partekatzea behar bezala sortu da. egin klik hemen irekitzeko"
|
||||||
},
|
},
|
||||||
"deletePlaylist": {
|
"deletePlaylist": {
|
||||||
"success": "$t(entity.playlist, {\"count\": 1}) behar bezala ezabatu da",
|
"success": "$t(entity.playlist, {\"count\": 1}) behar bezala ezabatu da",
|
||||||
@@ -988,7 +1007,10 @@
|
|||||||
"recentReleases": "azken argitalpenak",
|
"recentReleases": "azken argitalpenak",
|
||||||
"viewDiscography": "ikusi diskografia",
|
"viewDiscography": "ikusi diskografia",
|
||||||
"groupingTypeAll": "argitalpen mota guztiak",
|
"groupingTypeAll": "argitalpen mota guztiak",
|
||||||
"groupingTypePrimary": "argitalpen mota nagusiak"
|
"groupingTypePrimary": "argitalpen mota nagusiak",
|
||||||
|
"favoriteSongs": "abesti gogokoenak",
|
||||||
|
"topSongsCommunity": "komunitatea",
|
||||||
|
"topSongsPersonal": "pertsonala"
|
||||||
},
|
},
|
||||||
"itemDetail": {
|
"itemDetail": {
|
||||||
"copyPath": "kopiatu bidea arbelean",
|
"copyPath": "kopiatu bidea arbelean",
|
||||||
@@ -1006,6 +1028,13 @@
|
|||||||
},
|
},
|
||||||
"radioList": {
|
"radioList": {
|
||||||
"title": "irrati-kateak"
|
"title": "irrati-kateak"
|
||||||
|
},
|
||||||
|
"releasenotes": {
|
||||||
|
"noStableReleaseToCompare": "ez dago bertsio egonkorrik alderatzeko"
|
||||||
|
},
|
||||||
|
"windowBar": {
|
||||||
|
"paused": "(Pausatuta) ",
|
||||||
|
"privateMode": "(Modu pribatua)"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"releaseType": {
|
"releaseType": {
|
||||||
@@ -1038,7 +1067,19 @@
|
|||||||
"notContains": "ez dauka",
|
"notContains": "ez dauka",
|
||||||
"startsWith": "honekin hasten da",
|
"startsWith": "honekin hasten da",
|
||||||
"endsWith": "honekin amaitzen da",
|
"endsWith": "honekin amaitzen da",
|
||||||
"isNot": "ez da"
|
"isNot": "ez da",
|
||||||
|
"afterDate": "(data) ondoren da",
|
||||||
|
"after": "ondoren da",
|
||||||
|
"before": "lehenago da",
|
||||||
|
"beforeDate": "(data) baino lehenagokoa da",
|
||||||
|
"inTheLast": "azkenengoan dago",
|
||||||
|
"inPlaylist": "bertan dago",
|
||||||
|
"inTheRange": "tartean dago",
|
||||||
|
"inTheRangeDate": "(data) tartean dago",
|
||||||
|
"isGreaterThan": "hau baino handiagoa da",
|
||||||
|
"isLessThan": "hau baino gutxiago da",
|
||||||
|
"notInPlaylist": "ez dago barruan",
|
||||||
|
"notInTheLast": "ez dago azkenengoan"
|
||||||
},
|
},
|
||||||
"visualizer": {
|
"visualizer": {
|
||||||
"general": "Orokorra",
|
"general": "Orokorra",
|
||||||
|
|||||||
@@ -85,7 +85,7 @@
|
|||||||
"hotkey_zoomIn": "拡大",
|
"hotkey_zoomIn": "拡大",
|
||||||
"scrobble_description": "再生した音楽をメディアサーバーから Scrobble します",
|
"scrobble_description": "再生した音楽をメディアサーバーから Scrobble します",
|
||||||
"hotkey_browserForward": "ブラウザ 進む",
|
"hotkey_browserForward": "ブラウザ 進む",
|
||||||
"audioExclusiveMode_description": "排他出力モードを有効にします。このモードでは、システムの他の出力がロックされ、MPV のみがオーディオを出力できるようになります",
|
"audioExclusiveMode_description": "排他出力モードを有効にします。このモードでは、システムの他の出力がロックされ、MPV のみがオーディオを出力できるようになります。このモードが有効になっている間は、ビジュアライザーやシステムオーディオのキャプチャ機能は動作しません",
|
||||||
"discordUpdateInterval": "{{discord}} Rich Presence の更新間隔",
|
"discordUpdateInterval": "{{discord}} Rich Presence の更新間隔",
|
||||||
"themeLight": "テーマ (ライト)",
|
"themeLight": "テーマ (ライト)",
|
||||||
"fontType_optionBuiltIn": "組み込みフォント",
|
"fontType_optionBuiltIn": "組み込みフォント",
|
||||||
@@ -425,7 +425,11 @@
|
|||||||
"sidePlayQueueLayout_optionHorizontal": "水平",
|
"sidePlayQueueLayout_optionHorizontal": "水平",
|
||||||
"sidePlayQueueLayout_optionVertical": "垂直",
|
"sidePlayQueueLayout_optionVertical": "垂直",
|
||||||
"waveformLoadingDelay": "波形読み込みの遅延",
|
"waveformLoadingDelay": "波形読み込みの遅延",
|
||||||
"waveformLoadingDelay_description": "波形を読み込むまでの遅延時間(秒単位)を設定します。Web プレーヤー使用時にカクつきが発生する場合は、この値を増やしてください。"
|
"waveformLoadingDelay_description": "波形を読み込むまでの遅延時間(秒単位)を設定します。Web プレーヤー使用時にカクつきが発生する場合は、この値を増やしてください。",
|
||||||
|
"playerbarWaveformStretch": "波形伸縮",
|
||||||
|
"playerbarWaveformStretch_description": "波形を伸縮させて、利用可能なスペースを埋めます",
|
||||||
|
"preventSuspendOnPlayback_description": "音楽再生中にアプリケーションが停止しないようにします",
|
||||||
|
"preventSuspendOnPlayback": "再生の中断を防止する"
|
||||||
},
|
},
|
||||||
"action": {
|
"action": {
|
||||||
"editPlaylist": "$t(entity.playlist, {\"count\": 1}) を編集",
|
"editPlaylist": "$t(entity.playlist, {\"count\": 1}) を編集",
|
||||||
@@ -808,7 +812,7 @@
|
|||||||
"dynamicBackground": "ダイナミック背景",
|
"dynamicBackground": "ダイナミック背景",
|
||||||
"synchronized": "同期",
|
"synchronized": "同期",
|
||||||
"followCurrentLyric": "歌詞を再生位置に追従",
|
"followCurrentLyric": "歌詞を再生位置に追従",
|
||||||
"opacity": "非透過率",
|
"opacity": "不透明度",
|
||||||
"lyricSize": "歌詞のサイズ",
|
"lyricSize": "歌詞のサイズ",
|
||||||
"showLyricProvider": "歌詞の提供元を表示",
|
"showLyricProvider": "歌詞の提供元を表示",
|
||||||
"unsynchronized": "非同期",
|
"unsynchronized": "非同期",
|
||||||
@@ -817,7 +821,9 @@
|
|||||||
"lyricGap": "歌詞の間隔",
|
"lyricGap": "歌詞の間隔",
|
||||||
"dynamicImageBlur": "画像のぼかしサイズ",
|
"dynamicImageBlur": "画像のぼかしサイズ",
|
||||||
"dynamicIsImage": "背景画像を有効にする",
|
"dynamicIsImage": "背景画像を有効にする",
|
||||||
"lyricOffset": "歌詞のオフセット (ms)"
|
"lyricOffset": "歌詞のオフセット (ms)",
|
||||||
|
"lyricOpacityNonActive": "非アクティブな歌詞の不透明度",
|
||||||
|
"lyricScaleNonActive": "非アクティブな歌詞のスケール"
|
||||||
},
|
},
|
||||||
"upNext": "次へ",
|
"upNext": "次へ",
|
||||||
"lyrics": "歌詞",
|
"lyrics": "歌詞",
|
||||||
@@ -1033,7 +1039,8 @@
|
|||||||
"input_skipDuplicates": "重複をスキップ",
|
"input_skipDuplicates": "重複をスキップ",
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
"create": "$t(entity.playlist, {\"count\": 1}) {{playlist}} を作成する",
|
"create": "$t(entity.playlist, {\"count\": 1}) {{playlist}} を作成する",
|
||||||
"searchOrCreate": "$t(entity.playlist, {\"count\": 2}) を検索するか、入力して新しいプレイリストを作成してください"
|
"searchOrCreate": "$t(entity.playlist, {\"count\": 2}) を検索するか、入力して新しいプレイリストを作成してください",
|
||||||
|
"noneAdded": "$t(entity.playlist, {\"count\": 1}) {{playlist}} にトラックが追加されませんでした"
|
||||||
},
|
},
|
||||||
"updateServer": {
|
"updateServer": {
|
||||||
"title": "サーバーをアップデート",
|
"title": "サーバーをアップデート",
|
||||||
@@ -1341,6 +1348,7 @@
|
|||||||
"systemAudioConsentDecline": "拒否",
|
"systemAudioConsentDecline": "拒否",
|
||||||
"systemAudioConsentTitle": "システムオーディオへのアクセスを許可しますか?",
|
"systemAudioConsentTitle": "システムオーディオへのアクセスを許可しますか?",
|
||||||
"systemAudioCaptureFailed": "キャプチャを開始できませんでした: {{message}}",
|
"systemAudioCaptureFailed": "キャプチャを開始できませんでした: {{message}}",
|
||||||
"systemAudioNoAudioTrack": "音声トラックが返されませんでした。プロンプトが表示されたら、音声キャプチャが有効になっていることを確認してください。"
|
"systemAudioNoAudioTrack": "音声トラックが返されませんでした。プロンプトが表示されたら、音声キャプチャが有効になっていることを確認してください。",
|
||||||
|
"systemAudioExclusiveModeNotSupported": "オーディオ排他モードが有効になっている間は、ビジュアライザーは利用できません。MPV の設定でオーディオ排他モードを無効にしてから、もう一度お試しください。"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -352,7 +352,8 @@
|
|||||||
"input_skipDuplicates": "pomiń duplikaty",
|
"input_skipDuplicates": "pomiń duplikaty",
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
"create": "utwórz $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "utwórz $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "wyszukaj $t(entity.playlist, {\"count\": 2}) lub wpisz, aby utworzyć nową"
|
"searchOrCreate": "wyszukaj $t(entity.playlist, {\"count\": 2}) lub wpisz, aby utworzyć nową",
|
||||||
|
"noneAdded": "nie dodano utworów do $t(entity.playlist, {\"count\": 1}) '{{playlist}}'"
|
||||||
},
|
},
|
||||||
"updateServer": {
|
"updateServer": {
|
||||||
"title": "uaktualnij serwer",
|
"title": "uaktualnij serwer",
|
||||||
@@ -1066,7 +1067,11 @@
|
|||||||
"sidePlayQueueLayout_optionHorizontal": "poziomy",
|
"sidePlayQueueLayout_optionHorizontal": "poziomy",
|
||||||
"sidePlayQueueLayout_optionVertical": "pionowy",
|
"sidePlayQueueLayout_optionVertical": "pionowy",
|
||||||
"waveformLoadingDelay": "opóźnienie załadowania fali",
|
"waveformLoadingDelay": "opóźnienie załadowania fali",
|
||||||
"waveformLoadingDelay_description": "opóźnienie w sekundach przed załadowaniem fali. zwiększ tą wartość jeżeli doświadczasz zawieszania się odtwarzacza przeglądarkowego."
|
"waveformLoadingDelay_description": "opóźnienie w sekundach przed załadowaniem fali. zwiększ tą wartość jeżeli doświadczasz zawieszania się odtwarzacza przeglądarkowego.",
|
||||||
|
"playerbarWaveformStretch": "rozciąganie przebiegu",
|
||||||
|
"playerbarWaveformStretch_description": "rozciąga przebieg aby wypełnić dostępną przestrzeń",
|
||||||
|
"preventSuspendOnPlayback_description": "powstrzymuj wstrzymanie podczas odtwarzania muzyki",
|
||||||
|
"preventSuspendOnPlayback": "powstrzymuje wstrzymanie przy odtwarzaniu"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"config": {
|
"config": {
|
||||||
|
|||||||
+37
-10
@@ -170,7 +170,8 @@
|
|||||||
"explicit": "нецензурная лексика",
|
"explicit": "нецензурная лексика",
|
||||||
"externalLinks": "внешние ссылки",
|
"externalLinks": "внешние ссылки",
|
||||||
"explicitStatus": "признак нецензурного контента",
|
"explicitStatus": "признак нецензурного контента",
|
||||||
"newVersionAvailable": "доступна новая версия"
|
"newVersionAvailable": "доступна новая версия",
|
||||||
|
"numberOfResults": "{{numberOfResults}} результатов"
|
||||||
},
|
},
|
||||||
"entity": {
|
"entity": {
|
||||||
"album_one": "альбом",
|
"album_one": "альбом",
|
||||||
@@ -438,7 +439,17 @@
|
|||||||
"home": "$t(common.home)",
|
"home": "$t(common.home)",
|
||||||
"myLibrary": "Моя библиотека",
|
"myLibrary": "Моя библиотека",
|
||||||
"shared": "Публичные плейлисты $t(entity.playlist, {\"count\": 2})",
|
"shared": "Публичные плейлисты $t(entity.playlist, {\"count\": 2})",
|
||||||
"collections": "коллекции"
|
"collections": "коллекции",
|
||||||
|
"albumArtists": "$t(entity.albumArtist, {\"count\": 2})",
|
||||||
|
"albums": "$t(entity.album, {\"count\": 2})",
|
||||||
|
"artists": "$t(entity.artist, {\"count\": 2})",
|
||||||
|
"favorites": "$t(entity.favorite, {\"count\": 2})",
|
||||||
|
"folders": "$t(entity.folder, {\"count\": 2})",
|
||||||
|
"genres": "$t(entity.genre, {\"count\": 2})",
|
||||||
|
"radio": "$t(entity.radioStation, {\"count\": 2})",
|
||||||
|
"playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
|
"settings": "$t(common.setting, {\"count\": 2})",
|
||||||
|
"tracks": "$t(entity.track, {\"count\": 2})"
|
||||||
},
|
},
|
||||||
"fullscreenPlayer": {
|
"fullscreenPlayer": {
|
||||||
"config": {
|
"config": {
|
||||||
@@ -455,7 +466,9 @@
|
|||||||
"useImageAspectRatio": "использовать соотношение сторон изображения",
|
"useImageAspectRatio": "использовать соотношение сторон изображения",
|
||||||
"lyricGap": "пробел между словами",
|
"lyricGap": "пробел между словами",
|
||||||
"dynamicIsImage": "включить фоновое изображение",
|
"dynamicIsImage": "включить фоновое изображение",
|
||||||
"dynamicImageBlur": "сила размытия изображения"
|
"dynamicImageBlur": "сила размытия изображения",
|
||||||
|
"lyricOpacityNonActive": "непрозрачность неактивных слов",
|
||||||
|
"lyricScaleNonActive": "размер неактивных слов"
|
||||||
},
|
},
|
||||||
"upNext": "играет",
|
"upNext": "играет",
|
||||||
"lyrics": "слова",
|
"lyrics": "слова",
|
||||||
@@ -478,7 +491,8 @@
|
|||||||
"selectMusicFolder": "выбрать папку с музыкой",
|
"selectMusicFolder": "выбрать папку с музыкой",
|
||||||
"noMusicFolder": "папка с музыкой не выбрана",
|
"noMusicFolder": "папка с музыкой не выбрана",
|
||||||
"multipleMusicFolders": "{{count}} выбрано музыкальных папок",
|
"multipleMusicFolders": "{{count}} выбрано музыкальных папок",
|
||||||
"commandPalette": "открыть командную строку"
|
"commandPalette": "открыть командную строку",
|
||||||
|
"settings": "$t(common.setting, {\"count\": 2})"
|
||||||
},
|
},
|
||||||
"manageServers": {
|
"manageServers": {
|
||||||
"title": "сервера",
|
"title": "сервера",
|
||||||
@@ -522,7 +536,8 @@
|
|||||||
"title": "$t(common.home)",
|
"title": "$t(common.home)",
|
||||||
"explore": "откройте новое",
|
"explore": "откройте новое",
|
||||||
"recentlyPlayed": "игралось недавно",
|
"recentlyPlayed": "игралось недавно",
|
||||||
"recentlyReleased": "Новинки"
|
"recentlyReleased": "Новинки",
|
||||||
|
"genres": "$t(entity.genre, {\"count\": 2})"
|
||||||
},
|
},
|
||||||
"albumDetail": {
|
"albumDetail": {
|
||||||
"moreFromArtist": "больше от $t(entity.artist, {\"count\": 1})",
|
"moreFromArtist": "больше от $t(entity.artist, {\"count\": 1})",
|
||||||
@@ -556,10 +571,13 @@
|
|||||||
},
|
},
|
||||||
"genreList": {
|
"genreList": {
|
||||||
"showAlbums": "показать $t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2})",
|
"showAlbums": "показать $t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2})",
|
||||||
"showTracks": "показать $t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2})"
|
"showTracks": "показать $t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2})",
|
||||||
|
"title": "$t(entity.genre, {\"count\": 2})"
|
||||||
},
|
},
|
||||||
"trackList": {
|
"trackList": {
|
||||||
"artistTracks": "Треки {{artist}}"
|
"artistTracks": "Треки {{artist}}",
|
||||||
|
"genreTracks": "\"{{genre}}\" $t(entity.track, {\"count\": 2})",
|
||||||
|
"title": "$t(entity.track, {\"count\": 2})"
|
||||||
},
|
},
|
||||||
"globalSearch": {
|
"globalSearch": {
|
||||||
"commands": {
|
"commands": {
|
||||||
@@ -620,6 +638,12 @@
|
|||||||
},
|
},
|
||||||
"favorites": {
|
"favorites": {
|
||||||
"title": "$t(entity.favorite, {\"count\": 2})"
|
"title": "$t(entity.favorite, {\"count\": 2})"
|
||||||
|
},
|
||||||
|
"folderList": {
|
||||||
|
"title": "$t(entity.folder, {\"count\": 2})"
|
||||||
|
},
|
||||||
|
"playlistList": {
|
||||||
|
"title": "$t(entity.playlist, {\"count\": 2})"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"form": {
|
"form": {
|
||||||
@@ -660,7 +684,8 @@
|
|||||||
"input_skipDuplicates": "не добавлять дубликаты",
|
"input_skipDuplicates": "не добавлять дубликаты",
|
||||||
"create": "создать $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "создать $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "для создания нового списка выполните поиск по $t(entity.playlist, {\"count\": 2}) или введите соответствующий текст",
|
"searchOrCreate": "для создания нового списка выполните поиск по $t(entity.playlist, {\"count\": 2}) или введите соответствующий текст",
|
||||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})"
|
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||||
|
"noneAdded": "в плейлист $t(entity.playlist, {\"count\": 1}) '{{playlist}}' не было добавлено ни одного трека"
|
||||||
},
|
},
|
||||||
"updateServer": {
|
"updateServer": {
|
||||||
"title": "обновление сервера",
|
"title": "обновление сервера",
|
||||||
@@ -1060,7 +1085,8 @@
|
|||||||
"audioFadeOnStatusChange": "плавное изменение звука",
|
"audioFadeOnStatusChange": "плавное изменение звука",
|
||||||
"audioFadeOnStatusChange_description": "включает эффекты затухания и появления звука при изменении статуса (пауза/проигрывание)",
|
"audioFadeOnStatusChange_description": "включает эффекты затухания и появления звука при изменении статуса (пауза/проигрывание)",
|
||||||
"preventSleepOnPlayback_description": "запрещает спящий режим экрана, пока играет музыка",
|
"preventSleepOnPlayback_description": "запрещает спящий режим экрана, пока играет музыка",
|
||||||
"preventSleepOnPlayback": "не переходить в спящий режим"
|
"preventSleepOnPlayback": "не переходить в спящий режим",
|
||||||
|
"discordLinkType_none": "$t(common.none)"
|
||||||
},
|
},
|
||||||
"releaseType": {
|
"releaseType": {
|
||||||
"secondary": {
|
"secondary": {
|
||||||
@@ -1081,7 +1107,8 @@
|
|||||||
"other": "другие",
|
"other": "другие",
|
||||||
"broadcast": "транслировать",
|
"broadcast": "транслировать",
|
||||||
"ep": "эп",
|
"ep": "эп",
|
||||||
"single": "сингл"
|
"single": "сингл",
|
||||||
|
"album": "$t(entity.album, {\"count\": 1})"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"datetime": {
|
"datetime": {
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
{}
|
||||||
@@ -796,7 +796,9 @@
|
|||||||
"waveformLoadingDelay": "波形載入延遲",
|
"waveformLoadingDelay": "波形載入延遲",
|
||||||
"waveformLoadingDelay_description": "載入波形前的延遲(以秒為單位)。如果您在使用網頁播放器時遇到卡頓,請增加此值。",
|
"waveformLoadingDelay_description": "載入波形前的延遲(以秒為單位)。如果您在使用網頁播放器時遇到卡頓,請增加此值。",
|
||||||
"playerbarWaveformStretch": "波形拉伸",
|
"playerbarWaveformStretch": "波形拉伸",
|
||||||
"playerbarWaveformStretch_description": "拉伸波形來填補可用空間"
|
"playerbarWaveformStretch_description": "拉伸波形來填補可用空間",
|
||||||
|
"preventSuspendOnPlayback_description": "音樂播放時防止應用程式進入休眠",
|
||||||
|
"preventSuspendOnPlayback": "在播放時防止應用程式暫停"
|
||||||
},
|
},
|
||||||
"table": {
|
"table": {
|
||||||
"config": {
|
"config": {
|
||||||
@@ -1046,7 +1048,8 @@
|
|||||||
"success": "新增 $t(entity.trackWithCount, {\"count\": {{message}} }) 到 $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })",
|
"success": "新增 $t(entity.trackWithCount, {\"count\": {{message}} }) 到 $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })",
|
||||||
"title": "新增到$t(entity.playlist, {\"count\": 1})",
|
"title": "新增到$t(entity.playlist, {\"count\": 1})",
|
||||||
"create": "建立 $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
"create": "建立 $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||||
"searchOrCreate": "搜尋$t(entity.playlist, {\"count\": 2}) 或輸入內容以建立新項目"
|
"searchOrCreate": "搜尋$t(entity.playlist, {\"count\": 2}) 或輸入內容以建立新項目",
|
||||||
|
"noneAdded": "沒有曲目新增到 $t(entity.playlist, {\"count\": 1}) '{{playlist}}'"
|
||||||
},
|
},
|
||||||
"createPlaylist": {
|
"createPlaylist": {
|
||||||
"input_description": "$t(common.description)",
|
"input_description": "$t(common.description)",
|
||||||
|
|||||||
+4
-2
@@ -931,12 +931,14 @@ ipcMain.on(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
ipcMain.handle('power-save-blocker-start', () => {
|
ipcMain.handle('power-save-blocker-start', (_event, { full }: { full: boolean }) => {
|
||||||
if (powerSaveBlockerId !== null) {
|
if (powerSaveBlockerId !== null) {
|
||||||
return powerSaveBlockerId;
|
return powerSaveBlockerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
powerSaveBlockerId = powerSaveBlocker.start('prevent-display-sleep');
|
powerSaveBlockerId = powerSaveBlocker.start(
|
||||||
|
full ? 'prevent-display-sleep' : 'prevent-app-suspension',
|
||||||
|
);
|
||||||
return powerSaveBlockerId;
|
return powerSaveBlockerId;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -404,11 +404,12 @@ export const createAuthHeader = (): string => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const jfApiClient = (args: {
|
export const jfApiClient = (args: {
|
||||||
|
forceRemoteUrl?: boolean;
|
||||||
server: null | ServerListItemWithCredential;
|
server: null | ServerListItemWithCredential;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
url?: string;
|
url?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { server, signal, url } = args;
|
const { forceRemoteUrl, server, signal, url } = args;
|
||||||
|
|
||||||
return initClient(contract, {
|
return initClient(contract, {
|
||||||
api: async ({ body, headers, method, path }) => {
|
api: async ({ body, headers, method, path }) => {
|
||||||
@@ -418,7 +419,7 @@ export const jfApiClient = (args: {
|
|||||||
const { params, path: api } = parsePath(path);
|
const { params, path: api } = parsePath(path);
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
const serverUrl = getServerUrl(server);
|
const serverUrl = getServerUrl(server, forceRemoteUrl);
|
||||||
baseUrl = serverUrl;
|
baseUrl = serverUrl;
|
||||||
token = server?.credential;
|
token = server?.credential;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -395,10 +395,15 @@ export const JellyfinController: InternalControllerEndpoint = {
|
|||||||
userId: apiClientProps.server.userId,
|
userId: apiClientProps.server.userId,
|
||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
|
AlbumIds: query.id,
|
||||||
|
EnableUserData: true,
|
||||||
Fields: JF_FIELDS.SONG,
|
Fields: JF_FIELDS.SONG,
|
||||||
IncludeItemTypes: 'Audio',
|
IncludeItemTypes: 'Audio',
|
||||||
ParentId: query.id,
|
Recursive: true,
|
||||||
SortBy: 'ParentIndexNumber,IndexNumber,SortName',
|
SortBy: 'ParentIndexNumber,IndexNumber,SortName',
|
||||||
|
SortOrder: JFSortOrder.ASC,
|
||||||
|
StartIndex: 0,
|
||||||
|
UserId: apiClientProps.server.userId,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
@@ -928,6 +933,7 @@ export const JellyfinController: InternalControllerEndpoint = {
|
|||||||
Fields: JF_FIELDS.PLAYLIST_LIST,
|
Fields: JF_FIELDS.PLAYLIST_LIST,
|
||||||
IncludeItemTypes: 'Playlist',
|
IncludeItemTypes: 'Playlist',
|
||||||
Limit: query.limit,
|
Limit: query.limit,
|
||||||
|
MediaTypes: 'Audio',
|
||||||
Recursive: true,
|
Recursive: true,
|
||||||
SearchTerm: query.searchTerm,
|
SearchTerm: query.searchTerm,
|
||||||
SortBy: playlistListSortMap.jellyfin[query.sortBy],
|
SortBy: playlistListSortMap.jellyfin[query.sortBy],
|
||||||
|
|||||||
@@ -479,11 +479,12 @@ axiosClient.interceptors.response.use(
|
|||||||
);
|
);
|
||||||
|
|
||||||
export const ndApiClient = (args: {
|
export const ndApiClient = (args: {
|
||||||
|
forceRemoteUrl?: boolean;
|
||||||
server: null | ServerListItemWithCredential;
|
server: null | ServerListItemWithCredential;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
url?: string;
|
url?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { server, signal, url } = args;
|
const { forceRemoteUrl, server, signal, url } = args;
|
||||||
|
|
||||||
return initClient(contract, {
|
return initClient(contract, {
|
||||||
api: async ({ body, headers, method, path }) => {
|
api: async ({ body, headers, method, path }) => {
|
||||||
@@ -493,7 +494,7 @@ export const ndApiClient = (args: {
|
|||||||
const { params, path: api } = parsePath(path);
|
const { params, path: api } = parsePath(path);
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
const serverUrl = getServerUrl(server);
|
const serverUrl = getServerUrl(server, forceRemoteUrl);
|
||||||
baseUrl = serverUrl ? `${serverUrl}/api` : undefined;
|
baseUrl = serverUrl ? `${serverUrl}/api` : undefined;
|
||||||
token = server?.ndCredential;
|
token = server?.ndCredential;
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@@ -428,12 +428,13 @@ const silentlyTransformResponse = (data: any) => {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const ssApiClient = (args: {
|
export const ssApiClient = (args: {
|
||||||
|
forceRemoteUrl?: boolean;
|
||||||
server: null | ServerListItemWithCredential;
|
server: null | ServerListItemWithCredential;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
silent?: boolean;
|
silent?: boolean;
|
||||||
url?: string;
|
url?: string;
|
||||||
}) => {
|
}) => {
|
||||||
const { server, signal, silent, url } = args;
|
const { forceRemoteUrl, server, signal, silent, url } = args;
|
||||||
|
|
||||||
return initClient(contract, {
|
return initClient(contract, {
|
||||||
api: async ({ body, headers, method, path, rawQuery }) => {
|
api: async ({ body, headers, method, path, rawQuery }) => {
|
||||||
@@ -443,7 +444,7 @@ export const ssApiClient = (args: {
|
|||||||
const { params, path: api } = parsePath(path);
|
const { params, path: api } = parsePath(path);
|
||||||
|
|
||||||
if (server) {
|
if (server) {
|
||||||
const serverUrl = getServerUrl(server);
|
const serverUrl = getServerUrl(server, forceRemoteUrl);
|
||||||
baseUrl = serverUrl ? `${serverUrl}/rest` : undefined;
|
baseUrl = serverUrl ? `${serverUrl}/rest` : undefined;
|
||||||
const token = server.credential;
|
const token = server.credential;
|
||||||
const params = token.split(/&?\w=/gm);
|
const params = token.split(/&?\w=/gm);
|
||||||
|
|||||||
@@ -284,7 +284,10 @@ export const useDiscordRpc = () => {
|
|||||||
) {
|
) {
|
||||||
try {
|
try {
|
||||||
const info = await api.controller.getAlbumInfo({
|
const info = await api.controller.getAlbumInfo({
|
||||||
apiClientProps: { serverId: song._serverId },
|
apiClientProps: {
|
||||||
|
forceRemoteUrl: true,
|
||||||
|
serverId: song._serverId,
|
||||||
|
},
|
||||||
query: { id: song.albumId },
|
query: { id: song.albumId },
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -95,18 +95,20 @@ export const SynchronizedLyrics = ({
|
|||||||
const programmaticScrollRef = useRef(false);
|
const programmaticScrollRef = useRef(false);
|
||||||
|
|
||||||
const getCurrentLyric = (timeInMs: number) => {
|
const getCurrentLyric = (timeInMs: number) => {
|
||||||
if (lyricRef.current) {
|
|
||||||
const activeLyrics = lyricRef.current;
|
const activeLyrics = lyricRef.current;
|
||||||
for (let idx = 0; idx < activeLyrics.length; idx += 1) {
|
if (!activeLyrics?.length) {
|
||||||
if (timeInMs <= activeLyrics[idx][0]) {
|
|
||||||
return idx === 0 ? idx : idx - 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return activeLyrics.length - 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
let index = -1;
|
||||||
|
for (let idx = 0; idx < activeLyrics.length; idx += 1) {
|
||||||
|
if (timeInMs < activeLyrics[idx][0]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
index = idx;
|
||||||
|
}
|
||||||
|
|
||||||
|
return index;
|
||||||
};
|
};
|
||||||
|
|
||||||
const setCurrentLyricRef = useRef<
|
const setCurrentLyricRef = useRef<
|
||||||
@@ -141,7 +143,20 @@ export const SynchronizedLyrics = ({
|
|||||||
.forEach((node) => node.classList.remove('active'));
|
.forEach((node) => node.classList.remove('active'));
|
||||||
|
|
||||||
if (index === -1) {
|
if (index === -1) {
|
||||||
lyricRef.current = null;
|
const activeLyrics = lyricRef.current;
|
||||||
|
if (!activeLyrics?.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const firstTime = activeLyrics[0][0];
|
||||||
|
if (timeInMs < firstTime) {
|
||||||
|
const elapsed = performance.now() - start;
|
||||||
|
const delay = Math.max(0, firstTime - timeInMs - elapsed);
|
||||||
|
lyricTimer.current = setTimeout(() => {
|
||||||
|
setCurrentLyricRef.current(firstTime, nextEpoch, 0);
|
||||||
|
}, delay);
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +168,6 @@ export const SynchronizedLyrics = ({
|
|||||||
const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 || 0;
|
const offsetTop = currentLyric?.offsetTop - doc?.clientHeight / 2 || 0;
|
||||||
|
|
||||||
if (currentLyric === null) {
|
if (currentLyric === null) {
|
||||||
lyricRef.current = null;
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -140,9 +140,15 @@ export const WebPlayerEngine = (props: WebPlayerEngineProps) => {
|
|||||||
};
|
};
|
||||||
},
|
},
|
||||||
seekTo(seekTo: number) {
|
seekTo(seekTo: number) {
|
||||||
|
let type: 'fraction' | 'seconds' | undefined = undefined;
|
||||||
|
|
||||||
|
if (seekTo < 1) {
|
||||||
|
type = 'seconds';
|
||||||
|
}
|
||||||
|
|
||||||
playerNum === 1
|
playerNum === 1
|
||||||
? player1Ref.current?.seekTo(seekTo)
|
? player1Ref.current?.seekTo(seekTo, type)
|
||||||
: player2Ref.current?.seekTo(seekTo);
|
: player2Ref.current?.seekTo(seekTo, type);
|
||||||
},
|
},
|
||||||
setVolume(volume: number) {
|
setVolume(volume: number) {
|
||||||
setInternalVolume1(volume / 100 || 0);
|
setInternalVolume1(volume / 100 || 0);
|
||||||
|
|||||||
@@ -240,10 +240,16 @@ export function WebPlayer() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let type: 'fraction' | 'seconds' | undefined = undefined;
|
||||||
|
|
||||||
|
if (timestamp < 1) {
|
||||||
|
type = 'seconds';
|
||||||
|
}
|
||||||
|
|
||||||
if (num === 1) {
|
if (num === 1) {
|
||||||
playerRef.current?.player1()?.ref?.seekTo(timestamp);
|
playerRef.current?.player1()?.ref?.seekTo(timestamp, type);
|
||||||
} else {
|
} else {
|
||||||
playerRef.current?.player2()?.ref?.seekTo(timestamp);
|
playerRef.current?.player2()?.ref?.seekTo(timestamp, type);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
onPlayerStatus: async (properties) => {
|
onPlayerStatus: async (properties) => {
|
||||||
|
|||||||
@@ -8,17 +8,17 @@ const ipc = isElectron() ? window.api.ipc : null;
|
|||||||
|
|
||||||
export const usePowerSaveBlocker = () => {
|
export const usePowerSaveBlocker = () => {
|
||||||
const status = usePlayerStatus();
|
const status = usePlayerStatus();
|
||||||
const { preventSleepOnPlayback } = useWindowSettings();
|
const { preventSleepOnPlayback, preventSuspendOnPlayback } = useWindowSettings();
|
||||||
|
|
||||||
const startPowerSaveBlocker = useCallback(async () => {
|
const startPowerSaveBlocker = useCallback(async () => {
|
||||||
if (!ipc) return;
|
if (!ipc) return;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await ipc.invoke('power-save-blocker-start');
|
await ipc.invoke('power-save-blocker-start', { full: preventSleepOnPlayback });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Failed to start power save blocker:', error);
|
console.error('Failed to start power save blocker:', error);
|
||||||
}
|
}
|
||||||
}, []);
|
}, [preventSleepOnPlayback]);
|
||||||
|
|
||||||
const stopPowerSaveBlocker = useCallback(async () => {
|
const stopPowerSaveBlocker = useCallback(async () => {
|
||||||
if (!ipc) return;
|
if (!ipc) return;
|
||||||
@@ -31,16 +31,21 @@ export const usePowerSaveBlocker = () => {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!preventSleepOnPlayback) return;
|
if (!preventSleepOnPlayback || !preventSuspendOnPlayback) return;
|
||||||
|
|
||||||
if (status === PlayerStatus.PLAYING) {
|
if (status === PlayerStatus.PLAYING) {
|
||||||
startPowerSaveBlocker();
|
startPowerSaveBlocker();
|
||||||
} else {
|
} else {
|
||||||
stopPowerSaveBlocker();
|
stopPowerSaveBlocker();
|
||||||
}
|
}
|
||||||
}, [status, preventSleepOnPlayback, startPowerSaveBlocker, stopPowerSaveBlocker]);
|
}, [
|
||||||
|
status,
|
||||||
|
preventSleepOnPlayback,
|
||||||
|
startPowerSaveBlocker,
|
||||||
|
stopPowerSaveBlocker,
|
||||||
|
preventSuspendOnPlayback,
|
||||||
|
]);
|
||||||
|
|
||||||
// Clean up on unmount
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
return () => {
|
return () => {
|
||||||
stopPowerSaveBlocker();
|
stopPowerSaveBlocker();
|
||||||
@@ -56,8 +61,11 @@ const PowerSaveBlockerHookInner = () => {
|
|||||||
export const PowerSaveBlockerHook = () => {
|
export const PowerSaveBlockerHook = () => {
|
||||||
const isElectronEnv = isElectron();
|
const isElectronEnv = isElectron();
|
||||||
const preventSleepOnPlayback = useSettingsStore((state) => state.window.preventSleepOnPlayback);
|
const preventSleepOnPlayback = useSettingsStore((state) => state.window.preventSleepOnPlayback);
|
||||||
|
const preventSuspendOnPlayback = useSettingsStore(
|
||||||
|
(state) => state.window.preventSuspendOnPlayback,
|
||||||
|
);
|
||||||
|
|
||||||
if (!isElectronEnv || !preventSleepOnPlayback) {
|
if (!isElectronEnv || !preventSleepOnPlayback || !preventSuspendOnPlayback) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -184,7 +184,7 @@ export const WindowSettings = memo(() => {
|
|||||||
<Switch
|
<Switch
|
||||||
aria-label="Toggle prevent sleep on playback"
|
aria-label="Toggle prevent sleep on playback"
|
||||||
defaultChecked={settings.preventSleepOnPlayback}
|
defaultChecked={settings.preventSleepOnPlayback}
|
||||||
disabled={!isElectron()}
|
disabled={!isElectron() || settings.preventSuspendOnPlayback}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
if (!e) return;
|
if (!e) return;
|
||||||
localSettings?.set(
|
localSettings?.set(
|
||||||
@@ -206,6 +206,33 @@ export const WindowSettings = memo(() => {
|
|||||||
isHidden: !isElectron(),
|
isHidden: !isElectron(),
|
||||||
title: t('setting.preventSleepOnPlayback', { postProcess: 'sentenceCase' }),
|
title: t('setting.preventSleepOnPlayback', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
control: (
|
||||||
|
<Switch
|
||||||
|
aria-label="Toggle prevent suspend on playback"
|
||||||
|
defaultChecked={settings.preventSuspendOnPlayback}
|
||||||
|
disabled={!isElectron() || settings.preventSleepOnPlayback}
|
||||||
|
onChange={(e) => {
|
||||||
|
if (!e) return;
|
||||||
|
localSettings?.set(
|
||||||
|
'window_prevent_suspend_on_playback',
|
||||||
|
e.currentTarget.checked,
|
||||||
|
);
|
||||||
|
setSettings({
|
||||||
|
window: {
|
||||||
|
preventSuspendOnPlayback: e.currentTarget.checked,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
),
|
||||||
|
description: t('setting.preventSuspendOnPlayback', {
|
||||||
|
context: 'description',
|
||||||
|
postProcess: 'sentenceCase',
|
||||||
|
}),
|
||||||
|
isHidden: !isElectron(),
|
||||||
|
title: t('setting.preventSuspendOnPlayback', { postProcess: 'sentenceCase' }),
|
||||||
|
},
|
||||||
];
|
];
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|||||||
@@ -6,12 +6,8 @@ import { Link, NavLink, useNavigate } from 'react-router';
|
|||||||
|
|
||||||
import styles from './collapsed-sidebar.module.css';
|
import styles from './collapsed-sidebar.module.css';
|
||||||
|
|
||||||
import JellyfinLogo from '/@/renderer/features/servers/assets/jellyfin.png';
|
|
||||||
import NavidromeLogo from '/@/renderer/features/servers/assets/navidrome.png';
|
|
||||||
import OpenSubsonicLogo from '/@/renderer/features/servers/assets/opensubsonic.png';
|
|
||||||
import { CollapsedSidebarButton } from '/@/renderer/features/sidebar/components/collapsed-sidebar-button';
|
import { CollapsedSidebarButton } from '/@/renderer/features/sidebar/components/collapsed-sidebar-button';
|
||||||
import { CollapsedSidebarItem } from '/@/renderer/features/sidebar/components/collapsed-sidebar-item';
|
import { CollapsedSidebarItem } from '/@/renderer/features/sidebar/components/collapsed-sidebar-item';
|
||||||
import { ServerSelectorItems } from '/@/renderer/features/sidebar/components/server-selector-items';
|
|
||||||
import { getCollectionTo } from '/@/renderer/features/sidebar/components/sidebar-collection-list';
|
import { getCollectionTo } from '/@/renderer/features/sidebar/components/sidebar-collection-list';
|
||||||
import { SidebarIcon } from '/@/renderer/features/sidebar/components/sidebar-icon';
|
import { SidebarIcon } from '/@/renderer/features/sidebar/components/sidebar-icon';
|
||||||
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
|
import { AppMenu } from '/@/renderer/features/titlebar/components/app-menu';
|
||||||
@@ -19,7 +15,6 @@ import { AppRoute } from '/@/renderer/router/routes';
|
|||||||
import {
|
import {
|
||||||
SidebarItemType,
|
SidebarItemType,
|
||||||
useCollections,
|
useCollections,
|
||||||
useCurrentServer,
|
|
||||||
useSidebarCollapsedNavigation,
|
useSidebarCollapsedNavigation,
|
||||||
useSidebarItems,
|
useSidebarItems,
|
||||||
useWindowSettings,
|
useWindowSettings,
|
||||||
@@ -30,7 +25,7 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
|
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { LibraryItem, ServerType } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain-types';
|
||||||
import { Platform } from '/@/shared/types/types';
|
import { Platform } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const CollapsedSidebar = () => {
|
export const CollapsedSidebar = () => {
|
||||||
@@ -40,8 +35,6 @@ export const CollapsedSidebar = () => {
|
|||||||
const { windowBarStyle } = useWindowSettings();
|
const { windowBarStyle } = useWindowSettings();
|
||||||
const sidebarCollapsedNavigation = useSidebarCollapsedNavigation();
|
const sidebarCollapsedNavigation = useSidebarCollapsedNavigation();
|
||||||
const sidebarItems = useSidebarItems();
|
const sidebarItems = useSidebarItems();
|
||||||
const currentServer = useCurrentServer();
|
|
||||||
|
|
||||||
const translatedSidebarItemMap = useMemo(
|
const translatedSidebarItemMap = useMemo(
|
||||||
() => ({
|
() => ({
|
||||||
Albums: t('page.sidebar.albums', { postProcess: 'titleCase' }),
|
Albums: t('page.sidebar.albums', { postProcess: 'titleCase' }),
|
||||||
@@ -174,38 +167,6 @@ export const CollapsedSidebar = () => {
|
|||||||
/>
|
/>
|
||||||
),
|
),
|
||||||
)}
|
)}
|
||||||
{currentServer && (
|
|
||||||
<DropdownMenu offset={0} position="right-end" width={240}>
|
|
||||||
<DropdownMenu.Target>
|
|
||||||
<CollapsedSidebarItem
|
|
||||||
activeIcon={null}
|
|
||||||
component={Flex}
|
|
||||||
icon={
|
|
||||||
<img
|
|
||||||
className={styles.serverIcon}
|
|
||||||
src={
|
|
||||||
currentServer.type === ServerType.NAVIDROME
|
|
||||||
? NavidromeLogo
|
|
||||||
: currentServer.type === ServerType.JELLYFIN
|
|
||||||
? JellyfinLogo
|
|
||||||
: OpenSubsonicLogo
|
|
||||||
}
|
|
||||||
/>
|
|
||||||
}
|
|
||||||
label={''}
|
|
||||||
py="md"
|
|
||||||
style={{
|
|
||||||
cursor: 'pointer',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</DropdownMenu.Target>
|
|
||||||
<DropdownMenu.Dropdown>
|
|
||||||
<ScrollArea style={{ maxHeight: '95vh' }}>
|
|
||||||
<ServerSelectorItems />
|
|
||||||
</ScrollArea>
|
|
||||||
</DropdownMenu.Dropdown>
|
|
||||||
</DropdownMenu>
|
|
||||||
)}
|
|
||||||
</ScrollArea>
|
</ScrollArea>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -638,6 +638,7 @@ const WindowSettingsSchema = z.object({
|
|||||||
exitToTray: z.boolean(),
|
exitToTray: z.boolean(),
|
||||||
minimizeToTray: z.boolean(),
|
minimizeToTray: z.boolean(),
|
||||||
preventSleepOnPlayback: z.boolean(),
|
preventSleepOnPlayback: z.boolean(),
|
||||||
|
preventSuspendOnPlayback: z.boolean(),
|
||||||
releaseChannel: z.enum(['alpha', 'beta', 'latest']),
|
releaseChannel: z.enum(['alpha', 'beta', 'latest']),
|
||||||
startMinimized: z.boolean(),
|
startMinimized: z.boolean(),
|
||||||
tray: z.boolean(),
|
tray: z.boolean(),
|
||||||
@@ -1914,6 +1915,7 @@ const initialState: SettingsState = {
|
|||||||
exitToTray: false,
|
exitToTray: false,
|
||||||
minimizeToTray: false,
|
minimizeToTray: false,
|
||||||
preventSleepOnPlayback: false,
|
preventSleepOnPlayback: false,
|
||||||
|
preventSuspendOnPlayback: false,
|
||||||
releaseChannel: 'latest',
|
releaseChannel: 'latest',
|
||||||
startMinimized: false,
|
startMinimized: false,
|
||||||
tray: true,
|
tray: true,
|
||||||
|
|||||||
@@ -87,6 +87,7 @@ export const NDSongQueryFields = [
|
|||||||
{ label: 'Artist Date Rated', type: 'date', value: 'artistdaterated' },
|
{ label: 'Artist Date Rated', type: 'date', value: 'artistdaterated' },
|
||||||
{ label: 'Artist Is Favorite', type: 'boolean', value: 'artistloved' },
|
{ label: 'Artist Is Favorite', type: 'boolean', value: 'artistloved' },
|
||||||
{ label: 'Artist Play Count', type: 'number', value: 'artistplaycount' },
|
{ label: 'Artist Play Count', type: 'number', value: 'artistplaycount' },
|
||||||
|
{ label: 'Artist Rating', type: 'number', value: 'artistrating' },
|
||||||
{ label: 'Artists', type: 'string', value: 'artists' },
|
{ label: 'Artists', type: 'string', value: 'artists' },
|
||||||
{ label: 'ASIN', type: 'string', value: 'asin' },
|
{ label: 'ASIN', type: 'string', value: 'asin' },
|
||||||
{ label: 'Average Rating', type: 'number', value: 'averagerating' },
|
{ label: 'Average Rating', type: 'number', value: 'averagerating' },
|
||||||
@@ -158,7 +159,7 @@ export const NDSongQueryFields = [
|
|||||||
{ label: 'MusicBrainz Work Id', type: 'string', value: 'musicbrainz_workid' },
|
{ label: 'MusicBrainz Work Id', type: 'string', value: 'musicbrainz_workid' },
|
||||||
{ label: 'Name', type: 'string', value: 'title' },
|
{ label: 'Name', type: 'string', value: 'title' },
|
||||||
{ label: 'Original Date', type: 'date', value: 'originaldate' },
|
{ label: 'Original Date', type: 'date', value: 'originaldate' },
|
||||||
{ label: 'Original Year', type: 'date', value: 'originalyear' },
|
{ label: 'Original Year', type: 'number', value: 'originalyear' },
|
||||||
{ label: 'Performer', type: 'string', value: 'performer' },
|
{ label: 'Performer', type: 'string', value: 'performer' },
|
||||||
{ label: 'Play Count', type: 'number', value: 'playcount' },
|
{ label: 'Play Count', type: 'number', value: 'playcount' },
|
||||||
{ label: 'Playlist', type: 'playlist', value: 'id' },
|
{ label: 'Playlist', type: 'playlist', value: 'id' },
|
||||||
@@ -178,18 +179,18 @@ export const NDSongQueryFields = [
|
|||||||
{ label: 'ReplayGain Track Peak', type: 'number', value: 'replaygain_track_peak' },
|
{ label: 'ReplayGain Track Peak', type: 'number', value: 'replaygain_track_peak' },
|
||||||
{ label: 'Remixer', type: 'string', value: 'remixer' },
|
{ label: 'Remixer', type: 'string', value: 'remixer' },
|
||||||
{ label: 'Script', type: 'string', value: 'script' },
|
{ label: 'Script', type: 'string', value: 'script' },
|
||||||
{ label: 'Sample Rate', type: 'number', value: 'sampleRate' },
|
{ label: 'Sample Rate', type: 'number', value: 'samplerate' },
|
||||||
{ label: 'Size', type: 'number', value: 'size' },
|
{ label: 'Size', type: 'number', value: 'size' },
|
||||||
{ label: 'Sort Album', type: 'string', value: 'albumsort' },
|
{ label: 'Sort Album', type: 'string', value: 'sortalbum' },
|
||||||
{ label: 'Sort Album Artist', type: 'string', value: 'albumartistsort' },
|
{ label: 'Sort Album Artist', type: 'string', value: 'sortalbumartist' },
|
||||||
{ label: 'Sort Album Artists', type: 'string', value: 'albumartistssort' },
|
{ label: 'Sort Album Artists', type: 'string', value: 'albumartistssort' },
|
||||||
{ label: 'Sort Artist', type: 'string', value: 'artistsort' },
|
{ label: 'Sort Artist', type: 'string', value: 'sortartist' },
|
||||||
{ label: 'Sort Artists', type: 'string', value: 'artistssort' },
|
{ label: 'Sort Artists', type: 'string', value: 'artistssort' },
|
||||||
{ label: 'Sort Composer', type: 'string', value: 'composersort' },
|
{ label: 'Sort Composer', type: 'string', value: 'composersort' },
|
||||||
{ label: 'Sort Lyricist', type: 'string', value: 'lyricistsort' },
|
{ label: 'Sort Lyricist', type: 'string', value: 'lyricistsort' },
|
||||||
{ label: 'Sort Name', type: 'string', value: 'titlesort' },
|
{ label: 'Sort Name', type: 'string', value: 'sorttitle' },
|
||||||
{ label: 'Subtitle', type: 'string', value: 'subtitle' },
|
{ label: 'Subtitle', type: 'string', value: 'subtitle' },
|
||||||
{ label: 'Track Number', type: 'number', value: 'track' },
|
{ label: 'Track Number', type: 'number', value: 'tracknumber' },
|
||||||
{ label: 'Track Total', type: 'number', value: 'tracktotal' },
|
{ label: 'Track Total', type: 'number', value: 'tracktotal' },
|
||||||
{ label: 'Website', type: 'string', value: 'website' },
|
{ label: 'Website', type: 'string', value: 'website' },
|
||||||
{ label: 'Work', type: 'string', value: 'work' },
|
{ label: 'Work', type: 'string', value: 'work' },
|
||||||
|
|||||||
@@ -318,7 +318,7 @@ export const sortSongList = (songs: Song[], sortBy: SongListSort, sortOrder: Sor
|
|||||||
case SongListSort.YEAR:
|
case SongListSort.YEAR:
|
||||||
results = orderBy(
|
results = orderBy(
|
||||||
results,
|
results,
|
||||||
['releaseYear', (v) => v.album?.toLowerCase(), 'discNumber', 'track'],
|
['releaseYear', (v) => v.album?.toLowerCase(), 'discNumber', 'trackNumber'],
|
||||||
[order, order, order, order],
|
[order, order, order, order],
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -421,6 +421,7 @@ type ApiContext = {
|
|||||||
|
|
||||||
type BaseEndpointArgs = {
|
type BaseEndpointArgs = {
|
||||||
apiClientProps: {
|
apiClientProps: {
|
||||||
|
forceRemoteUrl?: boolean;
|
||||||
server?: null | ServerListItemWithCredential;
|
server?: null | ServerListItemWithCredential;
|
||||||
serverId: string;
|
serverId: string;
|
||||||
signal?: AbortSignal;
|
signal?: AbortSignal;
|
||||||
|
|||||||
Reference in New Issue
Block a user