1
0
mirror of https://github.com/Radarr/Radarr.git synced 2026-04-16 21:15:33 -04:00

Compare commits

...

205 Commits

Author SHA1 Message Date
Weblate
954a040d6e Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-03-18 12:33:26 +02:00
Mark McDowall
905b23618a Improve logging when login fails due to CryptographicException
(cherry picked from commit 1449941471cbb8885e9298317b9a30f2576d7941)
2025-03-16 13:12:41 +02:00
Bogdan
8decd5d8e1 Bump version to 5.20.2 2025-03-16 10:45:58 +02:00
Bogdan
8b5b177d16 New: Display indexer in download failed details 2025-03-16 01:41:37 +02:00
Bogdan
e6c6fceff8 Fixed: Inherit indexer, size and release group for marked as failed history 2025-03-16 01:41:37 +02:00
Weblate
dcc8b28a07 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2025-03-15 21:06:54 +02:00
Stevie Robinson
02baf4d7a4 Translate Frontend Components and Helpers
(cherry picked from commit e777b7018481b18ef18f1116f75983a037bf0849)

Closes #8995
2025-03-15 18:15:29 +02:00
Servarr
22ec1fe492 Multiple Translations updated by Weblate (#10925)
ignore-downstream






Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr

Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: fordas <fordas15@gmail.com>
2025-03-15 14:13:27 +02:00
fezster
a7dbdadd21 New: Add HDR Type to XBMC metadata video stream details (#10906)
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2025-03-12 14:33:46 +02:00
Bogdan
93581e4a2f Fixed: Spinning icon on toggling movie monitoring 2025-03-11 23:07:08 +02:00
Bogdan
4c8da09df6 Fixed: Movie Details crashing on invalid collection 2025-03-11 16:14:29 +02:00
Bogdan
89666175a6 Update recommendation message against using uTorrent
(cherry picked from commit 6d8c3f15b343a24fc31a212463af8ed2b5792508)
2025-03-11 11:32:13 +02:00
Mark McDowall
7a33e156a3 New: Truncate button text
(cherry picked from commit 093ee5b88db0470426f6132e66a5893e5cf89bab)
2025-03-11 11:29:31 +02:00
Mark McDowall
c7c07404b0 Improve wrapping of text in sidebar
(cherry picked from commit f58dfc5605738ebccdd6adc6f1ca2a7843c086b2)
2025-03-11 11:29:20 +02:00
Mark McDowall
abeeee9363 Upgrade 'eslint-plugin-react-hooks' to 5.2.0
(cherry picked from commit c86822b114bd0b7276b40cdf2bb6181ef35db3dc)
2025-03-11 11:27:52 +02:00
Bogdan
23c30734d2 Convert QualityProfileName to TypeScript
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-09 22:02:04 +02:00
Bogdan
939e45e646 Disable left/right arrow navigation when a modal is open on Movie Details 2025-03-09 21:46:08 +02:00
Weblate
16ceba2392 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/
Translation: Servarr/Radarr
2025-03-09 21:20:18 +02:00
Bogdan
94d620d878 Clear search results when switching between movies 2025-03-09 21:16:48 +02:00
hhjuhl
ee0db93a0a Use 'text-wrap: balance' for text wrapping on overview
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
(cherry picked from commit 160151c6e000c6620ba2e04ca6245317c5c9ba16)

Closes #10729
2025-03-09 19:27:24 +02:00
Bogdan
f815b31c33 Convert Movie Details to TypeScript
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-09 19:26:44 +02:00
Bogdan
c078191b3d Bump version to 5.20.1 2025-03-09 11:53:09 +02:00
Bogdan
653b358fd3 Convert Delete Movie Modal to TypeScript
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-08 16:36:12 +02:00
Bogdan
6a7ed22b44 Convert Movie History to TypeScript
Closes #10755

Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-08 16:04:08 +02:00
Mark McDowall
779292490a Convert SelectMovieRow to TypeScript
(cherry picked from commit 32ce09648cb9eb13c46b060f2665f3ce837261f2)
2025-03-08 15:16:12 +02:00
Mark McDowall
e4e96fc7f9 Convert Preview Rename to TypeScript
(cherry picked from commit a2fd23c84d0a9d01864119d2e643970845c9e49e)
2025-03-08 15:16:12 +02:00
Weblate
049bf7715e Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2025-03-08 15:16:04 +02:00
Bogdan
df4dfaac0b Bump SixLabors.ImageSharp to 3.1.7 2025-03-07 19:17:58 +02:00
Bogdan
89c96b0a80 Increase input sizes in edit movie modal
Closes #10749
2025-03-07 19:03:28 +02:00
Bogdan
7db12b6e58 Convert EditMovieModal to TypeScript
Towards #10700

Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-07 19:03:28 +02:00
Bogdan
28dee7bc01 Convert MoveMovieModal to TypeScript
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-03-07 19:03:19 +02:00
Bogdan
8ec60eb0a6 Convert Movie Formats/Status/CollectionLabel to TypeScript 2025-03-07 16:43:37 +02:00
Weblate
102849a697 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Chong Yao Jun <yaojun12345678910@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Stan Ulbrych <stanulbrych@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: pbarone <pbarone@live.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/
Translation: Servarr/Radarr
2025-03-07 14:03:05 +02:00
Bogdan
95da7d7b47 Convert Interactive Search to TypeScript 2025-03-04 15:15:04 +02:00
Weblate
22b5739967 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Eduardo045 <eduardomeirelles045@gmail.com>
Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Volodymyr <minecrafter7893@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: corwin007x <skopal.ondrej@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translation: Servarr/Radarr
2025-03-04 14:57:54 +02:00
Bogdan
cfba047d80 Fixed: Parsing some titles with FRA as French 2025-03-04 14:46:11 +02:00
Bogdan
576d404e70 Fixed: Replace diacritics in Clean Title naming tokens 2025-03-02 07:19:13 +02:00
Bogdan
5959d4e51a Fixed: Instance name must contain application name 2025-02-26 03:59:22 +02:00
Chaz Harris
2aca6c6e1d Bump devcontainer nodejs version to 20
(cherry picked from commit d8222c066c04d5219a21a6e7f9f3571a67e8dcca)
2025-02-25 20:06:02 +02:00
Bogdan
e8bbe0ee9f Bump Polly to 8.5.2 2025-02-25 19:51:19 +02:00
Bogdan
66332a110a Bump version to 5.20.0 2025-02-25 19:50:48 +02:00
Bogdan
36c66deb4b Recommend against using uTorrent 2025-02-25 12:50:11 +02:00
Weblate
edec432244 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-02-24 19:28:00 +02:00
Bogdan
554e15d438 New: Watch list sorting and rate limit for Trakt Import Lists 2025-02-23 14:59:38 +02:00
Bogdan
553645a07c Bump version to 5.19.2 2025-02-23 12:14:28 +02:00
Bogdan
7de7e83c5b New: Add Blu-ray link to movie details 2025-02-23 00:03:48 +02:00
Bogdan
b7a46bedb0 Fixed: Avoid checking for free space if other specifications fail first 2025-02-22 21:33:38 +02:00
Weblate
0925769377 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Al3xPdx007 <constantin.pdx@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Pablo <pablo@pabloarraiz.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: pelnoph <pierre.regnier.1984@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2025-02-22 18:34:51 +02:00
Servarr
72244362fe Automated API Docs update 2025-02-22 18:33:37 +02:00
Mark McDowall
c6526c34e9 Cleanse console log messages
(cherry picked from commit 609e964794e17343f63e1ecff3fef323e3d284ff)
2025-02-19 15:44:15 +02:00
Bogdan
efa2913dbc Translate Trakt popular list types 2025-02-19 15:28:05 +02:00
Mark McDowall
35c22a4ffa Fixed: Only show Additional Parameters on Trakt Popular list
(cherry picked from commit b122ee967009d53432f3d1dd196132487f3999e1)
2025-02-19 15:15:17 +02:00
Stevie Robinson
66d96e21da Fixed: Fallback to Instance Name for Discord notifications
(cherry picked from commit b99e06acc0a3ecae2857d9225b35424c82c67a2b)
2025-02-19 14:52:30 +02:00
Bogdan
36d4e9e6cd New: Movie Requested filter for interactive search 2025-02-18 04:42:10 +02:00
Weblate
7189d7b15c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: haru4a <haru4as95@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translation: Servarr/Radarr
2025-02-16 23:04:54 +02:00
Servarr
6e80113987 Automated API Docs update 2025-02-16 23:03:09 +02:00
Bogdan
bb8a0dda63 Fixed: Processing existing movie files via Manage Files 2025-02-16 21:36:10 +02:00
Bogdan
525ed65687 Fix download links for FileList when passkey contains spaces 2025-02-16 12:19:17 +02:00
Bogdan
3fbccc6af3 Bump version to 5.19.2 2025-02-16 12:19:04 +02:00
Bogdan
8e10eecfac Fixed: Close Metadata settings modal on saving 2025-02-15 13:34:21 +02:00
Bogdan
a3b1512552 Fixed: Parsing some titles with FRE as French and ITA as Italian 2025-02-13 17:31:39 +02:00
epmt7w3ugk
d375b5ffbe Fixed: Parse GER/DE releases as German language
Fix parsing for German language to correctly detect "GER" and "DE"
Update test for GER/DE language parsing.
2025-02-10 17:17:43 +02:00
Bogdan
884abc0368 Bump version to 5.19.1 2025-02-09 17:50:50 +02:00
Weblate
f8da7aae03 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gallyam Biktashev <gallyamb@gmail.com>
Co-authored-by: Gionatan Spedicato <natanoig444@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-02-07 19:14:05 -06:00
Connor Gallopo
c165118d4d Update README.md
Update Copyright Date
2025-02-07 14:01:42 -06:00
Robin Dadswell
b3dd571a92 New: Migrated StevenLu URL to new URL 2025-02-06 03:41:33 +02:00
Bogdan
dd900eb739 Building docs on ARM
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
(cherry picked from commit 147e732c9ca7a4c289d4f6386f1277650e11f15b)
2025-02-06 00:43:53 +02:00
Bogdan
66aae0c91c Fixed: Reject multi-part files with P1, P2, etc. 2025-02-04 03:40:06 +02:00
Servarr
d888a0a2b3 Automated API Docs update 2025-02-03 21:31:13 +02:00
Bogdan
cb5416a18c Improve message for unknown movie rejection in release searching 2025-02-03 18:06:48 +02:00
Bogdan
7977e0be05 Add reason enum to decision engine rejections
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2025-02-03 17:46:13 +02:00
Bogdan
cd836fef38 Bump version to 5.19.0 2025-02-03 14:12:21 +02:00
Mark McDowall
b0bfbe767c Add MediaInfo AudioLanguagesAll and update styling
(cherry picked from commit 572b8620c9693f6824ae0919d6a37ba69c7590b1)
2025-02-02 15:16:41 +02:00
Bogdan
528b93dabe Fixed: Format bitrate for primary streams in media info
Co-authored-by: Mark McDowall <markus.mcd5@gmail.com>
2025-02-02 13:58:44 +02:00
Bogdan
1edcbee5e1 Bump version to 5.18.4 2025-02-02 12:49:50 +02:00
Bogdan
8853dced9f Fixed: Health warning for downloading inside root folders
(cherry picked from commit 1e9fd02e9d2bf57247adcac5728e2a0d2b084b86)
2025-02-01 23:36:10 +02:00
Mark McDowall
c7aa1bae5e Fixed: Ignore special folders inside Blackhole watch folders
(cherry picked from commit e79dd6f8e689617b1fd9f96c639ac300669112c5)
2025-02-01 23:35:45 +02:00
Bogdan
405ae77070 New: Prefer newer Usenet releases
(cherry picked from commit 6a439f03273b376feda713ef04a6912fc3af9d0a)
2025-02-01 23:35:31 +02:00
Weblate
6236bc9b4f Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: Mailme Dashite <mailmedashite@protonmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translation: Servarr/Radarr
2025-01-31 23:30:40 +02:00
Bogdan
743c977e5b New: Refresh cache for tracked queue on movies update 2025-01-31 23:29:41 +02:00
Bogdan
c0e5646f07 Bump Polly and NLog.Layouts.ClefJsonLayout 2025-01-26 15:42:43 +02:00
Weblate
10094b4e66 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Craze <christian.strey@gmail.com>
Co-authored-by: Dimitar \"Topper\" Maznekov <d.maznekov@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: ηg <jonas.konrath@icloud.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fa/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2025-01-26 15:00:33 +02:00
Bogdan
d923406f08 Bump version to 5.18.3 2025-01-26 14:48:34 +02:00
Bogdan
69a9c72286 Fixed: Loading movies with duplicated translations 2025-01-26 14:47:13 +02:00
Bogdan
55b9477a01 Fixed: Cleanup duplicated movie translations 2025-01-26 14:47:13 +02:00
Bogdan
6b81f92137 Fixed: Import Movies page crashing on console.error with non-string values 2025-01-21 16:11:22 +02:00
Bogdan
3ceda1bcda New: Parse releases with JPN as Japanese and KOR as Korean 2025-01-20 03:59:38 +02:00
Luke Anderson
f1f1921517 Update Trakt ratings logo (#10822)
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2025-01-19 17:05:55 +02:00
Weblate
af0c96538a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dimitar \"Topper\" Maznekov <d.maznekov@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: ahgharaghani <ah.gharaghani@gmail.com>
Co-authored-by: keysuck <joshkkim@gmail.com>
Co-authored-by: warkurre86 <tom.novo.86@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fa/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2025-01-19 16:56:42 +02:00
jcassette
3d52f45b6a New: reflink support for ZFS
(cherry picked from commit a840bb542362d58006b6cc27affd58ee6b965b80)
2025-01-19 16:55:06 +02:00
Bogdan
d4715f119d Bump version to 5.18.2 2025-01-19 16:54:39 +02:00
kephasdev
d58135bf17 Fixed: Augmenting languages for releases with MULTI and other languages (#10842) 2025-01-17 20:32:09 +02:00
Bogdan
b452c10da3 Bump SonarCloud azure extension for UI analysis to 3.X
(cherry picked from commit 396b2ae7c10c7df749ea23ea93608b56482175a1)
2025-01-14 11:43:51 +02:00
Stevie Robinson
f6b364725d Additional logging for delay profile decisions
(cherry picked from commit fa0f77659cbd3e9efdae55bbedb30fd8288622a6)

Closes #10831
2025-01-12 20:40:59 +02:00
Stevie Robinson
99f6be3f3d New: Show release source in history grab details
(cherry picked from commit 1609f0c9647b89bf55b8c043eeffc8a61653a1e5)

Closes #10830
2025-01-12 20:40:59 +02:00
Stevie Robinson
c2ac49a873 Additional logging for custom format score
(cherry picked from commit 3c8268c428688cc703af76b648c9b3385858274f)

Closes #10828
2025-01-12 20:40:58 +02:00
Weblate
0e24a3e8bc Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <Ano10@users.noreply.translate.servarr.com>
Co-authored-by: Dimitar \"Topper\" Maznekov <d.maznekov@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Mickaël O <mickael.ouillon@ac-bordeaux.fr>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: xumei51201314 <xumei51201314@163.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2025-01-12 15:19:47 +02:00
Weblate
18032cc83b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <Ano10@users.noreply.translate.servarr.com>
Co-authored-by: Dimitar \"Topper\" Maznekov <d.maznekov@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Mickaël O <mickael.ouillon@ac-bordeaux.fr>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2025-01-12 15:19:09 +02:00
Bogdan
927eb38945 Bump version to 5.18.1 2025-01-12 15:16:00 +02:00
Qstick
5fac348613 Bump SonarCloud azure extension to 3.X
(cherry picked from commit 7b8e352d876cd8f8e5b6296f0c3938bed4db8bb8)
2025-01-11 17:44:00 -06:00
Bogdan
7ba9603449 Fixed: Sending Discord notifications with images without absolute links 2025-01-06 13:27:14 +02:00
Bogdan
e36de8ab8d New: Auto tag based on movie status 2025-01-06 04:24:29 +02:00
Stevie Robinson
f8704a1655 Translate backend: Autotagging + CF specs
Signed-off-by: Stevie Robinson <stevie.robinson@gmail.com>
(cherry picked from commit de1cc25c903924fecbca79fedb458d729ae584fd)

Towards #9647
2025-01-06 04:06:34 +02:00
Stevie Robinson
f507d5154e Fixed: Listening on all IPv4 Addresses
(cherry picked from commit 035c474f10c257331a5f47e863d24af82537e335)
2025-01-05 13:53:29 +02:00
Stevie Robinson
5f03e7142a Fixed: qBittorrent Ratio Limit Check
(cherry picked from commit 4dcc015fb19ceb57d2e8f4985c5137e765829d1c)
2025-01-05 13:53:17 +02:00
Bogdan
c0ebbee7c9 Bump version to 5.18.0 2025-01-05 13:52:57 +02:00
Bogdan
4051cf3d80 Fixed: Increase rate limit for PassThePopcorn 2025-01-02 23:16:48 +02:00
Weblate
9876ed64e2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: 1 <1228553526@qq.com>
Co-authored-by: Alexander Balya <alexander.balya@gmail.com>
Co-authored-by: Ano10 <Ano10@users.noreply.translate.servarr.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Matti Meikäläinen <diefor-93@hotmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Tommy Au <smarttommyau@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: marapavelka <mara.pavelka@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2025-01-02 23:13:41 +02:00
Bogdan
2f26974ecc New: Add Tagalog language 2025-01-02 21:16:30 +02:00
Siddhant Naik
25f66a3029 New: Add Marathi language 2025-01-02 19:41:08 +02:00
Bogdan
0e25b2708c Fixed: Sending Manual Interaction Required notifications to Discord for unknown movies 2024-12-31 18:20:16 +02:00
Bogdan
410870d21e Check if backup folder is writable on backup
(cherry picked from commit 8aad79fd3e14eb885724a5e5790803c289be2f25)

Closes #10806
2024-12-31 12:16:28 +02:00
Bogdan
a64d931904 Suggest adding IP to RPC whitelist for on failed Transmission auth
(cherry picked from commit f05e552e8e6dc02cd26444073ab9a678dcb36492)
2024-12-31 12:12:52 +02:00
Bogdan
f0a9e76cfc Bump version to 5.17.2 2024-12-30 00:58:56 +02:00
Mark McDowall
6f23c465ee Don't send session information to Sentry
(cherry picked from commit fae24e98fb9230c2f3701caef457332952c6723f)
2024-12-28 03:32:11 +02:00
Bogdan
af60cca9ae Fixed: Advanced settings for Metadata consumers 2024-12-23 12:15:04 +02:00
Mark McDowall
d34d23a052 Fixed: Movies updated during Import List Sync not reflected in the UI
(cherry picked from commit 1c30ecd66dd0fd1dafaf9ab0e41a11a54eaac132)

Closes #10794
2024-12-23 12:08:25 +02:00
Bogdan
0a0da42543 Bump version to 5.17.1 2024-12-22 13:23:52 +02:00
Bogdan
e5419f6f06 Bump System.Memory
Closes #10791
2024-12-21 11:20:28 +02:00
Bogdan
88d9c08f1a Bump MailKit to 4.8.0 and Microsoft.Data.SqlClient to 2.1.7
Closes #10790
2024-12-21 11:15:14 +02:00
Bogdan
6b4259757c Add test for do not prefer repacks/propers 2024-12-20 20:33:18 +02:00
Mark McDowall
f1d7c56d94 Fixed: Custom Format score bypassing upgrades not being allowed
(cherry picked from commit ebe23104d4b29a3c900a982fb84e75c27ed531ab)

Co-authored-by: CeruleanRed <toni.suta@gmail.com>
2024-12-20 20:33:18 +02:00
Mark McDowall
c81b2e80ee Convert MediaInfo to TypeScript
(cherry picked from commit 4e4bf3507f20c0f8581c66804f8ef406c41952d8)

Closes #10753
2024-12-20 15:37:16 +02:00
Mark McDowall
5efefd804b Upgrade @typescript-eslint packages to 8.181.1
(cherry picked from commit ed10b63fa0c161cac7e0a2084e53785ab1798208)
2024-12-17 13:15:06 +02:00
Mark McDowall
38f9543526 Upgrade Font Awesome to 6.7.1
(cherry picked from commit 016b5718386593c030f14fcac307c93ee1ceeca6)
2024-12-17 13:11:07 +02:00
Mark McDowall
aae68e681e Upgrade babel to 7.26.0
(cherry picked from commit bfcd017012730c97eb587ae2d2e91f72ee7a1de3)
2024-12-17 13:08:36 +02:00
Bogdan
1d21bbf78f Bump version to 5.17.0 2024-12-16 20:24:54 +02:00
Stevie Robinson
99c3c8ce5b Replace URLs in translations with tokens
(cherry picked from commit 98d60e1a8e9abce6b31b3cdd745eff0fed181458)
2024-12-16 15:40:58 +02:00
Weblate
85171e40a5 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2024-12-16 15:28:28 +02:00
Bogdan
86b656d323 Use minor version for core-js in babel/preset-env 2024-12-16 12:40:37 +02:00
Bogdan
5ae5d1043a Improve opening add movie modal for Discover Overview 2024-12-16 01:25:03 +02:00
Mark McDowall
b801aa0935 New: Add metadata links to telegram messages
Co-authored-by: Ivar Stangeby <istangeby@gmail.com>

Fixed errors sending Telegram notifications when links aren't available

(cherry picked from commit 4eab168267db716a9e897a992e3a7f6889571f9f)
(cherry picked from commit 4d7a3d0909437268b4ad0a0dbeb59d45b4435118)

Closes #10242
Closes #10489
2024-12-15 15:20:16 +02:00
Stevie Robinson
b2b5aa1f79 New: Optionally as Instance Name to Telegram notifications
(cherry picked from commit 36633b5d08c19158f185c0fa5faabbaec607fcb5)

Closes #10757
2024-12-15 14:43:23 +02:00
Mark McDowall
8c6ba9a543 Fixed: Augmenting languages from indexer for release with stale indexer ID
(cherry picked from commit cb7489ce8fe933920ea04297bd2941496a0c07c6)

Closes #10768
2024-12-15 14:43:23 +02:00
Mark McDowall
4e024c51d3 Fixed: Movies without tags bypassing tags on Download Client
(cherry picked from commit c0e264cfc520ee387bfc882c95a5822c655e0d9b)

Closes #10765
2024-12-15 14:43:23 +02:00
Mark McDowall
e4106f0ede Upgrade TypeScript and core-js
(cherry picked from commit 148480909917f69ff3b2ca547ccb4716dd56606e)

Closes #10763
2024-12-15 14:43:20 +02:00
Bogdan
9032ac20ff Bump version to 5.16.3 2024-12-15 10:04:38 +02:00
Bogdan
23fce4bf2e Fixed: Refresh backup list on deletion
(cherry picked from commit 3b00112447361b19c04851a510e63f812597a043)
2024-12-15 05:29:12 +02:00
Mark McDowall
64fd8552f8 Fixed: Error getting processes in some cases
(cherry picked from commit b552d4e9f7ca7388404aa0d52566010a54cb0244)
2024-12-15 05:28:39 +02:00
Weblate
e016410c10 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Rodion <rodyon009@gmail.com>
Co-authored-by: Tomer Horowitz <tomerh2001@gmail.com>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: farebyting <farelbyting@gmail.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: hhjuhl <hans@kopula.dk>
Co-authored-by: kaisernet <afimark7@gmail.com>
Co-authored-by: keysuck <joshkkim@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/id/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2024-12-14 02:33:47 +02:00
Bogdan
bea943adf8 New: Tooltip with extra genres on search and collections 2024-12-13 19:17:59 +02:00
Bogdan
9780d20f8a Improve is visible property check for discover movies 2024-12-13 19:14:41 +02:00
Bogdan
62722d45b0 Fixed: Using all movie genres for collection filters 2024-12-13 19:13:55 +02:00
Bogdan
27dd8e8cd5 New: Tooltip with extra genres on movie details page 2024-12-12 21:59:19 +02:00
Bogdan
6c47ede76b Fixed: Refreshing movie genres 2024-12-12 21:58:54 +02:00
Mark McDowall
7b9562bb38 Update React
(cherry picked from commit 4491df3ae7530f2167beebc3548dd01fd2cc1a12)

Towards #10703
2024-12-12 21:01:19 +02:00
Stevie Robinson
8b0b7c1cb0 New: Reactive search button on Wanted pages
(cherry picked from commit e8c3aa20bd92701a16dcd97c5e103b79b3683105)

Closes #10750
2024-12-12 20:42:55 +02:00
Mark McDowall
7ebd341cd6 Sync TimeSpanConverter with upstream
(cherry picked from commit 1374240321f08d1400faf95e84217e4b7a2d116b)

Closes #10756
2024-12-09 14:03:12 +02:00
Bogdan
6c85f166ff Bump version to 5.16.2 2024-12-08 11:22:50 +02:00
Servarr
45aabce107 Automated API Docs update 2024-12-04 14:09:02 +02:00
soup
0caa793df4 New: Add config file setting for CGNAT authentication bypass
(cherry picked from commit 4c41a4f368046f73f82306bbd73bec992392938b)
2024-12-04 13:30:56 +02:00
Stevie Robinson
9a107cc8d7 New: Add Languages to Webhook Notifications
(cherry picked from commit e039dc45e267cf717e00c0a49ba637012f37e3d7)

Closes #10733
2024-12-02 16:59:45 +02:00
Mark McDowall
a6d727fe2a New: Kometa metadata file creation disabled
(cherry picked from commit c62fc9d05bb9e1fe51b454d78e80bd9250e31f89)

Closes #10738
2024-12-02 16:56:12 +02:00
Servarr
01a53d3624 Automated API Docs update 2024-12-02 16:03:25 +02:00
Weblate
348c29c9d7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Robin Dadswell <robin@robindadswell.tech>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mryx007 <mryx@mail.de>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_Hans/
Translation: Servarr/Radarr
2024-12-02 15:34:43 +02:00
Bogdan
64739712c6 Add return type for movie lookup and import endpoints
Closes #10737
2024-12-02 15:29:50 +02:00
Bogdan
6ac9cca953 Avoid default category on existing Transmission configurations
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
(cherry picked from commit bd656ae7f66fc9224ef2a57857152ee5d54d54f8)
2024-12-02 15:12:07 +02:00
Bogdan
a2b38c5b7d New: Labels support for Transmission 4.0
(cherry picked from commit 675e3cd38a14ea33c27f2d66a4be2bf802e17d88)
2024-12-02 15:12:07 +02:00
Bogdan
3cc4105d71 Bump NLog, Npgsql, Ical.Net, IPAddressRange, ImageSharp and Polly 2024-12-02 14:30:38 +02:00
Mark McDowall
3449a5d3fe Fixed: Don't fail import if symlink target can't be resolved
(cherry picked from commit 8cb58a63d8ec1b290bc57ad2cf1e90809ceebce9)
2024-12-02 02:32:21 +02:00
Gylesie
5bac157d36 Remove unnecessary heap allocations in local IP check
(cherry picked from commit ed536a85ad5f2062bf6f01f80efddb19fa935f63)
2024-12-02 02:31:28 +02:00
Mark McDowall
114d260f42 Deprecate Sizeleft and Timeleft queue item properties
Rename SizeLeft and TimeLeft queue item properties

(cherry picked from commit b51a49097941e5f306cae5785c63985b319784fd)

Fixed: Error loading queue

(cherry picked from commit f9606518eef78117f1e06a8bcc34af57ab0d2454)
2024-12-01 19:25:45 +02:00
Bogdan
617b9c5d35 Console warnings for missing translations on development builds
(cherry picked from commit 67a1ecb0fea4e6c7dfdb68fbe3ef30d4c22398d8)

Closes #10669
2024-12-01 18:54:53 +02:00
Mark McDowall
ba4ccbb0bd Deluge communication improvements
(cherry picked from commit 183b8b574a4dd948b5fada94d0e645b87710f223)
2024-12-01 14:01:41 +02:00
Mark McDowall
b845268b3d New: Support for new SABnzbd history retention values
Closes #10699

(cherry picked from commit e361f18837d98c089f7dc9c0190221ca8e2cf225)
2024-12-01 14:01:09 +02:00
Bogdan
0fee552074 Bump version to 5.16.1 2024-12-01 14:00:15 +02:00
Mark McDowall
828b994ef4 Support Postgres with non-standard version string
(cherry picked from commit 40f4ef27b22113c1dae0d0cbdee8205132bed68a)
2024-12-01 11:47:19 +00:00
Weblate
7952fd325b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Albrt9527 <2563009889@qq.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Languages add-on <noreply-addon-languages@weblate.org>
Co-authored-by: Weblate <noreply-mt-weblate@weblate.org>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_HANS/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2024-11-30 02:30:22 +02:00
Barry Mieny
4b4e598b67 New: Add Afrikaans language 2024-11-30 02:29:04 +02:00
Bogdan
71ccebd0f5 Fix cutoff fixture 2024-11-30 02:12:26 +02:00
Mark McDowall
2607c67912 Fixed: Prevent lack of internet from stopping all health checks from running
(cherry picked from commit dba3a8243988d3e9870b841696303191e1703a0d)

Closes #10694
2024-11-30 02:05:47 +02:00
Bogdan
a626b4f3c4 Fixed: Custom Format upgrading not respecting 'Upgrades Allowed'
(cherry picked from commit 91c5e6f12292e522ceb9094825525fb3684b97c6)

Closes #10691
2024-11-30 02:01:46 +02:00
Bogdan
1526bf29f4 Fixed path in downloading to root folder check message 2024-11-30 01:59:16 +02:00
bpoxy
2194772736 New: Add Albanian language (#10663) 2024-11-28 01:00:33 +02:00
Gauthier
cd490d6334 New: Add headers setting in webhook connection
(cherry picked from commit 78fb20282de73c0ea47375895a807235385d90e3)
2024-11-28 00:58:27 +02:00
bakerboy448
ff609848d8 New: Replace 'Ben the Man' release group parsing with 'Ben the Men'
Closes #10676

(cherry picked from commit 202190d032257b3cd19e42606385db7052b2aae4)
2024-11-27 15:59:51 -06:00
Weblate
15b6f7212d Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Mizuyoru_TW <mizuyoru.tw@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: hebian <zyf200913@163.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2024-11-27 14:57:43 -06:00
Mark McDowall
af06a9f70d Webpack web target
(cherry picked from commit a90866a73e6cff9a286c23e60c74672f4c0d317a)
2024-11-27 11:12:43 +02:00
Servarr
c3fa440cf8 Multiple Translations updated by Weblate (#10688)
ignore-downstream


Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr

Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
2024-11-19 20:37:07 -06:00
Bogdan
0411d66520 Bump version to 5.16.0 2024-11-19 03:10:17 +02:00
Bogdan
179637fe8b Fixed: Release dates for Discover Movie posters 2024-11-19 00:40:44 +02:00
Weblate
09b4bf15cf Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translation: Servarr/Radarr
2024-11-17 14:00:33 +02:00
Mark McDowall
ea86d14ca7 Fixed: Normalize unicode characters when comparing paths for equality
(cherry picked from commit ceeec091f85d0094e07537b7f62f18292655a710)
2024-11-17 11:28:51 +02:00
Elias Benbourenane
2429dd91c6 Allow GetFileSize to follow symlinks
(cherry picked from commit ca0bb14027f3409014e7cf9ffa8e04e577001d77)
2024-11-17 11:28:35 +02:00
Mark McDowall
a752476cdb Fixed: Allow files to be moved from Torrent Blackhole even when remove is disabled
(cherry picked from commit f739fd0900695e2ff312d13985c87d84ae00ea75)
2024-11-17 11:27:35 +02:00
Bogdan
50ce480abf Pin ReportGenerator in Azure Pipelines for .NET 6 2024-11-15 22:18:40 +02:00
Weblate
0ef6e56e5d Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: Ardenet <1213193613@qq.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ar/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/bg/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/he/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/is/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/lv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pl/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/sv/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/th/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/uk/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_TW/
Translation: Servarr/Radarr
2024-11-07 17:04:54 +02:00
Bogdan
12d5014125 New: Track Kometa metadata files
Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com>

Fixes #10059
Fixes #10419
Closes #10311
2024-11-05 14:31:08 +02:00
Bogdan
c8301d425c Fix translation token for Mount Health Check 2024-11-04 19:26:46 +02:00
Servarr
b1df9b2401 Automated API Docs update 2024-11-04 15:41:58 +02:00
Mark McDowall
ff09da3a69 New: Filter queue by status
(cherry picked from commit fb540040ef66e90c55b82539b85df378d6c76bd3)

Closes #10648
2024-11-04 15:05:57 +02:00
Mark McDowall
3b9bd696fb New: Favorite folders in Manual Import
(cherry picked from commit 3ddc6ac6de5c27a9aab915672321c8818dc5da48)

Closes #10630
2024-11-04 14:36:38 +02:00
Weblate
9ab3e6bab7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Anonymous <noreply@weblate.org>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lars <lars.erik.heloe@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: mytelegrambot <lacsonluxur@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ja/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/radarr/zh_CN/
Translation: Servarr/Radarr
2024-11-04 13:26:17 +02:00
Mark McDowall
86f4f86a0a Fixed: Filtering queue by multiple qualities
(cherry picked from commit b8af3af9f16db96337832c2989f4e7ff3dc2ed30)

Closes #10647
2024-11-04 13:12:31 +02:00
Bogdan
40d95a04e3 Sync coding style with upstream for join methods
Towards #10637
2024-11-04 13:01:40 +02:00
Mark McDowall
ca724836ce Rename Manage Custom Formats to Manage Formats
(cherry picked from commit 0f225b05c00add562c9a6aa8cc4cf494e83176c1)

Closes #10629
2024-11-04 12:57:55 +02:00
Mark McDowall
10e3964111 New: Use instance name in PWA manifest
(cherry picked from commit 1fcfb88d2aa0126c4b3c878c8e310311ea57d04d)

Closes #10625
2024-11-04 12:54:59 +02:00
Mark McDowall
b22a86e1d7 New: Include source path with Webhook import event movie file
(cherry picked from commit 73208e2f60263b1236f094a2bf6c47ebd5a8a271)

Closes #10635
2024-11-04 12:53:12 +02:00
Mark McDowall
5976d66511 New: Reject files during import that have no audio tracks
(cherry picked from commit 978349e24135572889095c743d0e7fac734ba7e0)

Closes #10643
2024-11-04 12:51:14 +02:00
Bogdan
b4eff4d4f9 Show a movie path as example in Mount Health Check
Closes #10649
2024-11-04 12:38:48 +02:00
Mark McDowall
1414a09111 New: Add individual edit to Manage Custom Formats
(cherry picked from commit e006b405323c276eb5b7f2dd97b97c80394a6930)
2024-11-04 12:38:30 +02:00
Mark McDowall
b30efd0c62 Use current time for cache break in development
(cherry picked from commit 020ed32fcfab1c6fbe57af5ea650300272c93fd7)
2024-11-04 12:37:12 +02:00
Mark McDowall
def6950db4 Fixed: Use download client name for history column
(cherry picked from commit 1df0ba9e5aef2d2745a45c546c869837ac8e68db)
2024-11-04 12:36:55 +02:00
Mark McDowall
f23c2dbaba Increase retries for DebouncerFixture
(cherry picked from commit 78cf13d341e6690bf6079dd1819d060d002155a7)
2024-11-04 12:36:26 +02:00
Bogdan
186e9cdd23 Bump version to 5.15.1 2024-11-03 11:41:20 +02:00
527 changed files with 15031 additions and 10252 deletions

View File

@@ -6,7 +6,7 @@
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "16",
"version": "20",
"nvmVersion": "latest"
}
},

View File

@@ -87,4 +87,4 @@ This project is also supported by DigitalOcean
### License
* [GNU GPL v3](http://www.gnu.org/licenses/gpl.html)
* Copyright 2010-2024
* Copyright 2010-2025

View File

@@ -9,7 +9,7 @@ variables:
testsFolder: './_tests'
yarnCacheFolder: $(Pipeline.Workspace)/.yarn
nugetCacheFolder: $(Pipeline.Workspace)/.nuget/packages
majorVersion: '5.15.0'
majorVersion: '5.20.2'
minorVersion: $[counter('minorVersion', 2000)]
radarrVersion: '$(majorVersion).$(minorVersion)'
buildName: '$(Build.SourceBranchName).$(radarrVersion)'
@@ -1116,20 +1116,20 @@ stages:
vmImage: ${{ variables.windowsImage }}
steps:
- checkout: self # Need history for Sonar analysis
- task: SonarCloudPrepare@2
- task: SonarCloudPrepare@3
env:
SONAR_SCANNER_OPTS: ''
inputs:
SonarCloud: 'SonarCloud'
organization: 'radarr'
scannerMode: 'CLI'
scannerMode: 'cli'
configMode: 'manual'
cliProjectKey: 'Radarr_Radarr.UI'
cliProjectName: 'RadarrUI'
cliProjectVersion: '$(radarrVersion)'
cliSources: './frontend'
- task: SonarCloudAnalyze@2
- task: SonarCloudAnalyze@3
- job: Api_Docs
displayName: API Docs
dependsOn: Prepare
@@ -1205,12 +1205,12 @@ stages:
submodules: true
- powershell: Set-Service SCardSvr -StartupType Manual
displayName: Enable Windows Test Service
- task: SonarCloudPrepare@2
- task: SonarCloudPrepare@3
condition: eq(variables['System.PullRequest.IsFork'], 'False')
inputs:
SonarCloud: 'SonarCloud'
organization: 'radarr'
scannerMode: 'MSBuild'
scannerMode: 'dotnet'
projectKey: 'Radarr_Radarr'
projectName: 'Radarr'
projectVersion: '$(radarrVersion)'
@@ -1223,10 +1223,10 @@ stages:
./build.sh --backend -f net6.0 -r win-x64
TEST_DIR=_tests/net6.0/win-x64/publish/ ./test.sh Windows Unit Coverage
displayName: Coverage Unit Tests
- task: SonarCloudAnalyze@2
- task: SonarCloudAnalyze@3
condition: eq(variables['System.PullRequest.IsFork'], 'False')
displayName: Publish SonarCloud Results
- task: reportgenerator@5
- task: reportgenerator@5.3.11
displayName: Generate Coverage Report
inputs:
reports: '$(Build.SourcesDirectory)/CoverageResults/**/coverage.opencover.xml'

15
docs.sh
View File

@@ -1,13 +1,18 @@
#!/bin/bash
set -e
FRAMEWORK="net6.0"
PLATFORM=$1
ARCHITECTURE="${2:-x64}"
if [ "$PLATFORM" = "Windows" ]; then
RUNTIME="win-x64"
RUNTIME="win-$ARCHITECTURE"
elif [ "$PLATFORM" = "Linux" ]; then
RUNTIME="linux-x64"
RUNTIME="linux-$ARCHITECTURE"
elif [ "$PLATFORM" = "Mac" ]; then
RUNTIME="osx-x64"
RUNTIME="osx-$ARCHITECTURE"
else
echo "Platform must be provided as first arguement: Windows, Linux or Mac"
echo "Platform must be provided as first argument: Windows, Linux or Mac"
exit 1
fi
@@ -35,7 +40,7 @@ dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p
dotnet new tool-manifest
dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli
dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/net6.0/$RUNTIME/$application" v3 &
dotnet tool run swagger tofile --output ./src/Radarr.Api.V3/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v3 &
sleep 45

View File

@@ -210,7 +210,6 @@ module.exports = {
'no-undef-init': 'off',
'no-undefined': 'off',
'no-unused-vars': ['error', { args: 'none', ignoreRestSiblings: true }],
'no-use-before-define': 'error',
// Node.js and CommonJS

View File

@@ -26,6 +26,7 @@ module.exports = (env) => {
const config = {
mode: isProduction ? 'production' : 'development',
devtool: isProduction ? 'source-map' : 'eval-source-map',
target: 'web',
stats: {
children: false
@@ -186,7 +187,7 @@ module.exports = (env) => {
loose: true,
debug: false,
useBuiltIns: 'entry',
corejs: 3
corejs: '3.39'
}
]
]

View File

@@ -41,6 +41,7 @@ function HistoryDetails(props: HistoryDetailsProps) {
indexer,
releaseGroup,
movieMatchType,
releaseSource,
customFormatScore,
nzbInfoUrl,
downloadClient,
@@ -53,6 +54,31 @@ function HistoryDetails(props: HistoryDetailsProps) {
const downloadClientNameInfo = downloadClientName ?? downloadClient;
let releaseSourceMessage = '';
switch (releaseSource) {
case 'Unknown':
releaseSourceMessage = translate('Unknown');
break;
case 'Rss':
releaseSourceMessage = translate('Rss');
break;
case 'Search':
releaseSourceMessage = translate('Search');
break;
case 'UserInvokedSearch':
releaseSourceMessage = translate('UserInvokedSearch');
break;
case 'InteractiveSearch':
releaseSourceMessage = translate('InteractiveSearch');
break;
case 'ReleasePush':
releaseSourceMessage = translate('ReleasePush');
break;
default:
releaseSourceMessage = '';
}
return (
<DescriptionList>
<DescriptionListItem
@@ -88,6 +114,14 @@ function HistoryDetails(props: HistoryDetailsProps) {
/>
) : null}
{releaseSource ? (
<DescriptionListItem
descriptionClassName={styles.description}
title={translate('ReleaseSource')}
data={releaseSourceMessage}
/>
) : null}
{nzbInfoUrl ? (
<span>
<DescriptionListItemTitle>
@@ -131,7 +165,7 @@ function HistoryDetails(props: HistoryDetailsProps) {
}
if (eventType === 'downloadFailed') {
const { message } = data as DownloadFailedHistory;
const { message, indexer } = data as DownloadFailedHistory;
return (
<DescriptionList>
@@ -145,6 +179,10 @@ function HistoryDetails(props: HistoryDetailsProps) {
<DescriptionListItem title={translate('GrabId')} data={downloadId} />
) : null}
{indexer ? (
<DescriptionListItem title={translate('Indexer')} data={indexer} />
) : null}
{message ? (
<DescriptionListItem title={translate('Message')} data={message} />
) : null}

View File

@@ -37,7 +37,7 @@ interface HistoryDetailsModalProps {
sourceTitle: string;
data: HistoryData;
downloadId?: string;
isMarkingAsFailed: boolean;
isMarkingAsFailed?: boolean;
onMarkAsFailedPress: () => void;
onModalClose: () => void;
}

View File

@@ -154,9 +154,14 @@ function HistoryRow(props: HistoryRowProps) {
}
if (name === 'downloadClient') {
const downloadClientName =
'downloadClientName' in data ? data.downloadClientName : null;
const downloadClient =
'downloadClient' in data ? data.downloadClient : null;
return (
<TableRowCell key={name} className={styles.downloadClient}>
{'downloadClient' in data ? data.downloadClient : ''}
{downloadClientName ?? downloadClient ?? ''}
</TableRowCell>
);
}

View File

@@ -82,8 +82,7 @@ class AddNewMovie extends Component {
const {
error,
items,
hasExistingMovies,
colorImpairedMode
hasExistingMovies
} = this.props;
const term = this.state.term;
@@ -150,7 +149,6 @@ class AddNewMovie extends Component {
return (
<AddNewMovieSearchResultConnector
key={item.tmdbId}
colorImpairedMode={colorImpairedMode}
{...item}
/>
);
@@ -223,8 +221,7 @@ AddNewMovie.propTypes = {
items: PropTypes.arrayOf(PropTypes.object).isRequired,
hasExistingMovies: PropTypes.bool.isRequired,
onMovieLookupChange: PropTypes.func.isRequired,
onClearMovieLookup: PropTypes.func.isRequired,
colorImpairedMode: PropTypes.bool.isRequired
onClearMovieLookup: PropTypes.func.isRequired
};
export default AddNewMovie;

View File

@@ -6,7 +6,6 @@ import { clearAddMovie, lookupMovie } from 'Store/Actions/addMovieActions';
import { clearMovieFiles, fetchMovieFiles } from 'Store/Actions/movieFileActions';
import { clearQueueDetails, fetchQueueDetails } from 'Store/Actions/queueActions';
import { fetchRootFolders } from 'Store/Actions/rootFolderActions';
import createUISettingsSelector from 'Store/Selectors/createUISettingsSelector';
import hasDifferentItems from 'Utilities/Object/hasDifferentItems';
import selectUniqueIds from 'Utilities/Object/selectUniqueIds';
import parseUrl from 'Utilities/String/parseUrl';
@@ -17,15 +16,13 @@ function createMapStateToProps() {
(state) => state.addMovie,
(state) => state.movies.items.length,
(state) => state.router.location,
createUISettingsSelector(),
(addMovie, existingMoviesCount, location, uiSettings) => {
(addMovie, existingMoviesCount, location) => {
const { params } = parseUrl(location.search);
return {
...addMovie,
term: params.term,
hasExistingMovies: existingMoviesCount > 0,
colorImpairedMode: uiSettings.enableColorImpairedMode
hasExistingMovies: existingMoviesCount > 0
};
}
);

View File

@@ -91,6 +91,10 @@
margin-left: 5px;
}
.genres {
pointer-events: all;
}
.links {
margin-left: 5px;
pointer-events: all;

View File

@@ -10,6 +10,7 @@ import { icons, kinds, sizes, tooltipPositions } from 'Helpers/Props';
import MovieDetailsLinks from 'Movie/Details/MovieDetailsLinks';
import MovieStatusLabel from 'Movie/Details/MovieStatusLabel';
import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar';
import MovieGenres from 'Movie/MovieGenres';
import MoviePoster from 'Movie/MoviePoster';
import formatRuntime from 'Utilities/Date/formatRuntime';
import translate from 'Utilities/String/translate';
@@ -73,12 +74,9 @@ class AddNewMovieSearchResult extends Component {
isExistingMovie,
isExcluded,
isSmallScreen,
colorImpairedMode,
id,
monitored,
isAvailable,
movieFile,
queueItem,
runtime,
movieRuntimeFormat,
certification
@@ -249,9 +247,7 @@ class AddNewMovieSearchResult extends Component {
name={icons.GENRE}
size={13}
/>
<span className={styles.genres}>
{genres.slice(0, 3).join(', ')}
</span>
<MovieGenres className={styles.genres} genres={genres} />
</Label> :
null
}
@@ -280,20 +276,18 @@ class AddNewMovieSearchResult extends Component {
}
canFlip={true}
kind={kinds.INVERSE}
position={tooltipPositions.BOTTOM}
position={tooltipPositions.TOP}
/>
{
isExistingMovie && isSmallScreen &&
<MovieStatusLabel
status={status}
hasMovieFiles={hasMovieFile}
movieId={existingMovieId}
monitored={monitored}
isAvailable={isAvailable}
queueItem={queueItem}
id={id}
hasMovieFiles={hasMovieFile}
status={status}
useLabel={true}
colorImpairedMode={colorImpairedMode}
/>
}
</div>
@@ -338,12 +332,9 @@ AddNewMovieSearchResult.propTypes = {
isExistingMovie: PropTypes.bool.isRequired,
isExcluded: PropTypes.bool,
isSmallScreen: PropTypes.bool.isRequired,
id: PropTypes.number,
monitored: PropTypes.bool.isRequired,
isAvailable: PropTypes.bool.isRequired,
movieFile: PropTypes.object,
queueItem: PropTypes.object,
colorImpairedMode: PropTypes.bool,
runtime: PropTypes.number.isRequired,
movieRuntimeFormat: PropTypes.string.isRequired,
certification: PropTypes.string

View File

@@ -8,19 +8,16 @@ function createMapStateToProps() {
return createSelector(
createExistingMovieSelector(),
createDimensionsSelector(),
(state) => state.queue.details.items,
(state) => state.movieFiles.items,
(state, { internalId }) => internalId,
(state) => state.settings.ui.item.movieRuntimeFormat,
(isExistingMovie, dimensions, queueItems, movieFiles, internalId, movieRuntimeFormat) => {
const queueItem = queueItems.find((item) => internalId > 0 && item.movieId === internalId);
(isExistingMovie, dimensions, movieFiles, internalId, movieRuntimeFormat) => {
const movieFile = movieFiles.find((item) => internalId > 0 && item.movieId === internalId);
return {
existingMovieId: internalId,
isExistingMovie,
isSmallScreen: dimensions.isSmallScreen,
queueItem,
movieFile,
movieRuntimeFormat
};

View File

@@ -81,7 +81,6 @@ ImportMovieRow.propTypes = {
selectedMovie: PropTypes.object,
isExistingMovie: PropTypes.bool.isRequired,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
queued: PropTypes.bool.isRequired,
isSelected: PropTypes.bool,
onSelectedChange: PropTypes.func.isRequired,
onInputChange: PropTypes.func.isRequired

View File

@@ -131,7 +131,7 @@ class ImportMovieSelectMovie extends Component {
id={this._buttonId}
>
<Link
ref={ref}
// ref={ref}
className={styles.button}
component="div"
onPress={this.onPress}
@@ -255,7 +255,7 @@ class ImportMovieSelectMovie extends Component {
items.map((item) => {
return (
<ImportMovieSearchResultConnector
key={item.tvdbId}
key={item.tmdbId}
tmdbId={item.tmdbId}
title={item.title}
year={item.year}

View File

@@ -10,7 +10,7 @@ import CollectionConnector from 'Collection/CollectionConnector';
import NotFound from 'Components/NotFound';
import Switch from 'Components/Router/Switch';
import DiscoverMovieConnector from 'DiscoverMovie/DiscoverMovieConnector';
import MovieDetailsPageConnector from 'Movie/Details/MovieDetailsPageConnector';
import MovieDetailsPage from 'Movie/Details/MovieDetailsPage';
import MovieIndex from 'Movie/Index/MovieIndex';
import CustomFormatSettingsPage from 'Settings/CustomFormats/CustomFormatSettingsPage';
import DownloadClientSettingsConnector from 'Settings/DownloadClients/DownloadClientSettingsConnector';
@@ -67,7 +67,7 @@ function AppRoutes() {
<Route path="/add/discover" component={DiscoverMovieConnector} />
<Route path="/movie/:titleSlug" component={MovieDetailsPageConnector} />
<Route path="/movie/:titleSlug" component={MovieDetailsPage} />
{/*
Calendar

View File

@@ -1,11 +1,16 @@
import Column from 'Components/Table/Column';
import { SortDirection } from 'Helpers/Props/sortDirections';
import { ValidationFailure } from 'typings/pending';
import { FilterBuilderProp, PropertyFilter } from './AppState';
export interface Error {
responseJSON: {
message: string;
};
status?: number;
responseJSON:
| {
message: string | undefined;
}
| ValidationFailure[]
| undefined;
}
export interface AppSectionDeleteState {
@@ -51,6 +56,16 @@ export interface AppSectionItemState<T> {
item: T;
}
export interface AppSectionProviderState<T>
extends AppSectionDeleteState,
AppSectionSaveState {
isFetching: boolean;
isPopulated: boolean;
error: Error;
items: T[];
pendingChanges: Partial<T>;
}
interface AppSectionState<T> {
isFetching: boolean;
isPopulated: boolean;

View File

@@ -1,15 +1,19 @@
import BlocklistAppState from './BlocklistAppState';
import CalendarAppState from './CalendarAppState';
import CommandAppState from './CommandAppState';
import HistoryAppState from './HistoryAppState';
import ExtraFilesAppState from './ExtraFilesAppState';
import HistoryAppState, { MovieHistoryAppState } from './HistoryAppState';
import InteractiveImportAppState from './InteractiveImportAppState';
import MovieBlocklistAppState from './MovieBlocklistAppState';
import MovieCollectionAppState from './MovieCollectionAppState';
import MovieCreditAppState from './MovieCreditAppState';
import MovieFilesAppState from './MovieFilesAppState';
import MoviesAppState, { MovieIndexAppState } from './MoviesAppState';
import OrganizePreviewAppState from './OrganizePreviewAppState';
import ParseAppState from './ParseAppState';
import PathsAppState from './PathsAppState';
import QueueAppState from './QueueAppState';
import ReleasesAppState from './ReleasesAppState';
import RootFolderAppState from './RootFolderAppState';
import SettingsAppState from './SettingsAppState';
import SystemAppState from './SystemAppState';
@@ -50,6 +54,7 @@ export interface CustomFilter {
export interface AppSectionState {
isConnected: boolean;
isReconnecting: boolean;
isSidebarVisible: boolean;
version: string;
prevVersion?: string;
dimensions: {
@@ -64,16 +69,21 @@ interface AppState {
blocklist: BlocklistAppState;
calendar: CalendarAppState;
commands: CommandAppState;
extraFiles: ExtraFilesAppState;
history: HistoryAppState;
interactiveImport: InteractiveImportAppState;
movieBlocklist: MovieBlocklistAppState;
movieCollections: MovieCollectionAppState;
movieCredits: MovieCreditAppState;
movieFiles: MovieFilesAppState;
movieHistory: MovieHistoryAppState;
movieIndex: MovieIndexAppState;
movies: MoviesAppState;
organizePreview: OrganizePreviewAppState;
parse: ParseAppState;
paths: PathsAppState;
queue: QueueAppState;
releases: ReleasesAppState;
rootFolders: RootFolderAppState;
settings: SettingsAppState;
system: SystemAppState;

View File

@@ -0,0 +1,6 @@
import AppSectionState from 'App/State/AppSectionState';
import { ExtraFile } from 'MovieFile/ExtraFile';
type ExtraFilesAppState = AppSectionState<ExtraFile>;
export default ExtraFilesAppState;

View File

@@ -5,6 +5,8 @@ import AppSectionState, {
} from 'App/State/AppSectionState';
import History from 'typings/History';
export type MovieHistoryAppState = AppSectionState<History>;
interface HistoryAppState
extends AppSectionState<History>,
AppSectionFilterState<History>,

View File

@@ -1,11 +1,20 @@
import AppSectionState from 'App/State/AppSectionState';
import RecentFolder from 'InteractiveImport/Folder/RecentFolder';
import ImportMode from 'InteractiveImport/ImportMode';
import InteractiveImport from 'InteractiveImport/InteractiveImport';
interface FavoriteFolder {
folder: string;
}
interface RecentFolder {
folder: string;
lastUsed: string;
}
interface InteractiveImportAppState extends AppSectionState<InteractiveImport> {
originalItems: InteractiveImport[];
importMode: ImportMode;
favoriteFolders: FavoriteFolder[];
recentFolders: RecentFolder[];
}

View File

@@ -0,0 +1,6 @@
import { AppSectionProviderState } from 'App/State/AppSectionState';
import Metadata from 'typings/Metadata';
type MetadataAppState = AppSectionProviderState<Metadata>;
export default MetadataAppState;

View File

@@ -0,0 +1,6 @@
import AppSectionState from 'App/State/AppSectionState';
import Blocklist from 'typings/Blocklist';
type MovieBlocklistAppState = AppSectionState<Blocklist>;
export default MovieBlocklistAppState;

View File

@@ -1,7 +1,11 @@
import AppSectionState from 'App/State/AppSectionState';
import AppSectionState, {
AppSectionSaveState,
} from 'App/State/AppSectionState';
import MovieCollection from 'typings/MovieCollection';
interface MovieCollectionAppState extends AppSectionState<MovieCollection> {
interface MovieCollectionAppState
extends AppSectionState<MovieCollection>,
AppSectionSaveState {
itemMap: Record<number, number>;
}

View File

@@ -1,6 +1,6 @@
import AppSectionState from 'App/State/AppSectionState';
import MovieCredit from 'typings/MovieCredit';
interface MovieCreditAppState extends AppSectionState<MovieCredit> {}
type MovieCreditAppState = AppSectionState<MovieCredit>;
export default MovieCreditAppState;

View File

@@ -64,6 +64,8 @@ interface MoviesAppState
deleteOptions: {
addImportExclusion: boolean;
};
pendingChanges: Partial<Movie>;
}
export default MoviesAppState;

View File

@@ -0,0 +1,13 @@
import ModelBase from 'App/ModelBase';
import AppSectionState from 'App/State/AppSectionState';
export interface OrganizePreviewModel extends ModelBase {
movieId: number;
movieFileId: number;
existingPath: string;
newPath: string;
}
type OrganizePreviewAppState = AppSectionState<OrganizePreviewModel>;
export default OrganizePreviewAppState;

View File

@@ -0,0 +1,10 @@
import AppSectionState, {
AppSectionFilterState,
} from 'App/State/AppSectionState';
import Release from 'typings/Release';
interface ReleasesAppState
extends AppSectionState<Release>,
AppSectionFilterState<Release> {}
export default ReleasesAppState;

View File

@@ -20,6 +20,7 @@ import NamingConfig from 'typings/Settings/NamingConfig';
import NamingExample from 'typings/Settings/NamingExample';
import ReleaseProfile from 'typings/Settings/ReleaseProfile';
import UiSettings from 'typings/Settings/UiSettings';
import MetadataAppState from './MetadataAppState';
export interface DownloadClientAppState
extends AppSectionState<DownloadClient>,
@@ -36,8 +37,7 @@ export interface NamingAppState
extends AppSectionItemState<NamingConfig>,
AppSectionSaveState {}
export interface NamingExamplesAppState
extends AppSectionItemState<NamingExample> {}
export type NamingExamplesAppState = AppSectionItemState<NamingExample>;
export interface ImportListAppState
extends AppSectionState<ImportList>,
@@ -97,6 +97,7 @@ interface SettingsAppState {
indexerFlags: IndexerFlagSettingsAppState;
indexers: IndexerAppState;
languages: LanguageSettingsAppState;
metadata: MetadataAppState;
naming: NamingAppState;
namingExamples: NamingExamplesAppState;
notifications: NotificationAppState;

View File

@@ -22,7 +22,7 @@ function createMapStateToProps() {
return {
...collection,
movies: [...collection.movies].sort((a, b) => b.year - a.year),
genres: Array.from(new Set(allGenres)).slice(0, 3)
genres: Array.from(new Set(allGenres))
};
}
);

View File

@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Link from 'Components/Link/Link';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import EditMovieModalConnector from 'Movie/Edit/EditMovieModalConnector';
import EditMovieModal from 'Movie/Edit/EditMovieModal';
import MovieIndexProgressBar from 'Movie/Index/ProgressBar/MovieIndexProgressBar';
import MoviePoster from 'Movie/MoviePoster';
import translate from 'Utilities/String/translate';
@@ -172,7 +172,7 @@ class CollectionMovie extends Component {
collectionId={collectionId}
/>
<EditMovieModalConnector
<EditMovieModal
isOpen={isEditMovieModalOpen}
movieId={id}
onModalClose={this.onEditMovieModalClose}

View File

@@ -10,7 +10,8 @@ import Label from 'Components/Label';
import IconButton from 'Components/Link/IconButton';
import MonitorToggleButton from 'Components/MonitorToggleButton';
import { icons, sizes } from 'Helpers/Props';
import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector';
import MovieGenres from 'Movie/MovieGenres';
import QualityProfileName from 'Settings/Profiles/Quality/QualityProfileName';
import dimensions from 'Styles/Variables/dimensions';
import fonts from 'Styles/Variables/fonts';
import translate from 'Utilities/String/translate';
@@ -211,7 +212,7 @@ class CollectionOverview extends Component {
/>
<span className={styles.qualityProfileName}>
{
<QualityProfileNameConnector
<QualityProfileName
qualityProfileId={qualityProfileId}
/>
}
@@ -242,12 +243,10 @@ class CollectionOverview extends Component {
size={sizes.MEDIUM}
>
<Icon
name={icons.PROFILE}
name={icons.GENRE}
size={13}
/>
<span className={styles.genres}>
{genres.join(', ')}
</span>
<MovieGenres className={styles.genres} genres={genres} />
</Label>
}

View File

@@ -1,5 +1,6 @@
import React, { useEffect, useState } from 'react';
import StackTrace from 'stacktrace-js';
import translate from 'Utilities/String/translate';
import styles from './ErrorBoundaryError.css';
interface ErrorBoundaryErrorProps {
@@ -18,7 +19,7 @@ function ErrorBoundaryError(props: ErrorBoundaryErrorProps) {
className = styles.container,
messageClassName = styles.message,
detailsClassName = styles.details,
message = 'There was an error loading this content',
message = translate('ErrorLoadingContent'),
error,
info,
} = props;

View File

@@ -16,6 +16,7 @@ import MovieFilterBuilderRowValue from './MovieFilterBuilderRowValue';
import ProtocolFilterBuilderRowValue from './ProtocolFilterBuilderRowValue';
import QualityFilterBuilderRowValueConnector from './QualityFilterBuilderRowValueConnector';
import QualityProfileFilterBuilderRowValue from './QualityProfileFilterBuilderRowValue';
import QueueStatusFilterBuilderRowValue from './QueueStatusFilterBuilderRowValue';
import ReleaseStatusFilterBuilderRowValue from './ReleaseStatusFilterBuilderRowValue';
import TagFilterBuilderRowValueConnector from './TagFilterBuilderRowValueConnector';
import styles from './FilterBuilderRow.css';
@@ -80,6 +81,9 @@ function getRowValueConnector(selectedFilterBuilderProp) {
case filterBuilderValueTypes.QUALITY_PROFILE:
return QualityProfileFilterBuilderRowValue;
case filterBuilderValueTypes.QUEUE_STATUS:
return QueueStatusFilterBuilderRowValue;
case filterBuilderValueTypes.MOVIE:
return MovieFilterBuilderRowValue;

View File

@@ -0,0 +1,67 @@
import React from 'react';
import translate from 'Utilities/String/translate';
import FilterBuilderRowValue from './FilterBuilderRowValue';
import FilterBuilderRowValueProps from './FilterBuilderRowValueProps';
const statusTagList = [
{
id: 'queued',
get name() {
return translate('Queued');
},
},
{
id: 'paused',
get name() {
return translate('Paused');
},
},
{
id: 'downloading',
get name() {
return translate('Downloading');
},
},
{
id: 'completed',
get name() {
return translate('Completed');
},
},
{
id: 'failed',
get name() {
return translate('Failed');
},
},
{
id: 'warning',
get name() {
return translate('Warning');
},
},
{
id: 'delay',
get name() {
return translate('Delay');
},
},
{
id: 'downloadClientUnavailable',
get name() {
return translate('DownloadClientUnavailable');
},
},
{
id: 'fallback',
get name() {
return translate('Fallback');
},
},
];
function QueueStatusFilterBuilderRowValue(props: FilterBuilderRowValueProps) {
return <FilterBuilderRowValue {...props} tagList={statusTagList} />;
}
export default QueueStatusFilterBuilderRowValue;

View File

@@ -2,8 +2,11 @@ import React from 'react';
import translate from 'Utilities/String/translate';
import FilterBuilderRowValue from './FilterBuilderRowValue';
const protocols = [
{ id: 'tba', name: 'TBA' },
const statusTagList = [
{ id: 'tba',
get name() {
return translate('Tba');
} },
{
id: 'announced',
get name() {
@@ -33,7 +36,7 @@ const protocols = [
function ReleaseStatusFilterBuilderRowValue(props) {
return (
<FilterBuilderRowValue
tagList={protocols}
tagList={statusTagList}
{...props}
/>
);

View File

@@ -53,7 +53,7 @@ function CustomFiltersModalContent(props) {
<div className={styles.addButtonContainer}>
<Button onPress={onAddCustomFilter}>
Add Custom Filter
{translate('AddCustomFilter')}
</Button>
</div>
</ModalBody>

View File

@@ -1,9 +1,11 @@
import _ from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchIndexers } from 'Store/Actions/settingsActions';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput from './EnhancedSelectInput';
function createMapStateToProps() {
@@ -18,15 +20,17 @@ function createMapStateToProps() {
items
} = indexers;
const values = items.sort(sortByProp('name')).map((indexer) => ({
key: indexer.id,
value: indexer.name
}));
const values = _.map(items.sort(sortByProp('name')), (indexer) => {
return {
key: indexer.id,
value: indexer.name
};
});
if (includeAny) {
values.unshift({
key: 0,
value: '(Any)'
value: `(${translate('Any')})`
});
}

View File

@@ -1,156 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import KeyValueListInputItem from './KeyValueListInputItem';
import styles from './KeyValueListInput.css';
class KeyValueListInput extends Component {
//
// Lifecycle
constructor(props, context) {
super(props, context);
this.state = {
isFocused: false
};
}
//
// Listeners
onItemChange = (index, itemValue) => {
const {
name,
value,
onChange
} = this.props;
const newValue = [...value];
if (index == null) {
newValue.push(itemValue);
} else {
newValue.splice(index, 1, itemValue);
}
onChange({
name,
value: newValue
});
};
onRemoveItem = (index) => {
const {
name,
value,
onChange
} = this.props;
const newValue = [...value];
newValue.splice(index, 1);
onChange({
name,
value: newValue
});
};
onFocus = () => {
this.setState({
isFocused: true
});
};
onBlur = () => {
this.setState({
isFocused: false
});
const {
name,
value,
onChange
} = this.props;
const newValue = value.reduce((acc, v) => {
if (v.key || v.value) {
acc.push(v);
}
return acc;
}, []);
if (newValue.length !== value.length) {
onChange({
name,
value: newValue
});
}
};
//
// Render
render() {
const {
className,
value,
keyPlaceholder,
valuePlaceholder,
hasError,
hasWarning
} = this.props;
const { isFocused } = this.state;
return (
<div className={classNames(
className,
isFocused && styles.isFocused,
hasError && styles.hasError,
hasWarning && styles.hasWarning
)}
>
{
[...value, { key: '', value: '' }].map((v, index) => {
return (
<KeyValueListInputItem
key={index}
index={index}
keyValue={v.key}
value={v.value}
keyPlaceholder={keyPlaceholder}
valuePlaceholder={valuePlaceholder}
isNew={index === value.length}
onChange={this.onItemChange}
onRemove={this.onRemoveItem}
onFocus={this.onFocus}
onBlur={this.onBlur}
/>
);
})
}
</div>
);
}
}
KeyValueListInput.propTypes = {
className: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.arrayOf(PropTypes.object).isRequired,
hasError: PropTypes.bool,
hasWarning: PropTypes.bool,
keyPlaceholder: PropTypes.string,
valuePlaceholder: PropTypes.string,
onChange: PropTypes.func.isRequired
};
KeyValueListInput.defaultProps = {
className: styles.inputContainer,
value: []
};
export default KeyValueListInput;

View File

@@ -0,0 +1,104 @@
import classNames from 'classnames';
import React, { useCallback, useState } from 'react';
import { InputOnChange } from 'typings/inputs';
import KeyValueListInputItem from './KeyValueListInputItem';
import styles from './KeyValueListInput.css';
interface KeyValue {
key: string;
value: string;
}
export interface KeyValueListInputProps {
className?: string;
name: string;
value: KeyValue[];
hasError?: boolean;
hasWarning?: boolean;
keyPlaceholder?: string;
valuePlaceholder?: string;
onChange: InputOnChange<KeyValue[]>;
}
function KeyValueListInput({
className = styles.inputContainer,
name,
value = [],
hasError = false,
hasWarning = false,
keyPlaceholder,
valuePlaceholder,
onChange,
}: KeyValueListInputProps): JSX.Element {
const [isFocused, setIsFocused] = useState(false);
const handleItemChange = useCallback(
(index: number | null, itemValue: KeyValue) => {
const newValue = [...value];
if (index === null) {
newValue.push(itemValue);
} else {
newValue.splice(index, 1, itemValue);
}
onChange({ name, value: newValue });
},
[value, name, onChange]
);
const handleRemoveItem = useCallback(
(index: number) => {
const newValue = [...value];
newValue.splice(index, 1);
onChange({ name, value: newValue });
},
[value, name, onChange]
);
const onFocus = useCallback(() => setIsFocused(true), []);
const onBlur = useCallback(() => {
setIsFocused(false);
const newValue = value.reduce((acc: KeyValue[], v) => {
if (v.key || v.value) {
acc.push(v);
}
return acc;
}, []);
if (newValue.length !== value.length) {
onChange({ name, value: newValue });
}
}, [value, name, onChange]);
return (
<div
className={classNames(
className,
isFocused && styles.isFocused,
hasError && styles.hasError,
hasWarning && styles.hasWarning
)}
>
{[...value, { key: '', value: '' }].map((v, index) => (
<KeyValueListInputItem
key={index}
index={index}
keyValue={v.key}
value={v.value}
keyPlaceholder={keyPlaceholder}
valuePlaceholder={valuePlaceholder}
isNew={index === value.length}
onChange={handleItemChange}
onRemove={handleRemoveItem}
onFocus={onFocus}
onBlur={onBlur}
/>
))}
</div>
);
}
export default KeyValueListInput;

View File

@@ -5,13 +5,19 @@
&:last-child {
margin-bottom: 0;
border-bottom: 0;
}
}
.inputWrapper {
.keyInputWrapper {
flex: 1 0 0;
}
.valueInputWrapper {
flex: 1 0 0;
min-width: 40px;
}
.buttonWrapper {
flex: 0 0 22px;
}
@@ -20,4 +26,10 @@
.valueInput {
width: 100%;
border: none;
background-color: transparent;
color: var(--textColor);
&::placeholder {
color: var(--helpTextColor);
}
}

View File

@@ -2,10 +2,11 @@
// Please do not change this file!
interface CssExports {
'buttonWrapper': string;
'inputWrapper': string;
'itemContainer': string;
'keyInput': string;
'keyInputWrapper': string;
'valueInput': string;
'valueInputWrapper': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,124 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import IconButton from 'Components/Link/IconButton';
import { icons } from 'Helpers/Props';
import TextInput from './TextInput';
import styles from './KeyValueListInputItem.css';
class KeyValueListInputItem extends Component {
//
// Listeners
onKeyChange = ({ value: keyValue }) => {
const {
index,
value,
onChange
} = this.props;
onChange(index, { key: keyValue, value });
};
onValueChange = ({ value }) => {
// TODO: Validate here or validate at a lower level component
const {
index,
keyValue,
onChange
} = this.props;
onChange(index, { key: keyValue, value });
};
onRemovePress = () => {
const {
index,
onRemove
} = this.props;
onRemove(index);
};
onFocus = () => {
this.props.onFocus();
};
onBlur = () => {
this.props.onBlur();
};
//
// Render
render() {
const {
keyValue,
value,
keyPlaceholder,
valuePlaceholder,
isNew
} = this.props;
return (
<div className={styles.itemContainer}>
<div className={styles.inputWrapper}>
<TextInput
className={styles.keyInput}
name="key"
value={keyValue}
placeholder={keyPlaceholder}
onChange={this.onKeyChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
/>
</div>
<div className={styles.inputWrapper}>
<TextInput
className={styles.valueInput}
name="value"
value={value}
placeholder={valuePlaceholder}
onChange={this.onValueChange}
onFocus={this.onFocus}
onBlur={this.onBlur}
/>
</div>
<div className={styles.buttonWrapper}>
{
isNew ?
null :
<IconButton
name={icons.REMOVE}
tabIndex={-1}
onPress={this.onRemovePress}
/>
}
</div>
</div>
);
}
}
KeyValueListInputItem.propTypes = {
index: PropTypes.number,
keyValue: PropTypes.string.isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
keyPlaceholder: PropTypes.string.isRequired,
valuePlaceholder: PropTypes.string.isRequired,
isNew: PropTypes.bool.isRequired,
onChange: PropTypes.func.isRequired,
onRemove: PropTypes.func.isRequired,
onFocus: PropTypes.func.isRequired,
onBlur: PropTypes.func.isRequired
};
KeyValueListInputItem.defaultProps = {
keyPlaceholder: 'Key',
valuePlaceholder: 'Value'
};
export default KeyValueListInputItem;

View File

@@ -0,0 +1,89 @@
import React, { useCallback } from 'react';
import IconButton from 'Components/Link/IconButton';
import { icons } from 'Helpers/Props';
import TextInput from './TextInput';
import styles from './KeyValueListInputItem.css';
interface KeyValueListInputItemProps {
index: number;
keyValue: string;
value: string;
keyPlaceholder?: string;
valuePlaceholder?: string;
isNew: boolean;
onChange: (index: number, itemValue: { key: string; value: string }) => void;
onRemove: (index: number) => void;
onFocus: () => void;
onBlur: () => void;
}
function KeyValueListInputItem({
index,
keyValue,
value,
keyPlaceholder = 'Key',
valuePlaceholder = 'Value',
isNew,
onChange,
onRemove,
onFocus,
onBlur,
}: KeyValueListInputItemProps): JSX.Element {
const handleKeyChange = useCallback(
({ value: keyValue }: { value: string }) => {
onChange(index, { key: keyValue, value });
},
[index, value, onChange]
);
const handleValueChange = useCallback(
({ value }: { value: string }) => {
onChange(index, { key: keyValue, value });
},
[index, keyValue, onChange]
);
const handleRemovePress = useCallback(() => {
onRemove(index);
}, [index, onRemove]);
return (
<div className={styles.itemContainer}>
<div className={styles.keyInputWrapper}>
<TextInput
className={styles.keyInput}
name="key"
value={keyValue}
placeholder={keyPlaceholder}
onChange={handleKeyChange}
onFocus={onFocus}
onBlur={onBlur}
/>
</div>
<div className={styles.valueInputWrapper}>
<TextInput
className={styles.valueInput}
name="value"
value={value}
placeholder={valuePlaceholder}
onChange={handleValueChange}
onFocus={onFocus}
onBlur={onBlur}
/>
</div>
<div className={styles.buttonWrapper}>
{isNew ? null : (
<IconButton
name={icons.REMOVE}
tabIndex={-1}
onPress={handleRemovePress}
/>
)}
</div>
</div>
);
}
export default KeyValueListInputItem;

View File

@@ -14,6 +14,8 @@ function getType({ type, selectOptionsProviderAction }) {
return inputTypes.CHECK;
case 'device':
return inputTypes.DEVICE;
case 'keyValueList':
return inputTypes.KEY_VALUE_LIST;
case 'password':
return inputTypes.PASSWORD;
case 'number':
@@ -137,6 +139,8 @@ ProviderFieldFormGroup.propTypes = {
type: PropTypes.string.isRequired,
advanced: PropTypes.bool.isRequired,
hidden: PropTypes.string,
isDisabled: PropTypes.bool,
provider: PropTypes.string,
pending: PropTypes.bool.isRequired,
errors: PropTypes.arrayOf(PropTypes.object).isRequired,
warnings: PropTypes.arrayOf(PropTypes.object).isRequired,

View File

@@ -33,7 +33,7 @@ function createMapStateToProps() {
if (includeMixed) {
values.unshift({
key: 'mixed',
value: '(Mixed)',
value: `(${translate('Mixed')})`,
isDisabled: true
});
}

View File

@@ -55,7 +55,7 @@ function createMapStateToProps() {
values.push({
key: ADD_NEW_KEY,
value: 'Add a new path'
value: translate('AddANewPath')
});
return {

View File

@@ -2,6 +2,7 @@ import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import EnhancedSelectInputOption from './EnhancedSelectInputOption';
import styles from './RootFolderSelectInputOption.css';
@@ -47,14 +48,14 @@ function RootFolderSelectInputOption(props) {
freeSpace == null ?
null :
<div className={styles.freeSpace}>
{formatBytes(freeSpace)} Free
{translate('RootFolderSelectFreeSpace', { freeSpace: formatBytes(freeSpace) })}
</div>
}
{
isMissing ?
<div className={styles.isMissing}>
Missing
{translate('Missing')}
</div> :
null
}
@@ -67,8 +68,8 @@ RootFolderSelectInputOption.propTypes = {
id: PropTypes.string.isRequired,
value: PropTypes.string.isRequired,
freeSpace: PropTypes.number,
movieFolder: PropTypes.string,
isMissing: PropTypes.bool,
movieFolder: PropTypes.string,
isMobile: PropTypes.bool.isRequired,
isWindows: PropTypes.bool
};

View File

@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import formatBytes from 'Utilities/Number/formatBytes';
import translate from 'Utilities/String/translate';
import EnhancedSelectInputSelectedValue from './EnhancedSelectInputSelectedValue';
import styles from './RootFolderSelectInputSelectedValue.css';
@@ -39,7 +40,7 @@ function RootFolderSelectInputSelectedValue(props) {
{
freeSpace != null && includeFreeSpace &&
<div className={styles.freeSpace}>
{formatBytes(freeSpace)} Free
{translate('RootFolderSelectFreeSpace', { freeSpace: formatBytes(freeSpace) })}
</div>
}
</EnhancedSelectInputSelectedValue>

View File

@@ -8,27 +8,37 @@ import styles from './UMaskInput.css';
const umaskOptions = [
{
key: '755',
value: '755 - Owner write, Everyone else read',
get value() {
return translate('Umask755Description', { octal: '755' });
},
hint: 'drwxr-xr-x'
},
{
key: '775',
value: '775 - Owner & Group write, Other read',
get value() {
return translate('Umask775Description', { octal: '775' });
},
hint: 'drwxrwxr-x'
},
{
key: '770',
value: '770 - Owner & Group write',
get value() {
return translate('Umask770Description', { octal: '770' });
},
hint: 'drwxrwx---'
},
{
key: '750',
value: '750 - Owner write, Group read',
get value() {
return translate('Umask750Description', { octal: '750' });
},
hint: 'drwxr-x---'
},
{
key: '777',
value: '777 - Everyone write',
get value() {
return translate('Umask777Description', { octal: '777' });
},
hint: 'drwxrwxrwx'
}
];

View File

@@ -8,17 +8,20 @@ import { kinds } from 'Helpers/Props';
import { Kind } from 'Helpers/Props/kinds';
import styles from './Icon.css';
export type IconName = FontAwesomeIconProps['icon'];
export type IconKind = Extract<Kind, keyof typeof styles>;
export interface IconProps
extends Omit<
FontAwesomeIconProps,
'icon' | 'spin' | 'name' | 'title' | 'size'
> {
containerClassName?: ComponentProps<'span'>['className'];
name: FontAwesomeIconProps['icon'];
kind?: Extract<Kind, keyof typeof styles>;
name: IconName;
kind?: IconKind;
size?: number;
isSpinning?: FontAwesomeIconProps['spin'];
title?: string | (() => string);
title?: string | (() => string) | null;
}
export default function Icon({

View File

@@ -16,6 +16,10 @@
/** Kinds **/
.default {
color: inherit;
}
/** Sizes **/
.small {

View File

@@ -1,6 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'default': string;
'label': string;
'large': string;
'medium': string;

View File

@@ -1,54 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import { kinds, sizes } from 'Helpers/Props';
import styles from './InfoLabel.css';
function InfoLabel(props) {
const {
className,
name,
kind,
size,
outline,
children,
...otherProps
} = props;
return (
<span
className={classNames(
className,
styles[kind],
styles[size],
outline && styles.outline
)}
{...otherProps}
>
<div className={styles.name}>
{name}
</div>
<div>
{children}
</div>
</span>
);
}
InfoLabel.propTypes = {
className: PropTypes.string.isRequired,
name: PropTypes.string.isRequired,
kind: PropTypes.oneOf(kinds.all).isRequired,
size: PropTypes.oneOf(sizes.all).isRequired,
outline: PropTypes.bool.isRequired,
children: PropTypes.node.isRequired
};
InfoLabel.defaultProps = {
className: styles.label,
kind: kinds.DEFAULT,
size: sizes.SMALL,
outline: false
};
export default InfoLabel;

View File

@@ -0,0 +1,41 @@
import classNames from 'classnames';
import React, { ComponentProps, ReactNode } from 'react';
import { Kind } from 'Helpers/Props/kinds';
import { Size } from 'Helpers/Props/sizes';
import styles from './InfoLabel.css';
interface InfoLabelProps extends ComponentProps<'span'> {
className?: string;
name: string;
kind?: Extract<Kind, keyof typeof styles>;
size?: Extract<Size, keyof typeof styles>;
outline?: boolean;
children: ReactNode;
}
function InfoLabel({
className = styles.label,
name,
kind = 'default',
size = 'small',
outline = false,
children,
...otherProps
}: InfoLabelProps) {
return (
<span
className={classNames(
className,
styles[kind],
styles[size],
outline && styles.outline
)}
{...otherProps}
>
<div className={styles.name}>{name}</div>
<div>{children}</div>
</span>
);
}
export default InfoLabel;

View File

@@ -1,3 +1,4 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
@@ -7,26 +8,15 @@ const TIMEOUT = 1 / FPS * 1000;
class Marquee extends Component {
static propTypes = {
text: PropTypes.string,
title: PropTypes.string,
hoverToStop: PropTypes.bool,
loop: PropTypes.bool,
className: PropTypes.string
};
constructor(props, context) {
super(props, context);
static defaultProps = {
text: '',
title: '',
hoverToStop: true,
loop: false
};
state = {
animatedWidth: 0,
overflowWidth: 0,
direction: 0
};
this.state = {
animatedWidth: 0,
overflowWidth: 0,
direction: 0
};
}
componentDidMount() {
this.measureText();
@@ -138,7 +128,7 @@ class Marquee extends Component {
ref={(el) => {
this.container = el;
}}
className={`ui-marquee ${this.props.className}`}
className={classNames('ui-marquee', this.props.className)}
style={{ overflow: 'hidden' }}
>
<span
@@ -159,7 +149,7 @@ class Marquee extends Component {
ref={(el) => {
this.container = el;
}}
className={`ui-marquee ${this.props.className}`.trim()}
className={classNames('ui-marquee', this.props.className)}
style={{ overflow: 'hidden' }}
onMouseEnter={this.onHandleMouseEnter}
onMouseLeave={this.onHandleMouseLeave}
@@ -178,4 +168,20 @@ class Marquee extends Component {
}
}
Marquee.propTypes = {
text: PropTypes.string,
title: PropTypes.string,
hoverToStop: PropTypes.bool,
loop: PropTypes.bool,
className: PropTypes.string
};
Marquee.defaultProps = {
text: '',
title: '',
hoverToStop: true,
loop: false,
className: ''
};
export default Marquee;

View File

@@ -58,9 +58,9 @@ class FilterMenu extends Component {
>
<ButtonComponent
iconName={icons.FILTER}
showIndicator={selectedFilterKey !== 'all'}
text={translate('Filter')}
isDisabled={isDisabled}
showIndicator={selectedFilterKey !== 'all'}
/>
<FilterMenuContent

View File

@@ -3,7 +3,7 @@ import React, { Component } from 'react';
import { Manager, Popper, Reference } from 'react-popper';
import Portal from 'Components/Portal';
import { align } from 'Helpers/Props';
import getUniqueElememtId from 'Utilities/getUniqueElementId';
import getUniqueElementId from 'Utilities/getUniqueElementId';
import styles from './Menu.css';
const sharedPopperOptions = {
@@ -38,8 +38,8 @@ class Menu extends Component {
super(props, context);
this._scheduleUpdate = null;
this._menuButtonId = getUniqueElememtId();
this._menuContentId = getUniqueElememtId();
this._menuButtonId = getUniqueElementId();
this._menuContentId = getUniqueElementId();
this.state = {
isMenuOpen: false,

View File

@@ -18,7 +18,7 @@ function ModalError(props) {
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Error
{translate('Error')}
</ModalHeader>
<ModalBody>
@@ -26,7 +26,7 @@ function ModalError(props) {
messageClassName={styles.message}
detailsClassName={styles.details}
{...otherProps}
message={translate('ThereWasAnErrorLoadingThisItem')}
message={translate('ErrorLoadingItem')}
/>
</ModalBody>

View File

@@ -56,7 +56,7 @@ function KeyboardShortcutsModalContent(props) {
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Keyboard Shortcuts
{translate('KeyboardShortcuts')}
</ModalHeader>
<ModalBody>

View File

@@ -92,7 +92,7 @@ class MovieSearchInput extends Component {
if (item.type === ADD_NEW_TYPE) {
return (
<div className={styles.addNewMovieSuggestion}>
Search for {query}
{translate('SearchForQuery', { query })}
</div>
);
}

View File

@@ -79,7 +79,7 @@ class PageHeader extends Component {
<IconButton
className={styles.donate}
name={icons.HEART}
aria-label="Donate"
aria-label={translate('Donate')}
to="https://radarr.video/donate"
size={14}
title={translate('Donate')}

View File

@@ -10,7 +10,7 @@ function PageContentError(props) {
<PageContentBody>
<ErrorBoundaryError
{...props}
message={translate('ThereWasAnErrorLoadingThisPage')}
message={translate('ErrorLoadingPage')}
/>
</PageContentBody>
</div>

View File

@@ -24,6 +24,7 @@
composes: link;
padding: 10px 24px;
padding-left: 35px;
}
.isActiveLink {
@@ -41,10 +42,6 @@
text-align: center;
}
.noIcon {
margin-left: 25px;
}
.status {
float: right;
}

View File

@@ -8,7 +8,6 @@ interface CssExports {
'isActiveParentLink': string;
'item': string;
'link': string;
'noIcon': string;
'status': string;
}
export const cssExports: CssExports;

View File

@@ -63,9 +63,7 @@ class PageSidebarItem extends Component {
</span>
}
<span className={isChildItem ? styles.noIcon : null}>
{typeof title === 'function' ? title() : title}
</span>
{typeof title === 'function' ? title() : title}
{
!!StatusComponent &&

View File

@@ -23,11 +23,14 @@
display: flex;
align-items: center;
justify-content: center;
overflow: hidden;
height: 24px;
}
.label {
padding: 0 3px;
max-width: 100%;
max-height: 100%;
color: var(--toolbarLabelColor);
font-size: $extraSmallFontSize;
line-height: calc($extraSmallFontSize + 1px);

View File

@@ -1,58 +0,0 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import { icons } from 'Helpers/Props';
import styles from './PageToolbarButton.css';
function PageToolbarButton(props) {
const {
label,
iconName,
spinningName,
isDisabled,
isSpinning,
...otherProps
} = props;
return (
<Link
className={classNames(
styles.toolbarButton,
isDisabled && styles.isDisabled
)}
isDisabled={isDisabled || isSpinning}
{...otherProps}
>
<Icon
name={isSpinning ? (spinningName || iconName) : iconName}
isSpinning={isSpinning}
size={21}
/>
<div className={styles.labelContainer}>
<div className={styles.label}>
{label}
</div>
</div>
</Link>
);
}
PageToolbarButton.propTypes = {
label: PropTypes.string.isRequired,
iconName: PropTypes.object.isRequired,
spinningName: PropTypes.object,
isSpinning: PropTypes.bool,
isDisabled: PropTypes.bool,
onPress: PropTypes.func
};
PageToolbarButton.defaultProps = {
spinningName: icons.SPINNER,
isDisabled: false,
isSpinning: false
};
export default PageToolbarButton;

View File

@@ -0,0 +1,50 @@
import classNames from 'classnames';
import React from 'react';
import Icon, { IconName } from 'Components/Icon';
import Link, { LinkProps } from 'Components/Link/Link';
import { icons } from 'Helpers/Props';
import styles from './PageToolbarButton.css';
export interface PageToolbarButtonProps extends LinkProps {
label: string;
iconName: IconName;
spinningName?: IconName;
isSpinning?: boolean;
isDisabled?: boolean;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
overflowComponent?: React.ComponentType<any>;
}
function PageToolbarButton({
label,
iconName,
spinningName = icons.SPINNER,
isDisabled = false,
isSpinning = false,
overflowComponent,
...otherProps
}: PageToolbarButtonProps) {
return (
<Link
className={classNames(
styles.toolbarButton,
isDisabled && styles.isDisabled
)}
isDisabled={isDisabled || isSpinning}
title={label}
{...otherProps}
>
<Icon
name={isSpinning ? spinningName || iconName : iconName}
isSpinning={isSpinning}
size={21}
/>
<div className={styles.labelContainer}>
<div className={styles.label}>{label}</div>
</div>
</Link>
);
}
export default PageToolbarButton;

View File

@@ -1,7 +1,7 @@
import React, { ComponentPropsWithoutRef } from 'react';
import styles from './TableRowCell.css';
export interface TableRowCellProps extends ComponentPropsWithoutRef<'td'> {}
export type TableRowCellProps = ComponentPropsWithoutRef<'td'>;
export default function TableRowCell({
className = styles.cell,

View File

@@ -1,4 +1,5 @@
import React from 'react';
import { SortDirection } from 'Helpers/Props/sortDirections';
type PropertyFunction<T> = () => T;
@@ -9,6 +10,7 @@ interface Column {
className?: string;
columnLabel?: string;
isSortable?: boolean;
fixedSortDirection?: SortDirection;
isVisible: boolean;
isModifiable?: boolean;
}

View File

@@ -170,11 +170,11 @@ class TableOptionsModal extends Component {
{
canModifyColumns ?
<FormGroup>
<FormLabel>{translate('Columns')}</FormLabel>
<FormLabel>{translate('TableColumns')}</FormLabel>
<div>
<FormInputHelpText
text={translate('TableOptionsColumnsMessage')}
text={translate('TableColumnsHelpText')}
/>
<div className={styles.columns}>

View File

@@ -6,6 +6,7 @@ import Icon from 'Components/Icon';
import Link from 'Components/Link/Link';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './TablePager.css';
class TablePager extends Component {
@@ -156,7 +157,7 @@ class TablePager extends Component {
<div className={styles.recordsContainer}>
<div className={styles.records}>
Total records: {totalRecords}
{translate('TotalRecords', { totalRecords })}
</div>
</div>
</div>

View File

@@ -15,7 +15,7 @@ function TraktRating(props: TraktRatingProps) {
const { ratings, iconSize = 14, hideIcon = false } = props;
const traktImage =
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48IS0tIEdlbmVyYXRvcjogQWRvYmUgSWxsdXN0cmF0b3IgMTguMC4wLCBTVkcgRXhwb3J0IFBsdWctSW4gLiBTVkcgVmVyc2lvbjogNi4wMCBCdWlsZCAwKSAgLS0+PCFET0NUWVBFIHN2ZyBQVUJMSUMgIi0vL1czQy8vRFREIFNWRyAxLjEvL0VOIiAiaHR0cDovL3d3dy53My5vcmcvR3JhcGhpY3MvU1ZHLzEuMS9EVEQvc3ZnMTEuZHRkIj48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiAgICAgdmlld0JveD0iMCAwIDE0NC44IDE0NC44IiBlbmFibGUtYmFja2dyb3VuZD0ibmV3IDAgMCAxNDQuOCAxNDQuOCIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+ICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik0yOS41LDExMS44YzEwLjYsMTEuNiwyNS45LDE4LjgsNDIuOSwxOC44YzguNywwLDE2LjktMS45LDI0LjMtNS4zTDU2LjMsODVMMjkuNSwxMTEuOHoiLz4gICAgPHBhdGggZmlsbD0iI0VEMjIyNCIgZD0iTTU2LjEsNjAuNkwyNS41LDkxLjFMMjEuNCw4N2wzMi4yLTMyLjJoMGwzNy42LTM3LjZjLTUuOS0yLTEyLjItMy4xLTE4LjgtMy4xYy0zMi4yLDAtNTguMywyNi4xLTU4LjMsNTguMyAgICAgICBjMCwxMy4xLDQuMywyNS4yLDExLjcsMzVsMzAuNS0zMC41bDIuMSwybDQzLjcsNDMuN2MwLjktMC41LDEuNy0xLDIuNS0xLjZMNTYuMyw3Mi43TDI3LDEwMmwtNC4xLTQuMWwzMy40LTMzLjRsMi4xLDJsNTEsNTAuOSAgICAgICBjMC44LTAuNiwxLjUtMS4zLDIuMi0xLjlsLTU1LTU1TDU2LjEsNjAuNnoiLz4gICAgPHBhdGggZmlsbD0iI0VEMUMyNCIgZD0iTTExNS43LDExMS40YzkuMy0xMC4zLDE1LTI0LDE1LTM5YzAtMjMuNC0xMy44LTQzLjUtMzMuNi01Mi44TDYwLjQsNTYuMkwxMTUuNywxMTEuNHogTTc0LjUsNjYuOGwtNC4xLTQuMSAgICAgICBsMjguOS0yOC45bDQuMSw0LjFMNzQuNSw2Ni44eiBNMTAxLjksMjcuMUw2OC42LDYwLjRsLTQuMS00LjFMOTcuOCwyM0wxMDEuOSwyNy4xeiIvPiAgICA8Zz4gICAgICAgPGc+ICAgICAgICAgIDxwYXRoIGZpbGw9IiNFRDIyMjQiIGQ9Ik03Mi40LDE0NC44QzMyLjUsMTQ0LjgsMCwxMTIuMywwLDcyLjRDMCwzMi41LDMyLjUsMCw3Mi40LDBzNzIuNCwzMi41LDcyLjQsNzIuNCAgICAgICAgICAgICBDMTQ0LjgsMTEyLjMsMTEyLjMsMTQ0LjgsNzIuNCwxNDQuOHogTTcyLjQsNy4zQzM2LjUsNy4zLDcuMywzNi41LDcuMyw3Mi40czI5LjIsNjUuMSw2NS4xLDY1LjFzNjUuMS0yOS4yLDY1LjEtNjUuMSAgICAgICAgICAgICBTMTA4LjMsNy4zLDcyLjQsNy4zeiIvPiAgICAgICA8L2c+ICAgIDwvZz48L2c+PC9zdmc+';
'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0iVVRGLTgiPz4KPHN2ZyBpZD0iTGF5ZXJfMiIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIiB2aWV3Qm94PSIwIDAgNDggNDgiPgogIDxkZWZzPgogICAgPHN0eWxlPgogICAgICAuY2xzLTEgewogICAgICAgIGZpbGw6ICM5ZjQyYzY7CiAgICAgIH0KCiAgICAgIC5jbHMtMiB7CiAgICAgICAgZmlsbDogI2ZmZjsKICAgICAgfQogICAgPC9zdHlsZT4KICA8L2RlZnM+CiAgPGcgaWQ9Il94MkRfLXByb2R1Y3Rpb24iPgogICAgPGcgaWQ9ImxvZ29tYXJrLmNpcmNsZS5jb2xvciI+CiAgICAgIDxwYXRoIGlkPSJiYWNrZ3JvdW5kIiBjbGFzcz0iY2xzLTEiIGQ9Ik00OCwyNGMwLDYuNjItMi42OSwxMi42Mi03LjAzLDE2Ljk3LTQuMzQsNC4zNC0xMC4zNCw3LjAzLTE2Ljk3LDcuMDNDMTAuNzUsNDgsMCwzNy4yNSwwLDI0YzAtNi42MywyLjY5LTEyLjYzLDcuMDMtMTYuOTdDMTEuMzcsMi42OCwxNy4zNywwLDI0LDBzMTIuNjMsMi42OCwxNi45Nyw3LjAzYy4xNC4xNC4yNy4yOC40LjQyLjQ4LjUuOTQsMS4wMiwxLjM3LDEuNTYuMjEuMjYuNDEuNTIuNi43OS40My41Ny44MiwxLjE2LDEuMTgsMS43Ni4xOC4yOS4zNS41OC41MS44Ny4zNS42NC42OCwxLjI5Ljk2LDEuOTcsMS4zLDIuOTQsMi4wMSw2LjE4LDIuMDEsOS42WiIvPgogICAgICA8ZyBpZD0iY2hlY2tib3giPgogICAgICAgIDxwYXRoIGNsYXNzPSJjbHMtMiIgZD0iTTEyLjkzLDE4LjY3bC0xLjQ3LDEuNDYsMTQuNCwxNC40LDEuNDctMS40Ny00LjMyLTQuMzEsMTkuNzMtMTkuNzRjLS40My0uNTQtLjg5LTEuMDYtMS4zNy0xLjU2bC0xOS44MywxOS44My04LjYxLTguNjFaTTI4LjAyLDMyLjM3bDEuNDYtMS40Ni0yLjE1LTIuMTYsMTcuMTktMTcuMTljLS4zNi0uNi0uNzUtMS4xOS0xLjE4LTEuNzZsLTE4Ljk0LDE4Ljk1LDMuNjIsMy42MlpNMzAuMTgsMzAuMjFsMTUuODEtMTUuODFjLS4yOC0uNjgtLjYxLTEuMzMtLjk2LTEuOTdsLTE2LjMyLDE2LjMyLDEuNDcsMS40NlpNMTMuNjIsMTcuOTdsNy45Miw3LjkyLDEuNDctMS40Ny03LjkyLTcuOTItMS40NywxLjQ3Wk0yNS4xNywyMi4yN2wtNy45Mi03LjkyLTEuNDcsMS40Nyw3LjkyLDcuOTIsMS40Ny0xLjQ3Wk0yNCw0MS4zMmMtOS41NSwwLTE3LjMyLTcuNzctMTcuMzItMTcuMzJTMTQuNDUsNi42NywyNCw2LjY3YzIuNiwwLDUuMTEuNTYsNy40NCwxLjY4bC44OS0xLjg3Yy0yLjYxLTEuMjUtNS40Mi0xLjg4LTguMzMtMS44OEMxMy4zMSw0LjYsNC42MSwxMy4zLDQuNjEsMjRzOC43LDE5LjQsMTkuNCwxOS40YzcuNjQsMCwxNC41OS00LjUxLDE3LjcxLTExLjQ4bC0xLjg5LS44NWMtMi43OSw2LjIzLTksMTAuMjYtMTUuODIsMTAuMjZaIi8+CiAgICAgIDwvZz4KICAgIDwvZz4KICA8L2c+Cjwvc3ZnPg==';
const { value = 0, votes = 0 } = ratings.trakt;

View File

@@ -7,63 +7,63 @@ export const shortcuts = {
OPEN_KEYBOARD_SHORTCUTS_MODAL: {
key: '?',
get name() {
return translate('OpenThisModal');
return translate('KeyboardShortcutsOpenModal');
}
},
CLOSE_MODAL: {
key: 'Esc',
get name() {
return translate('CloseCurrentModal');
return translate('KeyboardShortcutsCloseModal');
}
},
ACCEPT_CONFIRM_MODAL: {
key: 'Enter',
get name() {
return translate('AcceptConfirmationModal');
return translate('KeyboardShortcutsConfirmModal');
}
},
MOVIE_SEARCH_INPUT: {
key: 's',
get name() {
return translate('FocusSearchBox');
return translate('KeyboardShortcutsFocusSearchBox');
}
},
SAVE_SETTINGS: {
key: 'mod+s',
get name() {
return translate('SaveSettings');
return translate('KeyboardShortcutsSaveSettings');
}
},
SCROLL_TOP: {
key: 'mod+home',
get name() {
return translate('MovieIndexScrollTop');
return translate('KeyboardShortcutsMovieIndexScrollTop');
}
},
SCROLL_BOTTOM: {
key: 'mod+end',
get name() {
return translate('MovieIndexScrollBottom');
return translate('KeyboardShortcutsMovieIndexScrollBottom');
}
},
DETAILS_NEXT: {
key: '→',
get name() {
return translate('MovieDetailsNextMovie');
return translate('KeyboardShortcutsMovieDetailsNextMovie');
}
},
DETAILS_PREVIOUS: {
key: '←',
get name() {
return translate('MovieDetailsPreviousMovie');
return translate('KeyboardShortcutsMovieDetailsPreviousMovie');
}
}
};

View File

@@ -1,5 +1,5 @@
{
"name": "Radarr",
"name": "__INSTANCE_NAME__",
"icons": [
{
"src": "__URL_BASE__/Content/Images/Icons/android-chrome-192x192.png",

View File

@@ -85,10 +85,16 @@ $hoverScale: 1.05;
flex: 1 0 auto;
}
.overviewContainer {
display: flex;
justify-content: space-between;
flex: 0 1 1000px;
flex-direction: column;
}
.overview {
composes: link;
flex: 0 1 1000px;
overflow: hidden;
min-height: 0;
}

View File

@@ -11,6 +11,7 @@ interface CssExports {
'link': string;
'lists': string;
'overview': string;
'overviewContainer': string;
'poster': string;
'posterContainer': string;
'title': string;

View File

@@ -133,14 +133,20 @@ class DiscoverMovieOverview extends Component {
/>
</div>
<MoviePoster
className={styles.poster}
<Link
className={styles.link}
style={elementStyle}
images={images}
size={250}
lazy={false}
overflow={true}
/>
{...linkProps}
>
<MoviePoster
className={styles.poster}
style={elementStyle}
images={images}
size={250}
lazy={false}
overflow={true}
/>
</Link>
</div>
</div>
@@ -242,11 +248,13 @@ class DiscoverMovieOverview extends Component {
</div>
<div className={styles.details}>
<div className={styles.overview}>
<TextTruncate
line={Math.floor(overviewHeight / (defaultFontSize * lineHeight))}
text={overview}
/>
<div className={styles.overviewContainer}>
<Link className={styles.overview} {...linkProps}>
<TextTruncate
line={Math.floor(overviewHeight / (defaultFontSize * lineHeight))}
text={overview}
/>
</Link>
</div>
<DiscoverMovieOverviewInfo
@@ -255,7 +263,6 @@ class DiscoverMovieOverview extends Component {
{...overviewOptions}
{...otherProps}
/>
</div>
</div>
</div>

View File

@@ -49,7 +49,7 @@ function isVisible(row, props) {
valueProp
} = row;
return _.has(props, valueProp) && (_.get(props, showProp) || props.sortKey === name);
return _.has(props, valueProp) && _.get(props, valueProp) !== null && (props[showProp] || props.sortKey === name);
}
function getInfoRowProps(row, props) {

View File

@@ -50,15 +50,13 @@ function DiscoverMoviePosterInfo(props) {
}
if (sortKey === 'inCinemas' && inCinemas) {
const inCinemasDate = getRelativeDate(
inCinemas,
const inCinemasDate = getRelativeDate({
date: inCinemas,
shortDateFormat,
showRelativeDates,
{
timeFormat,
timeForToday: false
}
);
timeFormat,
timeForToday: false
});
return (
<div className={styles.info} title={translate('InCinemas')}>
@@ -68,15 +66,13 @@ function DiscoverMoviePosterInfo(props) {
}
if (sortKey === 'digitalRelease' && digitalRelease) {
const digitalReleaseDate = getRelativeDate(
digitalRelease,
const digitalReleaseDate = getRelativeDate({
date: digitalRelease,
shortDateFormat,
showRelativeDates,
{
timeFormat,
timeForToday: false
}
);
timeFormat,
timeForToday: false
});
return (
<div className={styles.info} title={translate('DigitalRelease')}>
@@ -86,15 +82,13 @@ function DiscoverMoviePosterInfo(props) {
}
if (sortKey === 'physicalRelease' && physicalRelease) {
const physicalReleaseDate = getRelativeDate(
physicalRelease,
const physicalReleaseDate = getRelativeDate({
date: physicalRelease,
shortDateFormat,
showRelativeDates,
{
timeFormat,
timeForToday: false
}
);
timeFormat,
timeForToday: false
});
return (
<div className={styles.info} title={translate('PhysicalRelease')}>

View File

@@ -1,3 +1,4 @@
import translate from 'Utilities/String/translate';
import * as filterTypes from './filterTypes';
export const ARRAY = 'array';
@@ -20,49 +21,127 @@ export const all = [
export const possibleFilterTypes = {
[ARRAY]: [
{ key: filterTypes.CONTAINS, value: 'contains' },
{ key: filterTypes.NOT_CONTAINS, value: 'does not contain' }
{
key: filterTypes.CONTAINS,
value: () => translate('FilterContains')
},
{
key: filterTypes.NOT_CONTAINS,
value: () => translate('FilterDoesNotContain')
}
],
[CONTAINS]: [
{ key: filterTypes.CONTAINS, value: 'contains' }
{
key: filterTypes.CONTAINS,
value: () => translate('FilterContains')
}
],
[DATE]: [
{ key: filterTypes.LESS_THAN, value: 'is before' },
{ key: filterTypes.GREATER_THAN, value: 'is after' },
{ key: filterTypes.IN_LAST, value: 'in the last' },
{ key: filterTypes.NOT_IN_LAST, value: 'not in the last' },
{ key: filterTypes.IN_NEXT, value: 'in the next' },
{ key: filterTypes.NOT_IN_NEXT, value: 'not in the next' }
{
key: filterTypes.LESS_THAN,
value: () => translate('FilterIsBefore')
},
{
key: filterTypes.GREATER_THAN,
value: () => translate('FilterIsAfter')
},
{
key: filterTypes.IN_LAST,
value: () => translate('FilterInLast')
},
{
key: filterTypes.NOT_IN_LAST,
value: () => translate('FilterNotInLast')
},
{
key: filterTypes.IN_NEXT,
value: () => translate('FilterInNext')
},
{
key: filterTypes.NOT_IN_NEXT,
value: () => translate('FilterNotInNext')
}
],
[EQUAL]: [
{ key: filterTypes.EQUAL, value: 'is' }
{
key: filterTypes.EQUAL,
value: () => translate('FilterIs')
}
],
[EXACT]: [
{ key: filterTypes.EQUAL, value: 'is' },
{ key: filterTypes.NOT_EQUAL, value: 'is not' }
{
key: filterTypes.EQUAL,
value: () => translate('FilterIs')
},
{
key: filterTypes.NOT_EQUAL,
value: () => translate('FilterIsNot')
}
],
[NUMBER]: [
{ key: filterTypes.EQUAL, value: 'equal' },
{ key: filterTypes.GREATER_THAN, value: 'greater than' },
{ key: filterTypes.GREATER_THAN_OR_EQUAL, value: 'greater than or equal' },
{ key: filterTypes.LESS_THAN, value: 'less than' },
{ key: filterTypes.LESS_THAN_OR_EQUAL, value: 'less than or equal' },
{ key: filterTypes.NOT_EQUAL, value: 'not equal' }
{
key: filterTypes.EQUAL,
value: () => translate('FilterEqual')
},
{
key: filterTypes.GREATER_THAN,
value: () => translate('FilterGreaterThan')
},
{
key: filterTypes.GREATER_THAN_OR_EQUAL,
value: () => translate('FilterGreaterThanOrEqual')
},
{
key: filterTypes.LESS_THAN,
value: () => translate('FilterLessThan')
},
{
key: filterTypes.LESS_THAN_OR_EQUAL,
value: () => translate('FilterLessThanOrEqual')
},
{
key: filterTypes.NOT_EQUAL,
value: () => translate('FilterNotEqual')
}
],
[STRING]: [
{ key: filterTypes.CONTAINS, value: 'contains' },
{ key: filterTypes.NOT_CONTAINS, value: 'does not contain' },
{ key: filterTypes.EQUAL, value: 'equal' },
{ key: filterTypes.NOT_EQUAL, value: 'not equal' },
{ key: filterTypes.STARTS_WITH, value: 'starts with' },
{ key: filterTypes.NOT_STARTS_WITH, value: 'does not start with' },
{ key: filterTypes.ENDS_WITH, value: 'ends with' },
{ key: filterTypes.NOT_ENDS_WITH, value: 'does not end with' }
{
key: filterTypes.CONTAINS,
value: () => translate('FilterContains')
},
{
key: filterTypes.NOT_CONTAINS,
value: () => translate('FilterDoesNotContain')
},
{
key: filterTypes.EQUAL,
value: () => translate('FilterEqual')
},
{
key: filterTypes.NOT_EQUAL,
value: () => translate('FilterNotEqual')
},
{
key: filterTypes.STARTS_WITH,
value: () => translate('FilterStartsWith')
},
{
key: filterTypes.NOT_STARTS_WITH,
value: () => translate('FilterDoesNotStartWith')
},
{
key: filterTypes.ENDS_WITH,
value: () => translate('FilterEndsWith')
},
{
key: filterTypes.NOT_ENDS_WITH,
value: () => translate('FilterDoesNotEndWith')
}
]
};

View File

@@ -8,6 +8,7 @@ export const LANGUAGE = 'language';
export const PROTOCOL = 'protocol';
export const QUALITY = 'quality';
export const QUALITY_PROFILE = 'qualityProfile';
export const QUEUE_STATUS = 'queueStatus';
export const MOVIE = 'movie';
export const RELEASE_STATUS = 'releaseStatus';
export const MINIMUM_AVAILABILITY = 'minimumAvailability';

View File

@@ -15,6 +15,7 @@ import {
faFileVideo as farFileVideo,
faFolder as farFolder,
faHdd as farHdd,
faHeart as farHeart,
faKeyboard as farKeyboard,
faObjectGroup as farObjectGroup,
faObjectUngroup as farObjectUngroup,
@@ -174,6 +175,7 @@ export const GENRE = fasTheaterMasks;
export const GROUP = farObjectGroup;
export const HEALTH = fasMedkit;
export const HEART = fasHeart;
export const HEART_OUTLINE = farHeart;
export const HISTORY = fasHistory;
export const HOUSEKEEPING = fasHome;
export const IGNORE = fasTimesCircle;

View File

@@ -36,4 +36,5 @@ export type Kind =
| 'primary'
| 'purple'
| 'success'
| 'warning';
| 'warning'
| 'queue';

View File

@@ -0,0 +1,5 @@
.actions {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 70px;
}

View File

@@ -0,0 +1,7 @@
// This file is automatically generated.
// Please do not change this file!
interface CssExports {
'actions': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -0,0 +1,48 @@
import React, { SyntheticEvent, useCallback } from 'react';
import { useDispatch } from 'react-redux';
import IconButton from 'Components/Link/IconButton';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRowButton from 'Components/Table/TableRowButton';
import { icons } from 'Helpers/Props';
import { removeFavoriteFolder } from 'Store/Actions/interactiveImportActions';
import translate from 'Utilities/String/translate';
import styles from './FavoriteFolderRow.css';
interface FavoriteFolderRowProps {
folder: string;
onPress: (folder: string) => unknown;
}
function FavoriteFolderRow({ folder, onPress }: FavoriteFolderRowProps) {
const dispatch = useDispatch();
const handlePress = useCallback(() => {
onPress(folder);
}, [folder, onPress]);
const handleRemoveFavoritePress = useCallback(
(e: SyntheticEvent) => {
e.stopPropagation();
dispatch(removeFavoriteFolder({ folder }));
},
[folder, dispatch]
);
return (
<TableRowButton onPress={handlePress}>
<TableRowCell>{folder}</TableRowCell>
<TableRowCell className={styles.actions}>
<IconButton
title={translate('FavoriteFolderRemove')}
kind="danger"
name={icons.HEART}
onPress={handleRemoveFavoritePress}
/>
</TableRowCell>
</TableRowButton>
);
}
export default FavoriteFolderRow;

View File

@@ -1,7 +1,12 @@
.recentFoldersContainer {
.foldersContainer {
margin-top: 15px;
}
.foldersTitle {
border-bottom: 1px solid var(--borderColor);
font-size: 21px;
}
.buttonsContainer {
margin-top: 30px;
}

View File

@@ -5,7 +5,8 @@ interface CssExports {
'buttonContainer': string;
'buttonIcon': string;
'buttonsContainer': string;
'recentFoldersContainer': string;
'foldersContainer': string;
'foldersTitle': string;
}
export const cssExports: CssExports;
export default cssExports;

View File

@@ -1,4 +1,4 @@
import React, { useCallback, useState } from 'react';
import React, { useCallback, useMemo, useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
@@ -14,14 +14,23 @@ import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { icons, kinds, sizes } from 'Helpers/Props';
import { executeCommand } from 'Store/Actions/commandActions';
import {
addRecentFolder,
removeRecentFolder,
} from 'Store/Actions/interactiveImportActions';
import { addRecentFolder } from 'Store/Actions/interactiveImportActions';
import translate from 'Utilities/String/translate';
import FavoriteFolderRow from './FavoriteFolderRow';
import RecentFolderRow from './RecentFolderRow';
import styles from './InteractiveImportSelectFolderModalContent.css';
const favoriteFoldersColumns = [
{
name: 'folder',
label: () => translate('Folder'),
},
{
name: 'actions',
label: '',
},
];
const recentFoldersColumns = [
{
name: 'folder',
@@ -49,15 +58,22 @@ function InteractiveImportSelectFolderModalContent(
const { modalTitle, onFolderSelect, onModalClose } = props;
const [folder, setFolder] = useState('');
const dispatch = useDispatch();
const recentFolders = useSelector(
const { favoriteFolders, recentFolders } = useSelector(
createSelector(
(state: AppState) => state.interactiveImport.recentFolders,
(recentFolders) => {
return recentFolders;
(state: AppState) => state.interactiveImport,
(interactiveImport) => {
return {
favoriteFolders: interactiveImport.favoriteFolders,
recentFolders: interactiveImport.recentFolders,
};
}
)
);
const favoriteFolderMap = useMemo(() => {
return new Map(favoriteFolders.map((f) => [f.folder, f]));
}, [favoriteFolders]);
const onPathChange = useCallback(
({ value }: { value: string }) => {
setFolder(value);
@@ -90,13 +106,6 @@ function InteractiveImportSelectFolderModalContent(
onFolderSelect(folder);
}, [folder, onFolderSelect, dispatch]);
const onRemoveRecentFolderPress = useCallback(
(folderToRemove: string) => {
dispatch(removeRecentFolder({ folder: folderToRemove }));
},
[dispatch]
);
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
@@ -110,8 +119,34 @@ function InteractiveImportSelectFolderModalContent(
onChange={onPathChange}
/>
{favoriteFolders.length ? (
<div className={styles.foldersContainer}>
<div className={styles.foldersTitle}>
{translate('FavoriteFolders')}
</div>
<Table columns={favoriteFoldersColumns}>
<TableBody>
{favoriteFolders.map((favoriteFolder) => {
return (
<FavoriteFolderRow
key={favoriteFolder.folder}
folder={favoriteFolder.folder}
onPress={onRecentPathPress}
/>
);
})}
</TableBody>
</Table>
</div>
) : null}
{recentFolders.length ? (
<div className={styles.recentFoldersContainer}>
<div className={styles.foldersContainer}>
<div className={styles.foldersTitle}>
{translate('RecentFolders')}
</div>
<Table columns={recentFoldersColumns}>
<TableBody>
{recentFolders
@@ -123,8 +158,8 @@ function InteractiveImportSelectFolderModalContent(
key={recentFolder.folder}
folder={recentFolder.folder}
lastUsed={recentFolder.lastUsed}
isFavorite={favoriteFolderMap.has(recentFolder.folder)}
onPress={onRecentPathPress}
onRemoveRecentFolderPress={onRemoveRecentFolderPress}
/>
);
})}

View File

@@ -1,6 +0,0 @@
interface RecentFolder {
folder: string;
lastUsed: string;
}
export default RecentFolder;

View File

@@ -1,5 +1,5 @@
.actions {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 40px;
width: 70px;
}

View File

@@ -1,65 +0,0 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import IconButton from 'Components/Link/IconButton';
import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRowButton from 'Components/Table/TableRowButton';
import { icons } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './RecentFolderRow.css';
class RecentFolderRow extends Component {
//
// Listeners
onPress = () => {
this.props.onPress(this.props.folder);
};
onRemovePress = (event) => {
event.stopPropagation();
const {
folder,
onRemoveRecentFolderPress
} = this.props;
onRemoveRecentFolderPress(folder);
};
//
// Render
render() {
const {
folder,
lastUsed
} = this.props;
return (
<TableRowButton onPress={this.onPress}>
<TableRowCell>{folder}</TableRowCell>
<RelativeDateCell date={lastUsed} />
<TableRowCell className={styles.actions}>
<IconButton
title={translate('Remove')}
name={icons.REMOVE}
onPress={this.onRemovePress}
/>
</TableRowCell>
</TableRowButton>
);
}
}
RecentFolderRow.propTypes = {
folder: PropTypes.string.isRequired,
lastUsed: PropTypes.string.isRequired,
onPress: PropTypes.func.isRequired,
onRemoveRecentFolderPress: PropTypes.func.isRequired
};
export default RecentFolderRow;

View File

@@ -0,0 +1,85 @@
import React, { SyntheticEvent, useCallback } from 'react';
import { useDispatch } from 'react-redux';
import IconButton from 'Components/Link/IconButton';
import RelativeDateCell from 'Components/Table/Cells/RelativeDateCell';
import TableRowCell from 'Components/Table/Cells/TableRowCell';
import TableRowButton from 'Components/Table/TableRowButton';
import { icons } from 'Helpers/Props';
import {
addFavoriteFolder,
removeFavoriteFolder,
removeRecentFolder,
} from 'Store/Actions/interactiveImportActions';
import translate from 'Utilities/String/translate';
import styles from './RecentFolderRow.css';
interface RecentFolderRowProps {
folder: string;
lastUsed: string;
isFavorite: boolean;
onPress: (folder: string) => unknown;
}
function RecentFolderRow({
folder,
lastUsed,
isFavorite,
onPress,
}: RecentFolderRowProps) {
const dispatch = useDispatch();
const handlePress = useCallback(() => {
onPress(folder);
}, [folder, onPress]);
const handleFavoritePress = useCallback(
(e: SyntheticEvent) => {
e.stopPropagation();
if (isFavorite) {
dispatch(removeFavoriteFolder({ folder }));
} else {
dispatch(addFavoriteFolder({ folder }));
}
},
[folder, isFavorite, dispatch]
);
const handleRemovePress = useCallback(
(e: SyntheticEvent) => {
e.stopPropagation();
dispatch(removeRecentFolder({ folder }));
},
[folder, dispatch]
);
return (
<TableRowButton onPress={handlePress}>
<TableRowCell>{folder}</TableRowCell>
<RelativeDateCell date={lastUsed} />
<TableRowCell className={styles.actions}>
<IconButton
title={
isFavorite
? translate('FavoriteFolderRemove')
: translate('FavoriteFolderAdd')
}
kind={isFavorite ? 'danger' : 'default'}
name={isFavorite ? icons.HEART : icons.HEART_OUTLINE}
onPress={handleFavoritePress}
/>
<IconButton
title={translate('Remove')}
name={icons.REMOVE}
onPress={handleRemovePress}
/>
</TableRowCell>
</TableRowButton>
);
}
export default RecentFolderRow;

View File

@@ -192,10 +192,9 @@ const importModeSelector = createSelector(
}
);
interface InteractiveImportModalContentProps {
export interface InteractiveImportModalContentProps {
downloadId?: string;
movieId?: number;
seasonNumber?: number;
showMovie?: boolean;
allowMovieChange?: boolean;
showDelete?: boolean;
@@ -217,7 +216,6 @@ function InteractiveImportModalContent(
const {
downloadId,
movieId,
seasonNumber,
allowMovieChange = true,
showMovie = true,
showFilterExistingFiles = false,
@@ -343,7 +341,6 @@ function InteractiveImportModalContent(
fetchInteractiveImportItems({
downloadId,
movieId,
seasonNumber,
folder,
filterExistingFiles,
})

View File

@@ -24,6 +24,7 @@ import {
reprocessInteractiveImportItems,
updateInteractiveImportItem,
} from 'Store/Actions/interactiveImportActions';
import CustomFormat from 'typings/CustomFormat';
import { SelectStateInputProps } from 'typings/props';
import Rejection from 'typings/Rejection';
import formatBytes from 'Utilities/Number/formatBytes';
@@ -52,7 +53,7 @@ interface InteractiveImportRowProps {
quality?: QualityModel;
languages?: Language[];
size: number;
customFormats?: object[];
customFormats?: CustomFormat[];
customFormatScore?: number;
indexerFlags: number;
rejections: Rejection[];

View File

@@ -2,6 +2,7 @@ import ModelBase from 'App/ModelBase';
import Language from 'Language/Language';
import Movie from 'Movie/Movie';
import { QualityModel } from 'Quality/Quality';
import CustomFormat from 'typings/CustomFormat';
import Rejection from 'typings/Rejection';
export interface InteractiveImportCommandOptions {
@@ -27,7 +28,7 @@ interface InteractiveImport extends ModelBase {
languages: Language[];
movie?: Movie;
qualityWeight: number;
customFormats: object[];
customFormats: CustomFormat[];
indexerFlags: number;
rejections: Rejection[];
movieFileId?: number;

View File

@@ -4,9 +4,12 @@ import usePrevious from 'Helpers/Hooks/usePrevious';
import { sizes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import InteractiveImportSelectFolderModalContent from './Folder/InteractiveImportSelectFolderModalContent';
import InteractiveImportModalContent from './Interactive/InteractiveImportModalContent';
import InteractiveImportModalContent, {
InteractiveImportModalContentProps,
} from './Interactive/InteractiveImportModalContent';
interface InteractiveImportModalProps {
interface InteractiveImportModalProps
extends Omit<InteractiveImportModalContentProps, 'modalTitle'> {
isOpen: boolean;
folder?: string;
downloadId?: string;

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