Compare commits

..

661 Commits

Author SHA1 Message Date
Bond_009
c8c2956cc2 Remove unused import 2024-08-16 17:24:00 +02:00
Bond_009
38dd4c5f43 Don't sort media streams for media info
This way it keeps a logical order i.e. video info first, followed by
audio and subtitles
2024-08-16 17:23:31 +02:00
Bill Thornton
f2aeb2a23f Merge pull request #5918 from dmitrylyzo/boolean-defines
Convert defines to boolean
2024-08-16 11:09:30 -04:00
Bill Thornton
94ffad42cd Merge pull request #5913 from thornbill/index-refactor
Refactor app startup code
2024-08-16 11:05:32 -04:00
stanol
ac0979fd51 Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-08-16 07:41:32 -04:00
Dmitry Lyzo
2d8d23d646 Convert defines to boolean
Fixes disabling features as `USE_SYSTEM_FONTS=0`.
2024-08-16 11:13:34 +03:00
Kityn
aff5d941ef Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-08-16 03:41:32 -04:00
Mjöllnir
82323e9c1d Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-15 20:41:32 -04:00
venkata nadha reddy
f8e428789b Use production year for movies in video player (#5765)
* In video player, changes to display production year rather than release year for movies.

* making it consistent
2024-08-15 15:59:56 -04:00
Bas
05643b160b Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-08-15 15:41:32 -04:00
Francisco Zorat
e4a6a2d6bc Add 'how many times' is the speed of transcoding in Playback Info (#5753)
* feat: new display value for transcoding fps

* fix: undefined safety + || instead of ??

* forgot to add to contributors

* fix: apply suggestions

* chore: remove from contrib to rebase

* chore: add to contrib again

---------

Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-08-15 14:28:57 -04:00
alfred-delacosta
1172d9a2b9 Added artist list concatenation for albums that have over 10 artists (#4830)
* Added condition to display concatenated text if artist count is over 10. Fixed #4228

* Added string to strings.json. Used globalize.translate()

* Moved code to getArtistLinksHtml function

* Update src/controllers/itemDetails/index.js

Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>

* Simplify appending other artists string

* Update src/controllers/itemDetails/index.js

Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>

* Update src/controllers/itemDetails/index.js

Co-authored-by: felix920506 <felix920506@gmail.com>

* Update src/strings/en-us.json

Co-authored-by: felix920506 <felix920506@gmail.com>

---------

Co-authored-by: AJ <ajdlc@protonmail.com>
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
Co-authored-by: felix920506 <felix920506@gmail.com>
2024-08-15 14:06:43 -04:00
Bill Thornton
5010367163 Use consistent import style
Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>
2024-08-15 10:15:58 -04:00
Bill Thornton
422adde900 Use consistent import style 2024-08-15 02:33:50 -04:00
Bill Thornton
3e6fdc8f04 Update source tree in README 2024-08-14 16:52:56 -04:00
Bill Thornton
0a03b9a744 Move scroller lib to directory 2024-08-14 16:52:29 -04:00
gio-giorgio
32354b3a37 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-08-14 16:41:32 -04:00
Bill Thornton
4af7fc6e3e Move class change handlers to init 2024-08-14 16:33:25 -04:00
Bill Thornton
4f2edf416a Remove unused package manager 2024-08-14 16:24:56 -04:00
Bill Thornton
ab0fa6cfe6 Use async for loadPlugins 2024-08-14 16:22:40 -04:00
Bill Thornton
741c612920 Refactor init functions 2024-08-14 16:00:16 -04:00
Bill Thornton
d44804bf60 Organize index imports 2024-08-14 15:20:54 -04:00
Bill Thornton
056d802c56 Move globalize to lib 2024-08-14 14:00:09 -04:00
Bill Thornton
0ea5349422 Move libraries to lib 2024-08-14 13:57:38 -04:00
Bill Thornton
385a01d5ad Move polyfill loading 2024-08-14 13:57:38 -04:00
Andrei-Alexandru Bleorțu
7c651d0a5d Translated using Weblate (Romanian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ro/
2024-08-13 20:41:32 -04:00
GrantZ9001
803f2692ac Translated using Weblate (Finnish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/
2024-08-13 15:41:32 -04:00
jchuong
6d350b8aa4 Backport pull request #5910 from jellyfin-web/release-10.9.z
Fix "Download All" for Safari

Original-merge: 4071c44437

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-13 11:53:24 -04:00
thornbill
37fbfb3772 Backport pull request #5898 from jellyfin-web/release-10.9.z
Fix autoCast race condition

Original-merge: 7f575d724e

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-13 11:53:23 -04:00
viown
75d78a96b8 Backport pull request #5843 from jellyfin-web/release-10.9.z
Fix swipe gestures on android for book reader

Original-merge: 44afbc2357

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-13 11:53:21 -04:00
ilteoood
371994642d Backport pull request #5823 from jellyfin-web/release-10.9.z
Use navigate instead of resolver

Original-merge: 2e4e4050cd

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-13 11:53:20 -04:00
Doxterpepper
614c9e4481 Backport pull request #5730 from jellyfin-web/release-10.9.z
Add no-cache attribute for fetch requests to /system/info/public to prevent stale server info

Original-merge: a0e6da790c

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-13 11:53:19 -04:00
LudovicJ
b2d5a67f26 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-13 05:40:22 -04:00
Andrejs
d9fbac83a3 Translated using Weblate (Latvian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/
2024-08-12 04:53:23 -04:00
VOLO Digital Agency
01702ab252 Translated using Weblate (Swedish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sv/
2024-08-12 01:24:06 -04:00
Filippo Pesavento
9fe9666937 Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-08-11 11:41:32 -04:00
HanaO00
34b3cad72b Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-11 11:41:32 -04:00
Bill Thornton
ab9f3054d1 Merge pull request #5899 from jellyfin/renovate/fonts 2024-08-10 14:31:43 -04:00
Bill Thornton
1b105df025 Merge pull request #5900 from jellyfin/renovate/vitest 2024-08-10 14:30:53 -04:00
renovate[bot]
5dc2abb3e4 Update Vitest to v2.0.5 2024-08-10 08:20:40 +00:00
renovate[bot]
563be7e26a Update Fonts to v5.0.20 2024-08-10 08:20:21 +00:00
Bill Thornton
6dade2eb56 Merge pull request #5872 from gnattu/fix-audio-remux-check
Fix remux detection for pure audio session
2024-08-08 16:33:30 -04:00
Bill Thornton
df58d35e4d Merge pull request #5870 from gnattu/new-downmix-mode
Add AC-4 and RFC7845 downmix
2024-08-08 16:31:48 -04:00
Bill Thornton
35cb1010ed Merge pull request #5896 from thornbill/fix-cf-pages
Fix Cloudflare Pages CI issues
2024-08-08 16:18:35 -04:00
Bill Thornton
c3f8bf9dc5 Fix branch name passed to CF Pages for non-PR runs 2024-08-08 15:47:10 -04:00
Aldrin Papa
e96c140cb9 Translated using Weblate (Filipino)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fil/
2024-08-08 12:41:31 -04:00
Bill Thornton
866ac5010b Merge pull request #5894 from thornbill/migrate-cf-pages-action 2024-08-08 08:33:53 -04:00
無情天
9369c610d4 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-08-08 04:49:28 -04:00
Bill Thornton
ffbc6437dc Migrate to CF wrangler action 2024-08-08 02:43:02 -04:00
Bill Thornton
1a9f51c9b0 Merge pull request #5892 from thornbill/fix-cf-pages-branch-2 2024-08-07 17:26:41 -04:00
Bill Thornton
40b7aeddc2 Fix branch name passed to CF Pages for forks 2024-08-07 14:30:36 -04:00
Bill Thornton
236870e12e Merge pull request #5891 from thornbill/update-publish-ci
Refactor publish workflow
2024-08-07 13:33:27 -04:00
Bill Thornton
71edaab444 Refactor publish workflow 2024-08-07 12:37:12 -04:00
Bill Thornton
5f8039882e Merge pull request #5888 from thornbill/plugin-drawer-section 2024-08-07 03:10:45 -04:00
Bill Thornton
23657c858e Update plugin drawer section 2024-08-06 23:28:49 -04:00
oxixes
403e3ac33d Translated using Weblate (Spanish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/
2024-08-06 21:13:32 -04:00
Bill Thornton
1671cd5557 Merge pull request #5883 from jellyfin/renovate/ci-deps 2024-08-06 20:01:59 -04:00
queeup
2662522f29 Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-08-06 13:53:12 -04:00
renovate[bot]
2e18df729c Update CI dependencies 2024-08-06 17:30:27 +00:00
Matyáš Levíček
c225668b74 Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-08-06 04:32:23 -04:00
Guanghui Qin
0707a28e96 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-08-06 03:12:18 -04:00
Guanghui Qin
ae4db7a8cc Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-08-06 03:06:16 -04:00
queeup
6b5a9efbd0 Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-08-05 19:06:38 -04:00
queeup
a963d48abf Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-08-05 18:21:12 -04:00
queeup
7d55fea4d5 Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-08-05 18:20:58 -04:00
Bill Thornton
a771246378 Merge pull request #5879 from thornbill/publish-ci-pr-number
Add PR number to environment for debugging workflow
2024-08-05 14:56:07 -04:00
Bill Thornton
b2c7ab8bbc Add event type to environment for debugging workflow 2024-08-05 14:48:39 -04:00
Bill Thornton
debdf2d17e Add PR number to environment for debugging workflow 2024-08-05 14:16:45 -04:00
polyzen
da2d825625 Backport pull request #5829 from jellyfin-web/release-10.9.z
Display mute keyboard shortcut in uppercase

Original-merge: 7991d15177

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-05 11:14:41 -04:00
thornbill
031ed45c87 Backport pull request #5826 from jellyfin-web/release-10.9.z
Fix overly aggressive view caching

Original-merge: 4598d66688

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-05 11:14:39 -04:00
RaafatAkkad
fa3be557c5 Backport pull request #5669 from jellyfin-web/release-10.9.z
Force DoVi on browser.xboxOne as edgeUWP says it can't play it

Original-merge: 665678d5d7

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: thornbill <thornbill@users.noreply.github.com>
2024-08-05 11:14:38 -04:00
Bill Thornton
d99491180d Merge pull request #5877 from jellyfin/update-jf-sdk 2024-08-05 08:17:51 -04:00
jellyfin-bot
8cd77fe558 Update @jellyfin/sdk to 0.0.0-unstable.202408050429 2024-08-05 07:05:24 +00:00
Germain Carré
8b06969226 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-04 13:41:31 -04:00
Germain Carré
724e42a40c Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-04 09:41:31 -04:00
gnattu
8513f60f49 Simplify check 2024-08-04 19:26:16 +08:00
gnattu
ae02d972c4 Fix remux detection for pure audio session 2024-08-04 14:40:15 +08:00
gnattu
508facafbe Adds AC-4 and RFC7845 downmix 2024-08-04 12:57:21 +08:00
Franco Castillo
d770e40130 Translated using Weblate (Spanish (Argentina))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_AR/
2024-08-03 21:41:31 -04:00
Kankawee
69e792c7b9 Translated using Weblate (Thai)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/th/
2024-08-03 01:41:31 -04:00
Bill Thornton
abd3ebcb24 Merge pull request #5865 from jellyfin/renovate/ci-deps 2024-08-02 16:52:52 -04:00
Xavier Bestel
ef8afca49d Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-08-02 11:41:31 -04:00
renovate[bot]
8234237a0e Update actions/upload-artifact action to v4.3.5 2024-08-02 15:27:15 +00:00
Bill Thornton
04685d6dc0 Merge pull request #5860 from jellyfin/update-jf-sdk 2024-08-02 08:49:26 -04:00
Andrejs
86c9a63a0a Translated using Weblate (Latvian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/
2024-08-02 04:41:31 -04:00
jellyfin-bot
4b9533305f Update @jellyfin/sdk to 0.0.0-unstable.202408020501 2024-08-02 07:06:10 +00:00
Bill Thornton
8ceb8e14dd Merge pull request #5827 from thornbill/router-v13-unstable 2024-08-01 14:46:42 -04:00
Bill Thornton
9e0b2ffb9a Merge pull request #5854 from jellyfin/renovate/major-webpack
Update Webpack (major)
2024-08-01 13:56:44 -04:00
Bill Thornton
6a086e34de Merge pull request #5861 from jellyfin/renovate/webpack
Update dependency html-loader to v5.1.0
2024-08-01 13:50:36 -04:00
Bill Thornton
87151979f4 Merge pull request #5839 from jellyfin/renovate/tanstack-query-monorepo
Update tanstack-query monorepo to v5.51.11
2024-08-01 13:49:17 -04:00
Bill Thornton
f1868eca04 Merge pull request #5840 from jellyfin/renovate/emotion-monorepo
Update emotion monorepo to v11.13.0
2024-08-01 13:46:42 -04:00
Bill Thornton
740d2fb667 Merge pull request #5844 from jellyfin/renovate/jsdom-24.x
Update dependency jsdom to v24.1.1
2024-08-01 13:43:25 -04:00
renovate[bot]
ba043c6c41 Update emotion monorepo to v11.13.0 2024-08-01 17:43:11 +00:00
renovate[bot]
1820c77eec Update dependency html-loader to v5.1.0 2024-08-01 17:42:07 +00:00
renovate[bot]
22e48a5e23 Update tanstack-query monorepo to v5.51.11 2024-08-01 17:41:52 +00:00
Bill Thornton
693feca7fa Merge pull request #5838 from jellyfin/renovate/linters
Update dependency eslint-plugin-react to v7.35.0
2024-08-01 13:38:37 -04:00
enter-a-random-username
1f1e9d5dad Add chapter titles to trickplay popup (#5832) 2024-08-01 12:57:35 -04:00
Bill Thornton
9bceeff812 Merge pull request #5858 from jellyfin/renovate/postcss 2024-08-01 01:27:31 -04:00
Bill Thornton
376f5ba325 Merge pull request #5859 from jellyfin/renovate/markdown-it-14.x 2024-08-01 01:24:55 -04:00
Bill Thornton
ba8fb5eb81 Add legacy bang url redirects 2024-08-01 01:21:17 -04:00
Bill Thornton
dce7a36fcf Add RouterHistory to replace syncing for compatibility 2024-08-01 01:21:17 -04:00
renovate[bot]
fe8ed72d3a Update dependency postcss to v8.4.40 2024-08-01 05:21:06 +00:00
Bill Thornton
3315ce1e89 Merge pull request #5857 from jellyfin/fix-auotmation-trigger 2024-08-01 01:20:47 -04:00
renovate[bot]
30917b5afa Update dependency @types/markdown-it to v14.1.2 2024-08-01 05:20:11 +00:00
Bill Thornton
6e2c11faf9 Merge pull request #5853 from jellyfin/renovate/swiper-11.x 2024-08-01 01:19:17 -04:00
Bill Thornton
bdbcd9c651 Merge pull request #5822 from Aakash788/issue5794 2024-08-01 01:09:30 -04:00
renovate[bot]
356fe02e05 Update dependency swiper to v11.1.7 2024-08-01 05:07:01 +00:00
Bill Thornton
f3e616c7b5 Merge pull request #5849 from jellyfin/renovate/typescript 2024-08-01 01:06:10 -04:00
Bill Thornton
1137103706 Fix automation workflow trigger 2024-08-01 00:55:16 -04:00
Bill Thornton
d02b5361ff Merge pull request #5855 from jellyfin/update-jf-sdk 2024-08-01 00:17:36 -04:00
Bill Thornton
878af1bb0f Merge pull request #5856 from jellyfin/fix-publish-comment
Fix publish comment action on fork PRs
2024-07-31 23:58:44 -04:00
Bill Thornton
f7704cf8a6 Fix publish comment action on fork PRs 2024-07-31 23:48:20 -04:00
Aureo
3ee1714a6b Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-07-31 19:41:31 -04:00
jellyfin-bot
2426ee2526 Update @jellyfin/sdk to 0.0.0-unstable.202407310501 2024-07-31 07:04:52 +00:00
Micka149
3b6503cb63 Translated using Weblate (Russian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ru/
2024-07-30 14:41:31 -04:00
renovate[bot]
79c5268c4e Update Webpack 2024-07-30 18:26:49 +00:00
Bill Thornton
f2b0b17362 Merge pull request #5852 from jellyfin/renovate/jellyfin-libass-wasm-4.x 2024-07-30 11:31:11 -04:00
renovate[bot]
6982512f9d Update dependency @jellyfin/libass-wasm to v4.2.2 2024-07-30 15:19:27 +00:00
Bill Thornton
d3fdf7315e Merge pull request #5851 from jellyfin/update-jf-sdk 2024-07-30 11:18:51 -04:00
millallo
66796da115 Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-07-30 04:41:31 -04:00
jellyfin-bot
8c4bf474ef Update @jellyfin/sdk to 0.0.0-unstable.202407292104 2024-07-30 07:05:25 +00:00
renovate[bot]
0755db3c5f Update dependency typescript to v5.5.4 2024-07-30 01:30:52 +00:00
Bill Thornton
62646b3165 Merge pull request #5848 from jellyfin/renovate/tests 2024-07-29 17:28:10 -04:00
vyrmin
c1abea971f Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-07-29 11:41:31 -04:00
Bill Thornton
d8b2e054a2 Merge pull request #5847 from jellyfin/update-jf-sdk 2024-07-29 11:10:21 -04:00
Aakash788
fa9cadbd29 Replaced deprecated babel dependencies 2024-07-29 19:19:35 +05:30
renovate[bot]
a9b1523bc8 Update Tests to v2.0.4 2024-07-29 10:01:10 +00:00
Pierre Briois
aae6f9d8a0 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-07-29 04:41:31 -04:00
jellyfin-bot
1b18f65684 Update @jellyfin/sdk to 0.0.0-unstable.202407290501 2024-07-29 07:06:06 +00:00
rushmash
47a2712d73 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-28 11:41:31 -04:00
stanol
3c389ea6a8 Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-07-28 08:41:31 -04:00
aky
937a10edd9 Translated using Weblate (Korean)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ko/
2024-07-28 03:41:31 -04:00
renovate[bot]
914b6fd34d Update dependency jsdom to v24.1.1 2024-07-28 06:04:01 +00:00
Lukáš Kucharczyk
1152dbae4e Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-07-27 19:41:31 -04:00
Andi Chandler
eebcd6dc81 Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-07-27 17:41:31 -04:00
stanol
7490f9f89d Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-07-27 10:41:31 -04:00
hoanghuy309
89a6efd277 Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-07-27 08:41:31 -04:00
Bas
bb3e0bd6b9 Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-07-27 03:41:31 -04:00
renovate[bot]
8dd841ce57 Update dependency eslint-plugin-react to v7.35.0 2024-07-27 07:07:09 +00:00
Bill Thornton
cfa0ec6b53 Merge pull request #5760 from venkat-karasani/collection-header-names 2024-07-26 23:41:33 -04:00
venkata nadha reddy
b5708945b7 translate key change
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-27 01:45:20 +00:00
Bill Thornton
aaaf21a7b0 Merge pull request #5836 from jellyfin/renovate/emotion-monorepo
Update emotion monorepo to v11.12.0
2024-07-26 20:24:49 -04:00
Bill Thornton
bc859b0ac7 Merge pull request #5835 from jellyfin/renovate/react
Update dependency react-router-dom to v6.25.1
2024-07-26 20:22:46 -04:00
Bill Thornton
6660e0b80c Merge pull request #5833 from jellyfin/renovate/swiper-11.x
Update dependency swiper to v11.1.5
2024-07-26 20:20:31 -04:00
Bill Thornton
613313e8e6 Merge pull request #5837 from jellyfin/dependabot/npm_and_yarn/vite-5.3.5
Bump vite from 5.0.12 to 5.3.5
2024-07-26 20:18:29 -04:00
Bill Thornton
6ff494958a Merge pull request #5720 from jellyfin/dependabot/npm_and_yarn/ws-7.5.10
Bump ws from 7.5.9 to 7.5.10
2024-07-26 20:17:28 -04:00
Bill Thornton
90a3ea41dd Merge pull request #5383 from jellyfin/dependabot/npm_and_yarn/tar-6.2.1
Bump tar from 6.1.13 to 6.2.1
2024-07-26 20:16:33 -04:00
Bill Thornton
65959744d7 Merge pull request #5328 from jellyfin/dependabot/npm_and_yarn/express-4.19.2
Bump express from 4.18.1 to 4.19.2
2024-07-26 20:15:22 -04:00
Bill Thornton
26f97c8193 Merge pull request #5281 from jellyfin/dependabot/npm_and_yarn/follow-redirects-1.15.6
Bump follow-redirects from 1.15.4 to 1.15.6
2024-07-26 20:13:42 -04:00
dependabot[bot]
f7022297b7 Bump ws from 7.5.9 to 7.5.10
Bumps [ws](https://github.com/websockets/ws) from 7.5.9 to 7.5.10.
- [Release notes](https://github.com/websockets/ws/releases)
- [Commits](https://github.com/websockets/ws/compare/7.5.9...7.5.10)

---
updated-dependencies:
- dependency-name: ws
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 00:11:37 +00:00
dependabot[bot]
df08648633 Bump tar from 6.1.13 to 6.2.1
Bumps [tar](https://github.com/isaacs/node-tar) from 6.1.13 to 6.2.1.
- [Release notes](https://github.com/isaacs/node-tar/releases)
- [Changelog](https://github.com/isaacs/node-tar/blob/main/CHANGELOG.md)
- [Commits](https://github.com/isaacs/node-tar/compare/v6.1.13...v6.2.1)

---
updated-dependencies:
- dependency-name: tar
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 00:11:11 +00:00
dependabot[bot]
d08602f14e Bump vite from 5.0.12 to 5.3.5
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 5.0.12 to 5.3.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v5.3.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 00:11:06 +00:00
dependabot[bot]
4d27994b76 Bump express from 4.18.1 to 4.19.2
Bumps [express](https://github.com/expressjs/express) from 4.18.1 to 4.19.2.
- [Release notes](https://github.com/expressjs/express/releases)
- [Changelog](https://github.com/expressjs/express/blob/master/History.md)
- [Commits](https://github.com/expressjs/express/compare/4.18.1...4.19.2)

---
updated-dependencies:
- dependency-name: express
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 00:10:25 +00:00
dependabot[bot]
501b18f432 Bump follow-redirects from 1.15.4 to 1.15.6
Bumps [follow-redirects](https://github.com/follow-redirects/follow-redirects) from 1.15.4 to 1.15.6.
- [Release notes](https://github.com/follow-redirects/follow-redirects/releases)
- [Commits](https://github.com/follow-redirects/follow-redirects/compare/v1.15.4...v1.15.6)

---
updated-dependencies:
- dependency-name: follow-redirects
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-07-27 00:09:38 +00:00
Bill Thornton
ee87aea069 Merge pull request #5807 from jellyfin/renovate/babel
Update Babel
2024-07-26 20:07:25 -04:00
renovate[bot]
cefe0c429b Update emotion monorepo to v11.12.0 2024-07-27 00:04:48 +00:00
renovate[bot]
b086047dc8 Update dependency react-router-dom to v6.25.1 2024-07-27 00:04:31 +00:00
renovate[bot]
333bc9267d Update Babel 2024-07-26 23:59:18 +00:00
Bill Thornton
640cd7fc3c Merge pull request #5795 from jellyfin/renovate/tanstack-query-monorepo
Update tanstack-query monorepo to v5.51.9
2024-07-26 19:57:43 -04:00
Bill Thornton
e264a61d8b Merge pull request #5813 from jellyfin/renovate/linters
Update dependency eslint-plugin-react to v7.34.4
2024-07-26 19:55:20 -04:00
Bill Thornton
5ed5b0a9e5 Merge pull request #5834 from jellyfin/renovate/ci-deps
Update github/codeql-action action to v3.25.15
2024-07-26 19:52:33 -04:00
Bill Thornton
1bc7b23efc Merge pull request #5809 from jellyfin/renovate/webpack
Update dependency webpack to v5.93.0
2024-07-26 19:51:44 -04:00
Kityn
512f368bd7 Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-07-26 19:49:30 -04:00
renovate[bot]
fdd2c6bd34 Update github/codeql-action action to v3.25.15 2024-07-26 23:47:08 +00:00
Bill Thornton
35dd3aaddc Merge pull request #5808 from jellyfin/renovate/sass-1.x
Update dependency sass to v1.77.8
2024-07-26 19:46:43 -04:00
renovate[bot]
741585ead7 Update dependency webpack to v5.93.0 2024-07-26 23:45:49 +00:00
renovate[bot]
5e32e03010 Update dependency swiper to v11.1.5 2024-07-26 23:44:46 +00:00
Bill Thornton
2099c10090 Merge pull request #5819 from jellyfin/renovate/tests
Update Tests to v2.0.3
2024-07-26 19:44:12 -04:00
Bill Thornton
03f4251afb Merge pull request #5773 from thornbill/add-plugin-redesign 2024-07-26 19:34:59 -04:00
Bill Thornton
f4b31f5897 Merge pull request #5831 from jellyfin/update-jf-sdk 2024-07-26 18:43:43 -04:00
Bill Thornton
c3a00e277c Merge pull request #5781 from venkat-karasani/prevent-modal-close 2024-07-26 16:07:07 -04:00
venkat_karasani
2ed3aced2f Prevent modal clos on mouse press up if outside the dialog 2024-07-26 14:38:04 -04:00
Bill Thornton
b9dea3a788 Merge pull request #5734 from prsantos-com/sonarcloud-promise-rejection
Use Error instead of literal for promise rejection
2024-07-26 11:37:26 -04:00
Bill Thornton
08bbcb0681 Merge pull request #5620 from vdubuisson/fix/tv-detailLogo
Allow to display detailLogo on TV with CSS customization
2024-07-26 11:28:48 -04:00
Bill Thornton
40135836e4 Merge pull request #5218 from btopherjohnson/RemoveResetPassword
Remove reset password option for admin users
2024-07-26 11:27:29 -04:00
Valentin Dubuisson
10f599a574 Possible detailLogo on tv 2024-07-26 10:58:08 -04:00
nextlooper42
ed71680cf1 Translated using Weblate (Slovak)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/
2024-07-26 07:41:31 -04:00
Kityn
4235ec9eaa Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-07-26 07:41:31 -04:00
jellyfin-bot
5ea2180409 Update @jellyfin/sdk to 0.0.0-unstable.202407260528 2024-07-26 07:05:14 +00:00
Bas
01036a4f0c Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-07-26 02:41:31 -04:00
Metod
a8398fe204 Translated using Weblate (Slovenian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sl/
2024-07-26 01:21:46 -04:00
Bill Thornton
e92b9f0adc Merge pull request #5666 from ConnorS1110/update-up-next-dialog-text
Update up-next text when auto play next episode is disabled
2024-07-26 01:21:43 -04:00
renovate[bot]
903b95917e Update tanstack-query monorepo to v5.51.9 2024-07-25 09:08:25 +00:00
Samuele Esposito
8fb15c6fde Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-07-23 17:41:30 -04:00
renovate[bot]
6814e85c10 Update Tests to v2.0.3 2024-07-22 17:15:13 +00:00
Bill Thornton
39ef1d2ca2 Merge pull request #5815 from jellyfin/renovate/ci-deps
Update CatChen/eslint-suggestion-action action to v4.1.5
2024-07-22 13:14:21 -04:00
BlueDragon
37eaba2e5d Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-07-22 04:41:31 -04:00
BlueDragon
d5d04e043f Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-07-22 04:41:31 -04:00
BlueDragon
c543794f71 Translated using Weblate (Portuguese (Brazil))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/
2024-07-22 04:41:31 -04:00
BlueDragon
fb166a5c2c Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-07-22 04:41:30 -04:00
renovate[bot]
d452c1b32c Update CatChen/eslint-suggestion-action action to v4.1.5 2024-07-22 07:01:17 +00:00
Niels van Velzen
422bb3423e Merge pull request #5747 from jellyfin/update-jf-sdk
Update @jellyfin/sdk to 0.0.0-unstable.202407210501
2024-07-22 09:00:27 +02:00
jellyfin-bot
2dbccdc2d5 Update @jellyfin/sdk to 0.0.0-unstable.202407210501 2024-07-21 07:05:07 +00:00
thornbill
0090ccd893 Backport pull request #5810 from jellyfin-web/release-10.9.z
Fix chapter type options not showing for mixed libraries

Original-merge: c98822a7c6

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:36 -04:00
thornbill
0084cc856e Backport pull request #5806 from jellyfin-web/release-10.9.z
Fix dashboard body class sometimes missing

Original-merge: f3bb9f2eef

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:35 -04:00
thornbill
e5d2f8fddb Backport pull request #5776 from jellyfin-web/release-10.9.z
Fix invisible headings

Original-merge: 9e7ad28eaf

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:34 -04:00
polyzen
f3d2372d52 Backport pull request #5759 from jellyfin-web/release-10.9.z
Display previous/next keyboard shortcuts

Original-merge: 2d68f94ec6

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:32 -04:00
thornbill
6bf6e7fd18 Backport pull request #5741 from jellyfin-web/release-10.9.z
Disallow scripted content in epubs

Original-merge: e669a9be02

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:31 -04:00
dmitrylyzo
59db69227b Backport pull request #5740 from jellyfin-web/release-10.9.z
Don't change volume if it is physically controlled

Original-merge: e0a0c92b43

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:29 -04:00
thornbill
c5b338dc64 Backport pull request #5732 from jellyfin-web/release-10.9.z
Fix dashboard user page crash

Original-merge: 2d2d5bef94

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:53:28 -04:00
dmitrylyzo
fa9621e31a Backport pull request #5719 from jellyfin-web/release-10.9.z
Fix Trickplay thumbnail in older web engines

Original-merge: 9501c5097b

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:43:54 -04:00
GeorgeH005
a3c0fb05c3 Backport pull request #5553 from jellyfin-web/release-10.9.z
Fix Dolby Vision playback on webOS

Original-merge: 86ff77924e

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:43:53 -04:00
ConnorS1110
cf6eaa6b92 Backport pull request #5377 from jellyfin-web/release-10.9.z
Fix changing filters not resetting multiselected media cards

Original-merge: 798b408bd7

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-21 01:43:51 -04:00
renovate[bot]
a90130b42c Update dependency eslint-plugin-react to v7.34.4 2024-07-20 21:55:01 +00:00
Bill Thornton
be31bf188a Merge pull request #5811 from jellyfin/renovate/ci-deps 2024-07-20 02:08:48 -04:00
renovate[bot]
97333cbb77 Update github/codeql-action action to v3.25.13 2024-07-19 16:54:22 +00:00
venkata nadha reddy
3d9a119d38 Fix stuck page titles on admin dashboard (#5735)
* Fixed stuck page titles on admin dashboard.

* Updating contributors
2024-07-19 12:53:44 -04:00
Bill Thornton
5f61a431de Fix console errors 2024-07-19 11:30:57 -04:00
無情天
3c1e515172 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-07-18 16:41:30 -04:00
renovate[bot]
9740654974 Update dependency sass to v1.77.8 2024-07-18 20:18:02 +00:00
Bill Thornton
19725153af Merge pull request #5805 from jellyfin/renovate/tests
Update Tests to v2.0.2
2024-07-17 16:37:19 -04:00
Bill Thornton
bfced99e7c Merge pull request #5798 from grafixeyehero/Fix-mediaSourceIndicator
Fix invisible media source indicator in experimental
2024-07-17 16:32:27 -04:00
Andi Chandler
f15943e306 Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-07-17 15:41:30 -04:00
Justin
d79e35b0e0 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-07-17 15:41:30 -04:00
Bill Thornton
8061ae63ef Merge pull request #5797 from grafixeyehero/Fix-Progressbar-position
Fix progress bar position indicator in experimental
2024-07-17 15:18:22 -04:00
Bill Thornton
51f1dac1cb Merge pull request #5803 from jellyfin/renovate/sass-1.x
Update dependency sass to v1.77.7
2024-07-17 15:12:44 -04:00
renovate[bot]
3d07a2de66 Update Tests to v2.0.2 2024-07-17 19:12:41 +00:00
Bill Thornton
277bb1638f Merge pull request #5802 from thornbill/router-cleanup
Use lazy routes everywhere
2024-07-17 15:11:21 -04:00
rushmash
d7b5e0382f Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 08:12:03 -04:00
Troja
9d2b89df94 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 08:12:03 -04:00
rushmash
178ec00716 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:20:35 -04:00
Troja
9b22a40a77 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:20:35 -04:00
Troja
2c809f7a81 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:15:32 -04:00
Troja
105e3f2841 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:15:21 -04:00
Troja
e741c5ec3c Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:14:58 -04:00
Troja
0b888e364d Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:14:12 -04:00
rushmash
0de462adcb Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:14:12 -04:00
Troja
d24c1c8f71 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:12:52 -04:00
rushmash
73d1bc3b43 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:11:40 -04:00
Troja
9518a0d367 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:09:03 -04:00
rushmash
8fc0ef8081 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:09:03 -04:00
rushmash
fbb0518b24 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:08:17 -04:00
Troja
00574dbc00 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 07:08:17 -04:00
Troja
d64b0041e4 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 06:41:30 -04:00
Troja
eb6e09fd6a Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 04:41:30 -04:00
Troja
eaee9a975a Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-17 02:41:30 -04:00
renovate[bot]
d8ff541fa1 Update dependency sass to v1.77.7 2024-07-16 23:08:11 +00:00
Troja
5f8ccfae22 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-16 17:41:30 -04:00
Bill Thornton
255d982687 Fix home page loading with lazy 2024-07-16 17:05:32 -04:00
Bill Thornton
175b2d6c85 Unify routers and use lazy for app layouts 2024-07-16 16:30:29 -04:00
Bill Thornton
735f8b06ce Merge pull request #5801 from thornbill/no-lazy-home 2024-07-16 16:23:02 -04:00
Bill Thornton
9f61863b7d Fix home page crashing when using react-router lazy import 2024-07-16 14:48:56 -04:00
Troja
cfe6828042 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-16 11:41:30 -04:00
Troja
07851124c2 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-16 10:36:19 -04:00
Troja
c3505df833 Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-16 09:41:30 -04:00
stanol
88231fa380 Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-07-16 07:41:31 -04:00
andrianfajar
ae7347dbe3 Translated using Weblate (Indonesian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/id/
2024-07-16 07:41:30 -04:00
Troja
ece901a48c Translated using Weblate (Belarusian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/be/
2024-07-16 07:41:30 -04:00
nextlooper42
3c6f5c4e15 Translated using Weblate (Slovak)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/
2024-07-16 05:41:31 -04:00
Vlad
72414e91a4 Translated using Weblate (Russian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ru/
2024-07-16 05:41:30 -04:00
andrianfajar
d3da80a2ed Translated using Weblate (Indonesian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/id/
2024-07-16 05:41:30 -04:00
andrianfajar
59cf88c7db Translated using Weblate (Indonesian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/id/
2024-07-16 02:41:31 -04:00
Lukáš Kucharczyk
78e5ee82c0 Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-07-16 02:41:30 -04:00
Kityn
8ce14c8100 Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-07-15 20:41:30 -04:00
grafixeyehero
20f53388ae Fix progress bar position 2024-07-16 02:36:07 +03:00
grafixeyehero
60e11181af Fix invisible media source indicator 2024-07-16 02:33:02 +03:00
Bill Thornton
c631c96577 Merge pull request #5796 from jellyfin/renovate/major-tests 2024-07-15 18:30:53 -04:00
renovate[bot]
8445633cb8 Update Tests to v2 2024-07-15 22:13:10 +00:00
Bill Thornton
3eaabdbdc2 Merge pull request #5731 from thornbill/coverage 2024-07-15 18:12:07 -04:00
Bill Thornton
112f8627b5 Apply suggestions for reducing renders
Co-authored-by: grafixeyehero <32230989+grafixeyehero@users.noreply.github.com>
2024-07-15 17:24:07 -04:00
Bill Thornton
864b1a237a Add mutation resets 2024-07-15 17:24:07 -04:00
Bill Thornton
c143082f63 Fix configuration page link 2024-07-15 17:24:07 -04:00
Bill Thornton
e928a2ff95 Redesign add plugins page 2024-07-15 17:24:07 -04:00
Bill Thornton
5936ed10ca Merge pull request #5791 from nielsvanvelzen/no-format-string
Remove "open in browser" button for external id from metadata editor
2024-07-15 17:19:58 -04:00
Bill Thornton
7956967c17 Merge pull request #5678 from jellyfin/renovate/babel
Update Babel to v7.24.7
2024-07-15 17:11:58 -04:00
Bill Thornton
885f344eb8 Merge pull request #5743 from jellyfin/renovate/sass-1.x
Update dependency sass to v1.77.6
2024-07-15 17:10:22 -04:00
Bill Thornton
9f598f242a Merge pull request #5793 from jellyfin/renovate/postcss
Update dependency postcss-preset-env to v9.6.0
2024-07-15 17:09:39 -04:00
Bill Thornton
94adb279c0 Merge pull request #5627 from jellyfin/renovate/webpack
Update Webpack
2024-07-15 16:58:01 -04:00
renovate[bot]
baf54a3435 Update dependency sass to v1.77.6 2024-07-15 20:57:57 +00:00
renovate[bot]
6cafc1d5d7 Update dependency postcss-preset-env to v9.6.0 2024-07-15 20:57:03 +00:00
renovate[bot]
0f8683425e Update Babel to v7.24.7 2024-07-15 20:56:49 +00:00
Bill Thornton
185cce1718 Merge pull request #5792 from jellyfin/renovate/ci-deps
Update github/codeql-action action to v3.25.12
2024-07-15 16:55:24 -04:00
Bill Thornton
20476053fe Merge pull request #5702 from jellyfin/renovate/jsdom-24.x
Update dependency jsdom to v24.1.0
2024-07-15 16:53:17 -04:00
Bill Thornton
d8ba3f256c Merge pull request #5580 from jellyfin/renovate/core-js-3.x
Update dependency core-js to v3.37.1
2024-07-15 16:52:19 -04:00
renovate[bot]
d885954189 Update github/codeql-action action to v3.25.12 2024-07-15 20:50:15 +00:00
renovate[bot]
ed5d8c8033 Update Webpack 2024-07-15 20:50:02 +00:00
Bill Thornton
88ce014372 Merge pull request #5777 from jellyfin/renovate/cssnano-7.x
Update dependency cssnano to v7.0.4
2024-07-15 16:49:11 -04:00
Bill Thornton
845d237200 Merge pull request #5789 from thornbill/update-plugin-headings
Add headings and links to plugin pages
2024-07-15 16:46:18 -04:00
Bill Thornton
58219f688b Merge pull request #5790 from thornbill/lazy-routes
Use react-router lazy for dynamic route import
2024-07-15 16:45:13 -04:00
Bas
539587778b Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-07-15 16:22:42 -04:00
Bill Thornton
e0be16b272 Merge pull request #5625 from FintasticMan/add_prefer_transcode_video
Add setting for preferred video codec
2024-07-15 16:14:51 -04:00
Niels van Velzen
fb66b8e539 Remove "open in browser" button for external id from metadata editor 2024-07-15 21:59:38 +02:00
Bill Thornton
0dfc09529a Merge pull request #5607 from grafixeyehero/Refactor-Search--Page
Refactor search  page
2024-07-15 15:44:42 -04:00
Bill Thornton
ddb9f66609 Merge pull request #5787 from grafixeyehero/Fix-ParentThumbImage
Fix parent thumb image for next up and continue watching in experimental layout
2024-07-15 15:43:23 -04:00
grafixeyehero
fe31539d69 apply suggestion
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-15 22:15:52 +03:00
grafixeyehero
13d5cb2c84 revert translation key changes
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-15 22:13:35 +03:00
Bill Thornton
6aab016634 Merge pull request #5724 from grafixeyehero/Fix-RefreshIndicator
Fix Refresh Indicator in experimental layout
2024-07-15 14:20:45 -04:00
Bill Thornton
b70f42bd5f Merge pull request #5571 from grafixeyehero/Fix--Search-for-tab-library
Fix search for tab library in experimental layout
2024-07-15 14:19:27 -04:00
grafixeyehero
3adf4e8651 apply suggestion
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-15 20:39:57 +03:00
Bill Thornton
085e6e7f3d Merge pull request #5622 from grafixeyehero/Add-homevideos-view
Add Home videos and Photos View
2024-07-15 13:17:14 -04:00
grafixeyehero
f8cb8721d1 apply suggestion
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-07-15 20:16:19 +03:00
grafixeyehero
69afc01d44 Fix: Search for tab library 2024-07-15 20:09:17 +03:00
Bill Thornton
4a97b27218 Use react-router lazy for dynamic route import 2024-07-15 11:04:56 -04:00
Bill Thornton
f0626465b0 Add headings and links to plugin pages 2024-07-15 10:25:56 -04:00
Nyanmisaka
f071ea2a1f Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-07-15 03:41:30 -04:00
grafixeyehero
00de25eccf Fix Parent Thumb Image for NextUp And Resume 2024-07-14 23:53:12 +03:00
bartfaik04
f57b3a6355 Translated using Weblate (Hungarian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hu/
2024-07-14 06:41:30 -04:00
Connor Smith
076f6e56aa Update up-next text when auto play next episode is disabled 2024-07-13 12:30:26 -04:00
Filan Fisteku
1a221956e6 Translated using Weblate (Albanian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sq/
2024-07-13 07:41:29 -04:00
renovate[bot]
c0e0d83d30 Update dependency cssnano to v7.0.4 2024-07-13 00:26:46 +00:00
Obserty
ad18bbe54f Translated using Weblate (Portuguese (Brazil))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/
2024-07-12 14:41:30 -04:00
Bill Thornton
a22370e337 Merge pull request #5761 from venkat-karasani/remove-notifications-page 2024-07-12 11:09:50 -04:00
HeavenlyGyoza
b9448cf334 Translated using Weblate (Galician)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/gl/
2024-07-11 19:41:29 -04:00
HeavenlyGyoza
7d13ff006e Translated using Weblate (Galician)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/gl/
2024-07-11 13:41:29 -04:00
venkat_karasani
63556e5103 removed the unused translations from en-us.json 2024-07-11 12:05:57 -05:00
venkat_karasani
50d7ce860c cleanup: Remove the intermediate notifications dashboard page. 2024-07-11 12:04:22 -05:00
HeavenlyGyoza
a2e2c68f66 Translated using Weblate (Galician)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/gl/
2024-07-11 08:41:30 -04:00
Unn Krigul
476e137f8d Translated using Weblate (Estonian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/
2024-07-11 02:41:29 -04:00
Bill Thornton
3002a135ad Merge pull request #5531 from thornbill/add-commit-sha 2024-07-11 02:29:49 -04:00
Bill Thornton
423a934dfa Merge pull request #5770 from jellyfin/renovate/hls.js-1.x 2024-07-10 22:44:47 -04:00
renovate[bot]
9c314e36f9 Update dependency hls.js to v1.5.13 2024-07-11 00:05:47 +00:00
Bill Thornton
87d911c786 Merge pull request #5769 from jellyfin/renovate/tanstack-query-monorepo 2024-07-10 20:04:31 -04:00
renovate[bot]
6d874c649f Update tanstack-query monorepo to v5.49.2 2024-07-10 18:43:16 +00:00
Bill Thornton
ebc2ff22a7 Merge pull request #5767 from jellyfin/renovate/react 2024-07-10 14:42:22 -04:00
renovate[bot]
fb4f2db7ac Update dependency react-router-dom to v6.24.1 2024-07-10 12:50:25 +00:00
Bill Thornton
f3c532ffa3 Merge pull request #5766 from jellyfin/renovate/ci-deps 2024-07-10 03:51:51 -04:00
Bill Thornton
cad481e302 Merge pull request #5768 from jellyfin/renovate/typescript 2024-07-10 03:51:30 -04:00
renovate[bot]
1e9a81d949 Update dependency typescript to v5.5.3 2024-07-10 07:37:09 +00:00
renovate[bot]
54bcb64ee6 Update actions/setup-node action to v4.0.3 2024-07-10 07:34:42 +00:00
Bill Thornton
89ed0a2404 Merge pull request #5764 from jellyfin/renovate/linters 2024-07-10 03:34:10 -04:00
Davoud-Ghargozlou
f353a4c827 Fix return type in supports fullscreen (#4903)
* refactor: supportsFullScreen to return the same type

* Fix parentheses

Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>

---------

Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>
2024-07-10 01:17:21 -04:00
Bill Thornton
3236fb8819 Merge pull request #5733 from thornbill/error-boundary
Add error boundary for page crashes
2024-07-10 00:55:22 -04:00
Bill Thornton
0d9a8680fb Add error boundary for page crashes 2024-07-10 00:04:52 -04:00
Bill Thornton
9186c0af41 Merge pull request #5687 from shoffing/slider-play-pause
play/pause when Enter is pressed on non-dragging position slider
2024-07-10 00:04:20 -04:00
Steve Hoffing
5ef0428bba use a 'keydown' listener in video/index.js instead 2024-07-09 23:51:51 -04:00
Steve Hoffing
e28b55721d play/pause when Enter is pressed on non-dragging position slider 2024-07-09 23:51:51 -04:00
venkat_karasani
1ac161c82c fixed linting errors. 2024-07-08 22:01:51 -05:00
renovate[bot]
87cb0b81ba Update Linters 2024-07-09 01:05:36 +00:00
Bill Thornton
9a00a6c379 Merge pull request #5762 from jellyfin/renovate/ci-deps 2024-07-08 18:36:14 -04:00
Bill Thornton
8b5cae6e90 Merge pull request #5637 from jellyfin/renovate/postcss 2024-07-08 18:34:37 -04:00
renovate[bot]
feceba43c9 Update CI dependencies 2024-07-08 22:24:18 +00:00
Bill Thornton
488f593faa Merge pull request #5698 from jellyfin/renovate/hls.js-1.x 2024-07-08 18:23:28 -04:00
venkat_karasani
f1bc4b2009 If a collection only contains movies, Jellyfin will display it as 'Movies' instead of 'Videos' 2024-07-08 16:50:24 -05:00
renovate[bot]
e27a049696 Update dependency hls.js to v1.5.12 2024-07-08 18:45:01 +00:00
mjohl
d60ddeb9ed Translated using Weblate (Afrikaans)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/af/
2024-07-06 21:41:29 -04:00
renovate[bot]
765e4aee3e Update PostCSS 2024-07-07 00:22:38 +00:00
Blackspirits
ad025e6d39 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-07-05 04:41:29 -04:00
Blackspirits
565c4dc4a2 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-07-05 04:41:29 -04:00
Hilmar Gústafsson
3ee83bf4df Translated using Weblate (Icelandic)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/is/
2024-07-04 11:41:29 -04:00
Bill Thornton
be36fe69b2 Merge pull request #5576 from jellyfin/update-jf-sdk
Update @jellyfin/sdk to 0.0.0-unstable.202407020501
2024-07-02 10:52:04 -04:00
jellyfin-bot
32d63b16b2 Update @jellyfin/sdk to 0.0.0-unstable.202407020501 2024-07-02 10:46:35 -04:00
Bill Thornton
c4496e20ed Merge pull request #5746 from thornbill/remove-deprecated-sdk-function
Remove usage of deprecated getItemImageUrl
2024-07-02 10:46:14 -04:00
Bill Thornton
94f65820a6 Remove usage of deprecated getItemImageUrl 2024-07-02 10:18:03 -04:00
Marc
a8069127ab Translated using Weblate (Catalan)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ca/
2024-06-30 10:41:28 -04:00
Feraldragon
c40bf002df Translated using Weblate (Estonian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/
2024-06-29 16:41:28 -04:00
Bill Thornton
305de0640c Merge pull request #5739 from jellyfin/renovate/react 2024-06-28 23:59:42 -04:00
Leonardo de Macedo Sartorello
71946b722c Translated using Weblate (Portuguese (Brazil))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/
2024-06-28 23:41:28 -04:00
Tio
e192cd94ac Translated using Weblate (Portuguese (Brazil))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/
2024-06-28 15:41:29 -04:00
renovate[bot]
322ecea5ba Update dependency react-lazy-load-image-component to v1.6.2 2024-06-27 06:30:24 +00:00
Bill Thornton
568b8137b8 Merge pull request #5738 from jellyfin/renovate/ci-deps 2024-06-27 02:29:03 -04:00
lucas philippe
d8137838d0 Translated using Weblate (Portuguese (Brazil))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_BR/
2024-06-26 22:41:28 -04:00
renovate[bot]
802c5d3ee9 Update CI dependencies 2024-06-27 01:47:14 +00:00
Bill Thornton
bac77cb9d8 Merge pull request #5703 from jellyfin/renovate/cssnano-7.x 2024-06-26 21:46:26 -04:00
stanol
515ca379ad Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-06-26 16:41:28 -04:00
renovate[bot]
b1fe63ff52 Update dependency cssnano to v7.0.3 2024-06-26 10:28:51 +00:00
Peter Santos
c3ad26ea55 Use Error instead of literal for promise rejection 2024-06-25 22:37:34 -04:00
Bill Thornton
cf0d2076b5 Merge pull request #5585 from scampower3/lyrics-auto-scroll 2024-06-25 15:34:43 -04:00
Bill Thornton
4c24d40d76 Add test coverage support 2024-06-25 10:34:49 -04:00
dmitrylyzo
f30343cfca Backport pull request #5718 from jellyfin-web/release-10.9.z
HtmlVideoPlayer fix and cleanup

Original-merge: 18061ce247

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-24 20:30:57 -04:00
thornbill
2cbc9e4abf Backport pull request #5694 from jellyfin-web/release-10.9.z
Disable eval support in pdfjs

Original-merge: 4bb0c67340

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-23 11:42:26 -04:00
dmitrylyzo
85b0697a19 Backport pull request #5681 from jellyfin-web/release-10.9.z
Fix loading hides too early

Original-merge: 674b0b118f

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-23 11:42:25 -04:00
Chaitanya-Shahare
00e02888d2 Backport pull request #5680 from jellyfin-web/release-10.9.z
Fix episode overview markdown render

Original-merge: aed4ffa2cd

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-23 11:42:23 -04:00
grafixeyehero
4562f34995 Fix Refresh Indicator 2024-06-22 19:04:49 +03:00
Larvitar
6e3d93836b Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-06-21 15:41:28 -04:00
Tobias Karlsson
a8c1ba341f Translated using Weblate (Swedish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sv/
2024-06-20 03:23:19 -04:00
bene toffix
2eb4dfe513 Translated using Weblate (Catalan)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ca/
2024-06-19 12:41:28 -04:00
Luca Sonntag
72f5d1c73b Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-06-18 17:41:28 -04:00
Blackspirits
084d519dce Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-06-18 03:41:28 -04:00
Blackspirits
de06a0bc36 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-18 03:41:28 -04:00
Blackspirits
1dc54ba122 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-06-17 18:41:28 -04:00
Blackspirits
8f53b51f0c Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-17 18:41:28 -04:00
Blackspirits
20503930b2 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-06-17 16:41:28 -04:00
Blackspirits
a1e7b11595 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-17 16:41:28 -04:00
Daniel ひっかもりい
238c24d147 Translated using Weblate (Latvian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/
2024-06-17 12:41:28 -04:00
Daniel ひっかもりい
c538fd136c Translated using Weblate (Latvian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/
2024-06-17 10:41:28 -04:00
Nir Israel Hen
adc452497c Translated using Weblate (Hebrew)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/he/
2024-06-17 10:41:28 -04:00
ɴᴇᴋᴏ
7419e9b75f Translated using Weblate (Chinese (Traditional))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hant/
2024-06-17 01:41:28 -04:00
Taylor Lottner
d6bf192f46 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-06-17 01:41:28 -04:00
Daniel ひっかもりい
0489bb7549 Translated using Weblate (Latvian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/lv/
2024-06-16 21:41:28 -04:00
AfmanS
c91d9eb775 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-16 14:41:28 -04:00
Bas
fa6074757b Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-06-16 14:41:28 -04:00
Bas
ac6cc6ceee Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-06-16 14:41:28 -04:00
AfmanS
e5e68062f5 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-06-16 03:17:53 -04:00
AfmanS
80c64380bc Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-16 03:17:53 -04:00
Mirco Cau
fa0093b1bd Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-06-15 19:41:28 -04:00
AfmanS
c4e0f88b89 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-06-15 13:41:28 -04:00
Joseph Price
1a17ac76c9 Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-06-14 19:41:28 -04:00
Bill Thornton
827f652d25 Merge pull request #5707 from jellyfin/renovate/ci-deps 2024-06-14 00:25:43 -04:00
renovate[bot]
c5363123da Update CI dependencies 2024-06-14 03:26:01 +00:00
Kevin O'Connell
1675e46e33 Translated using Weblate (Irish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ga/
2024-06-13 08:41:28 -04:00
Bas
139f31b5fa Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-06-13 08:41:27 -04:00
Bill Thornton
a01f803237 Merge pull request #5588 from jellyfin/renovate/material-ui-monorepo 2024-06-12 12:36:04 -04:00
renovate[bot]
61e69e6eaa Update material-ui monorepo 2024-06-12 16:32:11 +00:00
LittleBigOwl
be386fb3c1 Migrate to x-data-grid v7 (#5597) 2024-06-12 12:30:43 -04:00
queeup
85f07ecc9e Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-06-12 09:41:28 -04:00
Bas
a28f7dce2f Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-06-12 06:41:27 -04:00
Justin
3ba2d13916 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-06-11 15:30:17 -04:00
無情天
b1f2f047a8 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-06-11 12:11:04 -04:00
renovate[bot]
d9d14ecd48 Update dependency jsdom to v24.1.0 2024-06-11 04:51:29 +00:00
liolio6
b9c79dfb23 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-06-10 18:41:27 -04:00
grafixeyehero
01bad67226 Remove unused component 2024-06-11 00:24:31 +03:00
grafixeyehero
9352ec12dc Refactor Search Page 2024-06-11 00:23:57 +03:00
renovate[bot]
5d18bdf191 Update dependency es-check to v7.2.1 (#5699)
Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com>
2024-06-10 14:56:10 -04:00
enter-a-random-username
ff2ed9aeab Use % for playback slider marker postions (#5394)
* Use % for slider postions

* Use calc to get the middle of the marker

* Update src/elements/emby-slider/emby-slider.js

Co-authored-by: Grady Hallenbeck <grhallenbeck@users.noreply.github.com>

---------

Co-authored-by: Grady Hallenbeck <grhallenbeck@users.noreply.github.com>
2024-06-10 14:53:30 -04:00
stanol
aab373264f Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-06-10 14:41:27 -04:00
Bill Thornton
c3d981a3b6 Merge pull request #5697 from jellyfin/renovate/ci-deps
Update github/codeql-action action to v3.25.8
2024-06-10 13:41:21 -04:00
Bill Thornton
da19e50a7e Merge pull request #5696 from jellyfin/renovate/swiper-11.x
Update dependency swiper to v11.1.4
2024-06-10 13:26:54 -04:00
renovate[bot]
fce269c842 Update github/codeql-action action to v3.25.8 2024-06-10 17:26:12 +00:00
Bill Thornton
e5833b2f74 Merge pull request #5695 from jellyfin/renovate/hls.js-1.x
Update dependency hls.js to v1.5.9
2024-06-10 13:23:52 -04:00
renovate[bot]
bd2fc8776d Update dependency swiper to v11.1.4 2024-06-10 17:21:17 +00:00
Bill Thornton
3702b6b227 Merge pull request #5591 from jellyfin/renovate/react-hook-resize-observer-2.x
Update dependency @react-hook/resize-observer to v2
2024-06-10 13:20:47 -04:00
renovate[bot]
8b46532bd0 Update dependency hls.js to v1.5.9 2024-06-10 17:18:04 +00:00
Bill Thornton
efb7b79e3d Merge pull request #5683 from jellyfin/renovate/linters
Update dependency eslint-plugin-react to v7.34.2
2024-06-10 13:17:32 -04:00
nextlooper42
a24fa94e1c Translated using Weblate (Slovak)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/
2024-06-10 05:41:27 -04:00
DJSweder
ab83d96079 Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-06-10 00:41:27 -04:00
Bill Thornton
1d647bcf03 Merge pull request #5631 from prsantos-com/sonarcloud-resolve-s6644 2024-06-09 17:02:20 -04:00
celticslment
e1d17a0a6b Translated using Weblate (Spanish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/
2024-06-09 06:41:27 -04:00
Kityn
4642564c31 Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-06-09 03:41:27 -04:00
renovate[bot]
887df400ab Update dependency @react-hook/resize-observer to v2 2024-06-09 07:05:55 +00:00
Bill Thornton
b7a3045066 Merge pull request #5238 from grafixeyehero/Update-to-React-18
Updates react to v18 and tanstack to v5.
2024-06-09 03:04:46 -04:00
grafixeyehero
11393ac3b2 add Legacy params interface 2024-06-09 09:01:52 +03:00
grafixeyehero
06e585e2bc apply suggestion
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-06-09 08:25:47 +03:00
grafixeyehero
4d37b47331 Replace UnratedItem import with full path
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-06-09 08:25:44 +03:00
grafixeyehero
8e23d50cb7 use logical OR ( || )
Co-authored-by: Bill Thornton <thornbill@users.noreply.github.com>
2024-06-09 08:25:42 +03:00
grafixeyehero
ac42b3a203 Update tanstack query to v5 2024-06-09 08:25:39 +03:00
grafixeyehero
be891c3a98 Update to React 18 2024-06-09 08:25:36 +03:00
LJQ
7b765b7785 Update Enum 2024-06-09 13:03:07 +08:00
Bill Thornton
b5d6e37fb3 Merge pull request #5483 from pypp/cleanup/remove-dlna-page
Remove DLNA dashboard page
2024-06-08 20:30:30 -04:00
Bill Thornton
1b27d7dcb8 Merge pull request #5505 from scampower3/add-options-displayorder
Add display options for tvdb plugin
2024-06-08 20:29:43 -04:00
Netanel Henya
14952d2fec cleanup: removed the DLNA dashboard page 2024-06-08 20:26:37 -04:00
Bill Thornton
0a40507f3d Merge pull request #5467 from scampower3/use-VideoDoViTitle-playbackinfo
Use VideoDoViTitle when available
2024-06-08 20:00:10 -04:00
hoanghuy309
97d03f37aa Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-06-08 00:41:27 -04:00
renovate[bot]
5b0280c46c Update dependency eslint-plugin-react to v7.34.2 2024-06-07 19:09:05 +00:00
Dr Aghosh B Prasad
d04df18ec6 Translated using Weblate (Malayalam)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ml/
2024-06-07 04:41:27 -04:00
Bill Thornton
16dfaac650 Merge pull request #5596 from jellyfin/renovate/sass-1.x 2024-06-07 01:20:17 -04:00
renovate[bot]
4e063dd361 Update dependency sass to v1.77.4 2024-06-07 00:09:14 +00:00
thornbill
0b8fcb96c8 Backport pull request #5668 from jellyfin-web/release-10.9.z
Remove IMDb references

Original-merge: 7e20d3032f

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-06 14:39:55 -04:00
dmitrylyzo
b568f7845e Backport pull request #5667 from jellyfin-web/release-10.9.z
Fix uneven slider value

Original-merge: 5495ef220a

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-06 14:39:53 -04:00
thornbill
83c1b47688 Backport pull request #5664 from jellyfin-web/release-10.9.z
Fix live tv images being ignored

Original-merge: d898afdf10

Merged-by: joshuaboniface <joshua@boniface.me>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-06 14:39:52 -04:00
Dan Johansen
42f41589ff Translated using Weblate (Danish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/
2024-06-06 07:41:27 -04:00
gnattu
bc089e6b1b Backport pull request #5662 from jellyfin-web/release-10.9.z
Mark desktop Opera as AV1 and HEVC ready in fmp4

Original-merge: 52aa8ebd49

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:54 -04:00
thornbill
1688829caf Backport pull request #5661 from jellyfin-web/release-10.9.z
Use display missing episodes setting in search

Original-merge: 2a110f6b5d

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:52 -04:00
ConnorS1110
0e07d8a19a Backport pull request #5660 from jellyfin-web/release-10.9.z
Fixed being unable to properly long press on cards to multiselect on Firefox

Original-merge: 5680c18ade

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:51 -04:00
thornbill
a24eb4533d Backport pull request #5658 from jellyfin-web/release-10.9.z
Update activity table column widths

Original-merge: ab781678c1

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:49 -04:00
thornbill
fae81839ec Backport pull request #5657 from jellyfin-web/release-10.9.z
Revert "Fix extra requests in standalone mode"

Original-merge: 574eddada8

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:48 -04:00
dmitrylyzo
5e8372c42d Backport pull request #5653 from jellyfin-web/release-10.9.z
Fix video OSD not fully hiding

Original-merge: 74a3bd8768

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:46 -04:00
mihawk90
bd6f11ea78 Backport pull request #5640 from jellyfin-web/release-10.9.z
Fix background being invisible with theme videos

Original-merge: 7854c4b20b

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-05 17:03:45 -04:00
Àlex Bravo
f950aaf784 Translated using Weblate (Catalan)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ca/
2024-06-04 16:41:27 -04:00
hoanghuy309
c0b2b04c4e Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-06-04 00:41:27 -04:00
Justin
611829978a Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-06-03 19:41:27 -04:00
Acrotos
3a20674ef5 Translated using Weblate (Romanian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ro/
2024-06-03 17:41:27 -04:00
bene toffix
cdcf5609dd Translated using Weblate (Catalan)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ca/
2024-06-03 13:41:27 -04:00
CasperDoesCoding
d311dec1db Translated using Weblate (Swedish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sv/
2024-06-02 11:41:27 -04:00
Bas
cb4d4928a3 Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-06-02 11:41:27 -04:00
esol693
9b6f47706f Translated using Weblate (Filipino)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fil/
2024-06-02 03:41:27 -04:00
grafixeyehero
fcffaab50e Backport pull request #5638 from jellyfin-web/release-10.9.z
Fix: Tv guide only covers half the screen in Experimental Layout

Original-merge: 60af8a68f8

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:07 -04:00
grafixeyehero
1fc471a0ed Backport pull request #5636 from jellyfin-web/release-10.9.z
Clear query and view cache on user logout

Original-merge: 4129676ed8

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:06 -04:00
grafixeyehero
7e0afdfd66 Backport pull request #5619 from jellyfin-web/release-10.9.z
Clear the cache view on user logout

Original-merge: 4959a777c9

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:05 -04:00
gnattu
39fa14a6f8 Backport pull request #5617 from jellyfin-web/release-10.9.z
Allow VideoStreamCopy for remote source fallback

Original-merge: 40e7dc9007

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:03 -04:00
scampower3
da80ba85ee Backport pull request #5612 from jellyfin-web/release-10.9.z
Fix user agent detection

Original-merge: 788ce37c43

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:02 -04:00
grafixeyehero
2da46ebc7a Backport pull request #5610 from jellyfin-web/release-10.9.z
Fix Search Field for Tv Mode

Original-merge: 003bc94e02

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-06-01 18:42:01 -04:00
Bas
406a20334e Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-06-01 18:41:27 -04:00
Albert Berg Hansen
c04b731eae Translated using Weblate (Danish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/
2024-06-01 09:41:27 -04:00
Torpeda
d77b7e177a Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-06-01 07:41:27 -04:00
Albert Berg Hansen
926d10e941 Translated using Weblate (Danish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/
2024-06-01 07:41:27 -04:00
huasbryan14
3ab1fbb1e4 Translated using Weblate (Spanish (Latin America))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_419/
2024-05-31 13:41:28 -04:00
Sultan Iskandar Maulana
76b6c4794e Translated using Weblate (Indonesian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/id/
2024-05-31 13:41:28 -04:00
Marcx
5aa3f2896d Translated using Weblate (Croatian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hr/
2024-05-31 13:41:28 -04:00
huasbryan14
6f21656e13 Translated using Weblate (Spanish (Mexico))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_MX/
2024-05-31 13:41:27 -04:00
Marcx
2d86a59e45 Translated using Weblate (Croatian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hr/
2024-05-31 11:34:22 -04:00
Misael
f1d511f5b4 Translated using Weblate (Spanish (Dominican Republic))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es_DO/
2024-05-30 21:41:27 -04:00
Bill Thornton
b6c13f3717 Merge pull request #5632 from jellyfin/renovate/ci-deps 2024-05-30 18:26:33 -04:00
dtalens
fd8c0ae64e Translated using Weblate (Catalan)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ca/
2024-05-30 13:41:27 -04:00
renovate[bot]
7f696c240a Update eps1lon/actions-label-merge-conflict action to v3.0.2 2024-05-30 10:33:49 +00:00
Peter Santos
a71b1f4e33 Resolve sonarcloud javascript:S6644 code smell 2024-05-29 23:46:41 -04:00
Justin
a5bd72667a Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-29 18:41:27 -04:00
FintasticMan
e146c3d95c Remove VP9 from codec selection 2024-05-29 12:50:23 +02:00
FintasticMan
b234888485 Add setting for preferred video codec 2024-05-29 12:14:19 +02:00
grafixeyehero
fd420a457f Add Homevideos View 2024-05-29 03:32:53 +03:00
hoanghuy309
ef6bbc8212 Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-05-28 02:41:26 -04:00
hoanghuy309
b08ceab5a8 Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-05-27 06:41:27 -04:00
Blackspirits
0525523d20 Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-05-27 06:41:26 -04:00
hoanghuy309
973961bd99 Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-05-26 22:41:26 -04:00
thornbill
1929ba8eb2 Backport pull request #5589 from jellyfin-web/release-10.9.z
Add support for user themes for mui components

Original-merge: 61976b8101

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-26 18:49:25 -04:00
hoanghuy309
669784bde5 Translated using Weblate (Vietnamese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/vi/
2024-05-26 12:41:26 -04:00
Ron Nuss
a41f7ad6c7 Translated using Weblate (Hebrew)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/he/
2024-05-26 06:41:26 -04:00
thornbill
9813c3efb9 Backport pull request #5601 from jellyfin-web/release-10.9.z
Fix chapter markers not updating

Original-merge: 167515dbf0

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:54 -04:00
thornbill
f0c43418da Backport pull request #5600 from jellyfin-web/release-10.9.z
Reset query cache on user logout

Original-merge: a88d03fe8f

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:52 -04:00
NotSaifA
d4e7ac039f Backport pull request #5599 from jellyfin-web/release-10.9.z
Show correct release date

Original-merge: 1ea598968c

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:50 -04:00
thornbill
decdb026fa Backport pull request #5593 from jellyfin-web/release-10.9.z
Fix chapter marker re-rendering

Original-merge: bd03c43716

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:49 -04:00
thornbill
711f61d93d Backport pull request #5590 from jellyfin-web/release-10.9.z
Fix positioning of the main animated page elements

Original-merge: f7f5ac99b0

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:47 -04:00
scampower3
5d606021ed Backport pull request #5587 from jellyfin-web/release-10.9.z
Fix square posters

Original-merge: 9e34ae8b42

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:46 -04:00
thornbill
d6130751e8 Backport pull request #5581 from jellyfin-web/release-10.9.z
Fix missing policy check for download all

Original-merge: bb9b4ce8bb

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:44 -04:00
thornbill
80abbb4574 Backport pull request #5573 from jellyfin-web/release-10.9.z
Fix playback interceptor rejecting

Original-merge: add01e332b

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:42 -04:00
gnattu
0a55ea2dd9 Backport pull request #5566 from jellyfin-web/release-10.9.z
Only connect to manual addresses specified by user

Original-merge: 3dcb42daac

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:40 -04:00
nielsvanvelzen
9cf57574fb Backport pull request #5563 from jellyfin-web/release-10.9.z
Fix chapter name XSS injection in progress bar

Original-merge: 7eb54e029f

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:39 -04:00
dmitrylyzo
94f34ddd13 Backport pull request #5558 from jellyfin-web/release-10.9.z
Fix `TypeError: Failed to construct 'Headers': No matching constructor signature.`

Original-merge: a806eeb3a7

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:37 -04:00
gnattu
22eb6bf3f6 Backport pull request #5526 from jellyfin-web/release-10.9.z
Don’t bind to keyevents of media keys when browser support mediaSession

Original-merge: 6da3dd7c86

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:36 -04:00
dmitrylyzo
6e32ea052d Backport pull request #5452 from jellyfin-web/release-10.9.z
Limit maximum FLAC audio channels in video to 2 on webOS

Original-merge: 9d9b69edd5

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-25 11:50:34 -04:00
DJSweder
d324461250 Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-05-25 03:41:26 -04:00
millallo
00dd77857d Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-05-24 12:41:27 -04:00
Leberkassemml
7a4c153971 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-24 12:41:26 -04:00
LJQ
a75338e3d2 Group component imports together 2024-05-24 21:33:18 +08:00
LJQ
2d2ca357c1 Sync focus with current playing lyrics 2024-05-24 21:32:20 +08:00
millallo
552ae8906d Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-05-24 06:41:27 -04:00
Kamran Imami
fdc305f0b5 Translated using Weblate (Persian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fa/
2024-05-24 06:41:26 -04:00
scampower3
15e35fa45f Update src/controllers/lyrics.js
Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>
2024-05-23 22:02:11 +08:00
scampower3
8c829fde46 Update src/controllers/lyrics.js
Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>
2024-05-23 22:01:07 +08:00
LJQ
65550e07c3 Rename None to NoScroll 2024-05-23 21:48:13 +08:00
LJQ
cfcfbe934b Instant scroll when enter webview. Enums to determine 2024-05-23 21:40:31 +08:00
LJQ
a4c88e59eb Disable autoscroll on touchmove 2024-05-23 20:48:50 +08:00
scampower3
dd5b442b50 Merge branch 'master' into lyrics-auto-scroll 2024-05-23 00:41:52 +08:00
LJQ
fa9b0e6c87 Add lyrics auto scroll 2024-05-23 00:34:45 +08:00
queeup
2d4621104b Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-05-22 10:41:26 -04:00
Dipanker Kaul
116a0ec06b Translated using Weblate (Hindi)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/hi/
2024-05-22 10:41:26 -04:00
queeup
b71aaa05a6 Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-05-21 21:41:26 -04:00
renovate[bot]
8a8cf2980c Update dependency core-js to v3.37.1 2024-05-21 20:18:13 +00:00
Bill Thornton
95afd3ff55 Merge pull request #5460 from scampower3/auto-people-editor-options 2024-05-20 23:40:46 -04:00
Bill Thornton
8961a19154 Add commit sha to version information 2024-05-20 22:31:19 -04:00
Bill Thornton
f2e6153541 Merge pull request #5478 from jellyfin/ci-no-pr-context-artifact 2024-05-20 22:29:45 -04:00
Bill Thornton
85f412d9a1 Merge pull request #5575 from jellyfin/renovate/swiper-11.x 2024-05-20 22:14:39 -04:00
Bill Thornton
f619446427 Merge pull request #5574 from jellyfin/renovate/postcss 2024-05-20 22:13:41 -04:00
Bill Thornton
28ad083a85 Merge pull request #5567 from jellyfin/renovate/ci-deps 2024-05-20 22:05:18 -04:00
renovate[bot]
705f3abaa5 Update dependency swiper to v11.1.3 2024-05-20 23:59:23 +00:00
renovate[bot]
6205762e16 Update dependency postcss-preset-env to v9.5.13 2024-05-20 23:59:07 +00:00
Thomas Schwery
ebfe6feb14 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-20 16:41:26 -04:00
Chimorin
f640844f34 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-20 16:41:26 -04:00
Blackspirits
8316736169 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-20 14:41:26 -04:00
Blackspirits
a746c0405d Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-05-20 14:41:26 -04:00
Blackspirits
0d2ae05285 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-20 12:41:26 -04:00
Blackspirits
9736da4bfb Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-05-20 12:41:26 -04:00
renovate[bot]
272a58a807 Update github/codeql-action action to v3.25.6 2024-05-20 15:58:21 +00:00
Bill Thornton
70392d69cc Merge pull request #5564 from jellyfin/renovate/swiper-11.x 2024-05-20 07:28:58 -04:00
renovate[bot]
9a7a1b0d69 Update dependency swiper to v11.1.2 2024-05-20 11:10:22 +00:00
Bill Thornton
f10328af07 Merge pull request #5562 from jellyfin/update-jf-sdk 2024-05-20 07:09:10 -04:00
Mathias Dejerud
4feb0de203 Translated using Weblate (Swedish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sv/
2024-05-20 05:41:26 -04:00
jellyfin-bot
c617343687 Update @jellyfin/sdk to 0.0.0-unstable.202405200501 2024-05-20 07:05:22 +00:00
stanol
60dbc895fc Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-05-19 10:41:26 -04:00
Adam
81f46e970f Translated using Weblate (English (United Kingdom))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/en_GB/
2024-05-19 08:46:04 -04:00
nextlooper42
ae4152cb22 Translated using Weblate (Slovak)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/
2024-05-19 07:40:45 -04:00
Bill Thornton
fc730b3681 Merge pull request #5454 from jellyfin/update-jf-sdk 2024-05-19 05:10:11 -04:00
Bas
a354017f44 Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-05-19 03:38:21 -04:00
jellyfin-bot
925fbc41ee Update @jellyfin/sdk to 0.0.0-unstable.202405190501 2024-05-19 07:05:18 +00:00
Lukáš Kucharczyk
eb6d04977a Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-05-19 02:54:59 -04:00
Bill Thornton
144445a227 Merge pull request #5150 from jellyfin/renovate/major-webpack 2024-05-18 11:38:08 -04:00
renovate[bot]
3f0cd3b842 Update Webpack 2024-05-18 15:31:15 +00:00
Bill Thornton
e0ecfd1b12 Merge pull request #5546 from jellyfin/renovate/cssnano-7.x 2024-05-18 11:29:44 -04:00
Bill Thornton
5051a6bbea Merge pull request #5549 from jellyfin/renovate/postcss 2024-05-18 11:03:56 -04:00
Bill Thornton
342d54cead Merge pull request #5366 from jellyfin/renovate/react 2024-05-18 10:51:09 -04:00
renovate[bot]
f887a28369 Update dependency cssnano to v7 2024-05-18 14:47:52 +00:00
Bill Thornton
03c38598c9 Merge pull request #5542 from jellyfin/renovate/sass-1.x 2024-05-18 10:47:01 -04:00
renovate[bot]
59c3e2ce09 Update dependency postcss-preset-env to v9.5.12 2024-05-18 14:45:31 +00:00
Bill Thornton
4861eaa988 Merge pull request #5539 from jellyfin/renovate/webpack 2024-05-18 10:45:24 -04:00
renovate[bot]
53a300ab3a Update React 2024-05-18 14:44:02 +00:00
Bill Thornton
59218796c9 Merge pull request #5370 from jellyfin/renovate/swiper-11.x 2024-05-18 10:43:38 -04:00
Bill Thornton
856328620c Merge pull request #5545 from jellyfin/renovate/markdown-it-14.x 2024-05-18 10:42:46 -04:00
queeup
af6bcde3b2 Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-05-18 09:41:26 -04:00
Lukas
9cc8405ce9 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-18 09:41:26 -04:00
Lukas
eb5b8118e6 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-18 08:22:48 -04:00
Lukas
2923961575 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-18 07:38:11 -04:00
Lukas
9e2c943f24 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-18 07:37:21 -04:00
Bill Thornton
6b055dc637 Merge pull request #5540 from jellyfin/renovate/core-js-3.x 2024-05-18 04:03:34 -04:00
Kityn
fcfefa8bd9 Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-05-18 04:00:28 -04:00
Bill Thornton
da0d140ba1 Merge pull request #5538 from jellyfin/renovate/typescript 2024-05-18 03:56:05 -04:00
renovate[bot]
388a04a20b Update dependency typescript to v5.4.5 2024-05-18 07:49:47 +00:00
Bill Thornton
3334924466 Merge pull request #5543 from jellyfin/renovate/tests 2024-05-18 03:48:21 -04:00
Bill Thornton
47f54d940d Merge pull request #5544 from jellyfin/renovate/catchen-eslint-suggestion-action-4.x 2024-05-18 03:46:42 -04:00
Bill Thornton
4f678d01fc Merge pull request #5534 from jellyfin/renovate/loadable-component-5.x 2024-05-18 03:26:04 -04:00
renovate[bot]
0847bd69a1 Update dependency @types/markdown-it to v14 2024-05-18 07:13:34 +00:00
Bill Thornton
789361973e Merge pull request #5537 from jellyfin/renovate/hls.js-1.x 2024-05-18 03:13:04 -04:00
Bill Thornton
436ced2b0b Merge pull request #5535 from jellyfin/renovate/markdown-it-13.x 2024-05-18 03:11:30 -04:00
Bill Thornton
7c8c2ba668 Merge pull request #5536 from jellyfin/renovate/react-lazy-load-image-component-1.x 2024-05-18 03:10:39 -04:00
renovate[bot]
d2882e464a Update CatChen/eslint-suggestion-action action to v4 2024-05-18 07:04:29 +00:00
renovate[bot]
c65646e4eb Update dependency vitest to v1.6.0 2024-05-18 07:04:22 +00:00
renovate[bot]
94bd8f013f Update dependency swiper to v11.1.1 2024-05-18 07:04:05 +00:00
renovate[bot]
4634b4938d Update dependency sass to v1.77.1 2024-05-18 07:03:49 +00:00
renovate[bot]
d1f8049db7 Update dependency core-js to v3.37.0 2024-05-18 07:03:17 +00:00
renovate[bot]
7f0b48a0c8 Update Webpack 2024-05-18 07:03:00 +00:00
renovate[bot]
5ce354e067 Update dependency hls.js to v1.5.8 2024-05-18 07:02:26 +00:00
renovate[bot]
219f815f00 Update dependency @types/react-lazy-load-image-component to v1.6.4 2024-05-18 07:02:05 +00:00
renovate[bot]
c3bad4c3cb Update dependency @types/markdown-it to v13.0.8 2024-05-18 07:01:49 +00:00
renovate[bot]
86c4f45f02 Update dependency @loadable/component to v5.16.4 2024-05-18 07:01:33 +00:00
Bill Thornton
4c462b772e Merge pull request #5533 from jellyfin/renovate/emotion-monorepo 2024-05-18 02:55:37 -04:00
renovate[bot]
2463f08a5b Update dependency @emotion/styled to v11.11.5 2024-05-18 06:51:37 +00:00
Bill Thornton
ebe3f05b2d Merge pull request #5532 from jellyfin/renovate/fonts 2024-05-18 02:50:23 -04:00
Bill Thornton
186bd02efc Merge pull request #5310 from jellyfin/renovate/material-ui-monorepo 2024-05-18 02:48:10 -04:00
Bill Thornton
dc186b376b Merge pull request #5360 from jellyfin/renovate/postcss 2024-05-18 02:46:24 -04:00
Bill Thornton
ae73bd2248 Merge pull request #5387 from jellyfin/renovate/babel 2024-05-18 02:44:55 -04:00
renovate[bot]
18a7945177 Update Fonts 2024-05-18 06:42:36 +00:00
Bill Thornton
6353ff4693 Merge pull request #5369 from jellyfin/renovate/linters 2024-05-18 02:40:44 -04:00
Bill Thornton
60f5d180b0 Merge pull request #5355 from jellyfin/renovate/usehooks-ts-3.x 2024-05-18 02:39:48 -04:00
Bill Thornton
622acdeb76 Merge pull request #5354 from jellyfin/renovate/jsdom-24.x 2024-05-18 02:37:51 -04:00
無情天
86bbb909c8 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-18 02:23:20 -04:00
Bas
e42667f2fe Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-05-18 02:23:20 -04:00
scampower3
32fc33894d Add setting to prioritise what audio codec to transcode to (#5434)
* Add setting to prioritise what audio codec to transcode to

* Add comment

* rename selectPreferredTranscodeAudio to preferredTranscodeAudio

* Add review changes

* Add review changes

* Add reviewed fixes

* Add help text.

* Fix elint

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>

* Change *AudioCodecInVideo  to *VideoAudioCodec  and move option to video advanced

* Update src/components/playbackSettings/playbackSettings.template.html

Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>

---------

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Dmitry Lyzo <56478732+dmitrylyzo@users.noreply.github.com>
2024-05-18 01:19:56 -04:00
thornbill
291d3099bb Backport pull request #5530 from jellyfin-web/release-10.9.z
Fix scheduled task dialog z-index

Original-merge: 3402f1beba

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:50 -04:00
thornbill
e2f805da19 Backport pull request #5529 from jellyfin-web/release-10.9.z
Restore library menu tabs functionality

Original-merge: 7ce8c070b3

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:49 -04:00
Schoggi0815
5b1a65112a Backport pull request #5519 from jellyfin-web/release-10.9.z
Fix chapter markings not displayed properly

Original-merge: b17ca028f8

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:47 -04:00
thornbill
6da354a92e Backport pull request #5518 from jellyfin-web/release-10.9.z
Fix syncplay playback starting before listener created

Original-merge: 25b1bcab50

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:46 -04:00
thornbill
017734a0bb Backport pull request #5517 from jellyfin-web/release-10.9.z
Fix video osd not hiding in experimental layout

Original-merge: ea1d069e90

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:45 -04:00
thornbill
cb01afce02 Backport pull request #5512 from jellyfin-web/release-10.9.z
Fix invalid sort order values

Original-merge: 0fcb1ff983

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:44 -04:00
thornbill
ae26c92a38 Backport pull request #5507 from jellyfin-web/release-10.9.z
Set the minimum server version to match the sdk

Original-merge: a358d34ea9

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:42 -04:00
thornbill
fcce771cd8 Backport pull request #5500 from jellyfin-web/release-10.9.z
Fix stored credentials not updating on logout

Original-merge: ea8ceaa727

Merged-by: thornbill <thornbill@users.noreply.github.com>

Backported-by: Joshua M. Boniface <joshua@boniface.me>
2024-05-17 13:52:41 -04:00
Jan Ledermann
6053c2f3f8 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-17 07:59:24 -04:00
Kityn
6d08637723 Translated using Weblate (Polish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pl/
2024-05-17 02:41:26 -04:00
Jonhnny Translate
b0380c157b Translated using Weblate (French (Canada))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/
2024-05-17 02:41:26 -04:00
Jonhnny Translate
9b5415aa8d Translated using Weblate (French (Canada))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/
2024-05-17 00:41:26 -04:00
Jonhnny Translate
bf1ee507ee Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-16 22:41:26 -04:00
Jonhnny Translate
7686de9655 Translated using Weblate (French (Canada))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/
2024-05-16 22:41:26 -04:00
Bill Thornton
5793dd7c01 Merge pull request #5514 from jellyfin/renovate/ci-deps 2024-05-16 17:44:21 -04:00
renovate[bot]
e92f1d2fc1 Update CI dependencies 2024-05-16 21:13:46 +00:00
Nicolas
b7063f28bd Translated using Weblate (Danish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/
2024-05-16 14:41:06 -04:00
Nicolas
fb010d52c8 Translated using Weblate (Danish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/da/
2024-05-16 13:59:18 -04:00
Matteo
7922ad3b14 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-16 11:41:26 -04:00
Jonhnny Translate
7f1182acc4 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-15 18:41:26 -04:00
Jonhnny Translate
c2f42e9eb0 Translated using Weblate (French (Canada))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/
2024-05-15 18:41:26 -04:00
Jonhnny Translate
b7295b9501 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-15 16:41:26 -04:00
Jonhnny Translate
2b876d2ff1 Translated using Weblate (French (Canada))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr_CA/
2024-05-15 16:41:26 -04:00
HanaO00
aee56294a3 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-15 13:27:44 -04:00
stanol
ba4ff83219 Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-05-15 08:41:26 -04:00
millallo
1c0adcb8c1 Translated using Weblate (Italian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/it/
2024-05-15 08:41:25 -04:00
renovate[bot]
83a50853fb Update material-ui monorepo 2024-05-15 12:30:28 +00:00
LilleMarkus
c5332dc98b Translated using Weblate (Estonian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/et/
2024-05-15 06:41:25 -04:00
LJQ
b316accfba Add display options for tvdb plugin 2024-05-15 01:35:47 +08:00
kimpig
b87c569391 Translated using Weblate (Korean)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ko/
2024-05-14 12:58:40 -04:00
stanol
99f9efd86a Translated using Weblate (Ukrainian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/uk/
2024-05-13 15:15:14 -04:00
queeup
cc2298cf3f Translated using Weblate (Turkish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/tr/
2024-05-13 12:41:25 -04:00
無情天
fa1876c35e Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-13 10:59:15 -04:00
無情天
5ab041176e Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-13 10:18:22 -04:00
Maxime Louet
90a21502f4 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-13 08:41:25 -04:00
Maxime Louet
d04045d6f5 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-13 07:00:03 -04:00
nextlooper42
add4f029e4 Translated using Weblate (Slovak)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/sk/
2024-05-13 05:15:18 -04:00
Bas
edc70fece4 Translated using Weblate (Dutch)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/nl/
2024-05-13 02:32:05 -04:00
jayrom23
2aadbf2758 Translated using Weblate (German)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/de/
2024-05-13 02:32:05 -04:00
Arios
83a520ef6f Translated using Weblate (Spanish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/es/
2024-05-13 00:41:25 -04:00
iafjwov4
d242fcf713 Translated using Weblate (French)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fr/
2024-05-12 21:22:27 -04:00
Mohamad-Nour-Als
166ad3149b Translated using Weblate (Arabic)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ar/
2024-05-12 21:22:27 -04:00
無情天
09ec147319 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-12 19:06:28 -04:00
無情天
00fa379c5d Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-12 18:19:53 -04:00
Lukáš Kucharczyk
b44a831d6c Translated using Weblate (Czech)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/cs/
2024-05-12 16:36:09 -04:00
Fernando Fernández
0f88248015 Remove the need for PR context artifacts in workflows
* Changing the branch of CF Pages to be of the following form: user/repo_name/branch

* Took the liberty to move the permissions key down below, so the name is always the first item (for consistency)

Signed-off-by: GitHub <noreply@github.com>
2024-05-12 18:49:38 +00:00
Blackspirits
a634bc798e Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-12 14:41:25 -04:00
Blackspirits
9e5963d4da Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-12 13:26:08 -04:00
Blackspirits
8b64f6df4c Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-05-12 13:26:08 -04:00
mozartbanging
cf5d876cd2 Translated using Weblate (Finnish)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/fi/
2024-05-12 13:26:07 -04:00
ntark
205635434e Translated using Weblate (Georgian)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/ka/
2024-05-12 11:41:26 -04:00
therealblitz00
2937f46da1 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-12 11:41:25 -04:00
無情天
b40cbb2b97 Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-12 00:41:25 -04:00
Blackspirits
01473b3bf1 Translated using Weblate (Portuguese)
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt/
2024-05-11 22:41:25 -04:00
Blackspirits
65bf19f67c Translated using Weblate (Portuguese (Portugal))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/pt_PT/
2024-05-11 22:41:25 -04:00
renovate[bot]
05ab24f904 Update dependency postcss-preset-env to v9.5.11 2024-05-11 22:13:48 +00:00
無情天
b33173938a Translated using Weblate (Chinese (Simplified))
Translation: Jellyfin/Jellyfin Web
Translate-URL: https://translate.jellyfin.org/projects/jellyfin/jellyfin-web/zh_Hans/
2024-05-11 15:24:05 -04:00
Jellyfin Release Bot
f94d395cc0 Bump version to 10.10.0 2024-05-11 14:24:07 -04:00
Jellyfin Release Bot
b6514c748d Bump version to 10.10.0 2024-05-11 14:24:04 -04:00
LJQ
12cb4a1f61 use VideoDoViTitle when available 2024-05-09 15:54:50 +08:00
LJQ
67f5eb4487 Dynamic generate selectPersonType Options 2024-05-07 18:41:26 +08:00
renovate[bot]
9844db1e18 Update Babel to v7.24.5 2024-05-06 19:43:00 +00:00
renovate[bot]
7cbb39600b Update Linters 2024-05-03 19:47:53 +00:00
renovate[bot]
84384e9f92 Update dependency usehooks-ts to v3 2024-04-11 17:03:50 +00:00
renovate[bot]
3a4c7948ad Update dependency jsdom to v24 2024-03-30 09:13:08 +00:00
Topher Johnson
7e8e6992f4 Remove reset password option for admin users
Because admin users shouldn't be able to reset their own password
without entering their password first, this commit removes the "reset
password" option for admin users.

Currently, hitting the reset password option as an admin will result in
a 400 Bad request saying "Admin user passwords must not be empty
(Parameter 'newPassword')"
2024-02-21 00:08:40 -08:00
405 changed files with 12341 additions and 7762 deletions

View File

@@ -79,6 +79,7 @@ module.exports = {
'operator-linebreak': ['error', 'before', { overrides: { '?': 'after', ':': 'after', '=': 'after' } }],
'padded-blocks': ['error', 'never'],
'prefer-const': ['error', { 'destructuring': 'all' }],
'prefer-promise-reject-errors': ['warn', { 'allowEmptyReject': true }],
'@typescript-eslint/prefer-for-of': ['error'],
'@typescript-eslint/prefer-optional-chain': ['error'],
'quotes': ['error', 'single', { 'avoidEscape': true, 'allowTemplateLiterals': false }],
@@ -263,6 +264,7 @@ module.exports = {
'UserParentalControlPage': 'writable',
'Windows': 'readonly',
// Build time definitions
__COMMIT_SHA__: 'readonly',
__JF_BUILD_VERSION__: 'readonly',
__PACKAGE_JSON_NAME__: 'readonly',
__PACKAGE_JSON_VERSION__: 'readonly',

View File

@@ -1,20 +1,22 @@
name: 'Automation'
name: Automation
concurrency:
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
cancel-in-progress: true
on:
push:
branches:
- master
pull_request_target:
types:
- synchronize
jobs:
triage:
name: 'Merge conflict labeling'
conflicts:
name: Merge conflict labeling
runs-on: ubuntu-latest
if: ${{ github.repository == 'jellyfin/jellyfin-web' }}
steps:
- uses: eps1lon/actions-label-merge-conflict@6d74047dcef155976a15e4a124dde2c7fe0c5522 # v3.0.1
- uses: eps1lon/actions-label-merge-conflict@1b1b1fcde06a9b3d089f3464c96417961dde1168 # v3.0.2
with:
dirtyLabel: 'merge conflict'
commentOnDirty: 'This pull request has merge conflicts. Please resolve the conflicts so the PR can be successfully reviewed and merged.'

View File

@@ -7,7 +7,7 @@ concurrency:
on:
push:
branches: [ master, release* ]
pull_request:
pull_request_target:
branches: [ master, release* ]
workflow_dispatch:
@@ -18,10 +18,12 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ github.event.pull_request.head.sha || github.sha }}
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -41,8 +43,87 @@ jobs:
mv dist/config.tmp.json dist/config.json
- name: Upload artifact
uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4.3.3
uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
with:
name: jellyfin-web__prod
path: |
dist
path: dist
publish:
name: Deploy to Cloudflare Pages
runs-on: ubuntu-latest
if: ${{ github.repository == 'jellyfin/jellyfin-web' }}
needs:
- run-build-prod
permissions:
contents: read
deployments: write
steps:
- name: Add comment
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
if: ${{ github.event_name == 'pull_request_target' }}
with:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | 🔄 Deploying... |
| **Preview URL** | Not available |
| **Type** | 🔀 Preview |
pr_number: ${{ github.event.pull_request.number }}
comment_tag: CFPages-deployment
mode: recreate
- name: Download workflow artifact
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
with:
name: jellyfin-web__prod
path: dist
- name: Publish to Cloudflare
id: cf
uses: cloudflare/wrangler-action@f84a562284fc78278ff9052435d9526f9c718361 # v3.7.0
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
command: pages deploy dist --project-name=jellyfin-web --branch=${{
(github.event_name != 'pull_request_target' || github.event.pull_request.head.repo.full_name == github.repository)
&& (github.event.pull_request.head.ref || github.ref_name)
|| format('{0}/{1}', github.event.pull_request.head.repo.full_name, github.event.pull_request.head.ref)
}} --commit-hash=${{ github.event.pull_request.head.sha || github.sha }}
- name: Update status comment (Success)
if: ${{ github.event_name == 'pull_request_target' && success() }}
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
with:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | ✅ Deployed! |
| **Preview URL** | ${{ steps.cf.outputs.deployment-url != '' && steps.cf.outputs.deployment-url || 'Not available' }} |
| **Type** | 🔀 Preview |
pr_number: ${{ github.event.pull_request.number }}
comment_tag: CFPages-deployment
mode: recreate
- name: Update status comment (Failure)
if: ${{ github.event_name == 'pull_request_target' && failure() }}
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
with:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
message: |
## Cloudflare Pages deployment
| **Latest commit** | <code>${{ github.event.pull_request.head.sha || github.sha }}</code> |
|-------------------|:-:|
| **Status** | ❌ Failure. Check workflow logs for details |
| **Preview URL** | Not available |
| **Type** | 🔀 Preview |
pr_number: ${{ github.event.pull_request.number }}
comment_tag: CFPages-deployment
mode: recreate

View File

@@ -19,16 +19,16 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Initialize CodeQL
uses: github/codeql-action/init@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/init@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0
with:
languages: javascript
queries: +security-extended
- name: Autobuild
uses: github/codeql-action/autobuild@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/autobuild@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@9fdb3e49720b44c48891d036bb502feb25684276 # v3.25.6
uses: github/codeql-action/analyze@eb055d739abdc2e8de2e5f4ba1a8b246daa779aa # v3.26.0

View File

@@ -18,7 +18,7 @@ jobs:
comment-id: ${{ github.event.comment.id }}
reactions: '+1'
- name: Checkout the latest code
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
token: ${{ secrets.JF_BOT_TOKEN }}
fetch-depth: 0

View File

@@ -1,65 +0,0 @@
name: Job messages
on:
workflow_call:
inputs:
branch:
required: false
type: string
commit:
required: true
type: string
preview_url:
required: false
type: string
build_workflow_run_id:
required: false
type: number
commenting_workflow_run_id:
required: true
type: string
in_progress:
required: true
type: boolean
outputs:
msg:
description: The composed message
value: ${{ jobs.msg.outputs.msg }}
marker:
description: Hidden marker to detect PR comments composed by the bot
value: "CFPages-deployment"
jobs:
msg:
name: Deployment status
runs-on: ubuntu-latest
outputs:
msg: ${{ env.msg }}
steps:
- name: Compose message
if: ${{ always() }}
id: compose
env:
COMMIT: ${{ inputs.commit }}
PREVIEW_URL: ${{ inputs.preview_url != '' && (inputs.branch != 'master' && inputs.preview_url || format('https://jellyfin-web.pages.dev ({0})', inputs.preview_url)) || 'Not available' }}
DEPLOY_STATUS: ${{ inputs.in_progress && '🔄 Deploying...' || (inputs.preview_url != '' && '✅ Deployed!' || '❌ Failure. Check workflow logs for details') }}
DEPLOYMENT_TYPE: ${{ inputs.branch != 'master' && '🔀 Preview' || '⚙️ Production' }}
BUILD_WORKFLOW_RUN: ${{ !inputs.in_progress && format('**[View build logs](https://github.com/{0}/actions/runs/{1})**', 'jellyfin/jellyfin-web', inputs.build_workflow_run_id) || '' }}
COMMENTING_WORKFLOW_RUN: ${{ format('**[View bot logs](https://github.com/{0}/actions/runs/{1})**', 'jellyfin/jellyfin-web', inputs.commenting_workflow_run_id) }}
# EOF is needed for multiline environment variables in a GitHub Actions context
run: |
echo "## Cloudflare Pages deployment" > $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "| **Latest commit** | <code>${COMMIT::7}</code> |" >> $GITHUB_STEP_SUMMARY
echo "|------------------------- |:----------------------------: |" >> $GITHUB_STEP_SUMMARY
echo "| **Status** | $DEPLOY_STATUS |" >> $GITHUB_STEP_SUMMARY
echo "| **Preview URL** | $PREVIEW_URL |" >> $GITHUB_STEP_SUMMARY
echo "| **Type** | $DEPLOYMENT_TYPE |" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "$BUILD_WORKFLOW_RUN" >> $GITHUB_STEP_SUMMARY
echo "$COMMENTING_WORKFLOW_RUN" >> $GITHUB_STEP_SUMMARY
COMPOSED_MSG=$(cat $GITHUB_STEP_SUMMARY)
echo "msg<<EOF" >> $GITHUB_ENV
echo "$COMPOSED_MSG" >> $GITHUB_ENV
echo "EOF" >> $GITHUB_ENV

View File

@@ -7,8 +7,6 @@ concurrency:
on:
pull_request_target:
branches: [ master, release* ]
types:
- synchronize
jobs:
run-eslint:
@@ -17,12 +15,12 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: ${{ github.event.pull_request.head.sha }}
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -33,6 +31,6 @@ jobs:
- name: Run eslint
if: ${{ github.repository == 'jellyfin/jellyfin-web' }}
uses: CatChen/eslint-suggestion-action@b110ac684564c7b73e47cc223eb7a5266ec83fd3 # v4.1.1
uses: CatChen/eslint-suggestion-action@bc82950fa97bb3e46d9cca16a8bf2ad3e3c010fc # v4.1.5
with:
github-token: ${{ secrets.GITHUB_TOKEN }}

View File

@@ -1,84 +0,0 @@
name: Publish
on:
workflow_run:
workflows:
- Build
types:
- completed
jobs:
publish:
name: Deploy to Cloudflare Pages
if: ${{ always() }}
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
# We set the environment variable here (and as an output) because,
# given no real runner is dispatched in compose-comment job (it's dispatched in the reusable workflow) in this workflow definition,
# the env. context is not valid.
env:
TARGET_BRANCH: |
${{
github.event.workflow_run.head_repository.full_name == github.repository
&& github.event.workflow_run.head_branch
|| format('{0}/{1}', github.event.workflow_run.head_repository.full_name, github.event.workflow_run.head_branch)
}}
outputs:
url: ${{ steps.cf.outputs.url }}
branch: ${{ env.TARGET_BRANCH }}
steps:
- name: Download workflow artifact
uses: dawidd6/action-download-artifact@09f2f74827fd3a8607589e5ad7f9398816f540fe # v3.1.4
with:
run_id: ${{ github.event.workflow_run.id }}
name: jellyfin-web__prod
path: dist
- name: Publish
id: cf
uses: cloudflare/pages-action@f0a1cd58cd66095dee69bfa18fa5efd1dde93bca # 1
with:
apiToken: ${{ secrets.CLOUDFLARE_API_TOKEN }}
accountId: ${{ secrets.CLOUDFLARE_ACCOUNT_ID }}
projectName: jellyfin-web
branch: ${{ env.TARGET_BRANCH }}
directory: dist
gitHubToken: ${{ secrets.GITHUB_TOKEN }}
compose-comment:
name: Compose comment
if: ${{ always() }}
uses: ./.github/workflows/job-messages.yml
needs:
- publish
with:
branch: ${{ needs.publish.outputs.branch }}
commit: ${{ github.event.workflow_run.head_commit.id }}
preview_url: ${{ needs.publish.outputs.url }}
build_workflow_run_id: ${{ github.event.workflow_run.id }}
commenting_workflow_run_id: ${{ github.run_id }}
in_progress: false
comment-status:
name: Create comment status
if: |
always() &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.pull_requests[0].number != ''
runs-on: ubuntu-latest
needs:
- compose-comment
steps:
- name: Update job summary in PR comment
uses: thollander/actions-comment-pull-request@fabd468d3a1a0b97feee5f6b9e499eab0dd903f6 # v2.5.0
with:
GITHUB_TOKEN: ${{ secrets.JF_BOT_TOKEN }}
message: ${{ needs.compose-comment.outputs.msg }}
pr_number: ${{ github.event.workflow_run.pull_requests[0].number }}
comment_tag: ${{ needs.compose-comment.outputs.marker }}
mode: recreate

View File

@@ -17,10 +17,10 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -41,10 +41,10 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -62,10 +62,10 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -86,10 +86,10 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -107,10 +107,10 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
- name: Setup node environment
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true

View File

@@ -16,13 +16,13 @@ jobs:
steps:
- name: Check out Git repository
uses: actions/checkout@a5ac7e51b41094c92402da3b24376905380afc29 # v4.1.6
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
with:
ref: master
token: ${{ secrets.JF_BOT_TOKEN }}
- name: Set up Node.js
uses: actions/setup-node@60edb5dd545a775178f52524783378180af0d1f8 # v4.0.2
uses: actions/setup-node@1e60f620b9541d16bece96c5465dc8ee9832be0b # v4.0.3
with:
node-version: 20
check-latest: true
@@ -35,7 +35,7 @@ jobs:
echo "JF_SDK_VERSION=${VERSION}" >> $GITHUB_ENV
- name: Open a pull request
uses: peter-evans/create-pull-request@6d6857d36972b65feb161a90e484f2984215f83e # v6.0.5
uses: peter-evans/create-pull-request@c5a7806660adbe173f04e3e038b0ccdcd758773c # v6.1.0
with:
token: ${{ secrets.JF_BOT_TOKEN }}
commit-message: Update @jellyfin/sdk to ${{env.JF_SDK_VERSION}}

9
.gitignore vendored
View File

@@ -3,6 +3,9 @@ dist
web
node_modules
# test coverage
coverage
# config
config.json
@@ -10,12 +13,6 @@ config.json
.idea
.vs
# log
yarn-error.log
# vim
*.sw?
# build artifacts
fedora/jellyfin-web-*.src.rpm
fedora/jellyfin-web-*.tar.gz

View File

@@ -87,9 +87,11 @@
- [JPUC1143](https://github.com/Jpuc1143)
- [David Angel](https://github.com/davidangel)
- [Pithaya](https://github.com/Pithaya)
- [Peter Santos](https://github.com/prsantos-com)
- [Chaitanya Shahare](https://github.com/Chaitanya-Shahare)
- [Connor Smith](https://github.com/ConnorS1110)
- [Venkat Karasani](https://github.com/venkat-karasani)
- [Connor Smith](https://github.com/ConnorS1110)
- [iFraan](https://github.com/iFraan)
## Emby Contributors

View File

@@ -85,8 +85,11 @@ Jellyfin Web is the frontend used for most of the clients available for end user
├── controllers # Legacy page views and controllers 🧹
├── elements # Basic webcomponents and React wrappers 🧹
├── hooks # Custom React hooks
├── legacy # Polyfills for legacy browsers
├── libraries # Third party libraries 🧹
├── lib # Reusable libraries
│   ├── globalize # Custom localization library
│   ├── legacy # Polyfills for legacy browsers
│   ├── navdrawer # Navigation drawer library for classic layout
│   └── scroller # Content scrolling library
├── plugins # Client plugins
├── scripts # Random assortment of visual components and utilities 🐉
├── strings # Translation files

View File

@@ -15,8 +15,8 @@ module.exports = {
'@babel/preset-react'
],
plugins: [
'@babel/plugin-proposal-class-properties',
'@babel/plugin-proposal-private-methods',
'@babel/plugin-transform-class-properties',
'@babel/plugin-transform-private-methods',
'babel-plugin-dynamic-import-polyfill'
]
};

10880
package-lock.json generated

File diff suppressed because it is too large Load Diff

View File

@@ -1,26 +1,28 @@
{
"name": "jellyfin-web",
"version": "10.9.11",
"version": "10.10.0",
"description": "Web interface for Jellyfin",
"repository": "https://github.com/jellyfin/jellyfin-web",
"license": "GPL-2.0-or-later",
"devDependencies": {
"@babel/core": "7.24.3",
"@babel/plugin-proposal-class-properties": "7.18.6",
"@babel/plugin-proposal-private-methods": "7.18.6",
"@babel/plugin-transform-modules-umd": "7.24.1",
"@babel/preset-env": "7.24.3",
"@babel/preset-react": "7.24.1",
"@babel/core": "7.24.9",
"@babel/plugin-transform-class-properties": "7.24.7",
"@babel/plugin-transform-modules-umd": "7.24.7",
"@babel/plugin-transform-private-methods": "7.24.7",
"@babel/preset-env": "7.24.8",
"@babel/preset-react": "7.24.7",
"@types/dompurify": "3.0.5",
"@types/escape-html": "1.0.4",
"@types/loadable__component": "5.13.9",
"@types/lodash-es": "4.17.12",
"@types/markdown-it": "13.0.7",
"@types/react": "17.0.79",
"@types/react-dom": "17.0.25",
"@types/markdown-it": "14.1.2",
"@types/react": "18.3.3",
"@types/react-dom": "18.3.0",
"@types/sortablejs": "1.15.8",
"@typescript-eslint/eslint-plugin": "5.62.0",
"@typescript-eslint/parser": "5.62.0",
"@uupaa/dynamic-import-polyfill": "1.0.2",
"@vitest/coverage-v8": "2.0.5",
"autoprefixer": "10.4.19",
"babel-loader": "9.1.3",
"babel-plugin-dynamic-import-polyfill": "1.0.0",
@@ -28,71 +30,70 @@
"confusing-browser-globals": "1.0.11",
"copy-webpack-plugin": "12.0.2",
"cross-env": "7.0.3",
"css-loader": "6.10.0",
"cssnano": "6.1.2",
"es-check": "7.1.1",
"css-loader": "7.1.2",
"cssnano": "7.0.4",
"es-check": "7.2.1",
"eslint": "8.57.0",
"eslint-plugin-compat": "4.2.0",
"eslint-plugin-eslint-comments": "3.2.0",
"eslint-plugin-import": "2.29.1",
"eslint-plugin-jsx-a11y": "6.8.0",
"eslint-plugin-react": "7.34.1",
"eslint-plugin-react-hooks": "4.6.0",
"eslint-plugin-sonarjs": "0.24.0",
"expose-loader": "4.1.0",
"eslint-plugin-jsx-a11y": "6.9.0",
"eslint-plugin-react": "7.35.0",
"eslint-plugin-react-hooks": "4.6.2",
"eslint-plugin-sonarjs": "0.25.1",
"expose-loader": "5.0.0",
"fork-ts-checker-webpack-plugin": "9.0.2",
"html-loader": "4.2.0",
"html-loader": "5.1.0",
"html-webpack-plugin": "5.6.0",
"jsdom": "23.2.0",
"mini-css-extract-plugin": "2.8.1",
"postcss": "8.4.38",
"postcss-loader": "7.3.4",
"postcss-preset-env": "9.5.2",
"jsdom": "24.1.1",
"mini-css-extract-plugin": "2.9.0",
"postcss": "8.4.40",
"postcss-loader": "8.1.1",
"postcss-preset-env": "9.6.0",
"postcss-scss": "4.0.9",
"sass": "1.72.0",
"sass-loader": "13.3.3",
"source-map-loader": "4.0.2",
"sass": "1.77.8",
"sass-loader": "15.0.0",
"source-map-loader": "5.0.0",
"speed-measure-webpack-plugin": "1.5.0",
"style-loader": "3.3.4",
"style-loader": "4.0.0",
"stylelint": "15.11.0",
"stylelint-config-rational-order": "0.1.2",
"stylelint-no-browser-hacks": "1.3.0",
"stylelint-order": "6.0.4",
"stylelint-scss": "5.3.2",
"ts-loader": "9.5.1",
"typescript": "5.4.3",
"vitest": "1.4.0",
"webpack": "5.91.0",
"webpack-bundle-analyzer": "4.10.1",
"typescript": "5.5.4",
"vitest": "2.0.5",
"webpack": "5.93.0",
"webpack-bundle-analyzer": "4.10.2",
"webpack-cli": "5.1.4",
"webpack-dev-server": "4.15.2",
"webpack-merge": "5.10.0",
"webpack-dev-server": "5.0.4",
"webpack-merge": "6.0.1",
"worker-loader": "3.0.8"
},
"dependencies": {
"@emotion/react": "11.11.4",
"@emotion/styled": "11.11.0",
"@fontsource/noto-sans": "5.0.21",
"@fontsource/noto-sans-hk": "5.0.18",
"@fontsource/noto-sans-jp": "5.0.18",
"@fontsource/noto-sans-kr": "5.0.18",
"@fontsource/noto-sans-sc": "5.0.18",
"@fontsource/noto-sans-tc": "5.0.18",
"@jellyfin/libass-wasm": "4.2.1",
"@jellyfin/sdk": "0.9.0",
"@loadable/component": "5.16.3",
"@mui/icons-material": "5.15.11",
"@mui/material": "5.15.11",
"@mui/x-data-grid": "6.19.5",
"@react-hook/resize-observer": "1.2.6",
"@tanstack/react-query": "4.36.1",
"@tanstack/react-query-devtools": "4.36.1",
"@types/react-lazy-load-image-component": "1.6.3",
"@emotion/react": "11.13.0",
"@emotion/styled": "11.13.0",
"@fontsource/noto-sans": "5.0.22",
"@fontsource/noto-sans-hk": "5.0.20",
"@fontsource/noto-sans-jp": "5.0.19",
"@fontsource/noto-sans-kr": "5.0.19",
"@fontsource/noto-sans-sc": "5.0.20",
"@fontsource/noto-sans-tc": "5.0.20",
"@jellyfin/libass-wasm": "4.2.2",
"@jellyfin/sdk": "0.0.0-unstable.202408050429",
"@mui/icons-material": "5.15.19",
"@mui/material": "5.15.19",
"@mui/x-data-grid": "7.6.1",
"@react-hook/resize-observer": "2.0.1",
"@tanstack/react-query": "5.51.11",
"@tanstack/react-query-devtools": "5.51.11",
"@types/react-lazy-load-image-component": "1.6.4",
"abortcontroller-polyfill": "1.7.5",
"blurhash": "2.0.5",
"classlist.js": "https://github.com/eligrey/classList.js/archive/1.2.20180112.tar.gz",
"classnames": "2.5.1",
"core-js": "3.36.1",
"core-js": "3.37.1",
"date-fns": "2.30.0",
"dompurify": "3.0.1",
"epubjs": "0.3.93",
@@ -101,7 +102,7 @@
"flv.js": "1.6.2",
"headroom.js": "0.12.0",
"history": "5.3.0",
"hls.js": "1.5.7",
"hls.js": "1.5.13",
"intersection-observer": "0.12.2",
"jellyfin-apiclient": "1.11.0",
"jquery": "3.7.1",
@@ -112,16 +113,16 @@
"material-design-icons-iconfont": "6.7.0",
"native-promise-only": "0.8.1",
"pdfjs-dist": "3.11.174",
"react": "17.0.2",
"react": "18.3.1",
"react-blurhash": "0.3.0",
"react-dom": "17.0.2",
"react-lazy-load-image-component": "1.6.0",
"react-router-dom": "6.22.3",
"react-dom": "18.3.1",
"react-lazy-load-image-component": "1.6.2",
"react-router-dom": "6.25.1",
"resize-observer-polyfill": "1.5.1",
"screenfull": "6.0.2",
"sortablejs": "1.15.2",
"swiper": "11.0.7",
"usehooks-ts": "2.16.0",
"swiper": "11.1.7",
"usehooks-ts": "3.1.0",
"webcomponents.js": "0.7.24",
"whatwg-fetch": "3.6.20"
},

View File

@@ -6,19 +6,17 @@ import { ApiProvider } from 'hooks/useApi';
import { WebConfigProvider } from 'hooks/useWebConfig';
import { queryClient } from 'utils/query/queryClient';
import RootAppRouter from './RootAppRouter';
import RootAppRouter from 'RootAppRouter';
const RootApp = () => {
return (
<QueryClientProvider client={queryClient}>
<ApiProvider>
<WebConfigProvider>
<RootAppRouter />
</WebConfigProvider>
</ApiProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
};
const RootApp = () => (
<QueryClientProvider client={queryClient}>
<ApiProvider>
<WebConfigProvider>
<RootAppRouter />
</WebConfigProvider>
</ApiProvider>
<ReactQueryDevtools initialIsOpen={false} />
</QueryClientProvider>
);
export default RootApp;

View File

@@ -13,23 +13,20 @@ import { useApi } from 'hooks/useApi';
import AppTabs from './components/AppTabs';
import AppDrawer from './components/drawer/AppDrawer';
import { DASHBOARD_APP_PATHS } from './routes/routes';
import './AppOverrides.scss';
interface AppLayoutProps {
drawerlessPaths: string[]
}
const DRAWERLESS_PATHS = [ DASHBOARD_APP_PATHS.MetadataManager ];
const AppLayout: FC<AppLayoutProps> = ({
drawerlessPaths
}) => {
export const Component: FC = () => {
const [ isDrawerActive, setIsDrawerActive ] = useState(false);
const location = useLocation();
const { user } = useApi();
const isMediumScreen = useMediaQuery((t: Theme) => t.breakpoints.up('md'));
const isDrawerAvailable = Boolean(user)
&& !drawerlessPaths.some(path => location.pathname.startsWith(`/${path}`));
&& !DRAWERLESS_PATHS.some(path => location.pathname.startsWith(`/${path}`));
const isDrawerOpen = isDrawerActive && isDrawerAvailable;
const onToggleDrawer = useCallback(() => {
@@ -95,5 +92,3 @@ const AppLayout: FC<AppLayoutProps> = ({
</Box>
);
};
export default AppLayout;

View File

@@ -2,7 +2,7 @@ import { LogLevel } from '@jellyfin/sdk/lib/generated-client/models/log-level';
import Chip from '@mui/material/Chip';
import React from 'react';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
const LogLevelChip = ({ level }: { level: LogLevel }) => {
let color: 'info' | 'warning' | 'error' | undefined;

View File

@@ -29,8 +29,8 @@ const AppDrawer: FC<ResponsiveDrawerProps> = ({
<ServerDrawerSection />
<DevicesDrawerSection />
<LiveTvDrawerSection />
<AdvancedDrawerSection />
<PluginDrawerSection />
<AdvancedDrawerSection />
</ResponsiveDrawer>
);

View File

@@ -1,36 +1,18 @@
import Article from '@mui/icons-material/Article';
import EditNotifications from '@mui/icons-material/EditNotifications';
import ExpandLess from '@mui/icons-material/ExpandLess';
import ExpandMore from '@mui/icons-material/ExpandMore';
import Extension from '@mui/icons-material/Extension';
import Lan from '@mui/icons-material/Lan';
import Schedule from '@mui/icons-material/Schedule';
import VpnKey from '@mui/icons-material/VpnKey';
import Collapse from '@mui/material/Collapse';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import ListSubheader from '@mui/material/ListSubheader';
import React from 'react';
import { useLocation } from 'react-router-dom';
import ListItemLink from 'components/ListItemLink';
import globalize from 'scripts/globalize';
const PLUGIN_PATHS = [
'/dashboard/plugins',
'/dashboard/plugins/catalog',
'/dashboard/plugins/repositories',
'/dashboard/plugins/add',
'/configurationpage'
];
import globalize from 'lib/globalize';
const AdvancedDrawerSection = () => {
const location = useLocation();
const isPluginSectionOpen = PLUGIN_PATHS.includes(location.pathname);
return (
<List
aria-labelledby='advanced-subheader'
@@ -64,36 +46,6 @@ const AdvancedDrawerSection = () => {
<ListItemText primary={globalize.translate('TabLogs')} />
</ListItemLink>
</ListItem>
<ListItem disablePadding>
<ListItemLink to='/dashboard/notifications'>
<ListItemIcon>
<EditNotifications />
</ListItemIcon>
<ListItemText primary={globalize.translate('Notifications')} />
</ListItemLink>
</ListItem>
<ListItem disablePadding>
<ListItemLink to='/dashboard/plugins' selected={false}>
<ListItemIcon>
<Extension />
</ListItemIcon>
<ListItemText primary={globalize.translate('TabPlugins')} />
{isPluginSectionOpen ? <ExpandLess /> : <ExpandMore />}
</ListItemLink>
</ListItem>
<Collapse in={isPluginSectionOpen} timeout='auto' unmountOnExit>
<List component='div' disablePadding>
<ListItemLink to='/dashboard/plugins' sx={{ pl: 4 }}>
<ListItemText inset primary={globalize.translate('TabMyPlugins')} />
</ListItemLink>
<ListItemLink to='/dashboard/plugins/catalog' sx={{ pl: 4 }}>
<ListItemText inset primary={globalize.translate('TabCatalog')} />
</ListItemLink>
<ListItemLink to='/dashboard/plugins/repositories' sx={{ pl: 4 }}>
<ListItemText inset primary={globalize.translate('TabRepositories')} />
</ListItemLink>
</List>
</Collapse>
<ListItem disablePadding>
<ListItemLink to='/dashboard/tasks'>
<ListItemIcon>

View File

@@ -1,4 +1,4 @@
import { Devices, Analytics, Input } from '@mui/icons-material';
import { Devices, Analytics } from '@mui/icons-material';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
@@ -7,7 +7,7 @@ import ListSubheader from '@mui/material/ListSubheader';
import React from 'react';
import ListItemLink from 'components/ListItemLink';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
const DevicesDrawerSection = () => {
return (
@@ -35,14 +35,6 @@ const DevicesDrawerSection = () => {
<ListItemText primary={globalize.translate('HeaderActivity')} />
</ListItemLink>
</ListItem>
<ListItem disablePadding>
<ListItemLink to='/dashboard/dlna'>
<ListItemIcon>
<Input />
</ListItemIcon>
<ListItemText primary={'DLNA'} />
</ListItemLink>
</ListItem>
</List>
);
};

View File

@@ -7,7 +7,7 @@ import ListSubheader from '@mui/material/ListSubheader';
import React from 'react';
import ListItemLink from 'components/ListItemLink';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
const LiveTvDrawerSection = () => {
return (

View File

@@ -1,41 +1,26 @@
import { ConfigurationPageInfo } from '@jellyfin/sdk/lib/generated-client';
import { getDashboardApi } from '@jellyfin/sdk/lib/utils/api/dashboard-api';
import { Folder } from '@mui/icons-material';
import Extension from '@mui/icons-material/Extension';
import Folder from '@mui/icons-material/Folder';
import Public from '@mui/icons-material/Public';
import List from '@mui/material/List';
import ListItem from '@mui/material/ListItem';
import ListItemIcon from '@mui/material/ListItemIcon';
import ListItemText from '@mui/material/ListItemText';
import ListSubheader from '@mui/material/ListSubheader';
import React, { useEffect, useState } from 'react';
import React, { useEffect } from 'react';
import ListItemLink from 'components/ListItemLink';
import { useApi } from 'hooks/useApi';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import Dashboard from 'utils/dashboard';
import { useConfigurationPages } from 'apps/dashboard/features/plugins/api/useConfigurationPages';
const PluginDrawerSection = () => {
const { api } = useApi();
const [ pagesInfo, setPagesInfo ] = useState<ConfigurationPageInfo[]>([]);
const {
data: pagesInfo,
error
} = useConfigurationPages({ enableInMainMenu: true });
useEffect(() => {
const fetchPluginPages = async () => {
if (!api) return;
const pagesResponse = await getDashboardApi(api)
.getConfigurationPages({ enableInMainMenu: true });
setPagesInfo(pagesResponse.data);
};
fetchPluginPages()
.catch(err => {
console.error('[PluginDrawerSection] unable to fetch plugin config pages', err);
});
}, [ api ]);
if (!api || pagesInfo.length < 1) {
return null;
}
if (error) console.error('[PluginDrawerSection] unable to fetch plugin config pages', error);
}, [ error ]);
return (
<List
@@ -46,19 +31,39 @@ const PluginDrawerSection = () => {
</ListSubheader>
}
>
{
pagesInfo.map(pageInfo => (
<ListItem key={pageInfo.PluginId} disablePadding>
<ListItemLink to={`/${Dashboard.getPluginUrl(pageInfo.Name)}`}>
<ListItemIcon>
{/* TODO: Support different icons? */}
<Folder />
</ListItemIcon>
<ListItemText primary={pageInfo.DisplayName} />
</ListItemLink>
</ListItem>
))
}
<ListItemLink
to='/dashboard/plugins'
includePaths={[ '/configurationpage' ]}
excludePaths={pagesInfo?.map(p => `/${Dashboard.getPluginUrl(p.Name)}`)}
>
<ListItemIcon>
<Extension />
</ListItemIcon>
<ListItemText primary={globalize.translate('TabMyPlugins')} />
</ListItemLink>
<ListItemLink
to='/dashboard/plugins/catalog'
includePaths={[ '/dashboard/plugins/repositories' ]}
>
<ListItemIcon>
<Public />
</ListItemIcon>
<ListItemText primary={globalize.translate('TabCatalog')} />
</ListItemLink>
{pagesInfo?.map(pageInfo => (
<ListItemLink
key={pageInfo.PluginId}
to={`/${Dashboard.getPluginUrl(pageInfo.Name)}`}
>
<ListItemIcon>
{/* TODO: Support different icons? */}
<Folder />
</ListItemIcon>
<ListItemText primary={pageInfo.DisplayName} />
</ListItemLink>
))}
</List>
);
};

View File

@@ -9,7 +9,7 @@ import React from 'react';
import { useLocation } from 'react-router-dom';
import ListItemLink from 'components/ListItemLink';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
const LIBRARY_PATHS = [
'/dashboard/libraries',

View File

@@ -0,0 +1,21 @@
import type { ConfigurationPageInfo } from '@jellyfin/sdk/lib/generated-client/models/configuration-page-info';
export const findBestConfigurationPage = (
configurationPages: ConfigurationPageInfo[],
pluginId: string
) => {
// Find candidates matching the plugin id
const candidates = configurationPages.filter(c => c.PluginId === pluginId);
// If none are found, return undefined
if (candidates.length === 0) return;
// If only one is found, return it
if (candidates.length === 1) return candidates[0];
// Prefer the first candidate with the EnableInMainMenu flag for consistency
const menuCandidate = candidates.find(c => !!c.EnableInMainMenu);
if (menuCandidate) return menuCandidate;
// Fallback to the first match
return candidates[0];
};

View File

@@ -0,0 +1,25 @@
import type { PluginInfo } from '@jellyfin/sdk/lib/generated-client/models/plugin-info';
import { PluginStatus } from '@jellyfin/sdk/lib/generated-client/models/plugin-status';
/**
* HACK: The Plugins API is returning garbage data in some cases,
* so we need to try to find the "best" match if multiple exist.
*/
export const findBestPluginInfo = (
pluginId: string,
plugins?: PluginInfo[]
) => {
if (!plugins) return;
// Find all plugin entries with a matching ID
const matches = plugins.filter(p => p.Id === pluginId);
// Get the first match (or undefined if none)
const firstMatch = matches?.[0];
if (matches.length > 1) {
return matches.find(p => p.Status === PluginStatus.Disabled) // Disabled entries take priority
|| matches.find(p => p.Status === PluginStatus.Restart) // Then entries specifying restart is needed
|| firstMatch; // Fallback to the first match
}
return firstMatch;
};

View File

@@ -0,0 +1,5 @@
export enum QueryKey {
ConfigurationPages = 'ConfigurationPages',
PackageInfo = 'PackageInfo',
Plugins = 'Plugins'
}

View File

@@ -0,0 +1,40 @@
import type { Api } from '@jellyfin/sdk';
import type { DashboardApiGetConfigurationPagesRequest } from '@jellyfin/sdk/lib/generated-client/api/dashboard-api';
import { getDashboardApi } from '@jellyfin/sdk/lib/utils/api/dashboard-api';
import { queryOptions, useQuery } from '@tanstack/react-query';
import type { AxiosRequestConfig } from 'axios';
import { useApi } from 'hooks/useApi';
import { QueryKey } from './queryKey';
const fetchConfigurationPages = async (
api?: Api,
params?: DashboardApiGetConfigurationPagesRequest,
options?: AxiosRequestConfig
) => {
if (!api) {
console.warn('[fetchConfigurationPages] No API instance available');
return [];
}
const response = await getDashboardApi(api)
.getConfigurationPages(params, options);
return response.data;
};
const getConfigurationPagesQuery = (
api?: Api,
params?: DashboardApiGetConfigurationPagesRequest
) => queryOptions({
queryKey: [ QueryKey.ConfigurationPages, params?.enableInMainMenu ],
queryFn: ({ signal }) => fetchConfigurationPages(api, params, { signal }),
enabled: !!api
});
export const useConfigurationPages = (
params?: DashboardApiGetConfigurationPagesRequest
) => {
const { api } = useApi();
return useQuery(getConfigurationPagesQuery(api, params));
};

View File

@@ -0,0 +1,24 @@
import type { PluginsApiDisablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api';
import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api';
import { useMutation } from '@tanstack/react-query';
import { useApi } from 'hooks/useApi';
import { queryClient } from 'utils/query/queryClient';
import { QueryKey } from './queryKey';
export const useDisablePlugin = () => {
const { api } = useApi();
return useMutation({
mutationFn: (params: PluginsApiDisablePluginRequest) => (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getPluginsApi(api!)
.disablePlugin(params)
),
onSuccess: () => {
void queryClient.invalidateQueries({
queryKey: [ QueryKey.Plugins ]
});
}
});
};

View File

@@ -0,0 +1,24 @@
import type { PluginsApiEnablePluginRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api';
import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api';
import { useMutation } from '@tanstack/react-query';
import { useApi } from 'hooks/useApi';
import { queryClient } from 'utils/query/queryClient';
import { QueryKey } from './queryKey';
export const useEnablePlugin = () => {
const { api } = useApi();
return useMutation({
mutationFn: (params: PluginsApiEnablePluginRequest) => (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getPluginsApi(api!)
.enablePlugin(params)
),
onSuccess: () => {
void queryClient.invalidateQueries({
queryKey: [ QueryKey.Plugins ]
});
}
});
};

View File

@@ -0,0 +1,27 @@
import type { PackageApiInstallPackageRequest } from '@jellyfin/sdk/lib/generated-client/api/package-api';
import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api';
import { useMutation } from '@tanstack/react-query';
import { useApi } from 'hooks/useApi';
import { queryClient } from 'utils/query/queryClient';
import { QueryKey } from './queryKey';
export const useInstallPackage = () => {
const { api } = useApi();
return useMutation({
mutationFn: (params: PackageApiInstallPackageRequest) => (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getPackageApi(api!)
.installPackage(params)
),
onSuccess: () => {
void queryClient.invalidateQueries({
queryKey: [ QueryKey.ConfigurationPages ]
});
void queryClient.invalidateQueries({
queryKey: [ QueryKey.Plugins ]
});
}
});
};

View File

@@ -0,0 +1,47 @@
import { queryOptions, useQuery } from '@tanstack/react-query';
import type { Api } from '@jellyfin/sdk';
import type { PackageApiGetPackageInfoRequest } from '@jellyfin/sdk/lib/generated-client/api/package-api';
import { getPackageApi } from '@jellyfin/sdk/lib/utils/api/package-api';
import type { AxiosRequestConfig } from 'axios';
import { useApi } from 'hooks/useApi';
import { QueryKey } from './queryKey';
const fetchPackageInfo = async (
api?: Api,
params?: PackageApiGetPackageInfoRequest,
options?: AxiosRequestConfig
) => {
if (!api) {
console.warn('[fetchPackageInfo] No API instance available');
return;
}
if (!params) {
console.warn('[fetchPackageInfo] Missing request params');
return;
}
const response = await getPackageApi(api)
.getPackageInfo(params, options);
return response.data;
};
const getPackageInfoQuery = (
api?: Api,
params?: PackageApiGetPackageInfoRequest
) => queryOptions({
// Don't retry since requests for plugins not available in repos fail
retry: false,
queryKey: [ QueryKey.PackageInfo, params?.name, params?.assemblyGuid ],
queryFn: ({ signal }) => fetchPackageInfo(api, params, { signal }),
enabled: !!api && !!params?.name
});
export const usePackageInfo = (
params?: PackageApiGetPackageInfoRequest
) => {
const { api } = useApi();
return useQuery(getPackageInfoQuery(api, params));
};

View File

@@ -0,0 +1,36 @@
import type { Api } from '@jellyfin/sdk';
import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api';
import { queryOptions, useQuery } from '@tanstack/react-query';
import type { AxiosRequestConfig } from 'axios';
import { useApi } from 'hooks/useApi';
import { QueryKey } from './queryKey';
const fetchPlugins = async (
api?: Api,
options?: AxiosRequestConfig
) => {
if (!api) {
console.warn('[fetchPlugins] No API instance available');
return [];
}
const response = await getPluginsApi(api)
.getPlugins(options);
return response.data;
};
const getPluginsQuery = (
api?: Api
) => queryOptions({
queryKey: [ QueryKey.Plugins ],
queryFn: ({ signal }) => fetchPlugins(api, { signal }),
enabled: !!api
});
export const usePlugins = () => {
const { api } = useApi();
return useQuery(getPluginsQuery(api));
};

View File

@@ -0,0 +1,27 @@
import type { PluginsApiUninstallPluginByVersionRequest } from '@jellyfin/sdk/lib/generated-client/api/plugins-api';
import { getPluginsApi } from '@jellyfin/sdk/lib/utils/api/plugins-api';
import { useMutation } from '@tanstack/react-query';
import { useApi } from 'hooks/useApi';
import { queryClient } from 'utils/query/queryClient';
import { QueryKey } from './queryKey';
export const useUninstallPlugin = () => {
const { api } = useApi();
return useMutation({
mutationFn: (params: PluginsApiUninstallPluginByVersionRequest) => (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
getPluginsApi(api!)
.uninstallPluginByVersion(params)
),
onSuccess: () => {
void queryClient.invalidateQueries({
queryKey: [ QueryKey.Plugins ]
});
void queryClient.invalidateQueries({
queryKey: [ QueryKey.ConfigurationPages ]
});
}
});
};

View File

@@ -0,0 +1,94 @@
import Link from '@mui/material/Link/Link';
import Paper, { type PaperProps } from '@mui/material/Paper/Paper';
import Skeleton from '@mui/material/Skeleton/Skeleton';
import Table from '@mui/material/Table/Table';
import TableBody from '@mui/material/TableBody/TableBody';
import TableCell from '@mui/material/TableCell/TableCell';
import TableContainer from '@mui/material/TableContainer/TableContainer';
import TableRow from '@mui/material/TableRow/TableRow';
import React, { FC } from 'react';
import { Link as RouterLink } from 'react-router-dom';
import globalize from 'lib/globalize';
import type { PluginDetails } from '../types/PluginDetails';
interface PluginDetailsTableProps extends PaperProps {
isPluginLoading: boolean
isRepositoryLoading: boolean
pluginDetails?: PluginDetails
}
const PluginDetailsTable: FC<PluginDetailsTableProps> = ({
isPluginLoading,
isRepositoryLoading,
pluginDetails,
...paperProps
}) => (
<TableContainer component={Paper} {...paperProps}>
<Table>
<TableBody>
<TableRow>
<TableCell variant='head'>
{globalize.translate('LabelStatus')}
</TableCell>
<TableCell>
{
(isPluginLoading && <Skeleton />)
|| pluginDetails?.status
|| globalize.translate('LabelNotInstalled')
}
</TableCell>
</TableRow>
<TableRow>
<TableCell variant='head'>
{globalize.translate('LabelVersion')}
</TableCell>
<TableCell>
{
(isPluginLoading && <Skeleton />)
|| pluginDetails?.version?.version
}
</TableCell>
</TableRow>
<TableRow>
<TableCell variant='head'>
{globalize.translate('LabelDeveloper')}
</TableCell>
<TableCell>
{
(isRepositoryLoading && <Skeleton />)
|| pluginDetails?.owner
|| globalize.translate('Unknown')
}
</TableCell>
</TableRow>
<TableRow
sx={{ '&:last-child td, &:last-child th': { border: 0 } }}
>
<TableCell variant='head'>
{globalize.translate('LabelRepository')}
</TableCell>
<TableCell>
{
(isRepositoryLoading && <Skeleton />)
|| (pluginDetails?.version?.repositoryUrl && (
<Link
component={RouterLink}
to={pluginDetails.version.repositoryUrl}
target='_blank'
rel='noopener noreferrer'
>
{pluginDetails.version.repositoryName}
</Link>
))
|| globalize.translate('Unknown')
}
</TableCell>
</TableRow>
</TableBody>
</Table>
</TableContainer>
);
export default PluginDetailsTable;

View File

@@ -0,0 +1,34 @@
import Paper from '@mui/material/Paper/Paper';
import Skeleton from '@mui/material/Skeleton/Skeleton';
import React, { type FC } from 'react';
interface PluginImageProps {
isLoading: boolean
alt?: string
url?: string
}
const PluginImage: FC<PluginImageProps> = ({
isLoading,
alt,
url
}) => (
<Paper sx={{ width: '100%', aspectRatio: 16 / 9, overflow: 'hidden' }}>
{isLoading && (
<Skeleton
variant='rectangular'
width='100%'
height='100%'
/>
)}
{url && (
<img
src={url}
alt={alt}
width='100%'
/>
)}
</Paper>
);
export default PluginImage;

View File

@@ -0,0 +1,67 @@
import Download from '@mui/icons-material/Download';
import DownloadDone from '@mui/icons-material/DownloadDone';
import ExpandMore from '@mui/icons-material/ExpandMore';
import Accordion from '@mui/material/Accordion/Accordion';
import AccordionDetails from '@mui/material/AccordionDetails/AccordionDetails';
import AccordionSummary from '@mui/material/AccordionSummary/AccordionSummary';
import Button from '@mui/material/Button/Button';
import Stack from '@mui/material/Stack/Stack';
import React, { type FC } from 'react';
import MarkdownBox from 'components/MarkdownBox';
import { parseISO8601Date, toLocaleString } from 'scripts/datetime';
import globalize from 'lib/globalize';
import type { PluginDetails } from '../types/PluginDetails';
import { VersionInfo } from '@jellyfin/sdk/lib/generated-client';
interface PluginRevisionsProps {
pluginDetails?: PluginDetails,
onInstall: (version?: VersionInfo) => () => void
}
const PluginRevisions: FC<PluginRevisionsProps> = ({
pluginDetails,
onInstall
}) => (
pluginDetails?.versions?.map(version => (
<Accordion key={version.checksum}>
<AccordionSummary
expandIcon={<ExpandMore />}
>
{version.version}
{version.timestamp && (<>
&nbsp;&mdash;&nbsp;
{toLocaleString(parseISO8601Date(version.timestamp))}
</>)}
</AccordionSummary>
<AccordionDetails>
<Stack spacing={2}>
<MarkdownBox
fallback={globalize.translate('LabelNoChangelog')}
markdown={version.changelog}
/>
{pluginDetails.status && version.version === pluginDetails.version?.version ? (
<Button
disabled
startIcon={<DownloadDone />}
variant='outlined'
>
{globalize.translate('LabelInstalled')}
</Button>
) : (
<Button
startIcon={<Download />}
variant='outlined'
onClick={onInstall(version)}
>
{globalize.translate('HeaderInstall')}
</Button>
)}
</Stack>
</AccordionDetails>
</Accordion>
))
);
export default PluginRevisions;

View File

@@ -0,0 +1,15 @@
import type { ConfigurationPageInfo, PluginStatus, VersionInfo } from '@jellyfin/sdk/lib/generated-client';
export interface PluginDetails {
canUninstall: boolean
description?: string
id: string
imageUrl?: string
isEnabled: boolean
name?: string
owner?: string
configurationPage?: ConfigurationPageInfo
status?: PluginStatus
version?: VersionInfo
versions: VersionInfo[]
}

View File

@@ -2,13 +2,12 @@ import { AsyncRouteType, type AsyncRoute } from 'components/router/AsyncRoute';
export const ASYNC_ADMIN_ROUTES: AsyncRoute[] = [
{ path: 'activity', type: AsyncRouteType.Dashboard },
{ path: 'dlna', type: AsyncRouteType.Dashboard },
{ path: 'notifications', type: AsyncRouteType.Dashboard },
{ path: 'playback/trickplay', type: AsyncRouteType.Dashboard },
{ path: 'plugins/:pluginId', page: 'plugins/plugin', type: AsyncRouteType.Dashboard },
{ path: 'users', type: AsyncRouteType.Dashboard },
{ path: 'users/access', type: AsyncRouteType.Dashboard },
{ path: 'users/add', type: AsyncRouteType.Dashboard },
{ path: 'users/parentalcontrol', type: AsyncRouteType.Dashboard },
{ path: 'users/password', type: AsyncRouteType.Dashboard },
{ path: 'users/profile', type: AsyncRouteType.Dashboard },
{ path: 'playback/trickplay', type: AsyncRouteType.Dashboard }
{ path: 'users/profile', type: AsyncRouteType.Dashboard }
];

View File

@@ -31,12 +31,6 @@ export const LEGACY_ADMIN_ROUTES: LegacyRoute[] = [
controller: 'dashboard/devices/device',
view: 'dashboard/devices/device.html'
}
}, {
path: 'plugins/add',
pageProps: {
controller: 'dashboard/plugins/add/index',
view: 'dashboard/plugins/add/index.html'
}
}, {
path: 'libraries',
pageProps: {

View File

@@ -1,16 +1,12 @@
import type { Redirect } from 'components/router/Redirect';
export const REDIRECTS: Redirect[] = [
{ from: 'addplugin.html', to: '/dashboard/plugins/add' },
{ from: 'apikeys.html', to: '/dashboard/keys' },
{ from: 'availableplugins.html', to: '/dashboard/plugins/catalog' },
{ from: 'dashboard.html', to: '/dashboard' },
{ from: 'dashboardgeneral.html', to: '/dashboard/settings' },
{ from: 'device.html', to: '/dashboard/devices/edit' },
{ from: 'devices.html', to: '/dashboard/devices' },
{ from: 'dlnaprofile.html', to: '/dashboard/dlna' },
{ from: 'dlnaprofiles.html', to: '/dashboard/dlna' },
{ from: 'dlnasettings.html', to: '/dashboard/dlna' },
{ from: 'edititemmetadata.html', to: '/metadata' },
{ from: 'encodingsettings.html', to: '/dashboard/playback/transcoding' },
{ from: 'installedplugins.html', to: '/dashboard/plugins' },
@@ -24,7 +20,6 @@ export const REDIRECTS: Redirect[] = [
{ from: 'metadataimages.html', to: '/dashboard/libraries/metadata' },
{ from: 'metadatanfo.html', to: '/dashboard/libraries/nfo' },
{ from: 'networking.html', to: '/dashboard/networking' },
{ from: 'notificationsettings.html', to: '/dashboard/notifications' },
{ from: 'playbackconfiguration.html', to: '/dashboard/playback/resume' },
{ from: 'repositories.html', to: '/dashboard/plugins/repositories' },
{ from: 'scheduledtask.html', to: '/dashboard/tasks/edit' },

View File

@@ -16,7 +16,7 @@ import Page from 'components/Page';
import UserAvatar from 'components/UserAvatar';
import { useApi } from 'hooks/useApi';
import { parseISO8601Date, toLocaleDateString, toLocaleTimeString } from 'scripts/datetime';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { toBoolean } from 'utils/string';
import LogLevelChip from '../components/activityTable/LogLevelChip';
@@ -60,7 +60,7 @@ const Activity = () => {
field: 'User',
headerName: globalize.translate('LabelUser'),
width: 60,
valueGetter: ({ row }) => users[row.UserId]?.Name,
valueGetter: ( value, row ) => users[row.UserId]?.Name,
renderCell: ({ row }) => (
<IconButton
size='large'
@@ -82,16 +82,16 @@ const Activity = () => {
headerName: globalize.translate('LabelDate'),
width: 90,
type: 'date',
valueGetter: ({ value }) => parseISO8601Date(value),
valueFormatter: ({ value }) => toLocaleDateString(value)
valueGetter: ( value ) => parseISO8601Date(value),
valueFormatter: ( value ) => toLocaleDateString(value)
},
{
field: 'Time',
headerName: globalize.translate('LabelTime'),
width: 100,
type: 'dateTime',
valueGetter: ({ row }) => parseISO8601Date(row.Date),
valueFormatter: ({ value }) => toLocaleTimeString(value)
valueGetter: ( value, row ) => parseISO8601Date(row.Date),
valueFormatter: ( value ) => toLocaleTimeString(value)
},
{
field: 'Severity',
@@ -113,7 +113,7 @@ const Activity = () => {
field: 'Overview',
headerName: globalize.translate('LabelOverview'),
width: 200,
valueGetter: ({ row }) => row.ShortOverview ?? row.Overview,
valueGetter: ( value, row ) => row.ShortOverview ?? row.Overview,
renderCell: ({ row }) => (
<OverviewCell {...row} />
)
@@ -147,7 +147,7 @@ const Activity = () => {
}
];
const onViewChange = useCallback((_e, newView: ActivityView | null) => {
const onViewChange = useCallback((_e: React.MouseEvent<HTMLElement, MouseEvent>, newView: ActivityView | null) => {
if (newView !== null) {
setActivityView(newView);
}

View File

@@ -1,33 +0,0 @@
import Alert from '@mui/material/Alert/Alert';
import Box from '@mui/material/Box/Box';
import Button from '@mui/material/Button/Button';
import React from 'react';
import { Link } from 'react-router-dom';
import Page from 'components/Page';
import globalize from 'scripts/globalize';
const DlnaPage = () => (
<Page
id='dlnaSettingsPage'
title='DLNA'
className='mainAnimatedPage type-interior'
>
<div className='content-primary'>
<h2>DLNA</h2>
<Alert severity='info'>
<Box sx={{ marginBottom: 2 }}>
{globalize.translate('DlnaMovedMessage')}
</Box>
<Button
component={Link}
to='/dashboard/plugins/add?name=DLNA&guid=33eba9cd7da14720967fdd7dae7b74a1'
>
{globalize.translate('GetThePlugin')}
</Button>
</Alert>
</div>
</Page>
);
export default DlnaPage;

View File

@@ -1,34 +0,0 @@
import Alert from '@mui/material/Alert/Alert';
import Box from '@mui/material/Box/Box';
import Button from '@mui/material/Button/Button';
import React from 'react';
import { Link } from 'react-router-dom';
import Page from 'components/Page';
import globalize from 'scripts/globalize';
const NotificationsPage = () => (
<Page
id='notificationSettingPage'
title={globalize.translate('Notifications')}
className='mainAnimatedPage type-interior'
>
<div className='content-primary'>
<h2>{globalize.translate('Notifications')}</h2>
<Alert severity='info'>
<Box sx={{ marginBottom: 2 }}>
{globalize.translate('NotificationsMovedMessage')}
</Box>
<Button
component={Link}
to='/dashboard/plugins/add?name=Webhook&guid=71552a5a5c5c4350a2aeebe451a30173'
>
{globalize.translate('GetThePlugin')}
</Button>
</Alert>
</div>
</Page>
);
export default NotificationsPage;

View File

@@ -1,7 +1,9 @@
import type { ProcessPriorityClass, ServerConfiguration, TrickplayScanBehavior } from '@jellyfin/sdk/lib/generated-client';
import React, { type FunctionComponent, useCallback, useEffect, useRef } from 'react';
import type { ServerConfiguration } from '@jellyfin/sdk/lib/generated-client/models/server-configuration';
import { TrickplayScanBehavior } from '@jellyfin/sdk/lib/generated-client/models/trickplay-scan-behavior';
import { ProcessPriorityClass } from '@jellyfin/sdk/lib/generated-client/models/process-priority-class';
import React, { type FC, useCallback, useEffect, useRef } from 'react';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import Page from '../../../../components/Page';
import SectionTitleContainer from '../../../../elements/SectionTitleContainer';
import ButtonElement from '../../../../elements/ButtonElement';
@@ -17,10 +19,10 @@ function onSaveComplete() {
toast(globalize.translate('SettingsSaved'));
}
const PlaybackTrickplay: FunctionComponent = () => {
const PlaybackTrickplay: FC = () => {
const element = useRef<HTMLDivElement>(null);
const loadConfig = useCallback((config) => {
const loadConfig = useCallback((config: ServerConfiguration) => {
const page = element.current;
const options = config.TrickplayOptions;
@@ -29,17 +31,17 @@ const PlaybackTrickplay: FunctionComponent = () => {
return;
}
(page.querySelector('.chkEnableHwAcceleration') as HTMLInputElement).checked = options.EnableHwAcceleration;
(page.querySelector('.chkEnableHwEncoding') as HTMLInputElement).checked = options.EnableHwEncoding;
(page.querySelector('#selectScanBehavior') as HTMLSelectElement).value = options.ScanBehavior;
(page.querySelector('#selectProcessPriority') as HTMLSelectElement).value = options.ProcessPriority;
(page.querySelector('#txtInterval') as HTMLInputElement).value = options.Interval;
(page.querySelector('#txtWidthResolutions') as HTMLInputElement).value = options.WidthResolutions.join(',');
(page.querySelector('#txtTileWidth') as HTMLInputElement).value = options.TileWidth;
(page.querySelector('#txtTileHeight') as HTMLInputElement).value = options.TileHeight;
(page.querySelector('#txtQscale') as HTMLInputElement).value = options.Qscale;
(page.querySelector('#txtJpegQuality') as HTMLInputElement).value = options.JpegQuality;
(page.querySelector('#txtProcessThreads') as HTMLInputElement).value = options.ProcessThreads;
(page.querySelector('.chkEnableHwAcceleration') as HTMLInputElement).checked = options?.EnableHwAcceleration || false;
(page.querySelector('.chkEnableHwEncoding') as HTMLInputElement).checked = options?.EnableHwEncoding || false;
(page.querySelector('#selectScanBehavior') as HTMLSelectElement).value = (options?.ScanBehavior || TrickplayScanBehavior.NonBlocking);
(page.querySelector('#selectProcessPriority') as HTMLSelectElement).value = (options?.ProcessPriority || ProcessPriorityClass.Normal);
(page.querySelector('#txtInterval') as HTMLInputElement).value = options?.Interval?.toString() || '10000';
(page.querySelector('#txtWidthResolutions') as HTMLInputElement).value = options?.WidthResolutions?.join(',') || '';
(page.querySelector('#txtTileWidth') as HTMLInputElement).value = options?.TileWidth?.toString() || '10';
(page.querySelector('#txtTileHeight') as HTMLInputElement).value = options?.TileHeight?.toString() || '10';
(page.querySelector('#txtQscale') as HTMLInputElement).value = options?.Qscale?.toString() || '4';
(page.querySelector('#txtJpegQuality') as HTMLInputElement).value = options?.JpegQuality?.toString() || '90';
(page.querySelector('#txtProcessThreads') as HTMLInputElement).value = options?.ProcessThreads?.toString() || '1';
loading.hide();
}, []);

View File

@@ -0,0 +1,443 @@
import { PluginStatus } from '@jellyfin/sdk/lib/generated-client/models/plugin-status';
import type { VersionInfo } from '@jellyfin/sdk/lib/generated-client/models/version-info';
import Alert from '@mui/material/Alert/Alert';
import Button from '@mui/material/Button/Button';
import Container from '@mui/material/Container/Container';
import FormControlLabel from '@mui/material/FormControlLabel/FormControlLabel';
import FormGroup from '@mui/material/FormGroup/FormGroup';
import Grid from '@mui/material/Grid/Grid';
import Skeleton from '@mui/material/Skeleton/Skeleton';
import Stack from '@mui/material/Stack/Stack';
import Switch from '@mui/material/Switch/Switch';
import Typography from '@mui/material/Typography/Typography';
import Delete from '@mui/icons-material/Delete';
import Download from '@mui/icons-material/Download';
import Settings from '@mui/icons-material/Settings';
import React, { type FC, useState, useCallback, useMemo } from 'react';
import { useSearchParams, Link as RouterLink, useParams } from 'react-router-dom';
import { findBestConfigurationPage } from 'apps/dashboard/features/plugins/api/configurationPage';
import { findBestPluginInfo } from 'apps/dashboard/features/plugins/api/pluginInfo';
import { useConfigurationPages } from 'apps/dashboard/features/plugins/api/useConfigurationPages';
import { useDisablePlugin } from 'apps/dashboard/features/plugins/api/useDisablePlugin';
import { useEnablePlugin } from 'apps/dashboard/features/plugins/api/useEnablePlugin';
import { useInstallPackage } from 'apps/dashboard/features/plugins/api/useInstallPackage';
import { usePackageInfo } from 'apps/dashboard/features/plugins/api/usePackageInfo';
import { usePlugins } from 'apps/dashboard/features/plugins/api/usePlugins';
import { useUninstallPlugin } from 'apps/dashboard/features/plugins/api/useUninstallPlugin';
import PluginImage from 'apps/dashboard/features/plugins/components/PluginImage';
import PluginDetailsTable from 'apps/dashboard/features/plugins/components/PluginDetailsTable';
import PluginRevisions from 'apps/dashboard/features/plugins/components/PluginRevisions';
import type { PluginDetails } from 'apps/dashboard/features/plugins/types/PluginDetails';
import ConfirmDialog from 'components/ConfirmDialog';
import Page from 'components/Page';
import { useApi } from 'hooks/useApi';
import globalize from 'lib/globalize';
import { getPluginUrl } from 'utils/dashboard';
import { getUri } from 'utils/api';
interface AlertMessage {
severity?: 'success' | 'info' | 'warning' | 'error'
messageKey: string
}
// Plugins from this url will be trusted and not prompt for confirmation when installing
const TRUSTED_REPO_URL = 'https://repo.jellyfin.org/';
const PluginPage: FC = () => {
const { api } = useApi();
const { pluginId } = useParams();
const [ searchParams ] = useSearchParams();
const disablePlugin = useDisablePlugin();
const enablePlugin = useEnablePlugin();
const installPlugin = useInstallPackage();
const uninstallPlugin = useUninstallPlugin();
const [ isEnabledOverride, setIsEnabledOverride ] = useState<boolean>();
const [ isInstallConfirmOpen, setIsInstallConfirmOpen ] = useState(false);
const [ isUninstallConfirmOpen, setIsUninstallConfirmOpen ] = useState(false);
const [ pendingInstallVersion, setPendingInstallVersion ] = useState<VersionInfo>();
const pluginName = searchParams.get('name') ?? undefined;
const {
data: configurationPages,
isError: isConfigurationPagesError,
isLoading: isConfigurationPagesLoading
} = useConfigurationPages();
const {
data: packageInfo,
isError: isPackageInfoError,
isLoading: isPackageInfoLoading
} = usePackageInfo(pluginName ? {
name: pluginName,
assemblyGuid: pluginId
} : undefined);
const {
data: plugins,
isLoading: isPluginsLoading,
isError: isPluginsError
} = usePlugins();
const isLoading =
isConfigurationPagesLoading || isPackageInfoLoading || isPluginsLoading;
const pluginDetails = useMemo<PluginDetails | undefined>(() => {
if (pluginId && !isPluginsLoading) {
const pluginInfo = findBestPluginInfo(pluginId, plugins);
let version;
if (pluginInfo) {
// Find the installed version
const repoVersion = packageInfo?.versions?.find(v => v.version === pluginInfo.Version);
version = repoVersion || {
version: pluginInfo.Version,
VersionNumber: pluginInfo.Version
};
} else {
// Use the latest version
version = packageInfo?.versions?.[0];
}
let imageUrl;
if (pluginInfo?.HasImage) {
imageUrl = getUri(`/Plugins/${pluginInfo.Id}/${pluginInfo.Version}/Image`, api);
}
return {
canUninstall: !!pluginInfo?.CanUninstall,
description: pluginInfo?.Description || packageInfo?.description || packageInfo?.overview,
id: pluginId,
imageUrl: imageUrl || packageInfo?.imageUrl || undefined,
isEnabled: (isEnabledOverride && pluginInfo?.Status === PluginStatus.Restart)
?? pluginInfo?.Status !== PluginStatus.Disabled,
name: pluginName || pluginInfo?.Name || packageInfo?.name,
owner: packageInfo?.owner,
status: pluginInfo?.Status,
configurationPage: findBestConfigurationPage(configurationPages || [], pluginId),
version,
versions: packageInfo?.versions || []
};
}
}, [
api,
configurationPages,
isEnabledOverride,
isPluginsLoading,
packageInfo?.description,
packageInfo?.imageUrl,
packageInfo?.name,
packageInfo?.overview,
packageInfo?.owner,
packageInfo?.versions,
pluginId,
pluginName,
plugins
]);
const alertMessages = useMemo(() => {
const alerts: AlertMessage[] = [];
if (disablePlugin.isError) {
alerts.push({ messageKey: 'PluginDisableError' });
}
if (enablePlugin.isError) {
alerts.push({ messageKey: 'PluginEnableError' });
}
if (installPlugin.isSuccess) {
alerts.push({
severity: 'success',
messageKey: 'MessagePluginInstalled'
});
}
if (installPlugin.isError) {
alerts.push({ messageKey: 'MessagePluginInstallError' });
}
if (uninstallPlugin.isError) {
alerts.push({ messageKey: 'PluginUninstallError' });
}
if (isConfigurationPagesError) {
alerts.push({ messageKey: 'PluginLoadConfigError' });
}
if (isPackageInfoError) {
alerts.push({
severity: 'warning',
messageKey: 'PluginLoadRepoError'
});
}
if (isPluginsError) {
alerts.push({ messageKey: 'MessageGetInstalledPluginsError' });
}
return alerts;
}, [
disablePlugin.isError,
enablePlugin.isError,
installPlugin.isError,
installPlugin.isSuccess,
isConfigurationPagesError,
isPackageInfoError,
isPluginsError,
uninstallPlugin.isError
]);
/** Enable/disable the plugin */
const toggleEnabled = useCallback(() => {
if (!pluginDetails?.version?.version) return;
console.debug('[PluginPage] %s plugin', pluginDetails.isEnabled ? 'disabling' : 'enabling', pluginDetails);
if (pluginDetails.isEnabled) {
disablePlugin.mutate({
pluginId: pluginDetails.id,
version: pluginDetails.version.version
}, {
onSuccess: () => {
setIsEnabledOverride(false);
},
onSettled: () => {
installPlugin.reset();
enablePlugin.reset();
uninstallPlugin.reset();
}
});
} else {
enablePlugin.mutate({
pluginId: pluginDetails.id,
version: pluginDetails.version.version
}, {
onSuccess: () => {
setIsEnabledOverride(true);
},
onSettled: () => {
installPlugin.reset();
disablePlugin.reset();
uninstallPlugin.reset();
}
});
}
}, [ disablePlugin, enablePlugin, installPlugin, pluginDetails, uninstallPlugin ]);
/** Install the plugin or prompt for confirmation if untrusted */
const onInstall = useCallback((version?: VersionInfo, isConfirmed = false) => () => {
if (!pluginDetails?.name) return;
const installVersion = version || pluginDetails.version;
if (!installVersion) return;
if (!isConfirmed && !installVersion.repositoryUrl?.startsWith(TRUSTED_REPO_URL)) {
console.debug('[PluginPage] plugin install needs confirmed', installVersion);
setPendingInstallVersion(installVersion);
setIsInstallConfirmOpen(true);
return;
}
console.debug('[PluginPage] installing plugin', installVersion);
installPlugin.mutate({
name: pluginDetails.name,
assemblyGuid: pluginDetails.id,
version: installVersion.version,
repositoryUrl: installVersion.repositoryUrl
}, {
onSettled: () => {
setPendingInstallVersion(undefined);
disablePlugin.reset();
enablePlugin.reset();
uninstallPlugin.reset();
}
});
}, [ disablePlugin, enablePlugin, installPlugin, pluginDetails, uninstallPlugin ]);
/** Confirm and install the plugin */
const onConfirmInstall = useCallback(() => {
console.debug('[PluginPage] confirmed installing plugin', pendingInstallVersion);
setIsInstallConfirmOpen(false);
onInstall(pendingInstallVersion, true)();
}, [ onInstall, pendingInstallVersion ]);
/** Close the install confirmation dialog */
const onCloseInstallConfirmDialog = useCallback(() => {
setPendingInstallVersion(undefined);
setIsInstallConfirmOpen(false);
}, []);
/** Show the uninstall confirmation dialog */
const onConfirmUninstall = useCallback(() => {
setIsUninstallConfirmOpen(true);
}, []);
/** Uninstall the plugin */
const onUninstall = useCallback(() => {
if (!pluginDetails?.version?.version) return;
console.debug('[PluginPage] uninstalling plugin', pluginDetails);
setIsUninstallConfirmOpen(false);
uninstallPlugin.mutate({
pluginId: pluginDetails.id,
version: pluginDetails.version.version
}, {
onSettled: () => {
disablePlugin.reset();
enablePlugin.reset();
installPlugin.reset();
}
});
}, [ disablePlugin, enablePlugin, installPlugin, pluginDetails, uninstallPlugin ]);
/** Close the uninstall confirmation dialog */
const onCloseUninstallConfirmDialog = useCallback(() => {
setIsUninstallConfirmOpen(false);
}, []);
return (
<Page
id='addPluginPage'
className='mainAnimatedPage type-interior'
>
<Container className='content-primary'>
{alertMessages.map(({ severity = 'error', messageKey }) => (
<Alert key={messageKey} severity={severity}>
{globalize.translate(messageKey)}
</Alert>
))}
<Grid container spacing={2} sx={{ marginTop: 0 }}>
<Grid item xs={12} lg={8}>
<Stack spacing={2}>
<Typography variant='h1'>
{pluginDetails?.name || pluginName}
</Typography>
<Typography sx={{ maxWidth: '80ch' }}>
{isLoading && !pluginDetails?.description ? (
<Skeleton />
) : (
pluginDetails?.description
)}
</Typography>
</Stack>
</Grid>
<Grid item lg={4} sx={{ display: { xs: 'none', lg: 'initial' } }}>
<PluginImage
isLoading={isLoading}
alt={pluginDetails?.name}
url={pluginDetails?.imageUrl}
/>
</Grid>
<Grid item xs={12} lg={8} sx={{ order: { xs: 1, lg: 'initial' } }}>
{!!pluginDetails?.versions.length && (
<>
<Typography variant='h3' sx={{ marginBottom: 2 }}>
{globalize.translate('HeaderRevisionHistory')}
</Typography>
<PluginRevisions
pluginDetails={pluginDetails}
onInstall={onInstall}
/>
</>
)}
</Grid>
<Grid item xs={12} lg={4}>
<Stack spacing={2} direction={{ xs: 'column', sm: 'row-reverse', lg: 'column' }}>
<Stack spacing={1} sx={{ flexBasis: '50%' }}>
{!isLoading && !pluginDetails?.status && (
<>
<Alert severity='info'>
{globalize.translate('ServerRestartNeededAfterPluginInstall')}
</Alert>
<Button
startIcon={<Download />}
onClick={onInstall()}
>
{globalize.translate('HeaderInstall')}
</Button>
</>
)}
{!isLoading && pluginDetails?.canUninstall && (
<FormGroup>
<FormControlLabel
control={
<Switch
checked={pluginDetails.isEnabled}
onChange={toggleEnabled}
disabled={pluginDetails.status === PluginStatus.Restart}
/>
}
label={globalize.translate('LabelEnablePlugin')}
/>
</FormGroup>
)}
{!isLoading && pluginDetails?.configurationPage?.Name && (
<Button
component={RouterLink}
to={`/${getPluginUrl(pluginDetails.configurationPage.Name)}`}
startIcon={<Settings />}
>
{globalize.translate('Settings')}
</Button>
)}
{!isLoading && pluginDetails?.canUninstall && (
<Button
color='error'
startIcon={<Delete />}
onClick={onConfirmUninstall}
>
{globalize.translate('ButtonUninstall')}
</Button>
)}
</Stack>
<PluginDetailsTable
isPluginLoading={isPluginsLoading}
isRepositoryLoading={isPackageInfoLoading}
pluginDetails={pluginDetails}
sx={{ flexBasis: '50%' }}
/>
</Stack>
</Grid>
</Grid>
</Container>
<ConfirmDialog
open={isInstallConfirmOpen}
title={globalize.translate('HeaderConfirmPluginInstallation')}
text={globalize.translate('MessagePluginInstallDisclaimer')}
onCancel={onCloseInstallConfirmDialog}
onConfirm={onConfirmInstall}
confirmButtonText={globalize.translate('HeaderInstall')}
/>
<ConfirmDialog
open={isUninstallConfirmOpen}
title={globalize.translate('HeaderUninstallPlugin')}
text={globalize.translate('UninstallPluginConfirmation', pluginName || '')}
onCancel={onCloseUninstallConfirmDialog}
onConfirm={onUninstall}
confirmButtonColor='error'
confirmButtonText={globalize.translate('ButtonUninstall')}
/>
</Page>
);
};
export default PluginPage;

View File

@@ -1,12 +1,12 @@
import React from 'react';
import { RouteObject } from 'react-router-dom';
import AppLayout from '../AppLayout';
import ConnectionRequired from 'components/ConnectionRequired';
import { ASYNC_ADMIN_ROUTES } from './_asyncRoutes';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { LEGACY_ADMIN_ROUTES } from './_legacyRoutes';
import ServerContentPage from 'components/ServerContentPage';
import ErrorBoundary from 'components/router/ErrorBoundary';
export const DASHBOARD_APP_PATHS = {
Dashboard: 'dashboard',
@@ -19,14 +19,15 @@ export const DASHBOARD_APP_ROUTES: RouteObject[] = [
element: <ConnectionRequired isAdminRequired />,
children: [
{
element: <AppLayout drawerlessPaths={[ DASHBOARD_APP_PATHS.MetadataManager ]} />,
lazy: () => import('../AppLayout'),
children: [
{
path: DASHBOARD_APP_PATHS.Dashboard,
children: [
...ASYNC_ADMIN_ROUTES.map(toAsyncPageRoute),
...LEGACY_ADMIN_ROUTES.map(toViewManagerPageRoute)
]
],
errorElement: <ErrorBoundary pageClasses={[ 'type-interior' ]} />
},
/* NOTE: The metadata editor might deserve a dedicated app in the future */

View File

@@ -1,10 +1,10 @@
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
import React, { FunctionComponent, useCallback, useEffect, useState, useRef } from 'react';
import type { BaseItemDto, DeviceInfo, UserDto } from '@jellyfin/sdk/lib/generated-client';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import loading from '../../../../components/loading/loading';
import libraryMenu from '../../../../scripts/libraryMenu';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import toast from '../../../../components/toast/toast';
import SectionTabs from '../../../../components/dashboard/users/SectionTabs';
import ButtonElement from '../../../../elements/ButtonElement';
@@ -14,13 +14,13 @@ import CheckBoxElement from '../../../../elements/CheckBoxElement';
import Page from '../../../../components/Page';
type ItemsArr = {
Name?: string;
Id?: string;
AppName?: string;
Name?: string | null;
Id?: string | null;
AppName?: string | null;
checkedAttribute?: string
};
const UserLibraryAccess: FunctionComponent = () => {
const UserLibraryAccess = () => {
const [ searchParams ] = useSearchParams();
const userId = searchParams.get('userId');
const [ userName, setUserName ] = useState('');
@@ -35,7 +35,7 @@ const UserLibraryAccess: FunctionComponent = () => {
select.dispatchEvent(evt);
};
const loadMediaFolders = useCallback((user, mediaFolders) => {
const loadMediaFolders = useCallback((user: UserDto, mediaFolders: BaseItemDto[]) => {
const page = element.current;
if (!page) {
@@ -46,7 +46,7 @@ const UserLibraryAccess: FunctionComponent = () => {
const itemsArr: ItemsArr[] = [];
for (const folder of mediaFolders) {
const isChecked = user.Policy.EnableAllFolders || user.Policy.EnabledFolders.indexOf(folder.Id) != -1;
const isChecked = user.Policy?.EnableAllFolders || user.Policy?.EnabledFolders?.indexOf(folder.Id || '') != -1;
const checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
Id: folder.Id,
@@ -58,11 +58,11 @@ const UserLibraryAccess: FunctionComponent = () => {
setMediaFoldersItems(itemsArr);
const chkEnableAllFolders = page.querySelector('.chkEnableAllFolders') as HTMLInputElement;
chkEnableAllFolders.checked = user.Policy.EnableAllFolders;
chkEnableAllFolders.checked = Boolean(user.Policy?.EnableAllFolders);
triggerChange(chkEnableAllFolders);
}, []);
const loadChannels = useCallback((user, channels) => {
const loadChannels = useCallback((user: UserDto, channels: BaseItemDto[]) => {
const page = element.current;
if (!page) {
@@ -73,7 +73,7 @@ const UserLibraryAccess: FunctionComponent = () => {
const itemsArr: ItemsArr[] = [];
for (const folder of channels) {
const isChecked = user.Policy.EnableAllChannels || user.Policy.EnabledChannels.indexOf(folder.Id) != -1;
const isChecked = user.Policy?.EnableAllChannels || user.Policy?.EnabledChannels?.indexOf(folder.Id || '') != -1;
const checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
Id: folder.Id,
@@ -91,11 +91,11 @@ const UserLibraryAccess: FunctionComponent = () => {
}
const chkEnableAllChannels = page.querySelector('.chkEnableAllChannels') as HTMLInputElement;
chkEnableAllChannels.checked = user.Policy.EnableAllChannels;
chkEnableAllChannels.checked = Boolean(user.Policy?.EnableAllChannels);
triggerChange(chkEnableAllChannels);
}, []);
const loadDevices = useCallback((user, devices) => {
const loadDevices = useCallback((user: UserDto, devices: DeviceInfo[]) => {
const page = element.current;
if (!page) {
@@ -106,7 +106,7 @@ const UserLibraryAccess: FunctionComponent = () => {
const itemsArr: ItemsArr[] = [];
for (const device of devices) {
const isChecked = user.Policy.EnableAllDevices || user.Policy.EnabledDevices.indexOf(device.Id) != -1;
const isChecked = user.Policy?.EnableAllDevices || user.Policy?.EnabledDevices?.indexOf(device.Id || '') != -1;
const checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
Id: device.Id,
@@ -119,18 +119,18 @@ const UserLibraryAccess: FunctionComponent = () => {
setDevicesItems(itemsArr);
const chkEnableAllDevices = page.querySelector('.chkEnableAllDevices') as HTMLInputElement;
chkEnableAllDevices.checked = user.Policy.EnableAllDevices;
chkEnableAllDevices.checked = Boolean(user.Policy?.EnableAllDevices);
triggerChange(chkEnableAllDevices);
if (user.Policy.IsAdministrator) {
if (user.Policy?.IsAdministrator) {
(page.querySelector('.deviceAccessContainer') as HTMLDivElement).classList.add('hide');
} else {
(page.querySelector('.deviceAccessContainer') as HTMLDivElement).classList.remove('hide');
}
}, []);
const loadUser = useCallback((user, mediaFolders, channels, devices) => {
setUserName(user.Name);
const loadUser = useCallback((user: UserDto, mediaFolders: BaseItemDto[], channels: BaseItemDto[], devices: DeviceInfo[]) => {
setUserName(user.Name || '');
libraryMenu.setTitle(user.Name);
loadChannels(user, channels);
loadMediaFolders(user, mediaFolders);

View File

@@ -1,7 +1,8 @@
import React, { FunctionComponent, useCallback, useEffect, useState, useRef } from 'react';
import type { BaseItemDto } from '@jellyfin/sdk/lib/generated-client';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import loading from '../../../../components/loading/loading';
import toast from '../../../../components/toast/toast';
import SectionTitleContainer from '../../../../elements/SectionTitleContainer';
@@ -17,16 +18,16 @@ type userInput = {
};
type ItemsArr = {
Name?: string;
Name?: string | null;
Id?: string;
};
const UserNew: FunctionComponent = () => {
const UserNew = () => {
const [ channelsItems, setChannelsItems ] = useState<ItemsArr[]>([]);
const [ mediaFoldersItems, setMediaFoldersItems ] = useState<ItemsArr[]>([]);
const element = useRef<HTMLDivElement>(null);
const getItemsResult = (items: ItemsArr[]) => {
const getItemsResult = (items: BaseItemDto[]) => {
return items.map(item =>
({
Id: item.Id,
@@ -35,7 +36,7 @@ const UserNew: FunctionComponent = () => {
);
};
const loadMediaFolders = useCallback((result) => {
const loadMediaFolders = useCallback((result: BaseItemDto[]) => {
const page = element.current;
if (!page) {
@@ -53,7 +54,7 @@ const UserNew: FunctionComponent = () => {
(page.querySelector('.chkEnableAllFolders') as HTMLInputElement).checked = false;
}, []);
const loadChannels = useCallback((result) => {
const loadChannels = useCallback((result: BaseItemDto[]) => {
const page = element.current;
if (!page) {

View File

@@ -1,8 +1,8 @@
import type { UserDto } from '@jellyfin/sdk/lib/generated-client';
import React, { FunctionComponent, useEffect, useState, useRef } from 'react';
import React, { useEffect, useState, useRef } from 'react';
import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import loading from '../../../../components/loading/loading';
import dom from '../../../../scripts/dom';
import confirm from '../../../../components/confirm/confirm';
@@ -21,7 +21,7 @@ type MenuEntry = {
icon?: string;
};
const UserProfiles: FunctionComponent = () => {
const UserProfiles = () => {
const [ users, setUsers ] = useState<UserDto[]>([]);
const element = useRef<HTMLDivElement>(null);

View File

@@ -1,10 +1,11 @@
import type { AccessSchedule, ParentalRating, UserDto } from '@jellyfin/sdk/lib/generated-client';
import { UnratedItem } from '@jellyfin/sdk/lib/generated-client/models/unrated-item';
import { DynamicDayOfWeek } from '@jellyfin/sdk/lib/generated-client/models/dynamic-day-of-week';
import escapeHTML from 'escape-html';
import React, { FunctionComponent, useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import AccessScheduleList from '../../../../components/dashboard/users/AccessScheduleList';
import TagList from '../../../../components/dashboard/users/TagList';
@@ -19,9 +20,12 @@ import Page from '../../../../components/Page';
import prompt from '../../../../components/prompt/prompt';
import ServerConnections from 'components/ServerConnections';
type UnratedItem = {
type NamedItem = {
name: string;
value: string;
value: UnratedItem;
};
type UnratedNamedItem = NamedItem & {
checkedAttribute: string
};
@@ -56,19 +60,19 @@ function handleSaveUser(
};
}
const UserParentalControl: FunctionComponent = () => {
const UserParentalControl = () => {
const [ searchParams ] = useSearchParams();
const userId = searchParams.get('userId');
const [ userName, setUserName ] = useState('');
const [ parentalRatings, setParentalRatings ] = useState<ParentalRating[]>([]);
const [ unratedItems, setUnratedItems ] = useState<UnratedItem[]>([]);
const [ unratedItems, setUnratedItems ] = useState<UnratedNamedItem[]>([]);
const [ accessSchedules, setAccessSchedules ] = useState<AccessSchedule[]>([]);
const [ allowedTags, setAllowedTags ] = useState<string[]>([]);
const [ blockedTags, setBlockedTags ] = useState<string[]>([]);
const element = useRef<HTMLDivElement>(null);
const populateRatings = useCallback((allParentalRatings) => {
const populateRatings = useCallback((allParentalRatings: ParentalRating[]) => {
let rating;
const ratings: ParentalRating[] = [];
@@ -93,7 +97,7 @@ const UserParentalControl: FunctionComponent = () => {
setParentalRatings(ratings);
}, []);
const loadUnratedItems = useCallback((user) => {
const loadUnratedItems = useCallback((user: UserDto) => {
const page = element.current;
if (!page) {
@@ -101,42 +105,42 @@ const UserParentalControl: FunctionComponent = () => {
return;
}
const items = [{
const items: NamedItem[] = [{
name: globalize.translate('Books'),
value: 'Book'
value: UnratedItem.Book
}, {
name: globalize.translate('Channels'),
value: 'ChannelContent'
value: UnratedItem.ChannelContent
}, {
name: globalize.translate('LiveTV'),
value: 'LiveTvChannel'
value: UnratedItem.LiveTvChannel
}, {
name: globalize.translate('Movies'),
value: 'Movie'
value: UnratedItem.Movie
}, {
name: globalize.translate('Music'),
value: 'Music'
value: UnratedItem.Music
}, {
name: globalize.translate('Trailers'),
value: 'Trailer'
value: UnratedItem.Trailer
}, {
name: globalize.translate('Shows'),
value: 'Series'
value: UnratedItem.Series
}];
const itemsArr: UnratedItem[] = [];
const unratedNamedItem: UnratedNamedItem[] = [];
for (const item of items) {
const isChecked = user.Policy.BlockUnratedItems.indexOf(item.value) != -1;
const isChecked = user.Policy?.BlockUnratedItems?.indexOf(item.value) != -1;
const checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
unratedNamedItem.push({
value: item.value,
name: item.name,
checkedAttribute: checkedAttribute
});
}
setUnratedItems(itemsArr);
setUnratedItems(unratedNamedItem);
const blockUnratedItems = page.querySelector('.blockUnratedItems') as HTMLDivElement;
blockUnratedItems.dispatchEvent(new CustomEvent('create'));
@@ -184,7 +188,7 @@ const UserParentalControl: FunctionComponent = () => {
}
}, []);
const renderAccessSchedule = useCallback((schedules) => {
const renderAccessSchedule = useCallback((schedules: AccessSchedule[]) => {
const page = element.current;
if (!page) {
@@ -200,7 +204,7 @@ const UserParentalControl: FunctionComponent = () => {
btnDelete.addEventListener('click', function () {
const index = parseInt(btnDelete.getAttribute('data-index') ?? '0', 10);
schedules.splice(index, 1);
const newindex = schedules.filter((i: number) => i != index);
const newindex = schedules.filter((_, i) => i != index);
renderAccessSchedule(newindex);
});
}
@@ -231,7 +235,7 @@ const UserParentalControl: FunctionComponent = () => {
});
}
(page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value = ratingValue;
(page.querySelector('#selectMaxParentalRating') as HTMLSelectElement).value = String(ratingValue);
if (user.Policy?.IsAdministrator) {
(page.querySelector('.accessScheduleSection') as HTMLDivElement).classList.add('hide');

View File

@@ -1,4 +1,4 @@
import React, { FunctionComponent, useCallback, useEffect, useState } from 'react';
import React, { useCallback, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import SectionTabs from '../../../../components/dashboard/users/SectionTabs';
@@ -7,7 +7,7 @@ import SectionTitleContainer from '../../../../elements/SectionTitleContainer';
import Page from '../../../../components/Page';
import loading from '../../../../components/loading/loading';
const UserPassword: FunctionComponent = () => {
const UserPassword = () => {
const [ searchParams ] = useSearchParams();
const userId = searchParams.get('userId');
const [ userName, setUserName ] = useState('');

View File

@@ -1,10 +1,10 @@
import type { SyncPlayUserAccessType, UserDto } from '@jellyfin/sdk/lib/generated-client';
import type { BaseItemDto, NameIdPair, SyncPlayUserAccessType, UserDto } from '@jellyfin/sdk/lib/generated-client';
import escapeHTML from 'escape-html';
import React, { FunctionComponent, useCallback, useEffect, useState, useRef } from 'react';
import React, { useCallback, useEffect, useState, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import ButtonElement from '../../../../elements/ButtonElement';
import CheckBoxElement from '../../../../elements/CheckBoxElement';
@@ -17,15 +17,10 @@ import toast from '../../../../components/toast/toast';
import SelectElement from '../../../../elements/SelectElement';
import Page from '../../../../components/Page';
type ResetProvider = AuthProvider & {
type ResetProvider = BaseItemDto & {
checkedAttribute: string
};
type AuthProvider = {
Name?: string;
Id?: string;
};
const getCheckedElementDataIds = (elements: NodeListOf<Element>) => (
Array.prototype.filter.call(elements, e => e.checked)
.map(e => e.getAttribute('data-id'))
@@ -40,13 +35,13 @@ function onSaveComplete() {
toast(globalize.translate('SettingsSaved'));
}
const UserEdit: FunctionComponent = () => {
const UserEdit = () => {
const [ searchParams ] = useSearchParams();
const userId = searchParams.get('userId');
const [ userName, setUserName ] = useState('');
const [ deleteFoldersAccess, setDeleteFoldersAccess ] = useState<ResetProvider[]>([]);
const [ authProviders, setAuthProviders ] = useState<AuthProvider[]>([]);
const [ passwordResetProviders, setPasswordResetProviders ] = useState<ResetProvider[]>([]);
const [ authProviders, setAuthProviders ] = useState<NameIdPair[]>([]);
const [ passwordResetProviders, setPasswordResetProviders ] = useState<NameIdPair[]>([]);
const [ authenticationProviderId, setAuthenticationProviderId ] = useState('');
const [ passwordResetProviderId, setPasswordResetProviderId ] = useState('');
@@ -63,48 +58,27 @@ const UserEdit: FunctionComponent = () => {
return window.ApiClient.getUser(userId);
};
const loadAuthProviders = useCallback((user, providers) => {
const page = element.current;
if (!page) {
console.error('Unexpected null reference');
return;
}
const loadAuthProviders = useCallback((page: HTMLDivElement, user: UserDto, providers: NameIdPair[]) => {
const fldSelectLoginProvider = page.querySelector('.fldSelectLoginProvider') as HTMLDivElement;
fldSelectLoginProvider.classList.toggle('hide', providers.length <= 1);
setAuthProviders(providers);
const currentProviderId = user.Policy.AuthenticationProviderId;
const currentProviderId = user.Policy?.AuthenticationProviderId || '';
setAuthenticationProviderId(currentProviderId);
}, []);
const loadPasswordResetProviders = useCallback((user, providers) => {
const page = element.current;
if (!page) {
console.error('Unexpected null reference');
return;
}
const loadPasswordResetProviders = useCallback((page: HTMLDivElement, user: UserDto, providers: NameIdPair[]) => {
const fldSelectPasswordResetProvider = page.querySelector('.fldSelectPasswordResetProvider') as HTMLDivElement;
fldSelectPasswordResetProvider.classList.toggle('hide', providers.length <= 1);
setPasswordResetProviders(providers);
const currentProviderId = user.Policy.PasswordResetProviderId;
const currentProviderId = user.Policy?.PasswordResetProviderId || '';
setPasswordResetProviderId(currentProviderId);
}, []);
const loadDeleteFolders = useCallback((user, mediaFolders) => {
const page = element.current;
if (!page) {
console.error('Unexpected null reference');
return;
}
const loadDeleteFolders = useCallback((page: HTMLDivElement, user: UserDto, mediaFolders: BaseItemDto[]) => {
window.ApiClient.getJSON(window.ApiClient.getUrl('Channels', {
SupportsMediaDeletion: true
})).then(function (channelsResult) {
@@ -112,22 +86,20 @@ const UserEdit: FunctionComponent = () => {
let checkedAttribute;
const itemsArr: ResetProvider[] = [];
for (const folder of mediaFolders) {
isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1;
for (const mediaFolder of mediaFolders) {
isChecked = user.Policy?.EnableContentDeletion || user.Policy?.EnableContentDeletionFromFolders?.indexOf(mediaFolder.Id || '') != -1;
checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
Id: folder.Id,
Name: folder.Name,
...mediaFolder,
checkedAttribute: checkedAttribute
});
}
for (const folder of channelsResult.Items) {
isChecked = user.Policy.EnableContentDeletion || user.Policy.EnableContentDeletionFromFolders.indexOf(folder.Id) != -1;
for (const channel of channelsResult.Items) {
isChecked = user.Policy?.EnableContentDeletion || user.Policy?.EnableContentDeletionFromFolders?.indexOf(channel.Id || '') != -1;
checkedAttribute = isChecked ? ' checked="checked"' : '';
itemsArr.push({
Id: folder.Id,
Name: folder.Name,
...channel,
checkedAttribute: checkedAttribute
});
}
@@ -135,14 +107,14 @@ const UserEdit: FunctionComponent = () => {
setDeleteFoldersAccess(itemsArr);
const chkEnableDeleteAllFolders = page.querySelector('.chkEnableDeleteAllFolders') as HTMLInputElement;
chkEnableDeleteAllFolders.checked = user.Policy.EnableContentDeletion;
chkEnableDeleteAllFolders.checked = user.Policy?.EnableContentDeletion || false;
triggerChange(chkEnableDeleteAllFolders);
}).catch(err => {
console.error('[useredit] failed to fetch channels', err);
});
}, []);
const loadUser = useCallback((user) => {
const loadUser = useCallback((user: UserDto) => {
const page = element.current;
if (!page) {
@@ -151,25 +123,25 @@ const UserEdit: FunctionComponent = () => {
}
window.ApiClient.getJSON(window.ApiClient.getUrl('Auth/Providers')).then(function (providers) {
loadAuthProviders(user, providers);
loadAuthProviders(page, user, providers);
}).catch(err => {
console.error('[useredit] failed to fetch auth providers', err);
});
window.ApiClient.getJSON(window.ApiClient.getUrl('Auth/PasswordResetProviders')).then(function (providers) {
loadPasswordResetProviders(user, providers);
loadPasswordResetProviders(page, user, providers);
}).catch(err => {
console.error('[useredit] failed to fetch password reset providers', err);
});
window.ApiClient.getJSON(window.ApiClient.getUrl('Library/MediaFolders', {
IsHidden: false
})).then(function (folders) {
loadDeleteFolders(user, folders.Items);
loadDeleteFolders(page, user, folders.Items);
}).catch(err => {
console.error('[useredit] failed to fetch media folders', err);
});
const disabledUserBanner = page.querySelector('.disabledUserBanner') as HTMLDivElement;
disabledUserBanner.classList.toggle('hide', !user.Policy.IsDisabled);
disabledUserBanner.classList.toggle('hide', !user.Policy?.IsDisabled);
const txtUserName = page.querySelector('#txtUserName') as HTMLInputElement;
txtUserName.disabled = false;
@@ -178,30 +150,30 @@ const UserEdit: FunctionComponent = () => {
const lnkEditUserPreferences = page.querySelector('.lnkEditUserPreferences') as HTMLDivElement;
lnkEditUserPreferences.setAttribute('href', 'mypreferencesmenu.html?userId=' + user.Id);
LibraryMenu.setTitle(user.Name);
setUserName(user.Name);
(page.querySelector('#txtUserName') as HTMLInputElement).value = user.Name;
(page.querySelector('.chkIsAdmin') as HTMLInputElement).checked = user.Policy.IsAdministrator;
(page.querySelector('.chkDisabled') as HTMLInputElement).checked = user.Policy.IsDisabled;
(page.querySelector('.chkIsHidden') as HTMLInputElement).checked = user.Policy.IsHidden;
(page.querySelector('.chkEnableCollectionManagement') as HTMLInputElement).checked = user.Policy.EnableCollectionManagement;
(page.querySelector('.chkEnableSubtitleManagement') as HTMLInputElement).checked = user.Policy.EnableSubtitleManagement;
(page.querySelector('.chkRemoteControlSharedDevices') as HTMLInputElement).checked = user.Policy.EnableSharedDeviceControl;
(page.querySelector('.chkEnableRemoteControlOtherUsers') as HTMLInputElement).checked = user.Policy.EnableRemoteControlOfOtherUsers;
(page.querySelector('.chkEnableDownloading') as HTMLInputElement).checked = user.Policy.EnableContentDownloading;
(page.querySelector('.chkManageLiveTv') as HTMLInputElement).checked = user.Policy.EnableLiveTvManagement;
(page.querySelector('.chkEnableLiveTvAccess') as HTMLInputElement).checked = user.Policy.EnableLiveTvAccess;
(page.querySelector('.chkEnableMediaPlayback') as HTMLInputElement).checked = user.Policy.EnableMediaPlayback;
(page.querySelector('.chkEnableAudioPlaybackTranscoding') as HTMLInputElement).checked = user.Policy.EnableAudioPlaybackTranscoding;
(page.querySelector('.chkEnableVideoPlaybackTranscoding') as HTMLInputElement).checked = user.Policy.EnableVideoPlaybackTranscoding;
(page.querySelector('.chkEnableVideoPlaybackRemuxing') as HTMLInputElement).checked = user.Policy.EnablePlaybackRemuxing;
(page.querySelector('.chkForceRemoteSourceTranscoding') as HTMLInputElement).checked = user.Policy.ForceRemoteSourceTranscoding;
(page.querySelector('.chkRemoteAccess') as HTMLInputElement).checked = user.Policy.EnableRemoteAccess == null || user.Policy.EnableRemoteAccess;
(page.querySelector('#txtRemoteClientBitrateLimit') as HTMLInputElement).value = user.Policy.RemoteClientBitrateLimit > 0 ?
(user.Policy.RemoteClientBitrateLimit / 1e6).toLocaleString(undefined, { maximumFractionDigits: 6 }) : '';
(page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value = user.Policy.LoginAttemptsBeforeLockout || '0';
(page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value = user.Policy.MaxActiveSessions || '0';
setUserName(user.Name || '');
(page.querySelector('#txtUserName') as HTMLInputElement).value = user.Name || '';
(page.querySelector('.chkIsAdmin') as HTMLInputElement).checked = !!user.Policy?.IsAdministrator;
(page.querySelector('.chkDisabled') as HTMLInputElement).checked = !!user.Policy?.IsDisabled;
(page.querySelector('.chkIsHidden') as HTMLInputElement).checked = !!user.Policy?.IsHidden;
(page.querySelector('.chkEnableCollectionManagement') as HTMLInputElement).checked = !!user.Policy?.EnableCollectionManagement;
(page.querySelector('.chkEnableSubtitleManagement') as HTMLInputElement).checked = !!user.Policy?.EnableSubtitleManagement;
(page.querySelector('.chkRemoteControlSharedDevices') as HTMLInputElement).checked = !!user.Policy?.EnableSharedDeviceControl;
(page.querySelector('.chkEnableRemoteControlOtherUsers') as HTMLInputElement).checked = !!user.Policy?.EnableRemoteControlOfOtherUsers;
(page.querySelector('.chkEnableDownloading') as HTMLInputElement).checked = !!user.Policy?.EnableContentDownloading;
(page.querySelector('.chkManageLiveTv') as HTMLInputElement).checked = !!user.Policy?.EnableLiveTvManagement;
(page.querySelector('.chkEnableLiveTvAccess') as HTMLInputElement).checked = !!user.Policy?.EnableLiveTvAccess;
(page.querySelector('.chkEnableMediaPlayback') as HTMLInputElement).checked = !!user.Policy?.EnableMediaPlayback;
(page.querySelector('.chkEnableAudioPlaybackTranscoding') as HTMLInputElement).checked = !!user.Policy?.EnableAudioPlaybackTranscoding;
(page.querySelector('.chkEnableVideoPlaybackTranscoding') as HTMLInputElement).checked = !!user.Policy?.EnableVideoPlaybackTranscoding;
(page.querySelector('.chkEnableVideoPlaybackRemuxing') as HTMLInputElement).checked = !!user.Policy?.EnablePlaybackRemuxing;
(page.querySelector('.chkForceRemoteSourceTranscoding') as HTMLInputElement).checked = !!user.Policy?.ForceRemoteSourceTranscoding;
(page.querySelector('.chkRemoteAccess') as HTMLInputElement).checked = user.Policy?.EnableRemoteAccess == null || user.Policy?.EnableRemoteAccess;
(page.querySelector('#txtRemoteClientBitrateLimit') as HTMLInputElement).value = user.Policy?.RemoteClientBitrateLimit && user.Policy?.RemoteClientBitrateLimit > 0 ?
(user.Policy?.RemoteClientBitrateLimit / 1e6).toLocaleString(undefined, { maximumFractionDigits: 6 }) : '';
(page.querySelector('#txtLoginAttemptsBeforeLockout') as HTMLInputElement).value = String(user.Policy?.MaxActiveSessions) || '0';
(page.querySelector('#txtMaxActiveSessions') as HTMLInputElement).value = String(user.Policy?.SyncPlayAccess) || '0';
if (window.ApiClient.isMinServerVersion('10.6.0')) {
(page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value = user.Policy.SyncPlayAccess;
(page.querySelector('#selectSyncPlayAccess') as HTMLSelectElement).value = String(user.Policy?.SyncPlayAccess);
}
loading.hide();
}, [loadAuthProviders, loadPasswordResetProviders, loadDeleteFolders ]);

View File

@@ -15,7 +15,7 @@ import AppDrawer, { isDrawerPath } from './components/drawers/AppDrawer';
import './AppOverrides.scss';
const AppLayout = () => {
export const Component = () => {
const [ isDrawerActive, setIsDrawerActive ] = useState(false);
const { user } = useApi();
const location = useLocation();
@@ -29,7 +29,7 @@ const AppLayout = () => {
}, [ isDrawerActive, setIsDrawerActive ]);
return (
<Box sx={{ position: 'relative', display: 'flex', height: '100%' }}>
<Box sx={{ position: 'relative', display: 'flex' }}>
<ElevationScroll elevate={false}>
<AppBar
position='fixed'
@@ -76,5 +76,3 @@ const AppLayout = () => {
</Box>
);
};
export default AppLayout;

View File

@@ -7,10 +7,6 @@ $mui-bp-xl: 1536px;
$drawer-width: 240px;
#reactRoot {
height: 100%;
}
// Fix main pages layout to work with drawer
.mainAnimatedPage {
@media all and (min-width: $mui-bp-md) {

View File

@@ -8,7 +8,7 @@ import { useTheme } from '@mui/material/styles';
import Tooltip from '@mui/material/Tooltip';
import { playbackManager } from 'components/playback/playbackmanager';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import Events from 'utils/events';
import RemotePlayMenu, { ID } from './menus/RemotePlayMenu';
@@ -33,7 +33,7 @@ const RemotePlayButton = () => {
const [ remotePlayMenuAnchorEl, setRemotePlayMenuAnchorEl ] = useState<null | HTMLElement>(null);
const isRemotePlayMenuOpen = Boolean(remotePlayMenuAnchorEl);
const onRemotePlayButtonClick = useCallback((event) => {
const onRemotePlayButtonClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
setRemotePlayMenuAnchorEl(event.currentTarget);
}, [ setRemotePlayMenuAnchorEl ]);
@@ -44,7 +44,7 @@ const RemotePlayButton = () => {
const [ remotePlayActiveMenuAnchorEl, setRemotePlayActiveMenuAnchorEl ] = useState<null | HTMLElement>(null);
const isRemotePlayActiveMenuOpen = Boolean(remotePlayActiveMenuAnchorEl);
const onRemotePlayActiveButtonClick = useCallback((event) => {
const onRemotePlayActiveButtonClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
setRemotePlayActiveMenuAnchorEl(event.currentTarget);
}, [ setRemotePlayActiveMenuAnchorEl ]);

View File

@@ -0,0 +1,62 @@
import React, { type FC } from 'react';
import {
Link,
URLSearchParamsInit,
createSearchParams,
useLocation,
useSearchParams
} from 'react-router-dom';
import SearchIcon from '@mui/icons-material/Search';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import globalize from 'lib/globalize';
const getUrlParams = (searchParams: URLSearchParams) => {
const parentId =
searchParams.get('parentId') || searchParams.get('topParentId');
const collectionType = searchParams.get('collectionType');
const params: URLSearchParamsInit = {};
if (parentId) {
params.parentId = parentId;
}
if (collectionType) {
params.collectionType = collectionType;
}
return params;
};
interface SearchButtonProps {
isTabsAvailable: boolean;
}
const SearchButton: FC<SearchButtonProps> = ({ isTabsAvailable }) => {
const location = useLocation();
const [searchParams] = useSearchParams();
const isSearchPath = location.pathname === '/search.html';
const createSearchLink = isTabsAvailable ?
{
pathname: '/search.html',
search: `?${createSearchParams(getUrlParams(searchParams))}`
} :
'/search.html';
return (
<Tooltip title={globalize.translate('Search')}>
<IconButton
size='large'
aria-label={globalize.translate('Search')}
color='inherit'
component={Link}
disabled={isSearchPath}
to={createSearchLink}
>
<SearchIcon />
</IconButton>
</Tooltip>
);
};
export default SearchButton;

View File

@@ -6,7 +6,7 @@ import React, { useCallback, useState } from 'react';
import { pluginManager } from 'components/pluginManager';
import { useApi } from 'hooks/useApi';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { PluginType } from 'types/plugin';
import AppSyncPlayMenu, { ID } from './menus/SyncPlayMenu';
@@ -17,7 +17,7 @@ const SyncPlayButton = () => {
const [ syncPlayMenuAnchorEl, setSyncPlayMenuAnchorEl ] = useState<null | HTMLElement>(null);
const isSyncPlayMenuOpen = Boolean(syncPlayMenuAnchorEl);
const onSyncPlayButtonClick = useCallback((event) => {
const onSyncPlayButtonClick = useCallback((event: React.MouseEvent<HTMLElement>) => {
setSyncPlayMenuAnchorEl(event.currentTarget);
}, [ setSyncPlayMenuAnchorEl ]);

View File

@@ -1,15 +1,10 @@
import SearchIcon from '@mui/icons-material/Search';
import IconButton from '@mui/material/IconButton';
import Tooltip from '@mui/material/Tooltip';
import React, { FC } from 'react';
import { Link, useLocation } from 'react-router-dom';
import React, { type FC } from 'react';
import { useLocation } from 'react-router-dom';
import AppToolbar from 'components/toolbar/AppToolbar';
import globalize from 'scripts/globalize';
import AppTabs from '../tabs/AppTabs';
import RemotePlayButton from './RemotePlayButton';
import SyncPlayButton from './SyncPlayButton';
import SearchButton from './SearchButton';
import { isTabPath } from '../tabs/tabRoutes';
interface AppToolbarProps {
@@ -45,18 +40,7 @@ const ExperimentalAppToolbar: FC<AppToolbarProps> = ({
<>
<SyncPlayButton />
<RemotePlayButton />
<Tooltip title={globalize.translate('Search')}>
<IconButton
size='large'
aria-label={globalize.translate('Search')}
color='inherit'
component={Link}
to='/search.html'
>
<SearchIcon />
</IconButton>
</Tooltip>
<SearchButton isTabsAvailable={isTabsAvailable} />
</>
)}
isDrawerAvailable={isDrawerAvailable}

View File

@@ -13,7 +13,7 @@ import React, { FC, useCallback, useState } from 'react';
import { Link } from 'react-router-dom';
import { enable, isEnabled } from 'scripts/autocast';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
interface RemotePlayActiveMenuProps extends MenuProps {
onMenuClose: () => void

View File

@@ -6,7 +6,7 @@ import Menu, { type MenuProps } from '@mui/material/Menu';
import MenuItem from '@mui/material/MenuItem';
import React, { FC, useEffect, useState } from 'react';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { playbackManager } from 'components/playback/playbackmanager';
import { pluginManager } from 'components/pluginManager';
import type { PlayTarget } from 'types/playTarget';

View File

@@ -20,9 +20,9 @@ import React, { FC, useCallback, useEffect, useState } from 'react';
import { pluginManager } from 'components/pluginManager';
import { useApi } from 'hooks/useApi';
import { useSyncPlayGroups } from 'hooks/useSyncPlayGroups';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { PluginType } from 'types/plugin';
import Events from 'utils/events';
import Events, { Event } from 'utils/events';
export const ID = 'app-sync-play-menu';
@@ -136,7 +136,7 @@ const SyncPlayMenu: FC<SyncPlayMenuProps> = ({
}
}, [ __legacyApiClient__, onMenuClose, syncPlay ]);
const updateSyncPlayGroup = useCallback((_e, enabled) => {
const updateSyncPlayGroup = useCallback((_e: Event, enabled: boolean) => {
if (syncPlay && enabled) {
setCurrentGroup(syncPlay.Manager.getGroupInfo() ?? undefined);
} else {

View File

@@ -18,7 +18,7 @@ import { appRouter } from 'components/router/appRouter';
import { useApi } from 'hooks/useApi';
import { useUserViews } from 'hooks/useUserViews';
import { useWebConfig } from 'hooks/useWebConfig';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import LibraryIcon from '../LibraryIcon';
import DrawerHeaderLink from './DrawerHeaderLink';

View File

@@ -2,7 +2,7 @@ import type { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/bas
import type { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type';
import React, { FC } from 'react';
import { useGetGenres } from 'hooks/useFetchItems';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import Loading from 'components/loading/LoadingComponent';
import GenresSectionContainer from './GenresSectionContainer';
import type { ParentId } from 'types/library';

View File

@@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import { ButtonGroup, IconButton } from '@mui/material';
import ViewModuleIcon from '@mui/icons-material/ViewModule';
import ViewListIcon from '@mui/icons-material/ViewList';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { LibraryViewSettings, ViewMode } from 'types/library';
import { LibraryTab } from 'types/libraryTab';
import ViewSettingsButton from './ViewSettingsButton';

View File

@@ -72,7 +72,7 @@ const ItemsView: FC<ItemsViewProps> = ({
const {
isLoading,
data: itemsResult,
isPreviousData,
isPlaceholderData,
refetch
} = useGetItemsViewByType(
viewType,
@@ -228,7 +228,7 @@ const ItemsView: FC<ItemsViewProps> = ({
<Pagination
totalRecordCount={totalRecordCount}
libraryViewSettings={libraryViewSettings}
isPreviousData={isPreviousData}
isPlaceholderData={isPlaceholderData}
setLibraryViewSettings={setLibraryViewSettings}
/>
)}
@@ -312,7 +312,7 @@ const ItemsView: FC<ItemsViewProps> = ({
<Pagination
totalRecordCount={totalRecordCount}
libraryViewSettings={libraryViewSettings}
isPreviousData={isPreviousData}
isPlaceholderData={isPlaceholderData}
setLibraryViewSettings={setLibraryViewSettings}
/>
</Box>

View File

@@ -1,7 +1,7 @@
import React, { FC, useCallback } from 'react';
import { IconButton } from '@mui/material';
import AddIcon from '@mui/icons-material/Add';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
const NewCollectionButton: FC = () => {
const showCollectionEditor = useCallback(() => {

View File

@@ -5,7 +5,7 @@ import Box from '@mui/material/Box';
import ButtonGroup from '@mui/material/ButtonGroup';
import IconButton from '@mui/material/IconButton';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import * as userSettings from 'scripts/settings/userSettings';
import { LibraryViewSettings } from 'types/library';
@@ -13,14 +13,14 @@ interface PaginationProps {
libraryViewSettings: LibraryViewSettings;
setLibraryViewSettings: React.Dispatch<React.SetStateAction<LibraryViewSettings>>;
totalRecordCount: number;
isPreviousData: boolean
isPlaceholderData: boolean
}
const Pagination: FC<PaginationProps> = ({
libraryViewSettings,
setLibraryViewSettings,
totalRecordCount,
isPreviousData
isPlaceholderData
}) => {
const limit = userSettings.libraryPageSize(undefined);
const startIndex = libraryViewSettings.StartIndex ?? 0;
@@ -65,7 +65,7 @@ const Pagination: FC<PaginationProps> = ({
<IconButton
title={globalize.translate('Previous')}
className='paper-icon-button-light btnPreviousPage autoSize'
disabled={startIndex == 0 || isPreviousData}
disabled={startIndex == 0 || isPlaceholderData}
onClick={onPreviousPageClick}
>
<ArrowBackIcon />
@@ -74,7 +74,7 @@ const Pagination: FC<PaginationProps> = ({
<IconButton
title={globalize.translate('Next')}
className='paper-icon-button-light btnNextPage autoSize'
disabled={startIndex + limit >= totalRecordCount || isPreviousData }
disabled={startIndex + limit >= totalRecordCount || isPlaceholderData }
onClick={onNextPageClick}
>
<ArrowForwardIcon />

View File

@@ -4,7 +4,7 @@ import { IconButton } from '@mui/material';
import PlayArrowIcon from '@mui/icons-material/PlayArrow';
import { playbackManager } from 'components/playback/playbackmanager';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { getFiltersQuery } from 'utils/items';
import { LibraryViewSettings } from 'types/library';
import { LibraryTab } from 'types/libraryTab';

View File

@@ -1,7 +1,7 @@
import React, { type FC } from 'react';
import { useGetProgramsSectionsWithItems, useGetTimers } from 'hooks/useFetchItems';
import { appRouter } from 'components/router/appRouter';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import Loading from 'components/loading/LoadingComponent';
import SectionContainer from './SectionContainer';
import { CardShape } from 'utils/card';

View File

@@ -4,7 +4,7 @@ import { IconButton } from '@mui/material';
import QueueIcon from '@mui/icons-material/Queue';
import { playbackManager } from 'components/playback/playbackmanager';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
interface QueueButtonProps {
item: BaseItemDto | undefined

View File

@@ -5,7 +5,7 @@ import { IconButton } from '@mui/material';
import ShuffleIcon from '@mui/icons-material/Shuffle';
import { playbackManager } from 'components/playback/playbackmanager';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { getFiltersQuery } from 'utils/items';
import { LibraryViewSettings } from 'types/library';
import { LibraryTab } from 'types/libraryTab';

View File

@@ -10,7 +10,7 @@ import FormControl from '@mui/material/FormControl';
import Select, { SelectChangeEvent } from '@mui/material/Select';
import SortByAlphaIcon from '@mui/icons-material/SortByAlpha';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { LibraryViewSettings } from 'types/library';
import { LibraryTab } from 'types/libraryTab';
import { ItemSortBy } from '@jellyfin/sdk/lib/models/api/item-sort-by';
@@ -36,6 +36,12 @@ const movieOrFavoriteOptions = [
{ label: 'Runtime', value: ItemSortBy.Runtime }
];
const photosOrPhotoAlbumsOptions = [
{ label: 'Name', value: ItemSortBy.SortName },
{ label: 'OptionRandom', value: ItemSortBy.Random },
{ label: 'OptionDateAdded', value: ItemSortBy.DateCreated }
];
const sortOptionsMapping: SortOptionsMapping = {
[LibraryTab.Movies]: movieOrFavoriteOptions,
[LibraryTab.Trailers]: [
@@ -89,6 +95,16 @@ const sortOptionsMapping: SortOptionsMapping = {
{ label: 'OptionReleaseDate', value: ItemSortBy.PremiereDate },
{ label: 'Runtime', value: ItemSortBy.Runtime },
{ label: 'OptionRandom', value: ItemSortBy.Random }
],
[LibraryTab.PhotoAlbums]: photosOrPhotoAlbumsOptions,
[LibraryTab.Photos]: photosOrPhotoAlbumsOptions,
[LibraryTab.Videos]: [
{ label: 'Name', value: ItemSortBy.SortName },
{ label: 'OptionDateAdded', value: ItemSortBy.DateCreated },
{ label: 'OptionDatePlayed', value: ItemSortBy.DatePlayed },
{ label: 'OptionPlayCount', value: ItemSortBy.PlayCount },
{ label: 'Runtime', value: ItemSortBy.Runtime },
{ label: 'OptionRandom', value: ItemSortBy.Random }
]
};

View File

@@ -8,7 +8,7 @@ import {
useGetSuggestionSectionsWithItems
} from 'hooks/useFetchItems';
import { appRouter } from 'components/router/appRouter';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import Loading from 'components/loading/LoadingComponent';
import SectionContainer from './SectionContainer';
import { CardShape } from 'utils/card';

View File

@@ -2,7 +2,7 @@ import React, { type FC } from 'react';
import Box from '@mui/material/Box';
import { useGetGroupsUpcomingEpisodes } from 'hooks/useFetchItems';
import Loading from 'components/loading/LoadingComponent';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import SectionContainer from './SectionContainer';
import { CardShape } from 'utils/card';
import type { LibraryViewProps } from 'types/library';

View File

@@ -15,7 +15,7 @@ import Select, { SelectChangeEvent } from '@mui/material/Select';
import Popover from '@mui/material/Popover';
import ViewComfyIcon from '@mui/icons-material/ViewComfy';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { LibraryViewSettings } from 'types/library';
import { LibraryTab } from 'types/libraryTab';

View File

@@ -15,7 +15,7 @@ import { styled } from '@mui/material/styles';
import Typography from '@mui/material/Typography';
import { useGetQueryFiltersLegacy, useGetStudios } from 'hooks/useFetchItems';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import FiltersFeatures from './FiltersFeatures';
import FiltersGenres from './FiltersGenres';

View File

@@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { EpisodeFilter, LibraryViewSettings } from 'types/library';
const episodeFilterOptions = [

View File

@@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { FeatureFilters, LibraryViewSettings } from 'types/library';
const featuresOptions = [

View File

@@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { LibraryViewSettings } from 'types/library';
import { SeriesStatus } from '@jellyfin/sdk/lib/generated-client';

View File

@@ -2,7 +2,7 @@ import React, { FC, useCallback } from 'react';
import FormGroup from '@mui/material/FormGroup';
import FormControlLabel from '@mui/material/FormControlLabel';
import Checkbox from '@mui/material/Checkbox';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { LibraryViewSettings } from 'types/library';
import { ItemFilter } from '@jellyfin/sdk/lib/generated-client';
import { LibraryTab } from 'types/libraryTab';
@@ -56,6 +56,8 @@ const FiltersStatus: FC<FiltersStatusProps> = ({
&& viewType !== LibraryTab.AlbumArtists
&& viewType !== LibraryTab.Songs
&& viewType !== LibraryTab.Channels
&& viewType !== LibraryTab.PhotoAlbums
&& viewType !== LibraryTab.Photos
) {
visibleFiltersStatus.push(ItemFilter.IsUnplayed);
visibleFiltersStatus.push(ItemFilter.IsPlayed);

View File

@@ -1,4 +1,4 @@
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import * as userSettings from 'scripts/settings/userSettings';
import { LibraryTab } from 'types/libraryTab';
@@ -184,6 +184,28 @@ const TabRoutes: TabRoute[] = [
value: LibraryTab.Episodes
}
]
},
{
path: '/homevideos.html',
tabs: [
{
index: 0,
label: globalize.translate('Photos'),
value: LibraryTab.Photos,
isDefault: true
},
{
index: 1,
label: globalize.translate('HeaderPhotoAlbums'),
value: LibraryTab.PhotoAlbums,
isDefault: true
},
{
index: 2,
label: globalize.translate('HeaderVideos'),
value: LibraryTab.Videos
}
]
}
];

View File

@@ -1,13 +1,15 @@
import { AsyncRoute, AsyncRouteType } from '../../../../components/router/AsyncRoute';
export const ASYNC_USER_ROUTES: AsyncRoute[] = [
{ path: 'home.html', page: 'home', type: AsyncRouteType.Experimental },
{ path: 'quickconnect', page: 'quickConnect' },
{ path: 'search.html', page: 'search' },
{ path: 'userprofile.html', page: 'user/userprofile' },
{ path: 'home.html', page: 'home', type: AsyncRouteType.Experimental },
{ path: 'movies.html', page: 'movies', type: AsyncRouteType.Experimental },
{ path: 'tv.html', page: 'shows', type: AsyncRouteType.Experimental },
{ path: 'music.html', page: 'music', type: AsyncRouteType.Experimental },
{ path: 'livetv.html', page: 'livetv', type: AsyncRouteType.Experimental },
{ path: 'mypreferencesdisplay.html', page: 'user/display', type: AsyncRouteType.Experimental }
{ path: 'mypreferencesdisplay.html', page: 'user/display', type: AsyncRouteType.Experimental },
{ path: 'homevideos.html', page: 'homevideos', type: AsyncRouteType.Experimental }
];

View File

@@ -1,15 +1,14 @@
import React, { FunctionComponent, useCallback, useEffect, useMemo, useRef } from 'react';
import React, { useCallback, useEffect, useMemo, useRef } from 'react';
import { useSearchParams } from 'react-router-dom';
import globalize from '../../../scripts/globalize';
import LibraryMenu from '../../../scripts/libraryMenu';
import globalize from '../../../lib/globalize';
import { clearBackdrop } from '../../../components/backdrop/backdrop';
import layoutManager from '../../../components/layoutManager';
import * as mainTabsManager from '../../../components/maintabsmanager';
import Page from '../../../components/Page';
import '../../../elements/emby-tabs/emby-tabs';
import '../../../elements/emby-button/emby-button';
import '../../../elements/emby-scroller/emby-scroller';
import Page from '../../../components/Page';
type OnResumeOptions = {
autoFocus?: boolean;
@@ -25,16 +24,18 @@ type ControllerProps = {
destroy: () => void;
};
const Home: FunctionComponent = () => {
const Home = () => {
const [ searchParams ] = useSearchParams();
const initialTabIndex = parseInt(searchParams.get('tab') ?? '0', 10);
const libraryMenu = useMemo(async () => ((await import('../../../scripts/libraryMenu')).default), []);
const mainTabsManager = useMemo(() => import('../../../components/maintabsmanager'), []);
const tabController = useRef<ControllerProps | null>();
const tabControllers = useMemo<ControllerProps[]>(() => [], []);
const element = useRef<HTMLDivElement>(null);
const setTitle = () => {
LibraryMenu.setTitle(null);
const setTitle = async () => {
(await libraryMenu).setTitle(null);
};
const getTabs = () => {
@@ -78,18 +79,6 @@ const Home: FunctionComponent = () => {
});
}, [ tabControllers ]);
const onViewDestroy = useCallback(() => {
if (tabControllers) {
tabControllers.forEach(function (t) {
if (t.destroy) {
t.destroy();
}
});
}
tabController.current = null;
}, [ tabControllers ]);
const loadTab = useCallback((index: number, previousIndex: number | null) => {
getTabController(index).then((controller) => {
const refresh = !controller.refreshed;
@@ -118,19 +107,23 @@ const Home: FunctionComponent = () => {
loadTab(newIndex, previousIndex);
}, [ loadTab, tabControllers ]);
const onResume = useCallback(() => {
setTitle();
const onSetTabs = useCallback(async () => {
(await mainTabsManager).setTabs(element.current, initialTabIndex, getTabs, getTabContainers, null, onTabChange, false);
}, [ initialTabIndex, mainTabsManager, onTabChange ]);
const onResume = useCallback(async () => {
void setTitle();
clearBackdrop();
const currentTabController = tabController.current;
if (!currentTabController) {
mainTabsManager.selectedTabIndex(initialTabIndex);
(await mainTabsManager).selectedTabIndex(initialTabIndex);
} else if (currentTabController?.onResume) {
currentTabController.onResume({});
}
(document.querySelector('.skinHeader') as HTMLDivElement).classList.add('noHomeButtonHeader');
}, [ initialTabIndex ]);
}, [ initialTabIndex, mainTabsManager ]);
const onPause = useCallback(() => {
const currentTabController = tabController.current;
@@ -141,13 +134,13 @@ const Home: FunctionComponent = () => {
}, []);
useEffect(() => {
mainTabsManager.setTabs(element.current, initialTabIndex, getTabs, getTabContainers, null, onTabChange, false);
void onSetTabs();
onResume();
void onResume();
return () => {
onPause();
};
}, [ initialTabIndex, onPause, onResume, onTabChange, onViewDestroy ]);
}, [ onPause, onResume, onSetTabs ]);
return (
<div ref={element}>

View File

@@ -0,0 +1,59 @@
import { BaseItemKind } from '@jellyfin/sdk/lib/generated-client/models/base-item-kind';
import React, { type FC } from 'react';
import useCurrentTab from 'hooks/useCurrentTab';
import Page from 'components/Page';
import PageTabContent from '../../components/library/PageTabContent';
import { LibraryTab } from 'types/libraryTab';
import { CollectionType } from '@jellyfin/sdk/lib/generated-client/models/collection-type';
import { LibraryTabContent, LibraryTabMapping } from 'types/libraryTabContent';
const photosTabContent: LibraryTabContent = {
viewType: LibraryTab.Photos,
collectionType: CollectionType.Homevideos,
isBtnPlayAllEnabled: true,
isBtnShuffleEnabled: true,
itemType: [BaseItemKind.Photo]
};
const photoAlbumsTabContent: LibraryTabContent = {
viewType: LibraryTab.PhotoAlbums,
collectionType: CollectionType.Homevideos,
isBtnPlayAllEnabled: true,
isBtnShuffleEnabled: true,
itemType: [BaseItemKind.PhotoAlbum]
};
const videosTabContent: LibraryTabContent = {
viewType: LibraryTab.Videos,
collectionType: CollectionType.Homevideos,
isBtnPlayAllEnabled: true,
isBtnShuffleEnabled: true,
itemType: [BaseItemKind.Video]
};
const homevideosTabMapping: LibraryTabMapping = {
0: photosTabContent,
1: photoAlbumsTabContent,
2: videosTabContent
};
const HomeVideos: FC = () => {
const { libraryId, activeTab } = useCurrentTab();
const currentTab = homevideosTabMapping[activeTab];
return (
<Page
id='homevideos'
className='mainAnimatedPage libraryPage backdropPage collectionEditorPage pageWithAbsoluteTabs withTabs'
backDropType='video, photo'
>
<PageTabContent
key={`${currentTab.viewType} - ${libraryId}`}
currentTab={currentTab}
parentId={libraryId}
/>
</Page>
);
};
export default HomeVideos;

View File

@@ -4,21 +4,19 @@ import { Navigate, RouteObject } from 'react-router-dom';
import { REDIRECTS } from 'apps/dashboard/routes/_redirects';
import ConnectionRequired from 'components/ConnectionRequired';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import BangRedirect from 'components/router/BangRedirect';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { toRedirectRoute } from 'components/router/Redirect';
import ErrorBoundary from 'components/router/ErrorBoundary';
import { ASYNC_USER_ROUTES } from './asyncRoutes';
import { LEGACY_PUBLIC_ROUTES, LEGACY_USER_ROUTES } from './legacyRoutes';
import VideoPage from './video';
import loadable from '@loadable/component';
import BangRedirect from 'components/router/BangRedirect';
const AppLayout = loadable(() => import('../AppLayout'));
export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [
{
path: '/*',
element: <AppLayout />,
lazy: () => import('../AppLayout'),
children: [
{
/* User routes: Any child route of this layout is authenticated */
@@ -32,7 +30,8 @@ export const EXPERIMENTAL_APP_ROUTES: RouteObject[] = [
path: 'video',
element: <VideoPage />
}
]
],
ErrorBoundary
},
/* Public routes */

View File

@@ -13,7 +13,7 @@ import React, { Fragment } from 'react';
import { appHost } from 'components/apphost';
import { useApi } from 'hooks/useApi';
import { useThemes } from 'hooks/useThemes';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplaySettingsValues } from './types';
import { useScreensavers } from './hooks/useScreensavers';

View File

@@ -6,7 +6,7 @@ import Stack from '@mui/material/Stack';
import Typography from '@mui/material/Typography';
import React from 'react';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplaySettingsValues } from './types';
interface ItemDetailPreferencesProps {

View File

@@ -7,7 +7,7 @@ import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import React from 'react';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplaySettingsValues } from './types';
interface LibraryPreferencesProps {

View File

@@ -10,7 +10,7 @@ import React from 'react';
import { appHost } from 'components/apphost';
import datetime from 'scripts/datetime';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DATE_LOCALE_OPTIONS, LANGUAGE_OPTIONS } from './constants';
import { DisplaySettingsValues } from './types';

View File

@@ -7,7 +7,7 @@ import TextField from '@mui/material/TextField';
import Typography from '@mui/material/Typography';
import React from 'react';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplaySettingsValues } from './types';
interface NextUpPreferencesProps {

View File

@@ -1,4 +1,4 @@
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
export const LANGUAGE_OPTIONS = [
{ value: 'auto', label: globalize.translate('Auto') },

View File

@@ -2,10 +2,15 @@ import { useCallback, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import toast from 'components/toast/toast';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplaySettingsValues } from '../types';
import { useDisplaySettings } from './useDisplaySettings';
type UpdateField = {
name: keyof DisplaySettingsValues;
value: string | boolean;
};
export function useDisplaySettingForm() {
const [urlParams] = useSearchParams();
const {
@@ -21,7 +26,7 @@ export function useDisplaySettingForm() {
}
}, [formValues, loading, displaySettings]);
const updateField = useCallback(({ name, value }) => {
const updateField = useCallback(({ name, value }: UpdateField) => {
if (formValues) {
setFormValues({
...formValues,

View File

@@ -2,7 +2,7 @@ import { useMemo } from 'react';
import { pluginManager } from 'components/pluginManager';
import { Plugin, PluginType } from 'types/plugin';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
export function useScreensavers() {
const screensavers = useMemo<Plugin[]>(() => {

View File

@@ -4,7 +4,7 @@ import Stack from '@mui/material/Stack';
import React, { useCallback } from 'react';
import Page from 'components/Page';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import { DisplayPreferences } from './DisplayPreferences';
import { ItemDetailPreferences } from './ItemDetailPreferences';
import { LibraryPreferences } from './LibraryPreferences';

View File

@@ -3,7 +3,7 @@ import React, { FC, FormEvent, useCallback, useMemo, useState } from 'react';
import { Link, useSearchParams } from 'react-router-dom';
import Page from 'components/Page';
import globalize from 'scripts/globalize';
import globalize from 'lib/globalize';
import InputElement from 'elements/InputElement';
import ButtonElement from 'elements/ButtonElement';
import { useApi } from 'hooks/useApi';

View File

@@ -5,6 +5,7 @@ import ConnectionRequired from 'components/ConnectionRequired';
import { toAsyncPageRoute } from 'components/router/AsyncRoute';
import { toViewManagerPageRoute } from 'components/router/LegacyRoute';
import { toRedirectRoute } from 'components/router/Redirect';
import ErrorBoundary from 'components/router/ErrorBoundary';
import AppLayout from '../AppLayout';
@@ -16,7 +17,7 @@ import BangRedirect from 'components/router/BangRedirect';
export const STABLE_APP_ROUTES: RouteObject[] = [
{
path: '/*',
element: <AppLayout />,
Component: AppLayout,
children: [
{
/* User routes */
@@ -24,7 +25,8 @@ export const STABLE_APP_ROUTES: RouteObject[] = [
children: [
...ASYNC_USER_ROUTES.map(toAsyncPageRoute),
...LEGACY_USER_ROUTES.map(toViewManagerPageRoute)
]
],
ErrorBoundary
},
/* Public routes */

View File

@@ -1,24 +1,25 @@
import React, { type FC, useEffect, useState } from 'react';
import { useSearchParams } from 'react-router-dom';
import { useDebounceValue } from 'usehooks-ts';
import { usePrevious } from 'hooks/usePrevious';
import globalize from 'lib/globalize';
import Page from 'components/Page';
import SearchFields from 'components/search/SearchFields';
import SearchResults from 'components/search/SearchResults';
import SearchSuggestions from 'components/search/SearchSuggestions';
import LiveTVSearchResults from 'components/search/LiveTVSearchResults';
import { usePrevious } from 'hooks/usePrevious';
import globalize from 'scripts/globalize';
import SearchResults from 'components/search/SearchResults';
const COLLECTION_TYPE_PARAM = 'collectionType';
const PARENT_ID_PARAM = 'parentId';
const QUERY_PARAM = 'query';
const SERVER_ID_PARAM = 'serverId';
const Search: FC = () => {
const [ searchParams, setSearchParams ] = useSearchParams();
const [searchParams, setSearchParams] = useSearchParams();
const parentIdQuery = searchParams.get(PARENT_ID_PARAM) || undefined;
const collectionTypeQuery = searchParams.get(COLLECTION_TYPE_PARAM) || undefined;
const urlQuery = searchParams.get(QUERY_PARAM) || '';
const [ query, setQuery ] = useState(urlQuery);
const [query, setQuery] = useState(urlQuery);
const prevQuery = usePrevious(query, '');
const [debouncedQuery] = useDebounceValue(query, 500);
useEffect(() => {
if (query !== prevQuery) {
@@ -49,23 +50,17 @@ const Search: FC = () => {
className='mainAnimatedPage libraryPage allLibraryPage noSecondaryNavPage'
>
<SearchFields query={query} onSearch={setQuery} />
{!query
&& <SearchSuggestions
parentId={searchParams.get(PARENT_ID_PARAM)}
{!query ? (
<SearchSuggestions
parentId={parentIdQuery}
/>
}
<SearchResults
serverId={searchParams.get(SERVER_ID_PARAM) || window.ApiClient.serverId()}
parentId={searchParams.get(PARENT_ID_PARAM)}
collectionType={searchParams.get(COLLECTION_TYPE_PARAM)}
query={query}
/>
<LiveTVSearchResults
serverId={searchParams.get(SERVER_ID_PARAM) || window.ApiClient.serverId()}
parentId={searchParams.get(PARENT_ID_PARAM)}
collectionType={searchParams.get(COLLECTION_TYPE_PARAM)}
query={query}
/>
) : (
<SearchResults
parentId={parentIdQuery}
collectionType={collectionTypeQuery}
query={debouncedQuery}
/>
)}
</Page>
);
};

View File

@@ -4,7 +4,7 @@ import React, { FunctionComponent, useEffect, useState, useRef, useCallback } fr
import { useSearchParams } from 'react-router-dom';
import Dashboard from '../../../../utils/dashboard';
import globalize from '../../../../scripts/globalize';
import globalize from '../../../../lib/globalize';
import LibraryMenu from '../../../../scripts/libraryMenu';
import { appHost } from '../../../../components/apphost';
import confirm from '../../../../components/confirm/confirm';

Some files were not shown because too many files have changed in this diff Show More