1
0
mirror of https://github.com/Sonarr/Sonarr.git synced 2026-03-05 13:20:20 -05:00

Compare commits

...

297 Commits

Author SHA1 Message Date
Weblate
578f95546b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: marudosurdo <marudosurdo@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ja/
Translation: Servarr/Sonarr
2024-07-24 21:34:30 -07:00
ManiMatter
9a613afa35 Treat forcedMetaDL from qBit as queued instead of downloading 2024-07-25 00:33:08 -04:00
Mark McDowall
5ad3d2efcc Fixed: Don't treat SubFrench as French audio language
Closes #6995
2024-07-24 21:32:18 -07:00
Bogdan
1ad722acda Fixed: Improve performance in Select Series Modal 2024-07-25 00:32:09 -04:00
Bogdan
bde5f68142 Refresh series with recently aired episodes with TBA titles
Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com>
2024-07-24 21:31:46 -07:00
Bogdan
fbda2d54c7 New: Display original language on series details and search results page
Closes #6984
2024-07-25 00:31:29 -04:00
Bogdan
2a26c6722a New: Ignore Litestream tables in Database 2024-07-25 00:30:56 -04:00
Bogdan
b7dfb8999d Improve tooltip for Next Airing on series Overview 2024-07-24 21:30:27 -07:00
Bogdan
1662521d40 Fixed: Display tag list when sort by tags on series Posters 2024-07-24 21:30:27 -07:00
Weblate
f8d75d174a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dream <seth.gecko.rr@gmail.com>
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/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-07-24 21:30:00 -07:00
Bogdan
80ca1a6ac2 Fixed: Editing Quality Profiles 2024-07-18 08:10:43 -07:00
Weblate
f59c0b16ca Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translation: Servarr/Sonarr
2024-07-16 21:42:50 -07:00
Mark McDowall
0e95ba2021 New: Allow major version updates to be installed 2024-07-16 21:39:49 -07:00
Mark McDowall
c023fc7008 New: Show update settings on all platforms 2024-07-16 21:39:49 -07:00
Mark McDowall
19466aa290 Fixed: Assume category path from qBittorent starting with '//' is a Windows UNC path
Radarr/Radarr#10162
2024-07-17 00:39:40 -04:00
Mark McDowall
4b5ef4907b Set default value for CustomColonReplacementFormat if not provided 2024-07-16 21:38:26 -07:00
Stevie Robinson
7b8d606a1b New: Wrap specifications in Custom Format and Auto Tagging modals 2024-07-17 00:38:15 -04:00
diamondpete
6a4824c029 Fixed: Remove apostrophe, backtick in contractions 2024-07-17 00:36:29 -04:00
Mark McDowall
1a1c8e6c08 New: Use natural sorting for lists of items in the UI
Closes #6955
2024-07-17 00:34:43 -04:00
Mark McDowall
e35b39b4b1 New: Add option to show tags on series Poster and Overview
Closes #6946
2024-07-16 21:34:25 -07:00
Mark McDowall
d3f14d5f5e Fixed: Parse Chinese anime formats with reverse title order 2024-07-16 21:34:11 -07:00
Mark McDowall
06936c4f22 Fixed: Parsing of Chinese anime with ordinal number in English title 2024-07-16 21:34:11 -07:00
Mark McDowall
0a28ff84e8 Fixed: Parsing of anime with 3 digit number in middle of title 2024-07-16 21:34:11 -07:00
Bogdan
703dee9383 New: Rating votes tooltip and series filter 2024-07-16 21:33:49 -07:00
Marc Carbonell
dca5239420 Remove extraneous indentation in RemoveFileExtension 2024-07-17 00:33:34 -04:00
Mark McDowall
1aaa9a14bc Bump version to 4.0.8 2024-07-15 21:36:26 -07:00
Weblate
c6c37a408a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translation: Servarr/Sonarr
2024-07-15 21:36:15 -07:00
Weblate
ae4a97b4ae Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dream <seth.gecko.rr@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translation: Servarr/Sonarr
2024-07-15 12:07:12 -07:00
Mark McDowall
3afae968eb Fixed: Import queue not processing after incomplete import 2024-07-15 12:03:53 -07:00
Mark McDowall
c01abbf3b5 Add 'On Import Complete' for Discord notifications 2024-07-15 12:03:31 -07:00
Mark McDowall
f5ccf98162 Rename 'On Upgrade' to 'On File Upgrade' 2024-07-15 12:03:31 -07:00
Mark McDowall
6afd3bd344 Bump version to 4.0.7 2024-07-14 16:44:07 -07:00
Weblate
acaf5cd353 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Rauniik <raunerjakub@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-07-14 16:43:56 -07:00
Sonarr
e97e5bfe8f Automated API Docs update
ignore-downstream
2024-07-09 22:22:48 -07:00
martylukyy
678872b879 Fixed: Parsing of some Web releases 2024-07-10 01:19:07 -04:00
Mark McDowall
10e9735c1c New: Update AutoTags on series update
Closes #6783
2024-07-10 01:02:23 -04:00
Mark McDowall
293a1bc618 New: Custom colon replacement option
Closes #6898
2024-07-10 01:02:04 -04:00
Bogdan
0c883f7886 Fixed: Removing pending release without blocklisting 2024-07-09 22:01:23 -07:00
Mark McDowall
46c7de379c New: Group updates for the same series for Kodi and Emby / Jellyfin 2024-07-09 22:00:57 -07:00
Mark McDowall
a83b521766 New: 'On Import Complete' notification when all episodes in a release are imported
Closes #363
2024-07-09 22:00:57 -07:00
Bogdan
1d06e40acb New: Queued episode count for seasons in series details 2024-07-09 21:59:41 -07:00
Weblate
bfcdc89f6a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Serhii Matrunchyk <serhii@digitalidea.studio>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/uk/
Translation: Servarr/Sonarr
2024-07-09 21:59:25 -07:00
Sonarr
67943edfbc Automated API Docs update
ignore-downstream
2024-07-05 16:35:21 -07:00
Mark McDowall
04f8595498 Custom Import List improvements
Fixed: Add placeholder title for Custom Import List title
New: Support 'title' property for Custom Import List
2024-07-05 16:35:08 -07:00
Bogdan
81ac73299a Fixed: Bulk series deletion for unmonitored series
Closes #6933
2024-07-05 19:34:56 -04:00
Mark McDowall
a779a5fad2 Fixed: Parsing of anime season releases with 3-digit number in title 2024-07-05 16:34:06 -07:00
Mark McDowall
bfe6a740fa Fixed: Parsing of anime releases using standard numbering
Closes #6925
2024-07-05 16:34:06 -07:00
Mark McDowall
c9ea40b874 New: Parse VFI as French
Closes #6927
2024-07-05 16:34:00 -07:00
Bogdan
4ee0ae1418 Fixed: History with unknown series 2024-07-05 16:33:50 -07:00
Bogdan
ac1da45ecd Fixed: Calculate Custom Formats after user specified options in Manual Import 2024-07-05 19:33:33 -04:00
Weblate
5c327d5be3 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: quek76 <quek@libertysurf.fr>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-07-05 16:31:56 -07:00
Mark McDowall
55c1ce2e3d Bump version to 4.0.6 2024-06-30 15:42:47 -07:00
Weblate
fd7f0ea973 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: Kshitij Burman <kburman6@gmail.com>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: damienmillet <contact@damien-millet.dev>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/hi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-06-30 15:42:41 -07:00
Bogdan
d5dff8e8d6 Fixed: Trimming disabled logs database
Closes #6918
2024-06-30 13:49:41 -04:00
Bogdan
8099ba10af Fixed: Already imported downloads appearing in Queue briefly 2024-06-30 13:47:00 -04:00
Mark McDowall
143ccb1e2a Remove seriesTitle from EpisodeResource
Closes #6841
2024-06-28 06:22:10 -07:00
Mark McDowall
29480d9544 Fixed: Don't use cleaned up release title for release title 2024-06-28 06:22:04 -07:00
Mark McDowall
6de536a7ad Fixed: Limit Queue maximum page size to 200
Closes #6899
2024-06-26 09:45:43 -07:00
Mark McDowall
bce848facf Fixed: Reprocessing items that were previously blocked during importing 2024-06-26 09:45:28 -07:00
Mark McDowall
ea4fe392a0 New: Remove websites in parentheses before parsing 2024-06-25 15:52:24 -07:00
Mark McDowall
45fe585944 Fixed: Prevent errors parsing releases in unexpected formats 2024-06-25 15:52:24 -07:00
Mark McDowall
a0d2933134 New: Ignore Deluge torrents without a title
Closes #6885
2024-06-25 18:52:12 -04:00
Mark McDowall
4c622fd412 New: Ability to select Plex Media Server from plex.tv
Closes #6887
2024-06-25 15:51:57 -07:00
Bogdan
fb060730c7 Fixed: Exclude invalid releases from Newznab and Torznab parsers 2024-06-25 15:51:41 -07:00
Mark McDowall
6d5ff9c4d6 New: Improve UI status when downloads cannot be imported automatically
Closes #6873
2024-06-25 18:51:20 -04:00
Mark McDowall
63bed3e670 New: Parse anime seasons with trailing number in title
Closes #6883
2024-06-25 15:51:03 -07:00
Weblate
e684c10432 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: MattiaPell <mattiapellegrini16@gmail.com>
Co-authored-by: Taylan Tatlı <taylantatli90@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-06-25 15:50:56 -07:00
Bogdan
d2509798e9 New: Display stats for delete multiple series modal 2024-06-17 20:40:04 -07:00
Bogdan
6c39855ebe Fix UpdatePackageProviderFixture for v4
ignore-downstream
2024-06-17 20:39:33 -07:00
Bogdan
a30e9da767 New: Ignore inaccessible folders when getting folders 2024-06-17 20:39:33 -07:00
Mark McDowall
f8e81396d4 Fixed: Importing from IMDb list 2024-06-17 20:39:22 -07:00
Mark McDowall
7fccf590a8 Fixed: Adding series with unknown items in queue 2024-06-17 23:39:13 -04:00
Stephan Sundermann
e1b937e8d5 New: Add TMDB ID support
Closes #6866
2024-06-17 23:38:41 -04:00
Bogdan
c331c8bd11 Ignore Grabbed from API docs
Run application in docs.sh specific to platform
2024-06-10 20:30:26 -07:00
Mark McDowall
52b72925f9 Fixed: Improve error messaging if config file isn't formatted correctly
Closes #6860
2024-06-10 20:30:13 -07:00
Mark McDowall
378fedcd9d Fixed: Skip invalid series paths during validation 2024-06-10 23:30:03 -04:00
Bogdan
a90ab1a8fd Fixed: Ignore case when resolving indexer by name in release push 2024-06-10 20:29:46 -07:00
Bogdan
0edc5ba99a Fixed: Ignore case for name validation in providers 2024-06-10 20:29:46 -07:00
Bogdan
ea54ade9bf New: Refresh cache for tracked queue on series add 2024-06-10 20:29:41 -07:00
Weblate
e07eb05e8b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: AlbertCoolGuy <Albert.rosenstand@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: xuzhihui <5894940@qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-06-10 20:29:28 -07:00
Bogdan
d9b771ab0b Fixed: Error sending Manual Interaction Required when series is unknown 2024-05-31 20:11:31 -04:00
Mark McDowall
6b08e849b8 Search for raw and clean titles for Newznab/Torznab indexers that support raw title searching 2024-05-31 17:10:32 -07:00
Mark McDowall
9c1f48ebc9 Fixed: Include full series title in episode search 2024-05-31 17:10:32 -07:00
Mark McDowall
fd3dd1ab7d New: Genres and Images for Webhooks and Notifiarr
Closes #6822
2024-05-31 17:10:13 -07:00
yammes08
11e5c5a11b Fixed: SDR Files Being Parsed As HLG 2024-05-31 20:09:53 -04:00
Weblate
48f0291884 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: r0bertreh <Robert.reh@live.de>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translation: Servarr/Sonarr
2024-05-31 17:09:11 -07:00
Mark McDowall
af0e55aef4 Bump version to 4.0.5 2024-05-29 16:23:16 -07:00
Weblate
39a439eb4c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Bao Trinh <servarr@baodtrinh.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
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>
Co-authored-by: mm519897405 <baiya@vip.qq.com>
Co-authored-by: thegamingcat13 <sandervanbeek2004@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/vi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-29 16:23:04 -07:00
Weblate
66940b283b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: mm519897405 <baiya@vip.qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-24 06:21:13 -07:00
Mark McDowall
2a662afaef Fixed: Time for episodes airing today being blank 2024-05-24 06:19:38 -07:00
Weblate
62a9c2519b Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: mm519897405 <baiya@vip.qq.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-22 20:09:18 -07:00
Mark McDowall
ca372bee25 Fixed: Queue and Calendar not loading 2024-05-22 20:07:31 -07:00
Sonarr
0904a0737e Automated API Docs update
ignore-downstream
2024-05-21 17:09:20 -07:00
Bogdan
70bc26dc19 Disable workflows on forks
ignore-downstream
2024-05-21 17:06:44 -07:00
Bogdan
a2e0002a08 Replace multiple occurrences in branch env variable
ignore-downstream
2024-05-21 17:06:44 -07:00
Bogdan
d7ceb11a64 Fixed: Trimming slashes from UrlBase when using environment variable 2024-05-21 17:06:44 -07:00
Bogdan
cc5b5463f2 Ignore Grabbed with STJson 2024-05-21 17:06:36 -07:00
Bogdan
9b4ff657af Update the wanted section for missing and cutoff unmet 2024-05-21 17:06:36 -07:00
Bogdan
aea50fa47e Bump Npgsql to 7.0.7
ignore-downstream
2024-05-21 17:06:28 -07:00
Mark McDowall
05edd44ed6 New: Include time for episode/season/series history 2024-05-21 17:06:18 -07:00
Bogdan
4440aa3cac New: Root folder exists validation for import lists 2024-05-21 17:06:09 -07:00
Bogdan
084fcc2295 Implement equality checks for providers 2024-05-21 17:05:48 -07:00
Weblate
536ff142c3 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Lizandra Candido da Silva <lizandra.c.s@gmail.com>
Co-authored-by: Ransack6086 <servarr.jubilant150@slmail.me>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Yi Cao <caoyi06@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: topnew <sznetim@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-05-21 17:05:34 -07:00
Mark McDowall
627b2a4289 New: Parse 480i Bluray/Remux as Bluray 480p
Closes #6801
2024-05-09 22:04:18 -07:00
Bogdan
9734c2d144 Fixed: Notifications with only On Rename enabled
ignore-downstream
2024-05-09 22:04:12 -07:00
Bogdan
c7c1e3ac9e Refactor PasswordInput to use type password 2024-05-09 22:04:04 -07:00
Bogdan
429444d085 Fixed: Text color for inputs on login page 2024-05-09 22:03:56 -07:00
Mark McDowall
5cb649e9d8 Fixed: Attempt to parse and reject ambiguous dates
Closes #6799
2024-05-09 22:03:44 -07:00
Mark McDowall
cac7d239ea Fixed: Parsing of partial season pack 2024-05-09 22:03:44 -07:00
Sonarr
3940059ea3 Automated API Docs update
ignore-downstream
2024-05-09 22:03:31 -07:00
Weblate
20d00fe88c Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Michael5564445 <michaelvelosk@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/uk/
Translation: Servarr/Sonarr
2024-05-09 22:03:24 -07:00
Mark McDowall
b4d05214ae Fixed: Ignore invalid movie tags when writing XBMC metadata
Co-authored-by: Bogdan <mynameisbogdan@users.noreply.github.com>
2024-05-08 18:45:19 -07:00
Mark McDowall
cc0a284660 New: Add series tags to Webhook and Notifiarr events 2024-05-08 18:45:19 -07:00
Mark McDowall
f50a263f4f New: Add Custom Format Score to file in Episode Details 2024-05-08 18:45:03 -07:00
Mark McDowall
29176c8367 New: Has Unmonitored Season filter for Series 2024-05-08 18:44:52 -07:00
Bogdan
1eddf3a152 Use number input for seed ratio 2024-05-08 18:44:36 -07:00
Bogdan
8360dd7a7b Fixed: Parsing long downloading/seeding values from Transmission 2024-05-08 18:44:27 -07:00
Bogdan
7e8d8500f2 Fixed: Next/previous/last air dates with Postgres DB
Closes #6790
2024-05-08 18:43:51 -07:00
Mark McDowall
cae134ec7b New: Dark theme for login screen
Closes #6751
2024-05-08 18:42:54 -07:00
Stevie Robinson
f81bb3ec19 New: Blocklist Custom Filters
Closes #6763
2024-05-08 18:42:41 -07:00
Bogdan
128309068d Fixed: Initialize databases after app folder migrations
Co-authored-by: Mark McDowall <mark@mcdowall.ca>
2024-05-08 18:42:15 -07:00
Mickaël Thomas
73a4bdea52 New: Support stoppedUP and stoppedDL states from qBittorrent 2024-05-08 18:41:59 -07:00
Bogdan
47ba002806 Fixed: Indexer flags for torrent release pushes 2024-05-04 18:56:52 -07:00
Mark McDowall
ba88185dea New: Treat batch releases with total episode count as full season release
Closes #6757
2024-05-04 18:56:15 -07:00
Mark McDowall
e24ce40eb8 Fixed: History with unknown episode
Closes #6782
2024-05-04 18:55:56 -07:00
Stevie Robinson
8be8c7f89c Add missing translation key 2024-05-04 18:55:44 -07:00
Bogdan
7166a6c019 Parameter binding for API requests 2024-05-04 18:55:12 -07:00
Mark McDowall
3fbe436138 Forward X-Forwarded-Host header
Closes #6764
2024-05-04 18:54:55 -07:00
Jared
92eab4b2e2 New: Config file setting to disable log database
Closes #6743
2024-05-04 18:54:42 -07:00
Mika
23c741fd00 Add file-count for Transmission RPC 2024-05-04 18:53:47 -07:00
Weblate
8ddf46113b 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: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-05-04 18:53:15 -07:00
Bogdan
c81ae65461 Fixed: Limit titles in task name to 10 series 2024-04-27 18:09:08 -07:00
Bogdan
efb3fa93e4 Fixed: Retrying download for pushed releases
ignore-downstream
#6752
2024-04-27 21:08:40 -04:00
Stevie Robinson
04bd535cfc New: Don't initially select 0 byte files in Interactive Import
Closes #6686
2024-04-27 21:07:41 -04:00
Bogdan
9738101042 Treat CorruptDatabaseException as a startup failure
ignore-downstream
2024-04-27 18:06:49 -07:00
Bogdan
1df7cdc65e New: Add KRaLiMaRKo and BluDragon to release group parsing exceptions
ignore-downstream
2024-04-27 18:06:38 -07:00
Jared
d051dac12c New: Optionally use Environment Variables for settings in config.xml
Closes #6744
2024-04-27 21:06:26 -04:00
Bogdan
5d01ecd30e Bump frontend dependencies
ignore-downstream
2024-04-27 18:05:16 -07:00
Mark McDowall
316b5cbf75 New: Validate that folders in paths don't start or end with a space
Closes #6709
2024-04-27 21:04:50 -04:00
Bogdan
2440672179 Bump SixLabors.ImageSharp to 3.1.4
ignore-downstream
2024-04-27 18:04:35 -07:00
Mark McDowall
a97fbcc40a Fixed: Improve paths longer than 256 on Windows failing to hardlink 2024-04-27 18:04:26 -07:00
Christopher
d738035fed New: Remove qBitorrent torrents that reach inactive seeding time 2024-04-27 21:04:16 -04:00
Mark McDowall
dc3e932102 macOS tests now run on arm64 2024-04-27 18:03:12 -07:00
Weblate
aded9d95f7 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Ano10 <arnaudthommeray+github@ik.me>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Mailme Dashite <mailmedashite@protonmail.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: aghus <aghus.m@outlook.com>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: maodun96 <435795439@qq.com>
Co-authored-by: toeiazarothis <patrickdealmeida89000@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-04-27 18:03:03 -07:00
Mark McDowall
b81c3ee4a8 Fix labeling config 2024-04-15 21:14:49 -07:00
Mark McDowall
cf6748a80c Fix merge conflict labeling 2024-04-15 21:14:49 -07:00
Sonarr
ef6cc7fa3a Automated API Docs update
ignore-downstream
2024-04-15 20:35:29 -07:00
Mark McDowall
f9b013a8bf New: Parse releases with multiple Ukranian audio tracks
Closes #6714
2024-04-15 20:25:41 -07:00
Bogdan
e966254462 Fixed: Re-testing edited providers will forcibly test them 2024-04-15 20:25:31 -07:00
Gauvino
016c4b353b Add merge conflict labeler 2024-04-15 23:25:13 -04:00
Uruk
d71c619f1a Update CI dependencies 2024-04-15 20:24:20 -07:00
Gauthier
6c232b062c New: Multi Language selection per indexer
Closes #2854
2024-04-15 23:24:05 -04:00
Josh McKinney
d6278fced4 Add dev container workspace
Allows the linting and style settings for the frontend to be applied even when you load the main repo as a workspace
2024-04-15 20:23:13 -07:00
Weblate
317ce39aa2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Altair <villagermd@outlook.com>
Co-authored-by: Fonkio <maxime.fabre10@gmail.com>
Co-authored-by: GkhnGRBZ <gkhn.gurbuz@hotmail.com>
Co-authored-by: Jacopo Luca Maria Latrofa <jacopo.latrofa@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-04-15 20:23:04 -07:00
Mark McDowall
941985f65b Bump version to 4.0.4 2024-04-13 10:05:01 -07:00
Mark McDowall
10daf97d81 Improve build step dependencies 2024-04-12 16:00:46 -07:00
Mark McDowall
6b08117d7d Improve release notes for main releases 2024-04-12 16:00:46 -07:00
Weblate
9afe1c4b3f Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: YSLG <1451164040@qq.com>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-04-12 16:00:37 -07:00
Mark McDowall
0fdbbd018c New: Parse absolute episode numbers within square brackets
Closes #6694
2024-04-12 16:00:16 -07:00
Sonarr
8a7b67c593 Automated API Docs update
ignore-downstream
2024-04-09 16:17:48 -07:00
Weblate
4b8afe3d33 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: myrad2267 <myrad2267@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-04-09 16:16:11 -07:00
Bogdan
476e7a7b94 Fixed: Changing Release Type in Manage Episodes
Closes #6706
2024-04-09 19:14:56 -04:00
Bogdan
1fcd2b492c Prevent multiple enumerations in Custom Formats token 2024-04-09 16:14:33 -07:00
Bogdan
1aef91041e New: Detect shfs mounts in disk space 2024-04-09 16:14:16 -07:00
Bogdan
fc06e51352 Fixed: Renaming episodes for a series
Closes #6640
2024-04-09 19:13:59 -04:00
Mark McDowall
f4c19a384b New: Auto tag series based on tags present/absent on series
Closes #6236
2024-04-09 16:13:30 -07:00
Josh McKinney
5061dc4b5e Add DevContainer, VSCode config and extensions.json 2024-04-09 19:12:58 -04:00
Mark McDowall
37863a8deb New: Option to prefix app name on Telegram notification titles 2024-04-09 19:12:20 -04:00
Mark McDowall
5c42935eb3 Fixed: Improve AniList testing with Media filters 2024-04-09 16:12:05 -07:00
Weblate
dac69445e4 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: Michael5564445 <michaelvelosk@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/uk/
Translation: Servarr/Sonarr
2024-04-05 23:13:02 -07:00
Qstick
aca10f6f4f Fixed: Skip move when source and destination are the same
ignore-downstream

Co-Authored-By: Colin Hebert <makkhdyn@gmail.com>
(cherry picked from commit 7a5ae56a96700f401726ac80b3031a25207d8f75)
2024-04-05 23:11:37 -07:00
Mark McDowall
74cdf01e49 New: Set 'Release Type' during Manual Import
Closes #6681
2024-04-06 02:11:17 -04:00
Mark McDowall
a169ebff2a Fixed: Sending ntfy.sh notifications with unicode characters
Closes #6679
2024-04-06 02:11:03 -04:00
fireph
7fc3bebc91 New: Footnote to indicate some renaming tokens support truncation 2024-04-06 02:10:42 -04:00
Till Krüss
e672996dbb Improve text for file deleted through UI/API 2024-04-06 02:09:55 -04:00
Stevie Robinson
238ba85f0a New: Informational text on Custom Formats modal 2024-04-06 02:08:57 -04:00
Cuki
1562d3bae3 Fixed: Use widely supported display mode for PWA 2024-04-06 02:08:08 -04:00
Jendrik Weise
7776ec9955 Reimport files imported prematurely during script import 2024-04-05 23:07:38 -07:00
Jendrik Weise
af5a681ab7 Fix ignoring title based on pre-rename episodefile 2024-04-05 23:07:38 -07:00
Jendrik Weise
0a7f3a12c2 Do not remove all extras when script importing 2024-04-05 23:07:38 -07:00
Jendrik Weise
2ef46e5b90 Fix incorrect subtitle copy regex 2024-04-05 23:07:38 -07:00
Mark McDowall
6003ca1696 Fixed: Deleted episodes not being unmonitored when series folder has been deleted
Closes #6678
2024-04-05 23:07:07 -07:00
Mark McDowall
0937ee6fef Fixed: Path parsing incorrectly treating series title as episode number 2024-04-05 23:06:56 -07:00
Mark McDowall
60ee7cc716 Fixed: Cleanse BHD RSS key in log files
Closes #6666
2024-04-06 02:06:35 -04:00
Mark McDowall
4e83820511 Bump version to 4.0.3 2024-03-31 21:52:19 -07:00
Sonarr
5a66b949cf Automated API Docs update
ignore-downstream
2024-03-31 21:43:33 -07:00
Weblate
f010f56290 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: 王锋 <17611382361@163.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-03-31 21:43:09 -07:00
Louis R
060b789bc6 Fixed: Exceptions when checking for routable IPv4 addresses 2024-03-28 01:31:28 -04:00
Bogdan
7353fe479d New: Allow HEAD requests to ping endpoint
Closes #6656
2024-03-28 01:30:45 -04:00
Alex Cortelyou
1ec1ce58e9 New: Add additional fields to Webhook Manual Interaction Required events 2024-03-28 01:30:21 -04:00
Stevie Robinson
35d0e6a6f8 Fixed: Handling torrents with relative path in rTorrent 2024-03-28 01:29:15 -04:00
Carlos Gustavo Sarmiento
588372fd95 Fixed: qBittorrent not correctly handling retention during testing 2024-03-28 01:28:41 -04:00
Bogdan
13c925b341 New: Advanced settings toggle in import list, notification and download client modals 2024-03-27 22:27:51 -07:00
iceypotato
1335efd487 New: My Anime List import list
Closes #5148
2024-03-27 22:27:34 -07:00
Mark McDowall
d338425951 Fixed: Use custom formats from import during rename 2024-03-27 22:27:25 -07:00
Mark McDowall
fc6494c569 Fixed: Task with removed series causing error 2024-03-27 22:27:14 -07:00
Weblate
c403b2cdd5 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Altair <villagermd@outlook.com>
Co-authored-by: Dani Talens <databio@gmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Stanislav <prekop3@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/sk/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-03-27 22:27:07 -07:00
Weblate
cf3d51bab2 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Casselluu <jack10193@163.com>
Co-authored-by: Gianmarco Novelli <rinogaetano94@live.it>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: MadaxDeLuXe <madaxdeluxe@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: infoaitek24 <info@aitekph.com>
Co-authored-by: reloxx <reloxx@interia.pl>
Co-authored-by: shimmyx <shimmygodx@gmail.com>
Co-authored-by: vfaergestad <vgf@hotmail.no>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nb_NO/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-03-21 21:21:30 -07:00
Mark McDowall
dec3fc6889 Fixed: Don't add series from import list with no matched TVDB ID 2024-03-22 00:21:04 -04:00
Mark McDowall
40bac23698 New: Support parsing season number from season folder when importing
Closes #903
2024-03-21 21:20:49 -07:00
Mark McDowall
88de927435 Fixed: Plex Watchlist import list 2024-03-21 21:20:27 -07:00
Mark McDowall
29204c93a3 New: Parsing multi-episode file with two and three digit episode numbers
Closes #6631
2024-03-21 21:20:13 -07:00
Mark McDowall
c641733781 Fixed: Task progress messages in the UI
Closes #6632
2024-03-21 21:20:08 -07:00
Weblate
58de0310fd Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Gianmarco Novelli <rinogaetano94@live.it>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: MadaxDeLuXe <madaxdeluxe@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: infoaitek24 <info@aitekph.com>
Co-authored-by: reloxx <reloxx@interia.pl>
Co-authored-by: vfaergestad <vgf@hotmail.no>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nb_NO/
Translation: Servarr/Sonarr
2024-03-21 21:20:01 -07:00
Bogdan
172b1a82d1 Sort series by title in task name 2024-03-21 21:19:23 -07:00
Bogdan
e14568adef Ensure not allowed cursor is shown for disabled select inputs 2024-03-21 21:19:23 -07:00
Weblate
381ce61aef Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Dennis Langthjem <dennis@langthjem.dk>
Co-authored-by: DimitriDR <dimitridroeck@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Ihor Mudryi <mudryy33@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/da/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/uk/
Translation: Servarr/Sonarr
2024-03-13 21:49:22 -07:00
Mark McDowall
9f705e4161 Fixed: Release push with only Magnet URL
Closes #6622
2024-03-13 21:47:50 -07:00
Mark McDowall
063dba22a8 Fixed: Disabled select option still selectable 2024-03-13 21:47:33 -07:00
Mark McDowall
6d552f2a60 New: Show Series title and season number after task name when applicable
Closes #6601
2024-03-13 21:47:22 -07:00
Mark McDowall
4d4d63921b Add notification for build success/failures 2024-03-14 00:47:01 -04:00
Alan Collins
6584d95331 New: Update Custom Format renaming token to allow excluding specific formats
Closes #6615
2024-03-14 00:46:33 -04:00
Bogdan
86034beccd Bump ImageSharp, Polly, DryIoc, STJson, WindowsServices 2024-03-13 21:44:23 -07:00
Mark McDowall
4aa56e3f91 Fixed: Parsing of some French and Spanish anime releases 2024-03-13 21:44:07 -07:00
Stevie Robinson
2ec071a5ec Update release profile download client warning 2024-03-09 23:54:21 -05:00
Alan Collins
d86aeb7472 New: Release Hash renaming token
Closes #6570
2024-03-09 23:54:06 -05:00
Alan Collins
48cb5d2271 New: 'Custom Format: Format Name' rename token 2024-03-09 23:53:02 -05:00
bakerboy448
a0329adeba Improve single file detected as full season messaging 2024-03-09 23:51:29 -05:00
Bogdan
89bef4af99 New: Wider modal for Interactive Search and Manual Import 2024-03-09 23:50:45 -05:00
Mark McDowall
a12cdb34bc Fixed: Error sending Manual Interaction Required notification 2024-03-07 18:11:36 -08:00
Bogdan
13e29bd257 Prevent NullRef in naming when truncating a null Release Group 2024-03-07 18:11:28 -08:00
Sonarr
61a7515041 Automated API Docs update
ignore-downstream
2024-03-07 17:34:04 -08:00
Weblate
2c25245860 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Jason54 <jason54700.jg@gmail.com>
Co-authored-by: Mark Martines <mark-martines@hotmail.com>
Co-authored-by: Maxence Winandy <maxence.winandy@gmail.com>
Co-authored-by: Stevie Robinson <stevie.robinson@gmail.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: linkin931 <931linkin@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ca/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/cs/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/el/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ko/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ro/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-03-07 17:30:56 -08:00
Bogdan
18aadb544e Fixed: Maintain release type for items in Manual Import 2024-03-07 20:30:20 -05:00
Helvio Pedreschi
c7dd7abf89 Fixed: WebApp functionality on Apple devices 2024-03-07 20:29:50 -05:00
CheAle14
d0e9504af0 Fix import list exclusion props 2024-03-07 17:26:29 -08:00
Bogdan
e81bb3b993 Persist page size for Import List Exclusions 2024-03-07 17:25:27 -08:00
Bogdan
f211433b77 Remove debugger from metadata source and rearrange some imports 2024-03-07 17:25:19 -08:00
Bogdan
2068c5393e Fixed: URL Base setting for Kodi connections 2024-03-07 17:25:19 -08:00
Mark McDowall
0183812cc5 Fixed: Overly aggressive exception release group parsing
Closes #6591
2024-03-07 17:25:10 -08:00
Bogdan
7f09903a06 New: Episode Requested filter for Interactive Search 2024-03-02 21:26:23 -08:00
Mark McDowall
fa4c11a943 New: Do not automatically unmonitor episodes renamed outside of Sonarr
Closes #6584
2024-03-02 21:23:27 -08:00
Sonarr
653963a247 Automated API Docs update
ignore-downstream
2024-03-02 21:22:27 -08:00
Mark McDowall
32c32e2f88 Fixed: Issue extracting subtitle information for unknown episodes 2024-03-02 21:22:15 -08:00
nopoz
07bd159436 New: Add download directory & move completed for Deluge
Closes #4575
2024-03-03 00:22:03 -05:00
Mark McDowall
20273b07ad Properly type validation errors/warnings 2024-03-02 21:21:24 -08:00
bakerboy448
e5f19f01fa Update AddSeries Messaging and Logging 2024-03-03 00:21:16 -05:00
Louis R
13af6f5779 Fixed: Don't disable IPv6 in IPv6-only Environment
Closes #6545
2024-03-03 00:20:36 -05:00
Mark McDowall
71c2c0570b Renamed SeasonPackSpecification to ReleaseTypeSpecification 2024-03-03 00:19:44 -05:00
Mark McDowall
64c6a8879b Queue Manual Import commands at high priority 2024-03-02 21:19:26 -08:00
Weblate
7f061a9583 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: Nicolò Castagnola <nipica@outlook.it>
Co-authored-by: Weblate <noreply@weblate.org>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/de/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translation: Servarr/Sonarr
2024-03-02 21:19:17 -08:00
The Dark
4285691064 New: Import list exclusion pagination
Closes #6079
2024-03-03 00:19:02 -05:00
Sonarr
de9899c60e Automated API Docs update
ignore-downstream
2024-03-01 17:33:41 -08:00
Weblate
6c8758c27a Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: fordas <fordas15@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translation: Servarr/Sonarr
2024-03-01 17:32:55 -08:00
Mark McDowall
086d3b5afa Increase migration timeout to 5 minutes 2024-03-01 17:26:26 -08:00
Mark McDowall
f8a0751775 New: Release Type (Single/Multi episode and Season Pack) for Custom Formats
Closes #3562
2024-03-01 17:26:26 -08:00
Mark McDowall
c99d81e79b New: Bypass archived history for failed downloads in SABnzbd 2024-03-01 17:26:10 -08:00
Mark McDowall
9fd193d2a8 New: URL Base setting for Media Server connections
Closes #4416
2024-03-01 17:24:52 -08:00
Bogdan
64f4365fe9 Update caniuse-lite 2024-03-01 17:24:41 -08:00
Bogdan
2773f77e1c New: Options button for Missing/Cutoff Unmet 2024-03-01 17:24:41 -08:00
Weblate
0a84b4a8e9 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-03-01 17:24:35 -08:00
Weblate
236d8e4c50 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-02-27 20:44:11 -08:00
Mark McDowall
16d3827dbd Fixed: Processing updated episodes in series after refresh
Closes #6560
2024-02-27 20:42:27 -08:00
Bogdan
fa600e62e0 Fixed: Error when download client information is unavailable for Manual Interaction Required event
Closes #6558
(cherry picked from commit 173b1d6a4c0f2125c4413c0c09b269d87a1f1ee8)

Co-authored-by: Qstick <qstick@gmail.com>
2024-02-27 23:42:08 -05:00
Mark McDowall
fb6fc568c5 Fixed: Don't store seasons from import list items in database
Closes #6555
2024-02-27 20:40:39 -08:00
Bogdan
1f97679868 Fixed: Selection of last added custom filter
Plus some translations and typos
2024-02-27 20:40:33 -08:00
Mark McDowall
b34e0f8259 Fixed: Ignore language in split episode title 2024-02-27 00:33:07 -05:00
Mark McDowall
4c170d0452 New: Update anime episodes by season/episode number instead of absolute episode number
Closes #6547
2024-02-26 21:32:46 -08:00
Mark McDowall
6dc0a88004 New: Search for recently aired anime episodes with added absolute episode number
Closes #2044
2024-02-26 21:32:46 -08:00
Mark McDowall
33b44a8a53 New: Option to sync season monitoring state when importing from another Sonarr instance
Closes #6542
2024-02-26 21:32:39 -08:00
Mark McDowall
cb72e752f9 Fixed: Parsing of subtitle languages separated by dash
Closes #6494
2024-02-27 00:32:31 -05:00
Weblate
a11ee7bc11 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: EDUYO <eduardoestabiel@gmail.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Magyar <kochnorbert@icloud.com>
Co-authored-by: Sadi A. Nogueira <contato@sadi.eti.br>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: Xupix <colinaubert25@gmail.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translation: Servarr/Sonarr
2024-02-26 21:32:04 -08:00
Stevie Robinson
98d60e1a8e Replace URLs in translations with tokens 2024-02-27 00:30:58 -05:00
Bruno Garcia
6377c688fc Update Sentry SDK add features
Co-authored-by: Stefan Jandl <reg@bitfox.at>
2024-02-27 00:30:32 -05:00
Mark McDowall
7a37f130f9 Bump version to 4.0.2 2024-02-26 20:54:08 -08:00
Mark McDowall
724dd7e733 Clean branch name to remove slashes 2024-02-20 21:23:52 -08:00
Weblate
e1be3b20e9 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: 闫锦彪 <yanjinbiaohere@163.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-02-20 20:20:43 -08:00
Sonarr
2f041f9ec1 Automated API Docs update
ignore-downstream
2024-02-20 20:20:28 -08:00
Mark McDowall
f10ccf587d Don't fail fast for integration tests 2024-02-20 20:12:57 -08:00
Mark McDowall
0242b40eda Use GitHubActionsTestLogger for test reporting 2024-02-20 20:12:57 -08:00
Bogdan
7a768b5d0f New: Indexer flags
Closes #2782
2024-02-20 23:12:45 -05:00
Mark McDowall
a57254640f Upgrade actions/setup-dotnet to v4 2024-02-20 20:10:36 -08:00
Mark McDowall
1a6f45bafd Upgrade actions/checkout to v4 2024-02-20 20:10:36 -08:00
Mark McDowall
c6071f6d81 Upgrade node to 20.11.1 2024-02-20 20:10:36 -08:00
Bogdan
2a47a237d4 Fix typo in log message matching by TVRage ID 2024-02-20 20:10:30 -08:00
Mark McDowall
a7607ac7d6 Fixed: Only match via TV Rage ID if TheTVDB ID is not available
Closes #6517
2024-02-20 20:10:17 -08:00
Mark McDowall
43797b326d New: Parse releases with season and episode numbers separated by a period
Closes #6492
2024-02-20 20:10:09 -08:00
Mark McDowall
5c4f829993 Fixed: Multi-word genres in Auto Tags
Fixed #6488
2024-02-20 20:10:02 -08:00
Bogdan
8dd8c95f36 Fixed: Avoid upgrades for custom formats cut-off already met 2024-02-20 20:09:52 -08:00
Weblate
6f6036a199 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: Chaoshuai Lü <lcs@meta.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Magyar <kochnorbert@icloud.com>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: fordas <fordas15@gmail.com>
Co-authored-by: wgwqd <wgwqd@163.com>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-02-20 20:08:04 -08:00
Mark McDowall
625e500132 Use 'paths-ignore' instead of 'path' with only negative matches 2024-02-17 22:39:18 -08:00
Weblate
39575b1248 Multiple Translations updated by Weblate
ignore-downstream

Co-authored-by: David13467 <davidnow00@gmail.com>
Co-authored-by: Fixer <ygj59783@zslsz.com>
Co-authored-by: Havok Dan <havokdan@yahoo.com.br>
Co-authored-by: Hicabi Erdem <bilgi@hicabierdem.com>
Co-authored-by: Lucas <sixagag973@fkcod.com>
Co-authored-by: Magyar <kochnorbert@icloud.com>
Co-authored-by: Oskari Lavinto <olavinto@protonmail.com>
Co-authored-by: Steve Hansen <steve@hansenconsultancy.be>
Co-authored-by: Weblate <noreply@weblate.org>
Co-authored-by: aghus <aghus.m@outlook.com>
Co-authored-by: bai0012 <baicongrui@gmail.com>
Co-authored-by: bogdan-rgb <b.hmelniczky@yandex.ru>
Co-authored-by: savin-msk <ns@a77.io>
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/es/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fi/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/fr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/hu/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/it/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/nl/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/pt_BR/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/ru/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/tr/
Translate-URL: https://translate.servarr.com/projects/servarr/sonarr/zh_CN/
Translation: Servarr/Sonarr
2024-02-13 16:56:10 -08:00
abcasada
f1d343218c Hints for week column and short dates in UI settings
(cherry picked from commit 4558f552820b52bb1f9cd97fdabe03654ce9924a)
2024-02-13 16:47:48 -08:00
Qstick
b0829d5537 Fixed: Correctly persist calendar custom filter selection
ignore-downstream
2024-02-13 16:47:41 -08:00
Bogdan
965e7c22d9 Fixed: Reprocessing multi-language file in Manage Episodes 2024-02-13 16:47:31 -08:00
Bogdan
75535e61d9 Fixed: Reprocessing custom formats for file in Manual Import 2024-02-13 16:47:31 -08:00
Bogdan
c0b17d9345 Show download client ID as hint in select options 2024-02-13 16:46:55 -08:00
Bogdan
84e657482d Improve messaging on indexer specified download client is not available 2024-02-13 16:46:55 -08:00
Bogdan
ed27bcf213 Fixed: Refresh tags state to clear removed tags by housekeeping
(cherry picked from commit 2510f44c25bee6fede27d9fa2b9614176d12cb55)
2024-02-13 16:46:46 -08:00
Bogdan
9ee2fe6f5c Fix typo 2024-02-13 16:46:38 -08:00
Bogdan
d5e19b8c3c Prevent useless builds 2024-02-13 16:46:38 -08:00
Sonarr
2957b40512 Automated API Docs update
ignore-downstream
2024-02-13 16:46:26 -08:00
Bogdan
9f46fc923d Fix typo for Downloaded Episodes Scan command name 2024-02-13 16:46:02 -08:00
Bogdan
7dc1e47504 Fix translation token for DL client directory help text 2024-02-13 16:46:02 -08:00
Bogdan
d15c116f13 Fix translation keys for indexer validation 2024-02-13 16:46:02 -08:00
Bogdan
dd704579df Improve add/loading error notices 2024-02-13 16:46:02 -08:00
Bogdan
bd9d4b484c Update Custom Format Deletion confirmation message
Consistency with the rest of the Delete*MessageText
2024-02-13 16:46:02 -08:00
725 changed files with 19226 additions and 6537 deletions

View File

@@ -0,0 +1,13 @@
// This file is used to open the backend and frontend in the same workspace, which is necessary as
// the frontend has vscode settings that are distinct from the backend
{
"folders": [
{
"path": ".."
},
{
"path": "../frontend"
}
],
"settings": {}
}

View File

@@ -0,0 +1,19 @@
// For format details, see https://aka.ms/devcontainer.json. For config options, see the
// README at: https://github.com/devcontainers/templates/tree/main/src/dotnet
{
"name": "Sonarr",
"image": "mcr.microsoft.com/devcontainers/dotnet:1-6.0",
"features": {
"ghcr.io/devcontainers/features/node:1": {
"nodeGypDependencies": true,
"version": "16",
"nvmVersion": "latest"
}
},
"forwardPorts": [8989],
"customizations": {
"vscode": {
"extensions": ["esbenp.prettier-vscode"]
}
}
}

View File

@@ -27,7 +27,7 @@ runs:
using: 'composite'
steps:
- name: Setup .NET
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
- name: Setup Postgres
if: ${{ inputs.use_postgres }}
@@ -77,7 +77,7 @@ runs:
- name: Run tests
shell: bash
run: dotnet test ./_tests/Sonarr.*.Test.dll --filter "${{ inputs.filter }}" --logger "trx;LogFileName=${{ env.RESULTS_NAME }}.trx"
run: dotnet test ./_tests/Sonarr.*.Test.dll --filter "${{ inputs.filter }}" --logger "trx;LogFileName=${{ env.RESULTS_NAME }}.trx" --logger "GitHubActions;summary.includePassedTests=true;summary.includeSkippedTests=true"
- name: Upload Test Results
if: ${{ !cancelled() }}
@@ -85,12 +85,3 @@ runs:
with:
name: results-${{ env.RESULTS_NAME }}
path: TestResults/*.trx
- name: Publish Test Results
uses: phoenix-actions/test-reporting@v12
with:
name: Test Results
output-to: step-summary
path: '*.trx'
reporter: dotnet-trx
working-directory: TestResults

12
.github/dependabot.yml vendored Normal file
View File

@@ -0,0 +1,12 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for more information:
# https://docs.github.com/github/administering-a-repository/configuration-options-for-dependency-updates
# https://containers.dev/guide/dependabot
version: 2
updates:
- package-ecosystem: "devcontainers"
directory: "/"
schedule:
interval: weekly

18
.github/labeler.yml vendored
View File

@@ -1,17 +1,23 @@
'connection':
- src/NzbDrone.Core/Notifications/**/*
- changed-files:
- any-glob-to-any-file: src/NzbDrone.Core/Notifications/**/*
'db-migration':
- src/NzbDrone.Core/Datastore/Migration/*
- changed-files:
- any-glob-to-any-file: src/NzbDrone.Core/Datastore/Migration/*
'download-client':
- src/NzbDrone.Core/Download/Clients/**/*
- changed-files:
- any-glob-to-any-file: src/NzbDrone.Core/Download/Clients/**/*
'indexer':
- src/NzbDrone.Core/Indexers/**/*
- changed-files:
- any-glob-to-any-file: src/NzbDrone.Core/Indexers/**/*
'parsing':
- src/NzbDrone.Core/Parser/**/*
- changed-files:
- any-glob-to-any-file: src/NzbDrone.Core/Parser/**/*
'ui-only':
- all: ['frontend/**/*']
- changed-files:
- any-glob-to-all-files: frontend/**/*

View File

@@ -26,10 +26,10 @@ jobs:
permissions:
contents: write
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@v4
- name: Setup dotnet
uses: actions/setup-dotnet@v3
uses: actions/setup-dotnet@v4
id: setup-dotnet
- name: Create openapi.json

View File

@@ -5,9 +5,14 @@ on:
branches:
- develop
- main
paths-ignore:
- "src/Sonarr.Api.*/openapi.json"
pull_request:
branches:
- develop
paths-ignore:
- "src/NzbDrone.Core/Localization/Core/**"
- "src/Sonarr.Api.*/openapi.json"
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
@@ -15,9 +20,9 @@ concurrency:
env:
FRAMEWORK: net6.0
BRANCH: ${{ github.head_ref || github.ref_name }}
RAW_BRANCH_NAME: ${{ github.head_ref || github.ref_name }}
SONARR_MAJOR_VERSION: 4
VERSION: 4.0.1
VERSION: 4.0.8
jobs:
backend:
@@ -27,103 +32,105 @@ jobs:
major_version: ${{ steps.variables.outputs.major_version }}
version: ${{ steps.variables.outputs.version }}
steps:
- name: Check out
uses: actions/checkout@v3
- name: Check out
uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v3
- name: Setup .NET
uses: actions/setup-dotnet@v4
- name: Setup Environment Variables
id: variables
shell: bash
run: |
# Add 800 to the build number because GitHub won't let us pick an arbitrary starting point
SONARR_VERSION="${{ env.VERSION }}.$((${{ github.run_number }}+800))"
DOTNET_VERSION=$(jq -r '.sdk.version' global.json)
- name: Setup Environment Variables
id: variables
shell: bash
run: |
# Add 800 to the build number because GitHub won't let us pick an arbitrary starting point
SONARR_VERSION="${{ env.VERSION }}.$((${{ github.run_number }}+800))"
DOTNET_VERSION=$(jq -r '.sdk.version' global.json)
echo "SDK_PATH=${{ env.DOTNET_ROOT }}/sdk/${DOTNET_VERSION}" >> "$GITHUB_ENV"
echo "SONARR_VERSION=$SONARR_VERSION" >> "$GITHUB_ENV"
echo "framework=${{ env.FRAMEWORK }}" >> "$GITHUB_OUTPUT"
echo "major_version=${{ env.SONARR_MAJOR_VERSION }}" >> "$GITHUB_OUTPUT"
echo "version=$SONARR_VERSION" >> "$GITHUB_OUTPUT"
echo "SDK_PATH=${{ env.DOTNET_ROOT }}/sdk/${DOTNET_VERSION}" >> "$GITHUB_ENV"
echo "SONARR_VERSION=$SONARR_VERSION" >> "$GITHUB_ENV"
echo "BRANCH=${RAW_BRANCH_NAME//\//-}" >> "$GITHUB_ENV"
- name: Enable Extra Platforms In SDK
shell: bash
run: ./build.sh --enable-extra-platforms-in-sdk
echo "framework=${{ env.FRAMEWORK }}" >> "$GITHUB_OUTPUT"
echo "major_version=${{ env.SONARR_MAJOR_VERSION }}" >> "$GITHUB_OUTPUT"
echo "version=$SONARR_VERSION" >> "$GITHUB_OUTPUT"
- name: Build Backend
shell: bash
run: ./build.sh --backend --enable-extra-platforms --packages
- name: Enable Extra Platforms In SDK
shell: bash
run: ./build.sh --enable-extra-platforms-in-sdk
# Test Artifacts
- name: Build Backend
shell: bash
run: ./build.sh --backend --enable-extra-platforms --packages
- name: Publish win-x64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: win-x64
# Test Artifacts
- name: Publish linux-x64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: linux-x64
- name: Publish win-x64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: win-x64
- name: Publish osx-x64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: osx-x64
- name: Publish linux-x64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: linux-x64
# Build Artifacts (grouped by OS)
- name: Publish FreeBSD Artifact
uses: actions/upload-artifact@v4
with:
name: build_freebsd
path: _artifacts/freebsd-*/**/*
- name: Publish Linux Artifact
uses: actions/upload-artifact@v4
with:
name: build_linux
path: _artifacts/linux-*/**/*
- name: Publish macOS Artifact
uses: actions/upload-artifact@v4
with:
name: build_macos
path: _artifacts/osx-*/**/*
- name: Publish Windows Artifact
uses: actions/upload-artifact@v4
with:
name: build_windows
path: _artifacts/win-*/**/*
- name: Publish osx-arm64 Test Artifact
uses: ./.github/actions/publish-test-artifact
with:
framework: ${{ env.FRAMEWORK }}
runtime: osx-arm64
# Build Artifacts (grouped by OS)
- name: Publish FreeBSD Artifact
uses: actions/upload-artifact@v4
with:
name: build_freebsd
path: _artifacts/freebsd-*/**/*
- name: Publish Linux Artifact
uses: actions/upload-artifact@v4
with:
name: build_linux
path: _artifacts/linux-*/**/*
- name: Publish macOS Artifact
uses: actions/upload-artifact@v4
with:
name: build_macos
path: _artifacts/osx-*/**/*
- name: Publish Windows Artifact
uses: actions/upload-artifact@v4
with:
name: build_windows
path: _artifacts/win-*/**/*
frontend:
runs-on: ubuntu-latest
steps:
- name: Check out
uses: actions/checkout@v3
- name: Check out
uses: actions/checkout@v4
- name: Volta
uses: volta-cli/action@v4
- name: Volta
uses: volta-cli/action@v4
- name: Yarn Intsall
run: yarn install
- name: Yarn Install
run: yarn install
- name: Lint
run: yarn lint
- name: Lint
run: yarn lint
- name: Stylelint
run: yarn stylelint
- name: Stylelint
run: yarn stylelint -f github
- name: Build
run: yarn build --env production
- name: Build
run: yarn build --env production
- name: Publish UI Artifact
uses: actions/upload-artifact@v4
with:
name: build_ui
path: _output/UI/**/*
- name: Publish UI Artifact
uses: actions/upload-artifact@v4
with:
name: build_ui
path: _output/UI/**/*
unit_test:
needs: backend
@@ -136,43 +143,44 @@ jobs:
artifact: tests-linux-x64
filter: TestCategory!=ManualTest&TestCategory!=WINDOWS&TestCategory!=IntegrationTest&TestCategory!=AutomationTest
- os: macos-latest
artifact: tests-osx-x64
artifact: tests-osx-arm64
filter: TestCategory!=ManualTest&TestCategory!=WINDOWS&TestCategory!=IntegrationTest&TestCategory!=AutomationTest
- os: windows-latest
artifact: tests-win-x64
filter: TestCategory!=ManualTest&TestCategory!=LINUX&TestCategory!=IntegrationTest&TestCategory!=AutomationTest
runs-on: ${{ matrix.os }}
steps:
- name: Check out
uses: actions/checkout@v3
- name: Check out
uses: actions/checkout@v4
- name: Test
uses: ./.github/actions/test
with:
os: ${{ matrix.os }}
artifact: ${{ matrix.artifact }}
pattern: Sonarr.*.Test.dll
filter: ${{ matrix.filter }}
- name: Test
uses: ./.github/actions/test
with:
os: ${{ matrix.os }}
artifact: ${{ matrix.artifact }}
pattern: Sonarr.*.Test.dll
filter: ${{ matrix.filter }}
unit_test_postgres:
needs: backend
runs-on: ubuntu-latest
steps:
- name: Check out
uses: actions/checkout@v3
- name: Check out
uses: actions/checkout@v4
- name: Test
uses: ./.github/actions/test
with:
os: ubuntu-latest
artifact: tests-linux-x64
pattern: Sonarr.*.Test.dll
filter: TestCategory!=ManualTest&TestCategory!=WINDOWS&TestCategory!=IntegrationTest&TestCategory!=AutomationTest
use_postgres: true
- name: Test
uses: ./.github/actions/test
with:
os: ubuntu-latest
artifact: tests-linux-x64
pattern: Sonarr.*.Test.dll
filter: TestCategory!=ManualTest&TestCategory!=WINDOWS&TestCategory!=IntegrationTest&TestCategory!=AutomationTest
use_postgres: true
integration_test:
needs: backend
strategy:
fail-fast: false
matrix:
os: [ubuntu-latest, macos-latest, windows-latest]
include:
@@ -182,10 +190,10 @@ jobs:
binary_artifact: build_linux
binary_path: linux-x64/${{ needs.backend.outputs.framework }}/Sonarr
- os: macos-latest
artifact: tests-osx-x64
artifact: tests-osx-arm64
filter: TestCategory!=ManualTest&TestCategory!=WINDOWS&TestCategory=IntegrationTest
binary_artifact: build_macos
binary_path: osx-x64/${{ needs.backend.outputs.framework }}/Sonarr
binary_path: osx-arm64/${{ needs.backend.outputs.framework }}/Sonarr
- os: windows-latest
artifact: tests-win-x64
filter: TestCategory!=ManualTest&TestCategory!=LINUX&TestCategory=IntegrationTest
@@ -193,23 +201,23 @@ jobs:
binary_path: win-x64/${{ needs.backend.outputs.framework }}/Sonarr
runs-on: ${{ matrix.os }}
steps:
- name: Check out
uses: actions/checkout@v3
- name: Check out
uses: actions/checkout@v4
- name: Test
uses: ./.github/actions/test
with:
os: ${{ matrix.os }}
artifact: ${{ matrix.artifact }}
pattern: Sonarr.*.Test.dll
filter: ${{ matrix.filter }}
integration_tests: true
binary_artifact: ${{ matrix.binary_artifact }}
binary_path: ${{ matrix.binary_path }}
- name: Test
uses: ./.github/actions/test
with:
os: ${{ matrix.os }}
artifact: ${{ matrix.artifact }}
pattern: Sonarr.*.Test.dll
filter: ${{ matrix.filter }}
integration_tests: true
binary_artifact: ${{ matrix.binary_artifact }}
binary_path: ${{ matrix.binary_path }}
deploy:
if: ${{ github.ref_name == 'develop' || github.ref_name == 'main' }}
needs: [backend, unit_test, unit_test_postgres, integration_test]
needs: [backend, frontend, unit_test, unit_test_postgres, integration_test]
secrets: inherit
uses: ./.github/workflows/deploy.yml
with:
@@ -217,3 +225,33 @@ jobs:
branch: ${{ github.ref_name }}
major_version: ${{ needs.backend.outputs.major_version }}
version: ${{ needs.backend.outputs.version }}
notify:
name: Discord Notification
needs:
[
backend,
frontend,
unit_test,
unit_test_postgres,
integration_test,
deploy,
]
if: ${{ !cancelled() && (github.ref_name == 'develop' || github.ref_name == 'main') }}
env:
STATUS: ${{ contains(needs.*.result, 'failure') && 'failure' || 'success' }}
runs-on: ubuntu-latest
steps:
- name: Notify
uses: tsickert/discord-webhook@v6.0.0
with:
webhook-url: ${{ secrets.DISCORD_WEBHOOK_URL }}
username: "GitHub Actions"
avatar-url: "https://github.githubassets.com/images/modules/logos_page/GitHub-Mark.png"
embed-title: "${{ github.workflow }}: ${{ env.STATUS == 'success' && 'Success' || 'Failure' }}"
embed-url: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"
embed-description: |
**Branch** ${{ github.ref }}
**Build** ${{ needs.backend.outputs.version }}
embed-color: ${{ env.STATUS == 'success' && '3066993' || '15158332' }}

26
.github/workflows/conflict_labeler.yml vendored Normal file
View File

@@ -0,0 +1,26 @@
name: Merge Conflict Labeler
on:
push:
branches:
- develop
pull_request_target:
branches:
- develop
types: [synchronize]
jobs:
label:
name: Labeling
runs-on: ubuntu-latest
if: ${{ github.repository == 'Sonarr/Sonarr' }}
permissions:
contents: read
pull-requests: write
steps:
- name: Apply label
uses: eps1lon/actions-label-merge-conflict@v3
with:
dirtyLabel: 'merge-conflict'
repoToken: '${{ secrets.GITHUB_TOKEN }}'

View File

@@ -41,7 +41,7 @@ jobs:
runs-on: ${{ matrix.os }}
steps:
- name: Check out
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Package
uses: ./.github/actions/package
@@ -60,7 +60,7 @@ jobs:
contents: write
steps:
- name: Check out
uses: actions/checkout@v3
uses: actions/checkout@v4
- name: Download release artifacts
uses: actions/download-artifact@v4
@@ -69,12 +69,38 @@ jobs:
pattern: release_*
merge-multiple: true
- name: Get Previous Release
id: previous-release
uses: cardinalby/git-get-release-action@v1
env:
GITHUB_TOKEN: ${{ github.token }}
with:
latest: true
prerelease: ${{ inputs.branch != 'main' }}
- name: Generate Release Notes
id: generate-release-notes
uses: actions/github-script@v7
with:
github-token: ${{ github.token }}
result-encoding: string
script: |
const { data } = await github.rest.repos.generateReleaseNotes({
owner: context.repo.owner,
repo: context.repo.repo,
tag_name: 'v${{ inputs.version }}',
target_commitish: '${{ github.sha }}',
previous_tag_name: '${{ steps.previous-release.outputs.tag_name }}',
})
return data.body
- name: Create release
uses: ncipollo/release-action@v1
with:
artifacts: _artifacts/Sonarr.*
commit: ${{ github.sha }}
generateReleaseNotes: true
generateReleaseNotes: false
body: ${{ steps.generate-release-notes.outputs.result }}
name: ${{ inputs.version }}
prerelease: ${{ inputs.branch != 'main' }}
skipIfReleaseExists: true

View File

@@ -8,5 +8,6 @@ jobs:
contents: read
pull-requests: write
runs-on: ubuntu-latest
if: github.repository == 'Sonarr/Sonarr'
steps:
- uses: actions/labeler@v4
- uses: actions/labeler@v5

View File

@@ -8,14 +8,15 @@ on:
jobs:
lock:
runs-on: ubuntu-latest
if: github.repository == 'Sonarr/Sonarr'
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v5
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '90'
issue-exclude-created-before: ''
issue-exclude-labels: 'one-day-maybe'
issue-lock-labels: ''
issue-lock-comment: ''
issue-inactive-days: '90'
exclude-issue-created-before: ''
exclude-any-issue-labels: 'one-day-maybe'
add-issue-labels: ''
issue-comment: ''
issue-lock-reason: 'resolved'
process-only: ''

View File

@@ -1,41 +0,0 @@
name: Publish Test Results
on:
workflow_run:
workflows: ['Build']
types:
- completed
permissions:
contents: read
actions: read
checks: write
jobs:
report:
if: ${{ github.event.workflow_run.conclusion != 'skipped' && github.event.workflow_run.conclusion != 'cancelled' }}
runs-on: ubuntu-latest
steps:
- name: Check out
uses: actions/checkout@v3
- name: Download Test Reports
uses: actions/download-artifact@v4
with:
path: test-results
pattern: results-*
merge-multiple: true
repository: ${{ github.event.repository.owner.login }}/${{ github.event.repository.name }}
run-id: ${{ github.event.workflow_run.id }}
github-token: ${{ secrets.GITHUB_TOKEN }}
- name: Publish Test Results
uses: phoenix-actions/test-reporting@v12
with:
list-suites: failed
list-tests: failed
name: Test Results
only-summary: true
path: '*.trx'
reporter: dotnet-trx
working-directory: test-results

1
.gitignore vendored
View File

@@ -127,6 +127,7 @@ coverage*.xml
coverage*.json
setup/Output/
*.~is
.mono
#VS outout folders
bin

7
.vscode/extensions.json vendored Normal file
View File

@@ -0,0 +1,7 @@
{
"recommendations": [
"esbenp.prettier-vscode",
"ms-dotnettools.csdevkit",
"ms-vscode-remote.remote-containers"
]
}

26
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,26 @@
{
"version": "0.2.0",
"configurations": [
{
// Use IntelliSense to find out which attributes exist for C# debugging
// Use hover for the description of the existing attributes
// For further information visit https://github.com/dotnet/vscode-csharp/blob/main/debugger-launchjson.md
"name": "Run Sonarr",
"type": "coreclr",
"request": "launch",
"preLaunchTask": "build dotnet",
// If you have changed target frameworks, make sure to update the program path.
"program": "${workspaceFolder}/_output/net6.0/Sonarr",
"args": [],
"cwd": "${workspaceFolder}",
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
"console": "integratedTerminal",
"stopAtEntry": false
},
{
"name": ".NET Core Attach",
"type": "coreclr",
"request": "attach"
}
]
}

44
.vscode/tasks.json vendored Normal file
View File

@@ -0,0 +1,44 @@
{
"version": "2.0.0",
"tasks": [
{
"label": "build dotnet",
"command": "dotnet",
"type": "process",
"args": [
"msbuild",
"-restore",
"${workspaceFolder}/src/Sonarr.sln",
"-p:GenerateFullPaths=true",
"-p:Configuration=Debug",
"-p:Platform=Posix",
"-consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "publish",
"command": "dotnet",
"type": "process",
"args": [
"publish",
"${workspaceFolder}/src/Sonarr.sln",
"-property:GenerateFullPaths=true",
"-consoleloggerparameters:NoSummary;ForceNoAlign"
],
"problemMatcher": "$msCompile"
},
{
"label": "watch",
"command": "dotnet",
"type": "process",
"args": [
"watch",
"run",
"--project",
"${workspaceFolder}/src/Sonarr.sln"
],
"problemMatcher": "$msCompile"
}
]
}

12
docs.sh
View File

@@ -25,17 +25,23 @@ slnFile=src/Sonarr.sln
platform=Posix
if [ "$PLATFORM" = "Windows" ]; then
application=Sonarr.Console.dll
else
application=Sonarr.dll
fi
dotnet clean $slnFile -c Debug
dotnet clean $slnFile -c Release
dotnet msbuild -restore $slnFile -p:Configuration=Debug -p:Platform=$platform -p:RuntimeIdentifiers=$RUNTIME -t:PublishAllRids
dotnet new tool-manifest
dotnet tool install --version 6.5.0 Swashbuckle.AspNetCore.Cli
dotnet tool install --version 6.6.2 Swashbuckle.AspNetCore.Cli
dotnet tool run swagger tofile --output ./src/Sonarr.Api.V3/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/Sonarr.dll" v3 &
dotnet tool run swagger tofile --output ./src/Sonarr.Api.V3/openapi.json "$outputFolder/$FRAMEWORK/$RUNTIME/$application" v3 &
sleep 30
sleep 45
kill %1

View File

@@ -2,6 +2,7 @@ import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Alert from 'Components/Alert';
import LoadingIndicator from 'Components/Loading/LoadingIndicator';
import FilterMenu from 'Components/Menu/FilterMenu';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import PageContent from 'Components/Page/PageContent';
import PageContentBody from 'Components/Page/PageContentBody';
@@ -20,6 +21,7 @@ import getSelectedIds from 'Utilities/Table/getSelectedIds';
import removeOldSelectedState from 'Utilities/Table/removeOldSelectedState';
import selectAll from 'Utilities/Table/selectAll';
import toggleSelected from 'Utilities/Table/toggleSelected';
import BlocklistFilterModal from './BlocklistFilterModal';
import BlocklistRowConnector from './BlocklistRowConnector';
class Blocklist extends Component {
@@ -114,9 +116,13 @@ class Blocklist extends Component {
error,
items,
columns,
selectedFilterKey,
filters,
customFilters,
totalRecords,
isRemoving,
isClearingBlocklistExecuting,
onFilterSelect,
...otherProps
} = this.props;
@@ -161,6 +167,15 @@ class Blocklist extends Component {
iconName={icons.TABLE}
/>
</TableOptionsModalWrapper>
<FilterMenu
alignMenu={align.RIGHT}
selectedFilterKey={selectedFilterKey}
filters={filters}
customFilters={customFilters}
filterModalConnectorComponent={BlocklistFilterModal}
onFilterSelect={onFilterSelect}
/>
</PageToolbarSection>
</PageToolbar>
@@ -180,7 +195,11 @@ class Blocklist extends Component {
{
isPopulated && !error && !items.length &&
<Alert kind={kinds.INFO}>
{translate('NoHistoryBlocklist')}
{
selectedFilterKey === 'all' ?
translate('NoHistoryBlocklist') :
translate('BlocklistFilterHasNoItems')
}
</Alert>
}
@@ -251,11 +270,15 @@ Blocklist.propTypes = {
error: PropTypes.object,
items: PropTypes.arrayOf(PropTypes.object).isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
selectedFilterKey: PropTypes.oneOfType([PropTypes.string, PropTypes.number]).isRequired,
filters: PropTypes.arrayOf(PropTypes.object).isRequired,
customFilters: PropTypes.arrayOf(PropTypes.object).isRequired,
totalRecords: PropTypes.number,
isRemoving: PropTypes.bool.isRequired,
isClearingBlocklistExecuting: PropTypes.bool.isRequired,
onRemoveSelected: PropTypes.func.isRequired,
onClearBlocklistPress: PropTypes.func.isRequired
onClearBlocklistPress: PropTypes.func.isRequired,
onFilterSelect: PropTypes.func.isRequired
};
export default Blocklist;

View File

@@ -6,6 +6,7 @@ import * as commandNames from 'Commands/commandNames';
import withCurrentPage from 'Components/withCurrentPage';
import * as blocklistActions from 'Store/Actions/blocklistActions';
import { executeCommand } from 'Store/Actions/commandActions';
import { createCustomFiltersSelector } from 'Store/Selectors/createClientSideCollectionSelector';
import createCommandExecutingSelector from 'Store/Selectors/createCommandExecutingSelector';
import { registerPagePopulator, unregisterPagePopulator } from 'Utilities/pagePopulator';
import Blocklist from './Blocklist';
@@ -13,10 +14,12 @@ import Blocklist from './Blocklist';
function createMapStateToProps() {
return createSelector(
(state) => state.blocklist,
createCustomFiltersSelector('blocklist'),
createCommandExecutingSelector(commandNames.CLEAR_BLOCKLIST),
(blocklist, isClearingBlocklistExecuting) => {
(blocklist, customFilters, isClearingBlocklistExecuting) => {
return {
isClearingBlocklistExecuting,
customFilters,
...blocklist
};
}
@@ -97,6 +100,10 @@ class BlocklistConnector extends Component {
this.props.setBlocklistSort({ sortKey });
};
onFilterSelect = (selectedFilterKey) => {
this.props.setBlocklistFilter({ selectedFilterKey });
};
onClearBlocklistPress = () => {
this.props.executeCommand({ name: commandNames.CLEAR_BLOCKLIST });
};
@@ -122,6 +129,7 @@ class BlocklistConnector extends Component {
onPageSelect={this.onPageSelect}
onRemoveSelected={this.onRemoveSelected}
onSortPress={this.onSortPress}
onFilterSelect={this.onFilterSelect}
onTableOptionChange={this.onTableOptionChange}
onClearBlocklistPress={this.onClearBlocklistPress}
{...this.props}
@@ -142,6 +150,7 @@ BlocklistConnector.propTypes = {
gotoBlocklistPage: PropTypes.func.isRequired,
removeBlocklistItems: PropTypes.func.isRequired,
setBlocklistSort: PropTypes.func.isRequired,
setBlocklistFilter: PropTypes.func.isRequired,
setBlocklistTableOption: PropTypes.func.isRequired,
clearBlocklist: PropTypes.func.isRequired,
executeCommand: PropTypes.func.isRequired

View File

@@ -0,0 +1,54 @@
import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import FilterModal from 'Components/Filter/FilterModal';
import { setBlocklistFilter } from 'Store/Actions/blocklistActions';
function createBlocklistSelector() {
return createSelector(
(state: AppState) => state.blocklist.items,
(blocklistItems) => {
return blocklistItems;
}
);
}
function createFilterBuilderPropsSelector() {
return createSelector(
(state: AppState) => state.blocklist.filterBuilderProps,
(filterBuilderProps) => {
return filterBuilderProps;
}
);
}
interface BlocklistFilterModalProps {
isOpen: boolean;
}
export default function BlocklistFilterModal(props: BlocklistFilterModalProps) {
const sectionItems = useSelector(createBlocklistSelector());
const filterBuilderProps = useSelector(createFilterBuilderPropsSelector());
const customFilterType = 'blocklist';
const dispatch = useDispatch();
const dispatchSetFilter = useCallback(
(payload: unknown) => {
dispatch(setBlocklistFilter(payload));
},
[dispatch]
);
return (
<FilterModal
// TODO: Don't spread all the props
{...props}
sectionItems={sectionItems}
filterBuilderProps={filterBuilderProps}
customFilterType={customFilterType}
dispatchSetFilter={dispatchSetFilter}
/>
);
}

View File

@@ -77,7 +77,7 @@ class HistoryRow extends Component {
onMarkAsFailedPress
} = this.props;
if (!episode) {
if (!series || !episode) {
return null;
}

View File

@@ -217,6 +217,7 @@ class Queue extends Component {
>
<TableOptionsModalWrapper
columns={columns}
maxPageSize={200}
{...otherProps}
optionsComponent={QueueOptionsConnector}
>

View File

@@ -70,6 +70,11 @@ function QueueStatus(props) {
iconName = icons.DOWNLOADED;
title = translate('Downloaded');
if (trackedDownloadState === 'importBlocked') {
title += ` - ${translate('UnableToImportAutomatically')}`;
iconKind = kinds.WARNING;
}
if (trackedDownloadState === 'importPending') {
title += ` - ${translate('WaitingToImport')}`;
iconKind = kinds.PURPLE;

View File

@@ -118,6 +118,7 @@ function RemoveQueueItemModal(props: RemoveQueueItemModalProps) {
{
key: 'blocklistAndSearch',
value: translate('BlocklistAndSearch'),
isDisabled: isPending,
hint: multipleSelected
? translate('BlocklistAndSearchMultipleHint')
: translate('BlocklistAndSearchHint'),
@@ -130,7 +131,7 @@ function RemoveQueueItemModal(props: RemoveQueueItemModalProps) {
: translate('BlocklistOnlyHint'),
},
];
}, [multipleSelected]);
}, [isPending, multipleSelected]);
const handleRemovalMethodChange = useCallback(
({ value }: { value: RemovalMethod }) => {

View File

@@ -24,7 +24,11 @@ function TimeleftCell(props) {
} = props;
if (status === 'delay') {
const date = getRelativeDate(estimatedCompletionTime, shortDateFormat, showRelativeDates);
const date = getRelativeDate({
date: estimatedCompletionTime,
shortDateFormat,
showRelativeDates
});
const time = formatTime(estimatedCompletionTime, timeFormat, { includeMinuteZero: true });
return (
@@ -40,7 +44,11 @@ function TimeleftCell(props) {
}
if (status === 'downloadClientUnavailable') {
const date = getRelativeDate(estimatedCompletionTime, shortDateFormat, showRelativeDates);
const date = getRelativeDate({
date: estimatedCompletionTime,
shortDateFormat,
showRelativeDates
});
const time = formatTime(estimatedCompletionTime, timeFormat, { includeMinuteZero: true });
return (

View File

@@ -69,6 +69,11 @@
height: 55px;
}
.originalLanguageName,
.network {
margin-left: 8px;
}
.tvdbLink {
composes: link from '~Components/Link/Link.css';

View File

@@ -4,6 +4,8 @@ interface CssExports {
'alreadyExistsIcon': string;
'content': string;
'icons': string;
'network': string;
'originalLanguageName': string;
'overlay': string;
'overview': string;
'poster': string;

View File

@@ -55,6 +55,7 @@ class AddNewSeriesSearchResult extends Component {
titleSlug,
year,
network,
originalLanguage,
status,
overview,
statistics,
@@ -145,14 +146,37 @@ class AddNewSeriesSearchResult extends Component {
<Label size={sizes.LARGE}>
<HeartRating
rating={ratings.value}
votes={ratings.votes}
iconSize={13}
/>
</Label>
{
originalLanguage?.name ?
<Label size={sizes.LARGE}>
<Icon
name={icons.LANGUAGE}
size={13}
/>
<span className={styles.originalLanguageName}>
{originalLanguage.name}
</span>
</Label> :
null
}
{
network ?
<Label size={sizes.LARGE}>
{network}
<Icon
name={icons.NETWORK}
size={13}
/>
<span className={styles.network}>
{network}
</span>
</Label> :
null
}
@@ -218,6 +242,7 @@ AddNewSeriesSearchResult.propTypes = {
titleSlug: PropTypes.string.isRequired,
year: PropTypes.number.isRequired,
network: PropTypes.string,
originalLanguage: PropTypes.object,
status: PropTypes.string.isRequired,
overview: PropTypes.string,
statistics: PropTypes.object.isRequired,

View File

@@ -12,11 +12,10 @@ function App({ store, history }) {
<DocumentTitle title={window.Sonarr.instanceName}>
<Provider store={store}>
<ConnectedRouter history={history}>
<ApplyTheme>
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ApplyTheme>
<ApplyTheme />
<PageConnector>
<AppRoutes app={App} />
</PageConnector>
</ConnectedRouter>
</Provider>
</DocumentTitle>

View File

@@ -30,7 +30,7 @@ import LogsTableConnector from 'System/Events/LogsTableConnector';
import Logs from 'System/Logs/Logs';
import Status from 'System/Status/Status';
import Tasks from 'System/Tasks/Tasks';
import UpdatesConnector from 'System/Updates/UpdatesConnector';
import Updates from 'System/Updates/Updates';
import getPathWithUrlBase from 'Utilities/getPathWithUrlBase';
import CutoffUnmetConnector from 'Wanted/CutoffUnmet/CutoffUnmetConnector';
import MissingConnector from 'Wanted/Missing/MissingConnector';
@@ -248,7 +248,7 @@ function AppRoutes(props) {
<Route
path="/system/updates"
component={UpdatesConnector}
component={Updates}
/>
<Route

View File

@@ -1,50 +0,0 @@
import PropTypes from 'prop-types';
import React, { Fragment, useCallback, useEffect } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
function createMapStateToProps() {
return createSelector(
(state) => state.settings.ui.item.theme || window.Sonarr.theme,
(
theme
) => {
return {
theme
};
}
);
}
function ApplyTheme({ theme, children }) {
// Update the CSS Variables
const updateCSSVariables = useCallback(() => {
const arrayOfVariableKeys = Object.keys(themes[theme]);
const arrayOfVariableValues = Object.values(themes[theme]);
// Loop through each array key and set the CSS Variables
arrayOfVariableKeys.forEach((cssVariableKey, index) => {
// Based on our snippet from MDN
document.documentElement.style.setProperty(
`--${cssVariableKey}`,
arrayOfVariableValues[index]
);
});
}, [theme]);
// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables(theme);
}, [updateCSSVariables, theme]);
return <Fragment>{children}</Fragment>;
}
ApplyTheme.propTypes = {
theme: PropTypes.string.isRequired,
children: PropTypes.object.isRequired
};
export default connect(createMapStateToProps)(ApplyTheme);

View File

@@ -0,0 +1,37 @@
import React, { Fragment, ReactNode, useCallback, useEffect } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import themes from 'Styles/Themes';
import AppState from './State/AppState';
interface ApplyThemeProps {
children: ReactNode;
}
function createThemeSelector() {
return createSelector(
(state: AppState) => state.settings.ui.item.theme || window.Sonarr.theme,
(theme) => {
return theme;
}
);
}
function ApplyTheme({ children }: ApplyThemeProps) {
const theme = useSelector(createThemeSelector());
const updateCSSVariables = useCallback(() => {
Object.entries(themes[theme]).forEach(([key, value]) => {
document.documentElement.style.setProperty(`--${key}`, value);
});
}, [theme]);
// On Component Mount and Component Update
useEffect(() => {
updateCSSVariables();
}, [updateCSSVariables, theme]);
return <Fragment>{children}</Fragment>;
}
export default ApplyTheme;

View File

@@ -19,6 +19,7 @@ export interface AppSectionSaveState {
export interface PagedAppSectionState {
pageSize: number;
totalRecords?: number;
}
export interface AppSectionFilterState<T> {
@@ -38,6 +39,7 @@ export interface AppSectionItemState<T> {
isFetching: boolean;
isPopulated: boolean;
error: Error;
pendingChanges: Partial<T>;
item: T;
}

View File

@@ -1,4 +1,5 @@
import InteractiveImportAppState from 'App/State/InteractiveImportAppState';
import BlocklistAppState from './BlocklistAppState';
import CalendarAppState from './CalendarAppState';
import CommandAppState from './CommandAppState';
import EpisodeFilesAppState from './EpisodeFilesAppState';
@@ -45,6 +46,7 @@ export interface CustomFilter {
}
export interface AppSectionState {
version: string;
dimensions: {
isSmallScreen: boolean;
width: number;
@@ -54,6 +56,7 @@ export interface AppSectionState {
interface AppState {
app: AppSectionState;
blocklist: BlocklistAppState;
calendar: CalendarAppState;
commands: CommandAppState;
episodeFiles: EpisodeFilesAppState;

View File

@@ -0,0 +1,8 @@
import Blocklist from 'typings/Blocklist';
import AppSectionState, { AppSectionFilterState } from './AppSectionState';
interface BlocklistAppState
extends AppSectionState<Blocklist>,
AppSectionFilterState<Blocklist> {}
export default BlocklistAppState;

View File

@@ -20,6 +20,7 @@ export interface SeriesIndexAppState {
showTitle: boolean;
showMonitored: boolean;
showQualityProfile: boolean;
showTags: boolean;
showSearchAction: boolean;
};
@@ -34,6 +35,7 @@ export interface SeriesIndexAppState {
showSeasonCount: boolean;
showPath: boolean;
showSizeOnDisk: boolean;
showTags: boolean;
showSearchAction: boolean;
};

View File

@@ -3,21 +3,27 @@ import AppSectionState, {
AppSectionItemState,
AppSectionSaveState,
AppSectionSchemaState,
PagedAppSectionState,
} from 'App/State/AppSectionState';
import Language from 'Language/Language';
import DownloadClient from 'typings/DownloadClient';
import ImportList from 'typings/ImportList';
import ImportListExclusion from 'typings/ImportListExclusion';
import ImportListOptionsSettings from 'typings/ImportListOptionsSettings';
import Indexer from 'typings/Indexer';
import IndexerFlag from 'typings/IndexerFlag';
import Notification from 'typings/Notification';
import QualityProfile from 'typings/QualityProfile';
import { UiSettings } from 'typings/UiSettings';
import General from 'typings/Settings/General';
import UiSettings from 'typings/Settings/UiSettings';
export interface DownloadClientAppState
extends AppSectionState<DownloadClient>,
AppSectionDeleteState,
AppSectionSaveState {}
export type GeneralAppState = AppSectionItemState<General>;
export interface ImportListAppState
extends AppSectionState<ImportList>,
AppSectionDeleteState,
@@ -40,19 +46,31 @@ export interface ImportListOptionsSettingsAppState
extends AppSectionItemState<ImportListOptionsSettings>,
AppSectionSaveState {}
export interface ImportListExclusionsSettingsAppState
extends AppSectionState<ImportListExclusion>,
AppSectionSaveState,
PagedAppSectionState,
AppSectionDeleteState {
pendingChanges: Partial<ImportListExclusion>;
}
export type IndexerFlagSettingsAppState = AppSectionState<IndexerFlag>;
export type LanguageSettingsAppState = AppSectionState<Language>;
export type UiSettingsAppState = AppSectionItemState<UiSettings>;
interface SettingsAppState {
advancedSettings: boolean;
downloadClients: DownloadClientAppState;
general: GeneralAppState;
importListExclusions: ImportListExclusionsSettingsAppState;
importListOptions: ImportListOptionsSettingsAppState;
importLists: ImportListAppState;
indexerFlags: IndexerFlagSettingsAppState;
indexers: IndexerAppState;
languages: LanguageSettingsAppState;
notifications: NotificationAppState;
qualityProfiles: QualityProfilesAppState;
ui: UiSettingsAppState;
importListOptions: ImportListOptionsSettingsAppState;
}
export default SettingsAppState;

View File

@@ -1,9 +1,12 @@
import SystemStatus from 'typings/SystemStatus';
import { AppSectionItemState } from './AppSectionState';
import Update from 'typings/Update';
import AppSectionState, { AppSectionItemState } from './AppSectionState';
export type SystemStatusAppState = AppSectionItemState<SystemStatus>;
export type UpdateAppState = AppSectionState<Update>;
interface SystemAppState {
updates: UpdateAppState;
status: SystemStatusAppState;
}

View File

@@ -28,7 +28,7 @@ class DayOfWeek extends Component {
if (view === calendarViews.WEEK) {
formatedDate = momentDate.format(calendarWeekColumnHeader);
} else if (view === calendarViews.FORECAST) {
formatedDate = getRelativeDate(date, shortDateFormat, showRelativeDates);
formatedDate = getRelativeDate({ date, shortDateFormat, showRelativeDates });
}
return (

View File

@@ -13,6 +13,8 @@ export interface CommandBody {
trigger: string;
suppressMessages: boolean;
seriesId?: number;
seriesIds?: number[];
seasonNumber?: number;
}
interface Command extends ModelBase {

View File

@@ -6,7 +6,7 @@ export const CLEAR_LOGS = 'ClearLog';
export const CUTOFF_UNMET_EPISODE_SEARCH = 'CutoffUnmetEpisodeSearch';
export const DELETE_LOG_FILES = 'DeleteLogFiles';
export const DELETE_UPDATE_LOG_FILES = 'DeleteUpdateLogFiles';
export const DOWNLOADED_EPSIODES_SCAN = 'DownloadedEpisodesScan';
export const DOWNLOADED_EPISODES_SCAN = 'DownloadedEpisodesScan';
export const EPISODE_SEARCH = 'EpisodeSearch';
export const INTERACTIVE_IMPORT = 'ManualImport';
export const MISSING_EPISODE_SEARCH = 'MissingEpisodeSearch';

View File

@@ -117,7 +117,7 @@ class FileBrowserModalContent extends Component {
className={styles.mappedDrivesWarning}
kind={kinds.WARNING}
>
<InlineMarkdown data={translate('MappedNetworkDrivesWindowsService')} />
<InlineMarkdown data={translate('MappedNetworkDrivesWindowsService', { url: 'https://wiki.servarr.com/sonarr/faq#why-cant-sonarr-see-my-files-on-a-remote-server' })} />
</Alert>
}

View File

@@ -1,3 +1,4 @@
import { maxBy } from 'lodash';
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import FormInputGroup from 'Components/Form/FormInputGroup';
@@ -8,6 +9,7 @@ import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import { inputTypes } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import FilterBuilderRow from './FilterBuilderRow';
import styles from './FilterBuilderModalContent.css';
@@ -49,7 +51,7 @@ class FilterBuilderModalContent extends Component {
if (id) {
dispatchSetFilter({ selectedFilterKey: id });
} else {
const last = customFilters[customFilters.length -1];
const last = maxBy(customFilters, 'id');
dispatchSetFilter({ selectedFilterKey: last.id });
}
@@ -107,7 +109,7 @@ class FilterBuilderModalContent extends Component {
this.setState({
labelErrors: [
{
message: 'Label is required'
message: translate('LabelIsRequired')
}
]
});
@@ -145,13 +147,13 @@ class FilterBuilderModalContent extends Component {
return (
<ModalContent onModalClose={onModalClose}>
<ModalHeader>
Custom Filter
{translate('CustomFilter')}
</ModalHeader>
<ModalBody>
<div className={styles.labelContainer}>
<div className={styles.label}>
Label
{translate('Label')}
</div>
<div className={styles.labelInputContainer}>
@@ -165,7 +167,9 @@ class FilterBuilderModalContent extends Component {
</div>
</div>
<div className={styles.label}>Filters</div>
<div className={styles.label}>
{translate('Filters')}
</div>
<div className={styles.rows}>
{
@@ -192,7 +196,7 @@ class FilterBuilderModalContent extends Component {
<ModalFooter>
<Button onPress={onCancelPress}>
Cancel
{translate('Cancel')}
</Button>
<SpinnerErrorButton
@@ -200,7 +204,7 @@ class FilterBuilderModalContent extends Component {
error={saveError}
onPress={this.onSaveFilterPress}
>
Save
{translate('Save')}
</SpinnerErrorButton>
</ModalFooter>
</ModalContent>

View File

@@ -3,6 +3,7 @@ import React, { Component } from 'react';
import SelectInput from 'Components/Form/SelectInput';
import IconButton from 'Components/Link/IconButton';
import { filterBuilderTypes, filterBuilderValueTypes, icons } from 'Helpers/Props';
import sortByProp from 'Utilities/Array/sortByProp';
import BoolFilterBuilderRowValue from './BoolFilterBuilderRowValue';
import DateFilterBuilderRowValue from './DateFilterBuilderRowValue';
import FilterBuilderRowValueConnector from './FilterBuilderRowValueConnector';
@@ -224,7 +225,7 @@ class FilterBuilderRow extends Component {
key: name,
value: typeof label === 'function' ? label() : label
};
}).sort((a, b) => a.value.localeCompare(b.value));
}).sort(sortByProp('value'));
const ValueComponent = getRowValueConnector(selectedFilterBuilderProp);

View File

@@ -3,7 +3,7 @@ import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { filterBuilderTypes } from 'Helpers/Props';
import * as filterTypes from 'Helpers/Props/filterTypes';
import sortByName from 'Utilities/Array/sortByName';
import sortByProp from 'Utilities/Array/sortByProp';
import FilterBuilderRowValue from './FilterBuilderRowValue';
function createTagListSelector() {
@@ -38,7 +38,7 @@ function createTagListSelector() {
}
return acc;
}, []).sort(sortByName);
}, []).sort(sortByProp('name'));
}
return _.uniqBy(items, 'id');

View File

@@ -2,7 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux';
import Series from 'Series/Series';
import createAllSeriesSelector from 'Store/Selectors/createAllSeriesSelector';
import sortByName from 'Utilities/Array/sortByName';
import sortByProp from 'Utilities/Array/sortByProp';
import FilterBuilderRowValue from './FilterBuilderRowValue';
import FilterBuilderRowValueProps from './FilterBuilderRowValueProps';
@@ -11,7 +11,7 @@ function SeriesFilterBuilderRowValue(props: FilterBuilderRowValueProps) {
const tagList = allSeries
.map((series) => ({ id: series.id, name: series.title }))
.sort(sortByName);
.sort(sortByProp('name'));
return <FilterBuilderRowValue {...props} tagList={tagList} />;
}

View File

@@ -37,8 +37,8 @@ class CustomFilter extends Component {
dispatchSetFilter
} = this.props;
// Assume that delete and then unmounting means the delete was successful.
// Moving this check to a ancestor would be more accurate, but would have
// Assume that delete and then unmounting means the deletion was successful.
// Moving this check to an ancestor would be more accurate, but would have
// more boilerplate.
if (this.state.isDeleting && id === selectedFilterKey) {
dispatchSetFilter({ selectedFilterKey: 'all' });

View File

@@ -5,6 +5,7 @@ import ModalBody from 'Components/Modal/ModalBody';
import ModalContent from 'Components/Modal/ModalContent';
import ModalFooter from 'Components/Modal/ModalFooter';
import ModalHeader from 'Components/Modal/ModalHeader';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import CustomFilter from './CustomFilter';
import styles from './CustomFiltersModalContent.css';
@@ -31,7 +32,7 @@ function CustomFiltersModalContent(props) {
<ModalBody>
{
customFilters
.sort((a, b) => a.label.localeCompare(b.label))
.sort((a, b) => sortByProp(a, b, 'label'))
.map((customFilter) => {
return (
<CustomFilter

View File

@@ -4,7 +4,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchDownloadClients } from 'Store/Actions/settingsActions';
import sortByName from 'Utilities/Array/sortByName';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput from './EnhancedSelectInput';
@@ -23,10 +23,11 @@ function createMapStateToProps() {
const filteredItems = items.filter((item) => item.protocol === protocolFilter);
const values = _.map(filteredItems.sort(sortByName), (downloadClient) => {
const values = _.map(filteredItems.sort(sortByProp('name')), (downloadClient) => {
return {
key: downloadClient.id,
value: downloadClient.name
value: downloadClient.name,
hint: `(${downloadClient.id})`
};
});

View File

@@ -19,7 +19,7 @@
.isDisabled {
opacity: 0.7;
cursor: not-allowed;
cursor: not-allowed !important;
}
.dropdownArrowContainer {

View File

@@ -271,26 +271,32 @@ class EnhancedSelectInput extends Component {
this.setState({ isOpen: !this.state.isOpen });
};
onSelect = (value) => {
if (Array.isArray(this.props.value)) {
let newValue = null;
const index = this.props.value.indexOf(value);
onSelect = (newValue) => {
const { name, value, values, onChange } = this.props;
const additionalProperties = values.find((v) => v.key === newValue)?.additionalProperties;
if (Array.isArray(value)) {
let arrayValue = null;
const index = value.indexOf(newValue);
if (index === -1) {
newValue = this.props.values.map((v) => v.key).filter((v) => (v === value) || this.props.value.includes(v));
arrayValue = values.map((v) => v.key).filter((v) => (v === newValue) || value.includes(v));
} else {
newValue = [...this.props.value];
newValue.splice(index, 1);
arrayValue = [...value];
arrayValue.splice(index, 1);
}
this.props.onChange({
name: this.props.name,
value: newValue
onChange({
name,
value: arrayValue,
additionalProperties
});
} else {
this.setState({ isOpen: false });
this.props.onChange({
name: this.props.name,
value
onChange({
name,
value: newValue,
additionalProperties
});
}
};
@@ -485,7 +491,7 @@ class EnhancedSelectInput extends Component {
values.map((v, index) => {
const hasParent = v.parentKey !== undefined;
const depth = hasParent ? 1 : 0;
const parentSelected = hasParent && value.includes(v.parentKey);
const parentSelected = hasParent && Array.isArray(value) && value.includes(v.parentKey);
return (
<OptionComponent
key={v.key}

View File

@@ -9,7 +9,8 @@ import EnhancedSelectInput from './EnhancedSelectInput';
const importantFieldNames = [
'baseUrl',
'apiPath',
'apiKey'
'apiKey',
'authToken'
];
function getProviderDataKey(providerData) {
@@ -34,7 +35,9 @@ function getSelectOptions(items) {
key: option.value,
value: option.name,
hint: option.hint,
parentKey: option.parentValue
parentKey: option.parentValue,
isDisabled: option.isDisabled,
additionalProperties: option.additionalProperties
};
});
}
@@ -147,7 +150,7 @@ EnhancedSelectInputConnector.propTypes = {
provider: PropTypes.string.isRequired,
providerData: PropTypes.object.isRequired,
name: PropTypes.string.isRequired,
value: PropTypes.arrayOf(PropTypes.oneOfType([PropTypes.number, PropTypes.string])).isRequired,
value: PropTypes.oneOfType([PropTypes.string, PropTypes.number, PropTypes.arrayOf(PropTypes.string), PropTypes.arrayOf(PropTypes.number)]).isRequired,
values: PropTypes.arrayOf(PropTypes.object).isRequired,
selectOptionsProviderAction: PropTypes.string,
onChange: PropTypes.func.isRequired,

View File

@@ -11,6 +11,7 @@ import DownloadClientSelectInputConnector from './DownloadClientSelectInputConne
import EnhancedSelectInput from './EnhancedSelectInput';
import EnhancedSelectInputConnector from './EnhancedSelectInputConnector';
import FormInputHelpText from './FormInputHelpText';
import IndexerFlagsSelectInput from './IndexerFlagsSelectInput';
import IndexerSelectInputConnector from './IndexerSelectInputConnector';
import KeyValueListInput from './KeyValueListInput';
import MonitorEpisodesSelectInput from './MonitorEpisodesSelectInput';
@@ -21,6 +22,7 @@ import PasswordInput from './PasswordInput';
import PathInputConnector from './PathInputConnector';
import QualityProfileSelectInputConnector from './QualityProfileSelectInputConnector';
import RootFolderSelectInputConnector from './RootFolderSelectInputConnector';
import SeriesTagInput from './SeriesTagInput';
import SeriesTypeSelectInput from './SeriesTypeSelectInput';
import TagInputConnector from './TagInputConnector';
import TagSelectInputConnector from './TagSelectInputConnector';
@@ -71,6 +73,9 @@ function getComponent(type) {
case inputTypes.INDEXER_SELECT:
return IndexerSelectInputConnector;
case inputTypes.INDEXER_FLAGS_SELECT:
return IndexerFlagsSelectInput;
case inputTypes.DOWNLOAD_CLIENT_SELECT:
return DownloadClientSelectInputConnector;
@@ -83,6 +88,9 @@ function getComponent(type) {
case inputTypes.DYNAMIC_SELECT:
return EnhancedSelectInputConnector;
case inputTypes.SERIES_TAG:
return SeriesTagInput;
case inputTypes.SERIES_TYPE_SELECT:
return SeriesTypeSelectInput;
@@ -279,6 +287,7 @@ FormInputGroup.propTypes = {
includeNoChange: PropTypes.bool,
includeNoChangeDisabled: PropTypes.bool,
selectedValueOptions: PropTypes.object,
indexerFlags: PropTypes.number,
pending: PropTypes.bool,
errors: PropTypes.arrayOf(PropTypes.object),
warnings: PropTypes.arrayOf(PropTypes.object),

View File

@@ -0,0 +1,62 @@
import React, { useCallback } from 'react';
import { useSelector } from 'react-redux';
import { createSelector } from 'reselect';
import AppState from 'App/State/AppState';
import EnhancedSelectInput from './EnhancedSelectInput';
const selectIndexerFlagsValues = (selectedFlags: number) =>
createSelector(
(state: AppState) => state.settings.indexerFlags,
(indexerFlags) => {
const value = indexerFlags.items.reduce((acc: number[], { id }) => {
// eslint-disable-next-line no-bitwise
if ((selectedFlags & id) === id) {
acc.push(id);
}
return acc;
}, []);
const values = indexerFlags.items.map(({ id, name }) => ({
key: id,
value: name,
}));
return {
value,
values,
};
}
);
interface IndexerFlagsSelectInputProps {
name: string;
indexerFlags: number;
onChange(payload: object): void;
}
function IndexerFlagsSelectInput(props: IndexerFlagsSelectInputProps) {
const { indexerFlags, onChange } = props;
const { value, values } = useSelector(selectIndexerFlagsValues(indexerFlags));
const onChangeWrapper = useCallback(
({ name, value }: { name: string; value: number[] }) => {
const indexerFlags = value.reduce((acc, flagId) => acc + flagId, 0);
onChange({ name, value: indexerFlags });
},
[onChange]
);
return (
<EnhancedSelectInput
{...props}
value={value}
values={values}
onChange={onChangeWrapper}
/>
);
}
export default IndexerFlagsSelectInput;

View File

@@ -4,7 +4,7 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import { fetchIndexers } from 'Store/Actions/settingsActions';
import sortByName from 'Utilities/Array/sortByName';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput from './EnhancedSelectInput';
@@ -20,7 +20,7 @@ function createMapStateToProps() {
items
} = indexers;
const values = _.map(items.sort(sortByName), (indexer) => {
const values = _.map(items.sort(sortByProp('name')), (indexer) => {
return {
key: indexer.id,
value: indexer.name

View File

@@ -2,7 +2,7 @@ import PropTypes from 'prop-types';
import React from 'react';
import monitorOptions from 'Utilities/Series/monitorOptions';
import translate from 'Utilities/String/translate';
import SelectInput from './SelectInput';
import EnhancedSelectInput from './EnhancedSelectInput';
function MonitorEpisodesSelectInput(props) {
const {
@@ -19,7 +19,7 @@ function MonitorEpisodesSelectInput(props) {
get value() {
return translate('NoChange');
},
disabled: true
isDisabled: true
});
}
@@ -29,12 +29,12 @@ function MonitorEpisodesSelectInput(props) {
get value() {
return `(${translate('Mixed')})`;
},
disabled: true
isDisabled: true
});
}
return (
<SelectInput
<EnhancedSelectInput
values={values}
{...otherProps}
/>

View File

@@ -1,7 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import monitorNewItemsOptions from 'Utilities/Series/monitorNewItemsOptions';
import SelectInput from './SelectInput';
import EnhancedSelectInput from './EnhancedSelectInput';
function MonitorNewItemsSelectInput(props) {
const {
@@ -16,7 +16,7 @@ function MonitorNewItemsSelectInput(props) {
values.unshift({
key: 'noChange',
value: 'No Change',
disabled: true
isDisabled: true
});
}
@@ -24,12 +24,12 @@ function MonitorNewItemsSelectInput(props) {
values.unshift({
key: 'mixed',
value: '(Mixed)',
disabled: true
isDisabled: true
});
}
return (
<SelectInput
<EnhancedSelectInput
values={values}
{...otherProps}
/>

View File

@@ -1,5 +0,0 @@
.input {
composes: input from '~Components/Form/TextInput.css';
font-family: $passwordFamily;
}

View File

@@ -1,7 +1,5 @@
import PropTypes from 'prop-types';
import React from 'react';
import TextInput from './TextInput';
import styles from './PasswordInput.css';
// Prevent a user from copying (or cutting) the password from the input
function onCopy(e) {
@@ -13,17 +11,14 @@ function PasswordInput(props) {
return (
<TextInput
{...props}
type="password"
onCopy={onCopy}
/>
);
}
PasswordInput.propTypes = {
className: PropTypes.string.isRequired
};
PasswordInput.defaultProps = {
className: styles.input
...TextInput.props
};
export default PasswordInput;

View File

@@ -27,6 +27,8 @@ function getType({ type, selectOptionsProviderAction }) {
return inputTypes.DYNAMIC_SELECT;
}
return inputTypes.SELECT;
case 'seriesTag':
return inputTypes.SERIES_TAG;
case 'tag':
return inputTypes.TEXT_TAG;
case 'tagSelect':

View File

@@ -4,13 +4,13 @@ import React, { Component } from 'react';
import { connect } from 'react-redux';
import { createSelector } from 'reselect';
import createSortedSectionSelector from 'Store/Selectors/createSortedSectionSelector';
import sortByName from 'Utilities/Array/sortByName';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import EnhancedSelectInput from './EnhancedSelectInput';
function createMapStateToProps() {
return createSelector(
createSortedSectionSelector('settings.qualityProfiles', sortByName),
createSortedSectionSelector('settings.qualityProfiles', sortByProp('name')),
(state, { includeNoChange }) => includeNoChange,
(state, { includeNoChangeDisabled }) => includeNoChangeDisabled,
(state, { includeMixed }) => includeMixed,
@@ -28,7 +28,7 @@ function createMapStateToProps() {
get value() {
return translate('NoChange');
},
disabled: includeNoChangeDisabled
isDisabled: includeNoChangeDisabled
});
}
@@ -38,7 +38,7 @@ function createMapStateToProps() {
get value() {
return `(${translate('Mixed')})`;
},
disabled: true
isDisabled: true
});
}

View File

@@ -0,0 +1,53 @@
import React, { useCallback } from 'react';
import TagInputConnector from './TagInputConnector';
interface SeriesTageInputProps {
name: string;
value: number | number[];
onChange: ({
name,
value,
}: {
name: string;
value: number | number[];
}) => void;
}
export default function SeriesTagInput(props: SeriesTageInputProps) {
const { value, onChange, ...otherProps } = props;
const isArray = Array.isArray(value);
const handleChange = useCallback(
({ name, value: newValue }: { name: string; value: number[] }) => {
if (isArray) {
onChange({ name, value: newValue });
} else {
onChange({
name,
value: newValue.length ? newValue[newValue.length - 1] : 0,
});
}
},
[isArray, onChange]
);
let finalValue: number[] = [];
if (isArray) {
finalValue = value;
} else if (value === 0) {
finalValue = [];
} else {
finalValue = [value];
}
return (
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore 2786 'TagInputConnector' isn't typed yet
<TagInputConnector
{...otherProps}
value={finalValue}
onChange={handleChange}
/>
);
}

View File

@@ -15,7 +15,7 @@ interface ISeriesTypeOption {
key: string;
value: string;
format?: string;
disabled?: boolean;
isDisabled?: boolean;
}
const seriesTypeOptions: ISeriesTypeOption[] = [
@@ -55,7 +55,7 @@ function SeriesTypeSelectInput(props: SeriesTypeSelectInputProps) {
values.unshift({
key: 'noChange',
value: translate('NoChange'),
disabled: includeNoChangeDisabled,
isDisabled: includeNoChangeDisabled,
});
}
@@ -63,7 +63,7 @@ function SeriesTypeSelectInput(props: SeriesTypeSelectInputProps) {
values.unshift({
key: 'mixed',
value: `(${translate('Mixed')})`,
disabled: true,
isDisabled: true,
});
}

View File

@@ -91,6 +91,7 @@ class TextTagInputConnector extends Component {
render() {
return (
<TagInput
delimiters={['Tab', 'Enter', ',']}
tagList={[]}
onTagAdd={this.onTagAdd}
onTagDelete={this.onTagDelete}

View File

@@ -1,29 +1,40 @@
import PropTypes from 'prop-types';
import React from 'react';
import Icon from 'Components/Icon';
import { icons } from 'Helpers/Props';
import Tooltip from 'Components/Tooltip/Tooltip';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
import translate from 'Utilities/String/translate';
import styles from './HeartRating.css';
function HeartRating({ rating, iconSize }) {
function HeartRating({ rating, votes, iconSize }) {
return (
<span className={styles.rating}>
<Icon
className={styles.heart}
name={icons.HEART}
size={iconSize}
/>
<Tooltip
anchor={
<span className={styles.rating}>
<Icon
className={styles.heart}
name={icons.HEART}
size={iconSize}
/>
{rating * 10}%
</span>
{rating * 10}%
</span>
}
tooltip={translate('CountVotes', { votes })}
kind={kinds.INVERSE}
position={tooltipPositions.TOP}
/>
);
}
HeartRating.propTypes = {
rating: PropTypes.number.isRequired,
votes: PropTypes.number.isRequired,
iconSize: PropTypes.number.isRequired
};
HeartRating.defaultProps = {
votes: 0,
iconSize: 14
};

View File

@@ -88,6 +88,15 @@
}
}
.purple {
border-color: var(--purple);
background-color: var(--purple);
&.outline {
color: var(--purple);
}
}
/** Sizes **/
.small {

View File

@@ -11,6 +11,7 @@ interface CssExports {
'medium': string;
'outline': string;
'primary': string;
'purple': string;
'small': string;
'success': string;
'warning': string;

View File

@@ -1,5 +1,6 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import sortByProp from 'Utilities/Array/sortByProp';
import translate from 'Utilities/String/translate';
import FilterMenuItem from './FilterMenuItem';
import MenuContent from './MenuContent';
@@ -47,7 +48,7 @@ class FilterMenuContent extends Component {
{
customFilters
.sort((a, b) => a.label.localeCompare(b.label))
.sort(sortByProp('label'))
.map((filter) => {
return (
<FilterMenuItem

View File

@@ -63,6 +63,13 @@
width: 1280px;
}
.extraExtraLarge {
composes: modal;
width: 1600px;
}
@media only screen and (max-width: $breakpointExtraLarge) {
.modal.extraLarge {
width: 90%;
@@ -90,7 +97,8 @@
.modal.small,
.modal.medium,
.modal.large,
.modal.extraLarge {
.modal.extraLarge,
.modal.extraExtraLarge {
max-height: 100%;
width: 100%;
height: 100% !important;

View File

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

View File

@@ -21,6 +21,7 @@ function createCleanSeriesSelector() {
tvdbId,
tvMazeId,
imdbId,
tmdbId,
tags = []
} = series;
@@ -33,6 +34,7 @@ function createCleanSeriesSelector() {
tvdbId,
tvMazeId,
imdbId,
tmdbId,
firstCharacter: title.charAt(0).toLowerCase(),
tags: tags.reduce((acc, id) => {
const matchingTag = allTags.find((tag) => tag.id === id);

View File

@@ -14,6 +14,7 @@ function SeriesSearchResult(props) {
tvdbId,
tvMazeId,
imdbId,
tmdbId,
tags
} = props;
@@ -73,6 +74,14 @@ function SeriesSearchResult(props) {
null
}
{
match.key === 'tmdbId' && tmdbId ?
<div className={styles.alternateTitle}>
TmdbId: {tmdbId}
</div> :
null
}
{
tag ?
<div className={styles.tagContainer}>
@@ -97,6 +106,7 @@ SeriesSearchResult.propTypes = {
tvdbId: PropTypes.number,
tvMazeId: PropTypes.number,
imdbId: PropTypes.string,
tmdbId: PropTypes.number,
tags: PropTypes.arrayOf(PropTypes.object).isRequired,
match: PropTypes.object.isRequired
};

View File

@@ -13,6 +13,7 @@ const fuseOptions = {
'tvdbId',
'tvMazeId',
'imdbId',
'tmdbId',
'tags.label'
]
};

View File

@@ -6,7 +6,13 @@ import { createSelector } from 'reselect';
import { fetchTranslations, saveDimensions, setIsSidebarVisible } from 'Store/Actions/appActions';
import { fetchCustomFilters } from 'Store/Actions/customFilterActions';
import { fetchSeries } from 'Store/Actions/seriesActions';
import { fetchImportLists, fetchLanguages, fetchQualityProfiles, fetchUISettings } from 'Store/Actions/settingsActions';
import {
fetchImportLists,
fetchIndexerFlags,
fetchLanguages,
fetchQualityProfiles,
fetchUISettings
} from 'Store/Actions/settingsActions';
import { fetchStatus } from 'Store/Actions/systemActions';
import { fetchTags } from 'Store/Actions/tagActions';
import createDimensionsSelector from 'Store/Selectors/createDimensionsSelector';
@@ -51,6 +57,7 @@ const selectIsPopulated = createSelector(
(state) => state.settings.qualityProfiles.isPopulated,
(state) => state.settings.languages.isPopulated,
(state) => state.settings.importLists.isPopulated,
(state) => state.settings.indexerFlags.isPopulated,
(state) => state.system.status.isPopulated,
(state) => state.app.translations.isPopulated,
(
@@ -61,6 +68,7 @@ const selectIsPopulated = createSelector(
qualityProfilesIsPopulated,
languagesIsPopulated,
importListsIsPopulated,
indexerFlagsIsPopulated,
systemStatusIsPopulated,
translationsIsPopulated
) => {
@@ -72,6 +80,7 @@ const selectIsPopulated = createSelector(
qualityProfilesIsPopulated &&
languagesIsPopulated &&
importListsIsPopulated &&
indexerFlagsIsPopulated &&
systemStatusIsPopulated &&
translationsIsPopulated
);
@@ -86,6 +95,7 @@ const selectErrors = createSelector(
(state) => state.settings.qualityProfiles.error,
(state) => state.settings.languages.error,
(state) => state.settings.importLists.error,
(state) => state.settings.indexerFlags.error,
(state) => state.system.status.error,
(state) => state.app.translations.error,
(
@@ -96,6 +106,7 @@ const selectErrors = createSelector(
qualityProfilesError,
languagesError,
importListsError,
indexerFlagsError,
systemStatusError,
translationsError
) => {
@@ -107,6 +118,7 @@ const selectErrors = createSelector(
qualityProfilesError ||
languagesError ||
importListsError ||
indexerFlagsError ||
systemStatusError ||
translationsError
);
@@ -120,6 +132,7 @@ const selectErrors = createSelector(
qualityProfilesError,
languagesError,
importListsError,
indexerFlagsError,
systemStatusError,
translationsError
};
@@ -174,6 +187,9 @@ function createMapDispatchToProps(dispatch, props) {
dispatchFetchImportLists() {
dispatch(fetchImportLists());
},
dispatchFetchIndexerFlags() {
dispatch(fetchIndexerFlags());
},
dispatchFetchUISettings() {
dispatch(fetchUISettings());
},
@@ -213,6 +229,7 @@ class PageConnector extends Component {
this.props.dispatchFetchQualityProfiles();
this.props.dispatchFetchLanguages();
this.props.dispatchFetchImportLists();
this.props.dispatchFetchIndexerFlags();
this.props.dispatchFetchUISettings();
this.props.dispatchFetchStatus();
this.props.dispatchFetchTranslations();
@@ -238,6 +255,7 @@ class PageConnector extends Component {
dispatchFetchQualityProfiles,
dispatchFetchLanguages,
dispatchFetchImportLists,
dispatchFetchIndexerFlags,
dispatchFetchUISettings,
dispatchFetchStatus,
dispatchFetchTranslations,
@@ -278,6 +296,7 @@ PageConnector.propTypes = {
dispatchFetchQualityProfiles: PropTypes.func.isRequired,
dispatchFetchLanguages: PropTypes.func.isRequired,
dispatchFetchImportLists: PropTypes.func.isRequired,
dispatchFetchIndexerFlags: PropTypes.func.isRequired,
dispatchFetchUISettings: PropTypes.func.isRequired,
dispatchFetchStatus: PropTypes.func.isRequired,
dispatchFetchTranslations: PropTypes.func.isRequired,

View File

@@ -244,7 +244,7 @@ class SignalRConnector extends Component {
handleWantedCutoff = (body) => {
if (body.action === 'updated') {
this.props.dispatchUpdateItem({
section: 'cutoffUnmet',
section: 'wanted.cutoffUnmet',
updateOnly: true,
...body.resource
});
@@ -254,7 +254,7 @@ class SignalRConnector extends Component {
handleWantedMissing = (body) => {
if (body.action === 'updated') {
this.props.dispatchUpdateItem({
section: 'missing',
section: 'wanted.missing',
updateOnly: true,
...body.resource
});

View File

@@ -15,6 +15,7 @@ class RelativeDateCell extends PureComponent {
className,
date,
includeSeconds,
includeTime,
showRelativeDates,
shortDateFormat,
longDateFormat,
@@ -39,7 +40,7 @@ class RelativeDateCell extends PureComponent {
title={formatDateTime(date, longDateFormat, timeFormat, { includeSeconds, includeRelativeDay: !showRelativeDates })}
{...otherProps}
>
{getRelativeDate(date, shortDateFormat, showRelativeDates, { timeFormat, includeSeconds, timeForToday: true })}
{getRelativeDate({ date, shortDateFormat, showRelativeDates, timeFormat, includeSeconds, includeTime, timeForToday: true })}
</Component>
);
}
@@ -49,6 +50,7 @@ RelativeDateCell.propTypes = {
className: PropTypes.string.isRequired,
date: PropTypes.string,
includeSeconds: PropTypes.bool.isRequired,
includeTime: PropTypes.bool.isRequired,
showRelativeDates: PropTypes.bool.isRequired,
shortDateFormat: PropTypes.string.isRequired,
longDateFormat: PropTypes.string.isRequired,
@@ -60,6 +62,7 @@ RelativeDateCell.propTypes = {
RelativeDateCell.defaultProps = {
className: styles.cell,
includeSeconds: false,
includeTime: false,
component: TableRowCell
};

View File

@@ -49,11 +49,12 @@ class TableOptionsModal extends Component {
onPageSizeChange = ({ value }) => {
let pageSizeError = null;
const maxPageSize = this.props.maxPageSize ?? 250;
if (value < 5) {
pageSizeError = translate('TablePageSizeMinimum', { minimumValue: '5' });
} else if (value > 250) {
pageSizeError = translate('TablePageSizeMaximum', { maximumValue: '250' });
} else if (value > maxPageSize) {
pageSizeError = translate('TablePageSizeMaximum', { maximumValue: `${maxPageSize}` });
} else {
this.props.onTableOptionChange({ pageSize: value });
}
@@ -248,6 +249,7 @@ TableOptionsModal.propTypes = {
isOpen: PropTypes.bool.isRequired,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
pageSize: PropTypes.number,
maxPageSize: PropTypes.number,
canModifyColumns: PropTypes.bool.isRequired,
optionsComponent: PropTypes.elementType,
onTableOptionChange: PropTypes.func.isRequired,

View File

@@ -1,6 +1,7 @@
import PropTypes from 'prop-types';
import React from 'react';
import { kinds } from 'Helpers/Props';
import sortByProp from 'Utilities/Array/sortByProp';
import Label from './Label';
import styles from './TagList.css';
@@ -8,7 +9,7 @@ function TagList({ tags, tagList }) {
const sortedTags = tags
.map((tagId) => tagList.find((tag) => tag.id === tagId))
.filter((tag) => !!tag)
.sort((a, b) => a.label.localeCompare(b.label));
.sort(sortByProp('label'));
return (
<div className={styles.tags}>

View File

@@ -25,14 +25,3 @@
font-family: 'Ubuntu Mono';
src: url('UbuntuMono-Regular.eot?#iefix&v=1.3.0') format('embedded-opentype'), url('UbuntuMono-Regular.woff?v=1.3.0') format('woff'), url('UbuntuMono-Regular.ttf?v=1.3.0') format('truetype');
}
/*
* text-security-disc
*/
@font-face {
font-weight: normal;
font-style: normal;
font-family: 'text-security-disc';
src: url('text-security-disc.woff?v=1.3.0') format('woff'), url('text-security-disc.ttf?v=1.3.0') format('truetype');
}

View File

@@ -15,5 +15,5 @@
"start_url": "../../../../",
"theme_color": "#3a3f51",
"background_color": "#3a3f51",
"display": "minimal-ui"
"display": "standalone"
}

View File

@@ -37,7 +37,7 @@ class EpisodeDetailsModal extends Component {
return (
<Modal
isOpen={isOpen}
size={sizes.EXTRA_LARGE}
size={sizes.EXTRA_EXTRA_LARGE}
closeOnBackgroundClick={this.state.closeOnBackgroundClick}
onModalClose={onModalClose}
>

View File

@@ -111,6 +111,8 @@ class EpisodeHistoryRow extends Component {
<RelativeDateCellConnector
date={date}
includeSeconds={true}
includeTime={true}
/>
<TableRowCell className={styles.actions}>

View File

@@ -0,0 +1,26 @@
import React from 'react';
import { useSelector } from 'react-redux';
import createIndexerFlagsSelector from 'Store/Selectors/createIndexerFlagsSelector';
interface IndexerFlagsProps {
indexerFlags: number;
}
function IndexerFlags({ indexerFlags = 0 }: IndexerFlagsProps) {
const allIndexerFlags = useSelector(createIndexerFlagsSelector);
const flags = allIndexerFlags.items.filter(
// eslint-disable-next-line no-bitwise
(item) => (indexerFlags & item.id) === item.id
);
return flags.length ? (
<ul>
{flags.map((flag, index) => {
return <li key={index}>{flag.name}</li>;
})}
</ul>
) : null;
}
export default IndexerFlags;

View File

@@ -17,6 +17,12 @@
width: 175px;
}
.customFormatScore {
composes: cell from '~Components/Table/Cells/TableRowCell.css';
width: 65px;
}
.actions {
composes: cell from '~Components/Table/Cells/TableRowCell.css';

View File

@@ -2,6 +2,7 @@
// Please do not change this file!
interface CssExports {
'actions': string;
'customFormatScore': string;
'customFormats': string;
'languages': string;
'quality': string;

View File

@@ -11,6 +11,7 @@ import EpisodeLanguages from 'Episode/EpisodeLanguages';
import EpisodeQuality from 'Episode/EpisodeQuality';
import { icons, kinds, tooltipPositions } from 'Helpers/Props';
import formatBytes from 'Utilities/Number/formatBytes';
import formatCustomFormatScore from 'Utilities/Number/formatCustomFormatScore';
import translate from 'Utilities/String/translate';
import MediaInfo from './MediaInfo';
import styles from './EpisodeFileRow.css';
@@ -55,6 +56,7 @@ class EpisodeFileRow extends Component {
languages,
quality,
customFormats,
customFormatScore,
qualityCutoffNotMet,
mediaInfo,
columns
@@ -127,6 +129,17 @@ class EpisodeFileRow extends Component {
);
}
if (name === 'customFormatScore') {
return (
<TableRowCell
key={name}
className={styles.customFormatScore}
>
{formatCustomFormatScore(customFormatScore, customFormats.length)}
</TableRowCell>
);
}
if (name === 'actions') {
return (
<TableRowCell
@@ -183,6 +196,7 @@ EpisodeFileRow.propTypes = {
quality: PropTypes.object.isRequired,
qualityCutoffNotMet: PropTypes.bool.isRequired,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
mediaInfo: PropTypes.object,
columns: PropTypes.arrayOf(PropTypes.object).isRequired,
onDeleteEpisodeFile: PropTypes.func.isRequired

View File

@@ -1,10 +1,11 @@
import PropTypes from 'prop-types';
import React, { Component } from 'react';
import Icon from 'Components/Icon';
import Label from 'Components/Label';
import ConfirmModal from 'Components/Modal/ConfirmModal';
import Table from 'Components/Table/Table';
import TableBody from 'Components/Table/TableBody';
import { kinds, sizes } from 'Helpers/Props';
import { icons, kinds, sizes } from 'Helpers/Props';
import QualityProfileNameConnector from 'Settings/Profiles/Quality/QualityProfileNameConnector';
import translate from 'Utilities/String/translate';
import EpisodeAiringConnector from './EpisodeAiringConnector';
@@ -42,6 +43,15 @@ const columns = [
isSortable: false,
isVisible: true
},
{
name: 'customFormatScore',
label: React.createElement(Icon, {
name: icons.SCORE,
title: () => translate('CustomFormatScore')
}),
isSortable: true,
isVisible: true
},
{
name: 'actions',
label: '',
@@ -94,6 +104,7 @@ class EpisodeSummary extends Component {
languages,
quality,
customFormats,
customFormatScore,
qualityCutoffNotMet,
onDeleteEpisodeFile
} = this.props;
@@ -143,6 +154,7 @@ class EpisodeSummary extends Component {
quality={quality}
qualityCutoffNotMet={qualityCutoffNotMet}
customFormats={customFormats}
customFormatScore={customFormatScore}
mediaInfo={mediaInfo}
columns={columns}
onDeleteEpisodeFile={onDeleteEpisodeFile}
@@ -179,6 +191,7 @@ EpisodeSummary.propTypes = {
quality: PropTypes.object,
qualityCutoffNotMet: PropTypes.bool,
customFormats: PropTypes.arrayOf(PropTypes.object),
customFormatScore: PropTypes.number.isRequired,
onDeleteEpisodeFile: PropTypes.func.isRequired
};

View File

@@ -31,7 +31,8 @@ function createMapStateToProps() {
languages,
quality,
qualityCutoffNotMet,
customFormats
customFormats,
customFormatScore
} = episodeFile;
return {
@@ -45,7 +46,8 @@ function createMapStateToProps() {
languages,
quality,
qualityCutoffNotMet,
customFormats
customFormats,
customFormatScore
};
}
);

View File

@@ -0,0 +1,17 @@
import ReleaseType from 'InteractiveImport/ReleaseType';
import translate from 'Utilities/String/translate';
export default function getReleaseTypeName(
releaseType?: ReleaseType
): string | null {
switch (releaseType) {
case 'singleEpisode':
return translate('SingleEpisode');
case 'multiEpisode':
return translate('MultiEpisode');
case 'seasonPack':
return translate('SeasonPack');
default:
return translate('Unknown');
}
}

View File

@@ -1,4 +1,5 @@
import ModelBase from 'App/ModelBase';
import ReleaseType from 'InteractiveImport/ReleaseType';
import Language from 'Language/Language';
import { QualityModel } from 'Quality/Quality';
import CustomFormat from 'typings/CustomFormat';
@@ -16,6 +17,8 @@ export interface EpisodeFile extends ModelBase {
languages: Language[];
quality: QualityModel;
customFormats: CustomFormat[];
indexerFlags: number;
releaseType: ReleaseType;
mediaInfo: MediaInfo;
qualityCutoffNotMet: boolean;
}

View File

@@ -0,0 +1,17 @@
import { useCallback, useState } from 'react';
export default function useModalOpenState(
initialState: boolean
): [boolean, () => void, () => void] {
const [isOpen, setOpen] = useState(initialState);
const setModalOpen = useCallback(() => {
setOpen(true);
}, [setOpen]);
const setModalClosed = useCallback(() => {
setOpen(false);
}, [setOpen]);
return [isOpen, setModalOpen, setModalClosed];
}

View File

@@ -62,12 +62,14 @@ import {
faFileExport as fasFileExport,
faFileInvoice as farFileInvoice,
faFilter as fasFilter,
faFlag as fasFlag,
faFolderOpen as fasFolderOpen,
faForward as fasForward,
faHeart as fasHeart,
faHistory as fasHistory,
faHome as fasHome,
faInfoCircle as fasInfoCircle,
faLanguage as fasLanguage,
faLaptop as fasLaptop,
faLevelUpAlt as fasLevelUpAlt,
faListCheck as fasListCheck,
@@ -154,6 +156,7 @@ export const FILE_MISSING = fasFileCircleQuestion;
export const FILTER = fasFilter;
export const FINALE_SEASON = fasCirclePause;
export const FINALE_SERIES = fasCircleStop;
export const FLAG = fasFlag;
export const FOOTNOTE = fasAsterisk;
export const FOLDER = farFolder;
export const FOLDER_OPEN = fasFolderOpen;
@@ -166,6 +169,7 @@ export const IGNORE = fasTimesCircle;
export const INFO = fasInfoCircle;
export const INTERACTIVE = fasUser;
export const KEYBOARD = farKeyboard;
export const LANGUAGE = fasLanguage;
export const LOGOUT = fasSignOutAlt;
export const MANAGE = fasListCheck;
export const MEDIA_INFO = farFileInvoice;

View File

@@ -12,10 +12,12 @@ export const PASSWORD = 'password';
export const PATH = 'path';
export const QUALITY_PROFILE_SELECT = 'qualityProfileSelect';
export const INDEXER_SELECT = 'indexerSelect';
export const INDEXER_FLAGS_SELECT = 'indexerFlagsSelect';
export const LANGUAGE_SELECT = 'languageSelect';
export const DOWNLOAD_CLIENT_SELECT = 'downloadClientSelect';
export const ROOT_FOLDER_SELECT = 'rootFolderSelect';
export const SELECT = 'select';
export const SERIES_TAG = 'seriesTag';
export const DYNAMIC_SELECT = 'dynamicSelect';
export const SERIES_TYPE_SELECT = 'seriesTypeSelect';
export const TAG = 'tag';
@@ -44,6 +46,7 @@ export const all = [
ROOT_FOLDER_SELECT,
LANGUAGE_SELECT,
SELECT,
SERIES_TAG,
DYNAMIC_SELECT,
SERIES_TYPE_SELECT,
TAG,

View File

@@ -3,5 +3,5 @@ export const SMALL = 'small';
export const MEDIUM = 'medium';
export const LARGE = 'large';
export const EXTRA_LARGE = 'extraLarge';
export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE];
export const EXTRA_EXTRA_LARGE = 'extraExtraLarge';
export const all = [EXTRA_SMALL, SMALL, MEDIUM, LARGE, EXTRA_LARGE, EXTRA_EXTRA_LARGE];

View File

@@ -77,7 +77,7 @@ function InteractiveImportSelectFolderModalContent(
dispatch(
executeCommand({
name: commandNames.DOWNLOADED_EPSIODES_SCAN,
name: commandNames.DOWNLOADED_EPISODES_SCAN,
path: folder,
})
);

View File

@@ -0,0 +1,34 @@
import React from 'react';
import Modal from 'Components/Modal/Modal';
import SelectIndexerFlagsModalContent from './SelectIndexerFlagsModalContent';
interface SelectIndexerFlagsModalProps {
isOpen: boolean;
indexerFlags: number;
modalTitle: string;
onIndexerFlagsSelect(indexerFlags: number): void;
onModalClose(): void;
}
function SelectIndexerFlagsModal(props: SelectIndexerFlagsModalProps) {
const {
isOpen,
indexerFlags,
modalTitle,
onIndexerFlagsSelect,
onModalClose,
} = props;
return (
<Modal isOpen={isOpen} onModalClose={onModalClose}>
<SelectIndexerFlagsModalContent
indexerFlags={indexerFlags}
modalTitle={modalTitle}
onIndexerFlagsSelect={onIndexerFlagsSelect}
onModalClose={onModalClose}
/>
</Modal>
);
}
export default SelectIndexerFlagsModal;

View File

@@ -0,0 +1,7 @@
.modalBody {
composes: modalBody from '~Components/Modal/ModalBody.css';
display: flex;
flex: 1 1 auto;
flex-direction: column;
}

View File

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

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