Compare commits
75 Commits
v1.21.0-ar
...
v1.21.0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
afd46ebee8 | ||
|
|
be47d1e56c | ||
|
|
2f2e00237d | ||
|
|
3d6b343413 | ||
|
|
9e5adeb610 | ||
|
|
ae29e5c5a2 | ||
|
|
dc8576768f | ||
|
|
422ef2cb76 | ||
|
|
001dcd328c | ||
|
|
0bd0912613 | ||
|
|
3148d31214 | ||
|
|
36584eee85 | ||
|
|
0e612f01f1 | ||
|
|
cd9d9ae8d2 | ||
|
|
ea2765f8c7 | ||
|
|
448e7c3a7d | ||
|
|
6ab3cd77a7 | ||
|
|
3dfbb0e0a5 | ||
|
|
726f62b9b6 | ||
|
|
81c30347f6 | ||
|
|
a397893217 | ||
|
|
12c5bbd778 | ||
|
|
06261c1118 | ||
|
|
686fe6fdf8 | ||
|
|
c80a1fa261 | ||
|
|
6167011ee5 | ||
|
|
bc399d95a0 | ||
|
|
519dd17d37 | ||
|
|
0761593411 | ||
|
|
caa45415b1 | ||
|
|
ed297d9d6c | ||
|
|
c6486c3643 | ||
|
|
f9695068a8 | ||
|
|
fd90adba4d | ||
|
|
970aa612fe | ||
|
|
71169944dc | ||
|
|
d77f9eb44e | ||
|
|
22f2037ea6 | ||
|
|
2cdf755c20 | ||
|
|
f99ab47c01 | ||
|
|
7e4175ff21 | ||
|
|
4157432aa7 | ||
|
|
741b2c4e9f | ||
|
|
6dbe9ea814 | ||
|
|
96328ab5c6 | ||
|
|
c31709681a | ||
|
|
0a3d7c5915 | ||
|
|
912c63e562 | ||
|
|
077513151e | ||
|
|
191f39e8bd | ||
|
|
048b6c1d90 | ||
|
|
a6a065ac0b | ||
|
|
abb0b2d763 | ||
|
|
d2668d3f49 | ||
|
|
bee6eb288f | ||
|
|
3473aed27e | ||
|
|
a9144a2167 | ||
|
|
59822d6e42 | ||
|
|
0bd1bee1fa | ||
|
|
46326f9d16 | ||
|
|
54b96cc451 | ||
|
|
7d2a187865 | ||
|
|
17df5dd072 | ||
|
|
4b48a36ad3 | ||
|
|
16bd3e9fd5 | ||
|
|
6360c82898 | ||
|
|
f1df9eeb2f | ||
|
|
a3973791fb | ||
|
|
157ab80be1 | ||
|
|
ac0f95b773 | ||
|
|
45ebfb937e | ||
|
|
85325cda7f | ||
|
|
5fc02d0d94 | ||
|
|
16902f85fb | ||
|
|
17b5a0bf9c |
2
.github/workflows/ci.yml
vendored
2
.github/workflows/ci.yml
vendored
@@ -12,7 +12,7 @@ jobs:
|
||||
test:
|
||||
name: Lint & Test Build
|
||||
runs-on: ubuntu-20.04
|
||||
container: node:12.18-alpine
|
||||
container: node:14.16-alpine
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
19
.github/workflows/release.yml
vendored
19
.github/workflows/release.yml
vendored
@@ -9,7 +9,7 @@ jobs:
|
||||
test:
|
||||
name: Lint & Test Build
|
||||
runs-on: ubuntu-20.04
|
||||
container: node:12.18-alpine
|
||||
container: node:14.16-alpine
|
||||
steps:
|
||||
- name: checkout
|
||||
uses: actions/checkout@v2
|
||||
@@ -33,7 +33,22 @@ jobs:
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v2
|
||||
with:
|
||||
node-version: 12
|
||||
node-version: 14
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v1
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v1
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
username: ${{ secrets.DOCKER_USERNAME }}
|
||||
password: ${{ secrets.DOCKER_TOKEN }}
|
||||
- name: Login to GitHub Container Registry
|
||||
uses: docker/login-action@v1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.repository_owner }}
|
||||
password: ${{ secrets.CR_PAT }}
|
||||
- name: Install dependencies
|
||||
run: yarn
|
||||
- name: Release
|
||||
|
||||
805
CHANGELOG.md
Normal file
805
CHANGELOG.md
Normal file
@@ -0,0 +1,805 @@
|
||||
# [1.21.0](https://github.com/sct/overseerr/compare/v1.20.1...v1.21.0) (2021-03-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* do not allow editing of user settings under certain conditions ([#1168](https://github.com/sct/overseerr/issues/1168)) ([001dcd3](https://github.com/sct/overseerr/commit/001dcd328c8d3b1c417fd7c7ee2aa20183b08eef))
|
||||
* **frontend:** check for ID instead of email after initial setup Plex login ([#1097](https://github.com/sct/overseerr/issues/1097)) ([778dda6](https://github.com/sct/overseerr/commit/778dda67d54df87347dd79577ef1bdc88d3c1d3f))
|
||||
* **frontend:** check if swr is validating to determine if we should fetch new data ([e5f5bdb](https://github.com/sct/overseerr/commit/e5f5bdb95c62eba31a3321a7457d354f0226bf85)), closes [#719](https://github.com/sct/overseerr/issues/719)
|
||||
* **frontend:** never hide available content in search results ([d48edeb](https://github.com/sct/overseerr/commit/d48edeb5a9bd8e2edce8bca0fea50e300bb7a1ae))
|
||||
* **lang:** add missing i18n strings ([6072e8a](https://github.com/sct/overseerr/commit/6072e8aa9a0f84e50c44a92af303aad15b5f3021))
|
||||
* **lang:** edit new Telegram-related strings to conform to style guide ([#1093](https://github.com/sct/overseerr/issues/1093)) ([bdf67e7](https://github.com/sct/overseerr/commit/bdf67e732b6c77cbae768a25edfc9a663ef0108b))
|
||||
* **notif:** loosen input validation on Pushover settings ([#1166](https://github.com/sct/overseerr/issues/1166)) ([3148d31](https://github.com/sct/overseerr/commit/3148d312141248653c5d1e42cd2882a67a339163))
|
||||
* **notif:** set URL for Discord embeds rather than adding a field for the link ([#1167](https://github.com/sct/overseerr/issues/1167)) ([0bd0912](https://github.com/sct/overseerr/commit/0bd0912613f0db24bd0da4ec956b5119133e35d4))
|
||||
* correctly send auto-approval notifictions for series ([8634081](https://github.com/sct/overseerr/commit/8634081c869a2078793ecf06b1b7e249bba0a2f8))
|
||||
* **lang:** fix singular form of season count ([#1080](https://github.com/sct/overseerr/issues/1080)) ([b57645d](https://github.com/sct/overseerr/commit/b57645d382361c856281e7a74295afe16c5390f2))
|
||||
* **requests:** add plex url to request item ([#1088](https://github.com/sct/overseerr/issues/1088)) ([420038d](https://github.com/sct/overseerr/commit/420038d5ffdd4070df03e5c5cb6ef8d6208fddb5))
|
||||
* **sonarr:** correctly search when updating existing sonarr series ([ed0a7fb](https://github.com/sct/overseerr/commit/ed0a7fbdf5122a26fa936e83b76a97c55781782d)), closes [#588](https://github.com/sct/overseerr/issues/588)
|
||||
* **ui:** add alt prop to studio/network logos & fix blinking text cursor ([#1095](https://github.com/sct/overseerr/issues/1095)) ([0c4637f](https://github.com/sct/overseerr/commit/0c4637f779d8904037b9cbd5fe9166cf05a891c5))
|
||||
* **ui:** add link to poster image on request items ([7289872](https://github.com/sct/overseerr/commit/7289872937d5bb94d027424760ee1ceb94095604))
|
||||
* **ui:** correct language usage re: "sync" vs. "scan" ([#1079](https://github.com/sct/overseerr/issues/1079)) ([e98f2b9](https://github.com/sct/overseerr/commit/e98f2b96058fb9c5af77be2e8a1bd07fb8fcca06))
|
||||
* **ui:** display "Season" vs. "Seasons" as appropriate, and fix request block "Seasons" formatting ([#1127](https://github.com/sct/overseerr/issues/1127)) ([45886cc](https://github.com/sct/overseerr/commit/45886ccef1bee57dc555060a491834567e45b59c))
|
||||
* **ui:** request list button sizes ([#1152](https://github.com/sct/overseerr/issues/1152)) ([fc73592](https://github.com/sct/overseerr/commit/fc73592b69c38191f91a68a020868b8e5ec2e2e2))
|
||||
* fix language filter link on movie detail pages ([#1142](https://github.com/sct/overseerr/issues/1142)) ([60d453b](https://github.com/sct/overseerr/commit/60d453b0bbba5e2060f72f40d1dde85ec6b05af4))
|
||||
* remove language/region filtering on studio/network results ([#1129](https://github.com/sct/overseerr/issues/1129)) ([109aca8](https://github.com/sct/overseerr/commit/109aca8229dc7b81cac314d84591f1c04c12ac2e))
|
||||
* **api:** check correct permissions for auto approve when requests are created ([3c1a72b](https://github.com/sct/overseerr/commit/3c1a72b038fd178b4be4dc082cd1496474148d7e))
|
||||
* **frontend:** status, requested by, and modified alignment fix ([#1109](https://github.com/sct/overseerr/issues/1109)) ([1a7dc1a](https://github.com/sct/overseerr/commit/1a7dc1acf57888d3d0285b58c1c97a824a232216))
|
||||
* **ui:** don't show "Password" user settings tab if current user lacks perms to modify the password ([#1063](https://github.com/sct/overseerr/issues/1063)) ([b146d11](https://github.com/sct/overseerr/commit/b146d11e2ffecedae76472b0491a4662ca4a4a4e))
|
||||
* **ui:** fix Radarr logo alignment ([#1068](https://github.com/sct/overseerr/issues/1068)) ([0fa005a](https://github.com/sct/overseerr/commit/0fa005a99cd868b5a235ae9ce65b4c64b05d0f47))
|
||||
* **ui:** fix request list UI behavior when season list is too long ([#1106](https://github.com/sct/overseerr/issues/1106)) ([8507691](https://github.com/sct/overseerr/commit/85076919c6ccbf052699b7d5f4ba8b6e5e5af74d))
|
||||
* **ui:** improve responsive design on new request list UI ([#1105](https://github.com/sct/overseerr/issues/1105)) ([1f8b03f](https://github.com/sct/overseerr/commit/1f8b03ff6f67ce76051667de05166da54ed3dc89))
|
||||
* **ui:** list all movie studios instead of just the first result ([#1110](https://github.com/sct/overseerr/issues/1110)) ([239202d](https://github.com/sct/overseerr/commit/239202d9c11f27410b0fa084bcc4c824b7136081))
|
||||
* add correct permission checks to modifying user password/permissions ([ddfc5e6](https://github.com/sct/overseerr/commit/ddfc5e6aa8fc636931f495d6f23d56367466e3b5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add tagline, episode runtime, genres list to media details & clean/refactor CSS into globals ([#1160](https://github.com/sct/overseerr/issues/1160)) ([2f2e002](https://github.com/sct/overseerr/commit/2f2e00237d43bdab85bfadc3c4f2fbcdde4c2e90))
|
||||
* **docker:** add tini to docker image ([#1017](https://github.com/sct/overseerr/issues/1017)) ([1629d02](https://github.com/sct/overseerr/commit/1629d02f3d8368bfd5f6fed05382974ae6fce51f))
|
||||
* **email:** add pgp support ([#1138](https://github.com/sct/overseerr/issues/1138)) ([9e5adeb](https://github.com/sct/overseerr/commit/9e5adeb610bdc4800ff536412d0ae8a11fb4338d))
|
||||
* **frontend:** add loading bar indicator ([#1170](https://github.com/sct/overseerr/issues/1170)) ([3d6b343](https://github.com/sct/overseerr/commit/3d6b3434138fec49c58f2bf74f781d5e2fc2911f))
|
||||
* **lang:** localize job names ([#1043](https://github.com/sct/overseerr/issues/1043)) ([594aad9](https://github.com/sct/overseerr/commit/594aad9d3ae9b323677f3af8c434d7664526593d))
|
||||
* **lang:** translations update from Weblate ([#1051](https://github.com/sct/overseerr/issues/1051)) ([69bf817](https://github.com/sct/overseerr/commit/69bf817f598babed99964f073259f827b60bd014))
|
||||
* **lang:** Translations update from Weblate ([#1131](https://github.com/sct/overseerr/issues/1131)) ([e4686d6](https://github.com/sct/overseerr/commit/e4686d664b52448e32488ff1c4236f72e01e9a29))
|
||||
* **notif:** add "Media Automatically Approved" notification type ([#1137](https://github.com/sct/overseerr/issues/1137)) ([f7d2723](https://github.com/sct/overseerr/commit/f7d2723fab2c30564fd23945709cd39b178a6eef))
|
||||
* **notif:** add settings for Discord bot username & avatar URL ([#1113](https://github.com/sct/overseerr/issues/1113)) ([3384eb1](https://github.com/sct/overseerr/commit/3384eb1c479114c0246cb22f9a933aa79fb95fcf))
|
||||
* **notif:** include poster image in Telegram notifications ([#1112](https://github.com/sct/overseerr/issues/1112)) ([48387e5](https://github.com/sct/overseerr/commit/48387e5b2f26c0c33acd436c6e1cf902d6c32101))
|
||||
* **scan:** add support for new plex tv agent ([#1144](https://github.com/sct/overseerr/issues/1144)) ([a51d2a2](https://github.com/sct/overseerr/commit/a51d2a24d51d092a0c6da608e3322f19a37c2d28))
|
||||
* **ui:** add user ID to profile header ([6e95c8b](https://github.com/sct/overseerr/commit/6e95c8b7a10e3467bfd2c3df84ccf886fe01ca5c))
|
||||
* add genre/studio/network view to Discover results ([#1067](https://github.com/sct/overseerr/issues/1067)) ([f28112f](https://github.com/sct/overseerr/commit/f28112f057df2589f31ae0d0b14e8b50e479fdb7))
|
||||
* add language-filtered Discover pages ([#1111](https://github.com/sct/overseerr/issues/1111)) ([7501161](https://github.com/sct/overseerr/commit/75011610e57f03098c8be9375d0c9ba1e3647e9b))
|
||||
* add studio/network sliders to discover ([1c6914f](https://github.com/sct/overseerr/commit/1c6914f5ce5c0d171c4609813915b50233a8e3ad))
|
||||
* **telegram:** add support for individual chat notifications ([#1027](https://github.com/sct/overseerr/issues/1027)) ([f6d00d8](https://github.com/sct/overseerr/commit/f6d00d8d1559879189f83739193c6e2acafde51d))
|
||||
* **ui:** display "Owner" role instead of "Admin" for user ID 1 ([#1050](https://github.com/sct/overseerr/issues/1050)) ([1b55d2d](https://github.com/sct/overseerr/commit/1b55d2dfbc06d900e7370a4ddfd81789a25bf00c))
|
||||
* **ui:** display season count on TV details page ([#1078](https://github.com/sct/overseerr/issues/1078)) ([4365231](https://github.com/sct/overseerr/commit/436523139e8f1594c352b17032734b4498d3994f))
|
||||
* **ui:** in Settings > Services, make Radarr/Sonarr server names and logos clickable links ([#1008](https://github.com/sct/overseerr/issues/1008)) ([6a1e389](https://github.com/sct/overseerr/commit/6a1e3891aa5f84b6adb1e475a6658a8cd4e34c22))
|
||||
* **ui:** request list redesign ([#1099](https://github.com/sct/overseerr/issues/1099)) ([cd21865](https://github.com/sct/overseerr/commit/cd21865c4d5be00c13c372e0b7a058f61ec855a2))
|
||||
|
||||
## [1.20.1](https://github.com/sct/overseerr/compare/v1.20.0...v1.20.1) (2021-02-28)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **notif:** escape application title in Telegram notifications ([#1012](https://github.com/sct/overseerr/issues/1012)) ([5560abf](https://github.com/sct/overseerr/commit/5560abf459b0350ff30b5e71d4208418fc8f3b3e))
|
||||
* **notif:** fixed typo in pushover hint ([#1029](https://github.com/sct/overseerr/issues/1029)) ([e9f2fe9](https://github.com/sct/overseerr/commit/e9f2fe910d72fa41bc27673ed43291211c3cac65))
|
||||
* **notifications:** correctly send tv auto approval notifications ([537850f](https://github.com/sct/overseerr/commit/537850f414a88df24c78794a2fd68e1e24ff73d1)), closes [#1041](https://github.com/sct/overseerr/issues/1041)
|
||||
* **plex-sync:** no longer incorrectly sets 4k availability when there isnt any ([3f9a116](https://github.com/sct/overseerr/commit/3f9a116b17d78eeb04f0f125a4f3af6f907c83dd)), closes [#990](https://github.com/sct/overseerr/issues/990)
|
||||
* **ui:** for server default options, display "All" region/language option instead of empty string ([#1042](https://github.com/sct/overseerr/issues/1042)) ([3fed26c](https://github.com/sct/overseerr/commit/3fed26cfbe74cb662ca531fd37b69f159a051ac1))
|
||||
* **ui:** show translated string on sonarr sucesss/failure toast messages ([#1035](https://github.com/sct/overseerr/issues/1035)) ([eefcbcd](https://github.com/sct/overseerr/commit/eefcbcd3ddfa5258ee24dbbbd79de5bf50310f27))
|
||||
* **ui:** use country-flag-icons instead of country-flag-emoji for RegionSelector ([#1011](https://github.com/sct/overseerr/issues/1011)) ([abcd7c9](https://github.com/sct/overseerr/commit/abcd7c997584c1310bd8b313ac38f30e335af8d7))
|
||||
* add missing default value for settings context ([084917f](https://github.com/sct/overseerr/commit/084917f02d399e2d29bb9927e033c2e6533f586c))
|
||||
* added missing language default for ssr context defaults ([9ce88ab](https://github.com/sct/overseerr/commit/9ce88abcc85d744d77172cd2357fdb4ff60dc5e4))
|
||||
* allow users to override language/region settings ([69294a7](https://github.com/sct/overseerr/commit/69294a7c4c5bbe55c5cd276786cdfd48ddbff889)), closes [#1013](https://github.com/sct/overseerr/issues/1013)
|
||||
|
||||
# [1.20.0](https://github.com/sct/overseerr/compare/v1.19.1...v1.20.0) (2021-02-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** add isAuthenticated middleware to base user route ([8a27c70](https://github.com/sct/overseerr/commit/8a27c7062599ea23dca115e6e6e95a594e1b219a))
|
||||
* **api:** sort users requests by most recent ([1798383](https://github.com/sct/overseerr/commit/17983837fc10661a59d29fc1531530fca0d77825))
|
||||
* **api:** Use POST instead of GET for API endpoints that mutate state ([#877](https://github.com/sct/overseerr/issues/877)) ([ff0b5ed](https://github.com/sct/overseerr/commit/ff0b5ed44132cc5a0cd178035796d042ba735a8d))
|
||||
* **auth:** handle sign-in attempts from emails with no password ([#933](https://github.com/sct/overseerr/issues/933)) ([5e37a96](https://github.com/sct/overseerr/commit/5e37a96bc017471f8dc4cbdd57f2e8c3568bd97f))
|
||||
* **frontend:** changed plex, request, and cog buttons to align properly on smaller mobile UIs ([#928](https://github.com/sct/overseerr/issues/928)) ([f1c3358](https://github.com/sct/overseerr/commit/f1c335815f2f17465cdd36ceb223e78a58149b3b))
|
||||
* **frontend:** check for id instead of email after logging in ([c4af4c4](https://github.com/sct/overseerr/commit/c4af4c42ab00f1a63a2f5326c9cd8b26c19f4f14))
|
||||
* **frontend:** Do not allow user w/ ID 1 to disable 'Admin' permission ([#965](https://github.com/sct/overseerr/issues/965)) ([77b2d9e](https://github.com/sct/overseerr/commit/77b2d9ea22a2f70cff58ac9421f3f6231bc93059))
|
||||
* **frontend:** handle empty array of media attributes ([#922](https://github.com/sct/overseerr/issues/922)) ([04fa9f7](https://github.com/sct/overseerr/commit/04fa9f79e2ec90082b3fa15590dd170f7d68ad52))
|
||||
* **frontend:** request and cog button would be misaligned without play on plex/watch trailer button ([#956](https://github.com/sct/overseerr/issues/956)) ([e28dfad](https://github.com/sct/overseerr/commit/e28dfadaf57d47887013c31dc5006332473156e3))
|
||||
* **frontend:** Update AdvancedRequester to reflect new /user API response ([#970](https://github.com/sct/overseerr/issues/970)) ([b4bac6a](https://github.com/sct/overseerr/commit/b4bac6a9157119a4f234933245944e133c127bd0))
|
||||
* **frontend:** use region settings instead of hardcoded 'US' value for movie/TV ratings ([#1006](https://github.com/sct/overseerr/issues/1006)) ([6ecd202](https://github.com/sct/overseerr/commit/6ecd202607cb48d559440da810ecc585e740542b))
|
||||
* **lang:** formatMessage should not use an object spread ([8a7fa00](https://github.com/sct/overseerr/commit/8a7fa00164fd5c5501da525baa29be97bac7e7c4))
|
||||
* **lang:** Remove unused strings and correct spelling of 'canceling'/'canceled' ([#981](https://github.com/sct/overseerr/issues/981)) ([5b64655](https://github.com/sct/overseerr/commit/5b646557765d1ad75e44e1c0e60e0291313c7746))
|
||||
* **login:** fix the gap when 'use your overseer account' was selected ([#870](https://github.com/sct/overseerr/issues/870)) ([d163e29](https://github.com/sct/overseerr/commit/d163e294599c4bd9bdc0a148db15c8e8541410d8))
|
||||
* **notif:** Do not HTML-escape email subjects ([#931](https://github.com/sct/overseerr/issues/931)) ([019622a](https://github.com/sct/overseerr/commit/019622aab1b94cc4d71cacbf0dc5cf64b62c8623))
|
||||
* **notif:** Remove extra newlines from Telegram notifications ([#973](https://github.com/sct/overseerr/issues/973)) ([bbea522](https://github.com/sct/overseerr/commit/bbea52249950eb98a8d3886f2bd7648a7d669bf4))
|
||||
* **plex:** Check Plex server access on user import ([#955](https://github.com/sct/overseerr/issues/955)) ([bdb3cb2](https://github.com/sct/overseerr/commit/bdb3cb202550e34d8951ac2b5015f97f6a5c1ebf))
|
||||
* **plex-sync:** get correct Plex metadata for Hama movie items ([#901](https://github.com/sct/overseerr/issues/901)) ([03cecb3](https://github.com/sct/overseerr/commit/03cecb33559e27199c5a174fc86de0c4550fe666)), closes [#898](https://github.com/sct/overseerr/issues/898)
|
||||
* **requests:** correctly filter requests out for users without view requests permission ([e118501](https://github.com/sct/overseerr/commit/e118501bf1dfa8dada2c57090e62631de620f3dd))
|
||||
* **requests:** correctly handle when tvdbid is missing ([#891](https://github.com/sct/overseerr/issues/891)) ([e037ba4](https://github.com/sct/overseerr/commit/e037ba48f173c06b0c9c8b03085edf832d770c06))
|
||||
* **search:** Handle search errors and escape * ([#893](https://github.com/sct/overseerr/issues/893)) ([034968e](https://github.com/sct/overseerr/commit/034968e4370eaea726c94730274349c083856813))
|
||||
* **services:** update all radarr/sonarr endpoints to use v3 ([da5ca02](https://github.com/sct/overseerr/commit/da5ca02f81fe91070afbda3e1ebc8d869fe39a8f))
|
||||
* **sonarr:** use qualityProfileId instad of profileId when adding series ([552a7e3](https://github.com/sct/overseerr/commit/552a7e30da5fc2cc0bd43b5aef79a0225c75d233))
|
||||
* **sync:** fix sonarr/plex sync fighting over availability ([9b73423](https://github.com/sct/overseerr/commit/9b73423d49e1e799cd82764a9ade8c75d92a28a2)), closes [#872](https://github.com/sct/overseerr/issues/872)
|
||||
* **ui:** add fallback for region display name ([f9c83e1](https://github.com/sct/overseerr/commit/f9c83e14e52a57d6865307b3324a61c04a77a541))
|
||||
* **ui:** add missing string for default Discover Language & edit string for default Discover Region ([#1004](https://github.com/sct/overseerr/issues/1004)) ([0acad8e](https://github.com/sct/overseerr/commit/0acad8e9fa65a9de6cecac9b6a4a5b2313ba8f06))
|
||||
* **ui:** Add tip & validation for Discord ID input ([#966](https://github.com/sct/overseerr/issues/966)) ([e70a4ec](https://github.com/sct/overseerr/commit/e70a4ecae613e045977e262fd7f9643f30985ab7))
|
||||
* **ui:** also allow 17 digit discord ids ([57c00c1](https://github.com/sct/overseerr/commit/57c00c1ea71c1229d5a59e1b8dadd84a646772b9)), closes [#971](https://github.com/sct/overseerr/issues/971)
|
||||
* **ui:** Automatically disable and uncheck user permissions with unmet requirements ([#941](https://github.com/sct/overseerr/issues/941)) ([c9a150b](https://github.com/sct/overseerr/commit/c9a150b1db2adbb305cf1a448489d7a8c14cf1cb))
|
||||
* **ui:** change font size in request list/user list dropdowns to prevent zoom on mobile ([fb9c878](https://github.com/sct/overseerr/commit/fb9c878db49c01d13773e8d2f94c93f840be0b82))
|
||||
* **ui:** Display 4K download status on 4K status badge ([#988](https://github.com/sct/overseerr/issues/988)) ([40b07c3](https://github.com/sct/overseerr/commit/40b07c35d40c03039e4bfa5ed1e73af7e8aa6a7d))
|
||||
* **ui:** Fix card sizes on person detail pages ([#881](https://github.com/sct/overseerr/issues/881)) ([a3042f8](https://github.com/sct/overseerr/commit/a3042f8e1b05a91d98f48a4aecb08e831a48fc56))
|
||||
* **ui:** Fix settings navigation horizontal scroll issues ([#987](https://github.com/sct/overseerr/issues/987)) ([8701fb2](https://github.com/sct/overseerr/commit/8701fb20d07773f4cc32e857b68575a813cf7e21))
|
||||
* **ui:** fix webhook URL validation regex ([baad19a](https://github.com/sct/overseerr/commit/baad19a2c94728313ee996fe1a0ffc64fbd9aaa3))
|
||||
* **ui:** fixed anime language profile typo ([#879](https://github.com/sct/overseerr/issues/879)) ([ee50761](https://github.com/sct/overseerr/commit/ee5076146ef3c5e8baba197a5b397d3c3f575262))
|
||||
* **ui:** Handle missing movie/series data ([#862](https://github.com/sct/overseerr/issues/862)) ([7c0ddad](https://github.com/sct/overseerr/commit/7c0ddad653393327226a877692f046d8693ddc66))
|
||||
* **ui:** Notification-related string/UI edits and field validation ([#985](https://github.com/sct/overseerr/issues/985)) ([c88fcb2](https://github.com/sct/overseerr/commit/c88fcb2e2d1c4b84527844a80680c15337626e72))
|
||||
* **ui:** rename global group class to form-group ([8056187](https://github.com/sct/overseerr/commit/8056187c3c0ea464a8f751aa6347ea1d35c01aac))
|
||||
* **ui:** Size cards appropriately based on base font size ([#871](https://github.com/sct/overseerr/issues/871)) ([282f28f](https://github.com/sct/overseerr/commit/282f28f2b9d0cc8c9105d01b43d4e1f730320b8b))
|
||||
* **ui/notif:** Custom application title in password-related emails and UI messages ([#979](https://github.com/sct/overseerr/issues/979)) ([4e2706b](https://github.com/sct/overseerr/commit/4e2706b4211b06f364910c327d84c2ceb45b2fe3))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translated using Weblate (French) ([#1007](https://github.com/sct/overseerr/issues/1007)) ([970da66](https://github.com/sct/overseerr/commit/970da664b2700b8cd9ad8dce0cbca1d37820eceb))
|
||||
* **lang:** translations update from Weblate ([#853](https://github.com/sct/overseerr/issues/853)) ([e156acc](https://github.com/sct/overseerr/commit/e156acc1ae2fa86b4441faacc0b58e1e993e0edc))
|
||||
* **lang:** translations update from Weblate ([#986](https://github.com/sct/overseerr/issues/986)) ([4296765](https://github.com/sct/overseerr/commit/4296765ad61bac09c2317b71b763366d328733e4))
|
||||
* **notif:** Add Pushbullet notification agent ([#950](https://github.com/sct/overseerr/issues/950)) ([29b97ef](https://github.com/sct/overseerr/commit/29b97ef6d85bbea31dd59b7ad857b0d8ab30bff0))
|
||||
* **notif:** Notification improvements ([#914](https://github.com/sct/overseerr/issues/914)) ([2768155](https://github.com/sct/overseerr/commit/2768155bbabe121a4c51fc1472461cd5114c4300))
|
||||
* **regions:** add region/original language setting for filtering Discover ([#732](https://github.com/sct/overseerr/issues/732)) ([#942](https://github.com/sct/overseerr/issues/942)) ([b557c06](https://github.com/sct/overseerr/commit/b557c06b0a78f5df5f64a05dc1e4511dae72df4f))
|
||||
* **requests:** add language profile support ([#860](https://github.com/sct/overseerr/issues/860)) ([53f6f59](https://github.com/sct/overseerr/commit/53f6f59798fa7e3f95959990a3df555db3c1c51e))
|
||||
* **ui:** Add 'Available' filter to request list and remove unused MediaRequestStatus.AVAILABLE enum value ([#905](https://github.com/sct/overseerr/issues/905)) ([9757e3a](https://github.com/sct/overseerr/commit/9757e3ae0c572fb46177e25154b29e0ceced665f))
|
||||
* **ui:** Add 'Page Size' setting for request/user list pages ([#957](https://github.com/sct/overseerr/issues/957)) ([621db89](https://github.com/sct/overseerr/commit/621db893281f0280fe773ac7dbdc44434895242c))
|
||||
* **ui:** Add separate permissions for 4K auto approval ([#908](https://github.com/sct/overseerr/issues/908)) ([53b7425](https://github.com/sct/overseerr/commit/53b7425f6711e250935e7bb024c38ff6c62e07d9))
|
||||
* **ui:** Add sort options to user list ([#913](https://github.com/sct/overseerr/issues/913)) ([ef5d019](https://github.com/sct/overseerr/commit/ef5d019c18d7f6cdbbb1e1b7f8ff7816ed9b117b))
|
||||
* **ui:** Add support for requesting collections in 4K ([#968](https://github.com/sct/overseerr/issues/968)) ([139341b](https://github.com/sct/overseerr/commit/139341b0434b41e7c31af36baacd8d65566a6a0c))
|
||||
* user profile/settings pages ([#958](https://github.com/sct/overseerr/issues/958)) ([bbb683e](https://github.com/sct/overseerr/commit/bbb683e637386ad8bbeb44dca97aac9cdaf11349))
|
||||
* **ui:** added content ratings for tv shows and movie ratings ([#878](https://github.com/sct/overseerr/issues/878)) ([c8b2a57](https://github.com/sct/overseerr/commit/c8b2a57721a51adcc7f90ec1acb48b127991d467))
|
||||
* **users:** add reset password flow ([#772](https://github.com/sct/overseerr/issues/772)) ([e5966bd](https://github.com/sct/overseerr/commit/e5966bd3fbfe172f264f4e986ad2aecf29ae1510))
|
||||
|
||||
## [1.19.1](https://github.com/sct/overseerr/compare/v1.19.0...v1.19.1) (2021-02-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **ui:** Fix webhook URL validation regex ([#864](https://github.com/sct/overseerr/issues/864)) ([726f62b](https://github.com/sct/overseerr/commit/726f62b9b69b5078e718f129e26abdf358f5cb06))
|
||||
|
||||
# [1.19.0](https://github.com/sct/overseerr/compare/v1.18.0...v1.19.0) (2021-02-05)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** filter out adult content from combined credits ([3052f12](https://github.com/sct/overseerr/commit/3052f12c91b3ce86128324e3698fff61bbce3f2a))
|
||||
* **cache:** use formatted numbers for displaying cache counts ([6c437c5](https://github.com/sct/overseerr/commit/6c437c515fc01b9fe4461968875e23542bae7542))
|
||||
* **email:** make image a link to the action url in request template ([ee0a7bd](https://github.com/sct/overseerr/commit/ee0a7bd8c0b3a79c292b0abceb2f780f3889e49f)), closes [#834](https://github.com/sct/overseerr/issues/834)
|
||||
* **frontend:** add github sponsor link to about page ([7c192d5](https://github.com/sct/overseerr/commit/7c192d54f422a5f2b55750535d2382e313f1d011))
|
||||
* **frontend:** correctly show 4k download tracker activity ([a7314f8](https://github.com/sct/overseerr/commit/a7314f876ea528fdec0fb0a2adaa36a01afcdf38))
|
||||
* **frontend:** fix possible division by zero in download status ([#839](https://github.com/sct/overseerr/issues/839)) ([c97c96a](https://github.com/sct/overseerr/commit/c97c96a30c50db7735f06c6d2d2f6193fb7da55e))
|
||||
* **frontend:** match request button color on titlecards to other request buttons ([5b39911](https://github.com/sct/overseerr/commit/5b39911e024513fab7a62948e653cee08fd166c7))
|
||||
* **frontend:** set 4k status on RequestItem when request is for 4k ([a3b00c3](https://github.com/sct/overseerr/commit/a3b00c3458b868506d4158fb24f0369fa5daefc5))
|
||||
* **frontend:** use consistent spinner style on TitleCard/Plex Presets ([cf7ebc4](https://github.com/sct/overseerr/commit/cf7ebc488db33725444c428b4244d780ab9d123b))
|
||||
* **html:** th elements should be nested under tr, not directly under thead ([#801](https://github.com/sct/overseerr/issues/801)) ([6e9ac27](https://github.com/sct/overseerr/commit/6e9ac275e19d56de8c7a366db970c7321f26fc8a))
|
||||
* **lang:** Add missing source strings & remove local user sign-in setting tip ([#828](https://github.com/sct/overseerr/issues/828)) ([c0769d4](https://github.com/sct/overseerr/commit/c0769d4f8f2bad88e4638d8c3cbcc0414b3ef6fb))
|
||||
* **lang:** Edit English language strings ([#820](https://github.com/sct/overseerr/issues/820)) ([f54df21](https://github.com/sct/overseerr/commit/f54df214af86d90ea8d7cfcd4e39022215c3568c))
|
||||
* **lang:** translate language names & change zh-Hant language code to zh-TW ([#793](https://github.com/sct/overseerr/issues/793)) ([3c5ae36](https://github.com/sct/overseerr/commit/3c5ae360fd179d794a78cc918fe97a09216ca6b2))
|
||||
* **notif/ui:** Use custom application title in notifications & sign-in page ([#849](https://github.com/sct/overseerr/issues/849)) ([38c76b5](https://github.com/sct/overseerr/commit/38c76b55e0039c489cb6a4a0a298aa6385406db4))
|
||||
* **radarr:** correctly set requested status after sending to radarr (with auto approve) ([ec44841](https://github.com/sct/overseerr/commit/ec448413569ddc2f24bb856d29084169979f9f05))
|
||||
* **sonarr-sync:** sonarr sync will no longer set shows with no episodes to partially available ([d20bd53](https://github.com/sct/overseerr/commit/d20bd530edaadc5887b0361358da80153e36505c)), closes [#796](https://github.com/sct/overseerr/issues/796)
|
||||
* **ui:** Add additional URL & email input validation ([#843](https://github.com/sct/overseerr/issues/843)) ([3f9bfeb](https://github.com/sct/overseerr/commit/3f9bfeb01a67b2b587c7548b02ee826722e65c0f))
|
||||
* **ui:** Don't display empty dropdown when no trailer available ([#804](https://github.com/sct/overseerr/issues/804)) ([95c2a21](https://github.com/sct/overseerr/commit/95c2a2169799d96413b47ab24506b330435643eb))
|
||||
* **ui:** dont show bulk edit options on user list if there is only one user ([b658ddf](https://github.com/sct/overseerr/commit/b658ddf5cf61b2bb9b93cb1a4ca716cd75e18bb4))
|
||||
* **ui:** Dynamically generate path to config in warning message ([#851](https://github.com/sct/overseerr/issues/851)) ([b531a64](https://github.com/sct/overseerr/commit/b531a642f601f4ef9bf39c2f5915402157e55372))
|
||||
* **ui:** fix tables extending outside viewport in mobile formats ([e270999](https://github.com/sct/overseerr/commit/e270999745f97c2860f6a5b84e897dc6da8d6001))
|
||||
* **ui:** Hide 'Mark 4k as Available' button if 4k not enabled ([#833](https://github.com/sct/overseerr/issues/833)) ([e4a50c3](https://github.com/sct/overseerr/commit/e4a50c33f105b440243885d72a9e96595a525447))
|
||||
* **ui:** Limit max width of forms & lists ([#845](https://github.com/sct/overseerr/issues/845)) ([b9d14a9](https://github.com/sct/overseerr/commit/b9d14a9fd0f3c94d8267755147a87fe3b77fa2c3))
|
||||
* **ui:** prevent names from getting squished in AdvancedRequester user selector ([06e9411](https://github.com/sct/overseerr/commit/06e941171a1d019fbb178624167c026f6df5271c))
|
||||
* **ui:** remove yup validation from display name on user edit page ([63d7e2b](https://github.com/sct/overseerr/commit/63d7e2b39858fcb1cc0819a680eebccded7f4451))
|
||||
* **ui:** Restore original port input size ([#814](https://github.com/sct/overseerr/issues/814)) ([1ccafc0](https://github.com/sct/overseerr/commit/1ccafc0ebd368d798f9571b83910336efa317e37))
|
||||
* **ui:** show request as option even if there are no radarr/sonarr servers ([b116281](https://github.com/sct/overseerr/commit/b116281196c264b4ec35b07f1b4ffa717e50ade5))
|
||||
* **ui:** uniform-size checkboxes, vertically-aligned form labels, and fixes for other UI imperfections/inconsistencies ([#737](https://github.com/sct/overseerr/issues/737)) ([e34fbf7](https://github.com/sct/overseerr/commit/e34fbf72fda34d69b9f25563fa81f88b3c20912a))
|
||||
* **ui:** Use minimum char validation message ([#850](https://github.com/sct/overseerr/issues/850)) ([7456bea](https://github.com/sct/overseerr/commit/7456bea2ae600a28cb933278ffb310b63a474d6a))
|
||||
* **ui:** validate application url and service external urls ([026795d](https://github.com/sct/overseerr/commit/026795d4c940cb4797d3e68089456a4c3defbb21))
|
||||
* **ui:** when PersonCard has no profilePath, correctly position name/role content ([3ffd5ab](https://github.com/sct/overseerr/commit/3ffd5ab0ee8ffa63199d1428e37206f9b59fb7a5))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **cache:** add cache table and flush cache option to settings ([996bd9f](https://github.com/sct/overseerr/commit/996bd9f14ed0f56767892c169b071be4f0f628d0))
|
||||
* **cache:** external API cache ([#786](https://github.com/sct/overseerr/issues/786)) ([20289b5](https://github.com/sct/overseerr/commit/20289b5960a93545cdff9331a1a7b613f382e702))
|
||||
* **docker:** Check for /app/config volume mount during setup ([#826](https://github.com/sct/overseerr/issues/826)) ([1e5f88f](https://github.com/sct/overseerr/commit/1e5f88f462b0c69db5f6ab8e0249a5905bc6952a))
|
||||
* **frontend:** add TheTVDB external link ([#800](https://github.com/sct/overseerr/issues/800)) ([72cffd7](https://github.com/sct/overseerr/commit/72cffd74a75984ba98c456c0ec006ec378a8dcec))
|
||||
* **lang:** add support for Hungarian language ([cfacb15](https://github.com/sct/overseerr/commit/cfacb151b52d08e19d2fcd603fb4bbcd78707cdf))
|
||||
* **lang:** translations update from Weblate ([#791](https://github.com/sct/overseerr/issues/791)) ([42295e0](https://github.com/sct/overseerr/commit/42295e076a7579b226d57407a20cb0ba044e9ec1))
|
||||
* **lang:** translations update from Weblate ([#819](https://github.com/sct/overseerr/issues/819)) ([9e5e4c2](https://github.com/sct/overseerr/commit/9e5e4c22f5b25df96f47875d599ed8685791382a))
|
||||
* **lang:** translations update from Weblate ([#841](https://github.com/sct/overseerr/issues/841)) ([e4f9b8a](https://github.com/sct/overseerr/commit/e4f9b8a9848f3af00e86fc7108c823ed0584609f))
|
||||
* **lang:** translations update from Weblate ([#852](https://github.com/sct/overseerr/issues/852)) ([c5be00e](https://github.com/sct/overseerr/commit/c5be00eebfd2b0e65295edbe282cbba22fffa660))
|
||||
* **ui:** Add local login setting ([#817](https://github.com/sct/overseerr/issues/817)) ([9d0d5b8](https://github.com/sct/overseerr/commit/9d0d5b86aae025e4647bb664c6412d42192e2fe7))
|
||||
* **ui:** added next airing date to TV Shows ([#842](https://github.com/sct/overseerr/issues/842)) ([4eae02a](https://github.com/sct/overseerr/commit/4eae02a7e14e377fd69ddd4a43774cb7e3d1855b))
|
||||
* new permission to allow users to see other users requests ([033ba9d](https://github.com/sct/overseerr/commit/033ba9d41bddf6dc1c4512d8404f747e57923bca)), closes [#840](https://github.com/sct/overseerr/issues/840)
|
||||
* request as another user ([59150f9](https://github.com/sct/overseerr/commit/59150f955f7003672ef19eb9d37156e93b79c97d))
|
||||
* **tv:** show cast for the entire show instead of only the last season ([#778](https://github.com/sct/overseerr/issues/778)) ([b239598](https://github.com/sct/overseerr/commit/b239598e64d33b78dc5d7972878840149aff360a)), closes [#775](https://github.com/sct/overseerr/issues/775)
|
||||
* **ui:** Add custom title functionality ([#825](https://github.com/sct/overseerr/issues/825)) ([35c6bfc](https://github.com/sct/overseerr/commit/35c6bfc0216bf879353b3ee546b439a06c8e6121))
|
||||
|
||||
# [1.18.0](https://github.com/sct/overseerr/compare/v1.17.2...v1.18.0) (2021-01-30)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** prevent duplicate movie requests ([421f4c1](https://github.com/sct/overseerr/commit/421f4c17f0f206bbe7bfcbf2819014b8c7f55b6a)), closes [#705](https://github.com/sct/overseerr/issues/705)
|
||||
* **build:** fix sqlite3 build error ([#691](https://github.com/sct/overseerr/issues/691)) ([3a1f6d5](https://github.com/sct/overseerr/commit/3a1f6d5706c8fc100e88425f3d89a26a0325af79))
|
||||
* **frontend:** add poster not found image to request card and request list item ([ae9a1b3](https://github.com/sct/overseerr/commit/ae9a1b3e940ac2abf6e842d91f458daab3dd0f0d))
|
||||
* **frontend:** add poster not found image to tv details page ([0b05545](https://github.com/sct/overseerr/commit/0b055458d0ddbfd4c87ebf9b0562f161fa3445a3))
|
||||
* **frontend:** dont show external links unless slug is set ([946bd2d](https://github.com/sct/overseerr/commit/946bd2db5ecde0748b2e9bc5edfe7ca6000ec3d5))
|
||||
* **frontend:** fix server name position on plex settings page ([86efcd8](https://github.com/sct/overseerr/commit/86efcd82c34ad6490f2899ebf6f84cdd1bffc498))
|
||||
* **frontend:** fixed mismatched rounded sizing on new login ([5e352c2](https://github.com/sct/overseerr/commit/5e352c201fc2f731ca5f713ecb6901527ef354da)), closes [#721](https://github.com/sct/overseerr/issues/721)
|
||||
* **ip logging:** add env var for proxy to fix ip logging on failed logins ([#756](https://github.com/sct/overseerr/issues/756)) ([9342a40](https://github.com/sct/overseerr/commit/9342a40bbc03f7fdda23e3876b3a4a81ea8532c0))
|
||||
* **lang:** add missing i18n strings for notification settings ([2f75c4c](https://github.com/sct/overseerr/commit/2f75c4c6aed42a15bb47d3652272de8f852ec79f))
|
||||
* **notifications:** only send a single notification when standard media becomes available ([b5fd1d5](https://github.com/sct/overseerr/commit/b5fd1d520cd2a7be6e6356a25129e93af1caf542)), closes [#770](https://github.com/sct/overseerr/issues/770)
|
||||
* **permissions:** use default user permissions when creating a local user ([#713](https://github.com/sct/overseerr/issues/713)) ([660ada0](https://github.com/sct/overseerr/commit/660ada0b2025eb2c06d9054fd0a7b5a632af6af2))
|
||||
* **radarr:** fix request bug which made it unable to be added to radarr ([#760](https://github.com/sct/overseerr/issues/760)) ([45a2779](https://github.com/sct/overseerr/commit/45a277964b0c39346d7216873812e0ebe505cb79))
|
||||
* **radarr:** return the updated data when updating radarr request ([#765](https://github.com/sct/overseerr/issues/765)) ([0c6d478](https://github.com/sct/overseerr/commit/0c6d4780c355ffe1a951268fb6949491d435bbf1))
|
||||
* **requests:** handle when tvdbid is null ([#657](https://github.com/sct/overseerr/issues/657)) ([2da0da8](https://github.com/sct/overseerr/commit/2da0da826ae1d73467bc8a671fda7cc5ca1f14c9))
|
||||
* **sonarr-sync:** correctly set series with no seasons to requested status ([3812989](https://github.com/sct/overseerr/commit/3812989a1ce1e07d4af09149008043a6e2e94060)), closes [#762](https://github.com/sct/overseerr/issues/762)
|
||||
* **sync:** do not update series status if already available and no new seasons ([136d874](https://github.com/sct/overseerr/commit/136d874cba37babf9c0670844b002871710e6d99)), closes [#777](https://github.com/sct/overseerr/issues/777)
|
||||
* **ui:** Capitalization, punctuation, and grammar inconsistences & errors ([#731](https://github.com/sct/overseerr/issues/731)) ([f05d4a0](https://github.com/sct/overseerr/commit/f05d4a0d0b42905fcaee49b2471bb1f4ee77fffe))
|
||||
* lookup movie by imdbid if tmdbid does not exits for plex movie agent ([#711](https://github.com/sct/overseerr/issues/711)) ([e972288](https://github.com/sct/overseerr/commit/e97228899a5936b2525c8060abfa14b5ce31658d))
|
||||
* show recently added series even if they are not complete ([d0c830e](https://github.com/sct/overseerr/commit/d0c830e80d389f9e0f48a9b83659331f54630d03))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translated using Weblate (Dutch) ([059995e](https://github.com/sct/overseerr/commit/059995e0ef3370a3192bd386fa6875ca0f58690a))
|
||||
* **lang:** translated using Weblate (French) ([4789583](https://github.com/sct/overseerr/commit/4789583d66305ac7b3d393659b2f3604c0acc576))
|
||||
* **lang:** translations update from Weblate ([#727](https://github.com/sct/overseerr/issues/727)) ([71875ef](https://github.com/sct/overseerr/commit/71875efb48246dbb0139ad15a4261a5661fcfe17))
|
||||
* **lang:** update languages and fix merge conflict ([083a74a](https://github.com/sct/overseerr/commit/083a74a686d202cce5775bf9752caaa9a626cf45))
|
||||
* **ui:** Move PROXY setting to UI ([#782](https://github.com/sct/overseerr/issues/782)) ([f1dd5e7](https://github.com/sct/overseerr/commit/f1dd5e7e12c1f602449c4769173dbce71e3569d0))
|
||||
* add manual availability buttons to manage slideover ([67f8aef](https://github.com/sct/overseerr/commit/67f8aef00d98c834b60cb6152ccd5cb7b5709d12)), closes [#672](https://github.com/sct/overseerr/issues/672)
|
||||
* **media:** add link to the item on plex ([#735](https://github.com/sct/overseerr/issues/735)) ([1d7150c](https://github.com/sct/overseerr/commit/1d7150c24ec5ad347093889bfceab61b664900d5))
|
||||
* Radarr & Sonarr Sync ([#734](https://github.com/sct/overseerr/issues/734)) ([ec5fb83](https://github.com/sct/overseerr/commit/ec5fb836785855eb4846fd33b49faeb94c40506a))
|
||||
* **frontend:** add option to hide all available items from discovery ([#699](https://github.com/sct/overseerr/issues/699)) ([6c1742e](https://github.com/sct/overseerr/commit/6c1742e94ccfc6c13cf1d25fd9e893ee1f431aae))
|
||||
* **lang:** add support for Portuguese (Portugal) language ([e044146](https://github.com/sct/overseerr/commit/e044146aa55109a1eccfde9650b26beb0d5ec9a6))
|
||||
* **lang:** translated using Weblate (Dutch) ([6d0f7d4](https://github.com/sct/overseerr/commit/6d0f7d4b50370c420c1017f32d48313074543743))
|
||||
* **lang:** translated using Weblate (Italian) ([9aa5c12](https://github.com/sct/overseerr/commit/9aa5c121644518c1fbb308a487c26d8998bb5a36))
|
||||
* **lang:** translated using Weblate (Portuguese (Portugal)) ([f001fb3](https://github.com/sct/overseerr/commit/f001fb3b33d4fb749acb70c45b8a55a5bbef570c))
|
||||
* **lang:** translated using Weblate (Spanish) ([4f94d22](https://github.com/sct/overseerr/commit/4f94d227fc3096bcb8a1e5cf12fe9222d6c6b711))
|
||||
* **login:** add request ip to the failed request log ([#714](https://github.com/sct/overseerr/issues/714)) ([2d31ea9](https://github.com/sct/overseerr/commit/2d31ea940ac0a1a84d2150743798b41ff6490317))
|
||||
* **users:** add editable usernames ([#715](https://github.com/sct/overseerr/issues/715)) ([20ca3f2](https://github.com/sct/overseerr/commit/20ca3f2f5fcf4a9eb0d6a8be671bb4fb1f5e6178))
|
||||
* pre-populate server info from plex.tv API ([#563](https://github.com/sct/overseerr/issues/563)) ([82ac76b](https://github.com/sct/overseerr/commit/82ac76b0540ba1133cb5384744d2499c2488a4e8))
|
||||
* **auth:** Add optional CSRF protection ([#697](https://github.com/sct/overseerr/issues/697)) ([6e25891](https://github.com/sct/overseerr/commit/6e2589178b99f8f32f0ded9a7cfd9921c33e9b60))
|
||||
* ability to edit user settings in bulk ([#597](https://github.com/sct/overseerr/issues/597)) ([4b0241c](https://github.com/sct/overseerr/commit/4b0241c3b34d4229f928c21defb10a1c051264d1))
|
||||
* **lang:** translated using Weblate (English) ([9bb11af](https://github.com/sct/overseerr/commit/9bb11afc6b4a109ae1e14d41c9fe2b71f19c470a))
|
||||
* **lang:** translated using Weblate (German) ([c2a3e8e](https://github.com/sct/overseerr/commit/c2a3e8ed5243925dce991ec7995ae831702dbc7b))
|
||||
* **lang:** translated using Weblate (Portuguese (Brazil)) ([32f4916](https://github.com/sct/overseerr/commit/32f4916c4a926097f31ed472aee031536b847bb7))
|
||||
* **lang:** translated using Weblate (Portuguese (Brazil)) ([98570c9](https://github.com/sct/overseerr/commit/98570c920e4904a594bb7464161b985094958f84))
|
||||
* **notifications:** add option to send notifications for auto-approved requests ([21db367](https://github.com/sct/overseerr/commit/21db3676d1464b63384b04c0c2926cb2a6252e9b)), closes [#267](https://github.com/sct/overseerr/issues/267)
|
||||
|
||||
## [1.17.2](https://github.com/sct/overseerr/compare/v1.17.1...v1.17.2) (2021-01-20)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **requests:** allow declined season requests to be re-requested ([e1032ff](https://github.com/sct/overseerr/commit/e1032ff5dfac4a8c9d4da9cf2788c19822343ad9)), closes [#690](https://github.com/sct/overseerr/issues/690)
|
||||
* **requests:** update requests to approved when parent media is set as available ([78444a9](https://github.com/sct/overseerr/commit/78444a9e643829823162389dee60cca70da56bff)), closes [#688](https://github.com/sct/overseerr/issues/688)
|
||||
|
||||
## [1.17.1](https://github.com/sct/overseerr/compare/v1.17.0...v1.17.1) (2021-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** show auto approval on series request modal only with correct permissions ([8927c6d](https://github.com/sct/overseerr/commit/8927c6d2e39dbda2b1121095a7273f5cab1c9b74)), closes [#687](https://github.com/sct/overseerr/issues/687)
|
||||
|
||||
# [1.17.0](https://github.com/sct/overseerr/compare/v1.16.0...v1.17.0) (2021-01-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** improve rottentomatoes rating matching for movies ([7db62ab](https://github.com/sct/overseerr/commit/7db62ab824eefc42e6db16e42d52f4266b136f82)), closes [#494](https://github.com/sct/overseerr/issues/494)
|
||||
* **build:** remove cross import from client to server for UserType ([23624bd](https://github.com/sct/overseerr/commit/23624bd144af5df4c31995b68ce48105b95b20f6))
|
||||
* **frontend:** clarify which fields are required in radarr/sonarr modals ([860d71e](https://github.com/sct/overseerr/commit/860d71ed69a69a1a3f74b79290ef471e04f57a6b)), closes [#575](https://github.com/sct/overseerr/issues/575)
|
||||
* **frontend:** do not show failed media status on request list for declined requests ([00944b1](https://github.com/sct/overseerr/commit/00944b1ec2db8ddc5742448f6448f7364c473a98)), closes [#664](https://github.com/sct/overseerr/issues/664)
|
||||
* **frontend:** fix button styling on details page on small screen sizes ([d9e0c90](https://github.com/sct/overseerr/commit/d9e0c90e76d80aef0c67318e00e997804805f46e))
|
||||
* **frontend:** fix request button height ([a262727](https://github.com/sct/overseerr/commit/a2627270784bdef8644875fa5c5a7349a0b7fd81))
|
||||
* **frontend:** request dropdown menu now properly shows up over collection button ([b491be1](https://github.com/sct/overseerr/commit/b491be1b1e7f6aa588274230e695e4c5302b961e))
|
||||
* **frontend:** show correct request status on request cards for 4k requests ([1aa0005](https://github.com/sct/overseerr/commit/1aa0005b4298fc1af9c1d0bf1f357738c0fa2673))
|
||||
* **lang:** add missing see more i18n string for SeeMoreCard ([d9919ab](https://github.com/sct/overseerr/commit/d9919abb8998d28558ddec35b8e60ab2af75d5b7))
|
||||
* **lang:** change email auth user/pass strings to SMTP Username/Password ([a77a2aa](https://github.com/sct/overseerr/commit/a77a2aa3ebb1be353d534db5b07647ac26c60e15))
|
||||
* **notifications:** correctly compare seasons before sending series notifications ([f17fa2a](https://github.com/sct/overseerr/commit/f17fa2a2db8144bac89936f588627e8dd37bf54a))
|
||||
* **notifications:** only send one available notification for standard media ([fc6f7cc](https://github.com/sct/overseerr/commit/fc6f7ccea586165a30022b6d5554911c66ece6df))
|
||||
* **notifications:** send media declined email ([eb6fc8a](https://github.com/sct/overseerr/commit/eb6fc8a19099469794d471db0b48a258c2866633)), closes [#679](https://github.com/sct/overseerr/issues/679)
|
||||
* **plex-sync:** improve plex sync error handling. add session id to fix stuck runs ([a740b07](https://github.com/sct/overseerr/commit/a740b07f06f892b72a651b928af28ce71cb495ee))
|
||||
* **plex-sync:** store plex added date and sort recently added by it ([d688a96](https://github.com/sct/overseerr/commit/d688a967596afcba9799b8133089bebb5add27cf))
|
||||
* **requests:** select the correct radarr/sonarr server when sending request to service ([e0d9f89](https://github.com/sct/overseerr/commit/e0d9f891e797c3839f976b75a871903b6f2e55f1))
|
||||
* **server:** support absolute paths for CONFIG_DIRECTORY ([51d8fba](https://github.com/sct/overseerr/commit/51d8fba9162b9e148a35ced69e7e035438c8b0f1))
|
||||
* **user edit:** fix user edit not being able to be saved ([#651](https://github.com/sct/overseerr/issues/651)) ([b04d00e](https://github.com/sct/overseerr/commit/b04d00ef509d6f13c1f9677b3f318331782c0086))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **api:** /request/count endpoint ([#682](https://github.com/sct/overseerr/issues/682)) ([192cfd8](https://github.com/sct/overseerr/commit/192cfd8a8ea9ab942d5bb265d42050917a2f5a04))
|
||||
* **frontend:** add see more card to media sliders ([587e8db](https://github.com/sct/overseerr/commit/587e8db15e9c19b4c58406e3e4215d8bf87d8762))
|
||||
* **frontend:** add template variable help button to custom webhook settings page ([29c5bc4](https://github.com/sct/overseerr/commit/29c5bc40975e7ab0a2e08bb77294f164f0c60769))
|
||||
* **lang:** add support for Chinese (Traditional) language ([686c4f7](https://github.com/sct/overseerr/commit/686c4f71bf930625af082ac5e14dc5f79f5c42eb))
|
||||
* **lang:** Translations update from Weblate ([#604](https://github.com/sct/overseerr/issues/604)) ([801e765](https://github.com/sct/overseerr/commit/801e76524d6ea0887249f1630402e9c3a3430b44))
|
||||
* **login:** add local users functionality ([#591](https://github.com/sct/overseerr/issues/591)) ([492e19d](https://github.com/sct/overseerr/commit/492e19df4014e67dc6a2de5903a33c25e13fcf45))
|
||||
* **notifications:** add notification for declined requests ([2f97f61](https://github.com/sct/overseerr/commit/2f97f61a6e8846975774aa16950a39ada2b1a016)), closes [#663](https://github.com/sct/overseerr/issues/663)
|
||||
* **notifications:** Webhook Notifications ([#632](https://github.com/sct/overseerr/issues/632)) ([a7cc7c5](https://github.com/sct/overseerr/commit/a7cc7c59753dd9649b2ec37eb9d46fe4fa8e1e1c))
|
||||
* **requests:** Request Overrides & Request Editing ([#653](https://github.com/sct/overseerr/issues/653)) ([bdb3372](https://github.com/sct/overseerr/commit/bdb33722e6df09dd6d8caa36b104b61c6b8dc00d))
|
||||
* **server:** add CONFIG_DIRECTORY env var to control config directory location ([fa8f112](https://github.com/sct/overseerr/commit/fa8f112c31ccb5ee6244f776bc97e76d81958539))
|
||||
* 4K Requests ([#559](https://github.com/sct/overseerr/issues/559)) ([6b2df24](https://github.com/sct/overseerr/commit/6b2df24a2e8f96dd2277a814d7e02015d1f80cdc))
|
||||
* map AniDB IDs from Hama agent to tvdb/tmdb/imdb IDs ([#538](https://github.com/sct/overseerr/issues/538)) ([0600ac7](https://github.com/sct/overseerr/commit/0600ac7c3a1bc0cdd906634d5f77ea3e99b10e94)), closes [#453](https://github.com/sct/overseerr/issues/453)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* **deps:** revert back to next@10.0.3 until sharp optional dependency bug is fixed ([7962964](https://github.com/sct/overseerr/commit/79629645aacc1a042919834da79bff0c1f69c9d6))
|
||||
|
||||
# [1.16.0](https://github.com/sct/overseerr/compare/v1.15.0...v1.16.0) (2021-01-07)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** adjust titlecard badge styling ([effc809](https://github.com/sct/overseerr/commit/effc80977a4ed732092254248f82363e52233171))
|
||||
* **frontend:** apply same titlecard hover effect to personcard ([67f2b57](https://github.com/sct/overseerr/commit/67f2b57f00216ded3b34965629d6fdd2f16bc25f))
|
||||
* **frontend:** only animate titlecard when showDetail is true ([0ab4c3c](https://github.com/sct/overseerr/commit/0ab4c3c36fe2c1ded142b6931111516f7f990a41))
|
||||
* **frontend:** use hardware acceleration for titlecard scale ([88810bf](https://github.com/sct/overseerr/commit/88810bf0a4ef74299f6541b60fa91cea3610f99c))
|
||||
* **plex-sync:** do not run plex sync if no admin exists ([493d82b](https://github.com/sct/overseerr/commit/493d82b6b066d77609cf66e005fd1f1472b8e011))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translations update from Weblate ([#495](https://github.com/sct/overseerr/issues/495)) ([b04eda6](https://github.com/sct/overseerr/commit/b04eda6c8a3bfcaa2a14b8a29612fdf690c9fba0))
|
||||
* **lang:** Translations update from Weblate ([#580](https://github.com/sct/overseerr/issues/580)) ([2bfe0f2](https://github.com/sct/overseerr/commit/2bfe0f2bf66956763ab26d5c54f26e6c456f59f7))
|
||||
* **notifications:** add pushover integration ([#574](https://github.com/sct/overseerr/issues/574)) ([ee5d018](https://github.com/sct/overseerr/commit/ee5d0181fc9a673b27aefd1d09b0a78c3d2e4f55))
|
||||
|
||||
# [1.15.0](https://github.com/sct/overseerr/compare/v1.14.1...v1.15.0) (2021-01-04)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** return 202 when same seasons are requested again ([5c84702](https://github.com/sct/overseerr/commit/5c847026aad79fcac4d020786ded9f867696c226))
|
||||
* **build:** fixes build to include commit tag for app build step ([289864a](https://github.com/sct/overseerr/commit/289864af1a995ce04834bf8a220cc238e1954d19))
|
||||
* **docs:** fix typo in build instructions ([#503](https://github.com/sct/overseerr/issues/503)) ([2b27a71](https://github.com/sct/overseerr/commit/2b27a715b07c27200ba1e5e9623629a34389276d))
|
||||
* **frontend:** add i18n for request text on titlecard ([a524b9c](https://github.com/sct/overseerr/commit/a524b9c4c8968f6823d33eb270dc26069fe4a725))
|
||||
* **frontend:** add localized strings for status checker ([2dcda39](https://github.com/sct/overseerr/commit/2dcda39d40d820419e098bd6f1101eb820e5b42d))
|
||||
* **frontend:** center text in movie auto-approve modal on small screens ([#510](https://github.com/sct/overseerr/issues/510)) ([1438b08](https://github.com/sct/overseerr/commit/1438b08cf0b358d79c6688c64be99f1718ec2d23)), closes [#507](https://github.com/sct/overseerr/issues/507)
|
||||
* **frontend:** change titlecard to only have a request button ([b5a3a7a](https://github.com/sct/overseerr/commit/b5a3a7a89fcaf86dd794dc419711677b53646577))
|
||||
* **frontend:** combine duplicate credits on a persons detail page ([d188f6f](https://github.com/sct/overseerr/commit/d188f6ffadff1564c47d5f33138e35498bed29fd)), closes [#504](https://github.com/sct/overseerr/issues/504)
|
||||
* **frontend:** disable pointer-events on titlecard badges ([ce06879](https://github.com/sct/overseerr/commit/ce0687922a94588b3492e8ddf2e84f54dd1a0d4e))
|
||||
* **frontend:** fix count of requests in request list ([f124d73](https://github.com/sct/overseerr/commit/f124d732a2911abdccb5abc11471efe61cc20f7a))
|
||||
* **frontend:** fix sliders overflowing on firefox ([67ac9e0](https://github.com/sct/overseerr/commit/67ac9e075f0ca1cfe7e4766d9168815d7ab600fa)), closes [#566](https://github.com/sct/overseerr/issues/566)
|
||||
* **frontend:** full season request modal fits on a smaller mobile UI ([#535](https://github.com/sct/overseerr/issues/535)) ([12db7a0](https://github.com/sct/overseerr/commit/12db7a065ad566b47d46de4b949343290894f153))
|
||||
* **frontend:** handle currentLibrary possibly being null on first manual sync ([93b57a7](https://github.com/sct/overseerr/commit/93b57a76f10a823615ca11ff59f523b67aa30fad))
|
||||
* **frontend:** increase titlecard status badge size on larger screens ([ba106c4](https://github.com/sct/overseerr/commit/ba106c447d76db2f9ac70a60c5b38cc60ab554fe))
|
||||
* **frontend:** search clear button now correctly triggers routing ([343f466](https://github.com/sct/overseerr/commit/343f466788abc308b91a414ef61bba816ac8875c))
|
||||
* **frontend:** set locale cookie expiration to be much longer ([fae4818](https://github.com/sct/overseerr/commit/fae481895736eab81d52eb93788beb00669fb355))
|
||||
* **frontend:** show movie/series badges always ([8cbf39a](https://github.com/sct/overseerr/commit/8cbf39a9d12eaee7720fa4721c350c1ef9dee856))
|
||||
* **frontend:** update login/setup images ([058fb65](https://github.com/sct/overseerr/commit/058fb65495baa08a0bd4c9e0aef320c6fc7d017b))
|
||||
* **holiday:** remove special holiday slider ([8c09033](https://github.com/sct/overseerr/commit/8c0903393cf2cb2a929ba70a8ab6ddcc4cba0574))
|
||||
* correctly deal with tmdb id duplicates between movies/series ([721ed9a](https://github.com/sct/overseerr/commit/721ed9a93087a57ae749388bddcacf26022e3df6)), closes [#526](https://github.com/sct/overseerr/issues/526)
|
||||
* use new commit tag file for app version as well ([d00e470](https://github.com/sct/overseerr/commit/d00e470b55327489b49d770144b7cfdb24045be6))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **email:** add sendername to email notification ([#506](https://github.com/sct/overseerr/issues/506)) ([0185bb1](https://github.com/sct/overseerr/commit/0185bb1a7084c1faeb61fb1c63e34e26732711c8))
|
||||
* **frontend:** add clear-field-icon to search field ([#498](https://github.com/sct/overseerr/issues/498)) ([7434a26](https://github.com/sct/overseerr/commit/7434a26f76b5e9f74918f3e1a34443d20ecfcbe4))
|
||||
* **frontend:** add documentation link to about page ([c034496](https://github.com/sct/overseerr/commit/c034496f557a031aed35cd28dc7221d8cdf36643))
|
||||
* **frontend:** add telegram integration ([#491](https://github.com/sct/overseerr/issues/491)) ([c8d4d67](https://github.com/sct/overseerr/commit/c8d4d674f412082ad9e9da09abd79660365cf728))
|
||||
* **frontend:** filter/sorting for request list ([5add44c](https://github.com/sct/overseerr/commit/5add44cfb0379aa6fed7c3b867230292feacc684)), closes [#431](https://github.com/sct/overseerr/issues/431)
|
||||
* **notifications:** control notifcation types per agent ([8af6a1f](https://github.com/sct/overseerr/commit/8af6a1f566769c583af7dd9e18d162717835b7cc)), closes [#513](https://github.com/sct/overseerr/issues/513)
|
||||
* status checker to prompt users to reload their frontend when app version changes ([75a4264](https://github.com/sct/overseerr/commit/75a426437a4182e21da13684066966dd5bf8fc5e))
|
||||
|
||||
## [1.14.1](https://github.com/sct/overseerr/compare/v1.14.0...v1.14.1) (2021-01-02)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **holiday:** remove special holiday slider ([22f2037](https://github.com/sct/overseerr/commit/22f2037ea6c5a0ba2ffa4d69f2b7cf42bdcf8575))
|
||||
|
||||
# [1.14.0](https://github.com/sct/overseerr/compare/v1.13.0...v1.14.0) (2020-12-25)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** add margin to ButtonWithDropdown component on movie/tv details page ([06fc98b](https://github.com/sct/overseerr/commit/06fc98b6b958221fa180f57f702c348f15b31f1c))
|
||||
* **frontend:** correctly position title card hover section ([#486](https://github.com/sct/overseerr/issues/486)) ([4b7af86](https://github.com/sct/overseerr/commit/4b7af86111a0300e1a137f23fa4ad1639fa55feb))
|
||||
* **frontend:** fix missing styles for alert component ([de3d288](https://github.com/sct/overseerr/commit/de3d288949b60d3a3af889d69a62bea2bc799ed7))
|
||||
* **frontend:** fix mobile dropdown in notifications settings ([6353cda](https://github.com/sct/overseerr/commit/6353cda5825f442dd539886c7b9ba437edf27ac4))
|
||||
* **frontend:** fix scaling titlecard content position ([bd94740](https://github.com/sct/overseerr/commit/bd947409e6e8ff313011b77adc76ccd5f9112c78))
|
||||
* **frontend:** improve flex header on movie/tv details page ([d7b1c28](https://github.com/sct/overseerr/commit/d7b1c2840690c144ebf29a360defcbd6fdb21354))
|
||||
* **frontend:** invalid dom-nesting title card fix ([#482](https://github.com/sct/overseerr/issues/482)) ([f2ebba7](https://github.com/sct/overseerr/commit/f2ebba7b1df775d33d2af6abc3ee2c9de5f2e57a)), closes [#476](https://github.com/sct/overseerr/issues/476)
|
||||
* **frontend:** remove vote permission for now ([5d06a34](https://github.com/sct/overseerr/commit/5d06a347311bd10c05d8f58068ca7104e265dcca))
|
||||
* **frontend:** sort person detail credits by tmdb votes ([17518db](https://github.com/sct/overseerr/commit/17518dbe7f545100770a892d03d1f8508adc3650))
|
||||
* **frontend:** status badge Unavailable renamed to Requested ([ed94a0f](https://github.com/sct/overseerr/commit/ed94a0f335c59de526dd812aea7616313fe002fd)), closes [#374](https://github.com/sct/overseerr/issues/374)
|
||||
* **frontend:** update titlecard status badge to new requested colors ([8f292d5](https://github.com/sct/overseerr/commit/8f292d538b937ea133175089979ef02599f6fef4))
|
||||
* **logs:** rotate logs on a daily basis instead of incrementing log filename ([395cbb2](https://github.com/sct/overseerr/commit/395cbb2be6c62f1d7573593e49a93615eaf22853))
|
||||
* improve apple-touch-icon and android app icons ([329a814](https://github.com/sct/overseerr/commit/329a814a8fb791122266c0b04b05848c71d68ba1))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translations update from Weblate ([#479](https://github.com/sct/overseerr/issues/479)) ([c8c74b0](https://github.com/sct/overseerr/commit/c8c74b0ae54fcc524aa8b2edf5a5c5e5db6c1638))
|
||||
* **notifications:** add slack notification agent ([1163e81](https://github.com/sct/overseerr/commit/1163e81adc7da1e8334155ebee5b4672a22143db)), closes [#365](https://github.com/sct/overseerr/issues/365)
|
||||
* add collections ([#484](https://github.com/sct/overseerr/issues/484)) ([a333a09](https://github.com/sct/overseerr/commit/a333a095820ce3f10857026ba4770a2fffeed7cb)), closes [#418](https://github.com/sct/overseerr/issues/418)
|
||||
* add separate auto approve permissions for Movies/Series ([4809257](https://github.com/sct/overseerr/commit/480925781691de456abc427fbbba161be11a3a8a)), closes [#268](https://github.com/sct/overseerr/issues/268)
|
||||
* simple failed request handling ([#474](https://github.com/sct/overseerr/issues/474)) ([02969d5](https://github.com/sct/overseerr/commit/02969d5426245062a2f53475d83c4a8639632c9d))
|
||||
* YouTube Movie/TV Trailers ([#454](https://github.com/sct/overseerr/issues/454)) ([e88dc83](https://github.com/sct/overseerr/commit/e88dc83aeba0475e3ad421d5ab130cea4fc9a806))
|
||||
|
||||
# [1.13.0](https://github.com/sct/overseerr/compare/v1.12.1...v1.13.0) (2020-12-23)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** correctly return firstAirDate for series in search endpoints ([32b4c99](https://github.com/sct/overseerr/commit/32b4c99950659d9e1da2ffa93c22383c54d0d904)), closes [#462](https://github.com/sct/overseerr/issues/462)
|
||||
* **email:** correctly log errors when emails fail to send ([0980fa5](https://github.com/sct/overseerr/commit/0980fa54f9fc3bdfae6c57fa5a20ce3b2a88a677))
|
||||
* **frontend:** added new Radarr v3 logo ([#471](https://github.com/sct/overseerr/issues/471)) ([3bbc716](https://github.com/sct/overseerr/commit/3bbc716434dc04bfe6b55de9898eb2c0ecb03baa))
|
||||
* **frontend:** approve and decline button (in manage panel) will now fit on mobile ([#441](https://github.com/sct/overseerr/issues/441)) ([66ef72d](https://github.com/sct/overseerr/commit/66ef72dd42912d83ea8f86aabb75fbee547f8de9))
|
||||
* **frontend:** filter out undefined backdrop paths for person details page ([2e0e4d5](https://github.com/sct/overseerr/commit/2e0e4d5129ed4912415f61eb8d1da41e88ddcaff))
|
||||
* **frontend:** show backdrops instead of posters for new person detail design ([9f5f920](https://github.com/sct/overseerr/commit/9f5f920c23007363aa7f53ebef0b61236d4f53ea))
|
||||
* clarify full sync runs every 24 hours ([0c8a180](https://github.com/sct/overseerr/commit/0c8a180189b2610bab2fa977d458743d8a60343e))
|
||||
* **plex-sync:** match correct tmdb format for movies ([4205e32](https://github.com/sct/overseerr/commit/4205e32ae71bc18c07209f1c82e6af1cb5f01335))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **email:** option to allow self signed certificates ([6898357](https://github.com/sct/overseerr/commit/6898357b13a6aa53a55709ea95819c2b3df6784c))
|
||||
* **frontend:** adjust person details design and add improved truncate ([1fb7ea7](https://github.com/sct/overseerr/commit/1fb7ea72589d2908ae80a2a688881d4eb3c050e5))
|
||||
* **frontend:** first air date added to TV details page ([#470](https://github.com/sct/overseerr/issues/470)) ([a7db01f](https://github.com/sct/overseerr/commit/a7db01fba483ca633a6eb9d39eb085ab9939d4d2))
|
||||
* **lang:** translations update from Weblate ([#410](https://github.com/sct/overseerr/issues/410)) ([941fe19](https://github.com/sct/overseerr/commit/941fe1990454439cf05b48ef92bd3493432f8ed8))
|
||||
* **logs:** rotate log files if they reach 20MB in size ([22002ab](https://github.com/sct/overseerr/commit/22002ab4c76aace2bb202ac58da605b7a6f75d6d)), closes [#438](https://github.com/sct/overseerr/issues/438)
|
||||
* **notifications:** include direct links to media in notifications ([659fa50](https://github.com/sct/overseerr/commit/659fa505f0db32262ad0041cddb4daea893e6d65)), closes [#437](https://github.com/sct/overseerr/issues/437)
|
||||
* **plex-sync:** add support for hama guid's ([ffe9e19](https://github.com/sct/overseerr/commit/ffe9e19c3b99de6af1185900e292da641ff44320)), closes [#453](https://github.com/sct/overseerr/issues/453)
|
||||
|
||||
## [1.12.1](https://github.com/sct/overseerr/compare/v1.12.0...v1.12.1) (2020-12-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **migration:** fixes issue migrating away from the unique imdbId constraint ([69fd7a5](https://github.com/sct/overseerr/commit/69fd7a5511215674a5c22ba48627f221da900229))
|
||||
|
||||
# [1.12.0](https://github.com/sct/overseerr/compare/v1.11.0...v1.12.0) (2020-12-22)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** fix cross-imported type crashing build ([f35dae5](https://github.com/sct/overseerr/commit/f35dae56a583a5545375318fa5be994ae1f2557f))
|
||||
* **api:** prevent checking first admin account for plex server access ([22006e9](https://github.com/sct/overseerr/commit/22006e9dbde82609440f89bde9a40887b4742682))
|
||||
* **frontend:** add name, short_name and start_url to manifest ([#424](https://github.com/sct/overseerr/issues/424)) ([c6836e0](https://github.com/sct/overseerr/commit/c6836e02c810e8adb12c3a4b110f9604cf5b7b81))
|
||||
* **frontend:** adjust person card layout to deal with overflowing content ([4891298](https://github.com/sct/overseerr/commit/48912988915ae40606a900a6f1dd23fc25ed567f)), closes [#416](https://github.com/sct/overseerr/issues/416)
|
||||
* **frontend:** allow more special characters in search input ([5deb64a](https://github.com/sct/overseerr/commit/5deb64a87fd70e97da27a025ad11fb8ace0e0b57)), closes [#430](https://github.com/sct/overseerr/issues/430)
|
||||
* **logs:** improve logging when adding to sonarr/radarr ([4b50522](https://github.com/sct/overseerr/commit/4b505223b881a750007e3fbc7d4bcb9677d4d412))
|
||||
* only run migrations in production ([ab9cef3](https://github.com/sct/overseerr/commit/ab9cef3624b5db1ec03507553a69d33b87857e29))
|
||||
* **notifications:** always update the media table when seasons become available ([0916b58](https://github.com/sct/overseerr/commit/0916b58594a00db98c6701fdcaee4f3c3e08904e))
|
||||
* **plex-sync:** fixes processing movies using TMDB agent ([764db94](https://github.com/sct/overseerr/commit/764db94f1bd7866309684d5bd56033b21cbc2e0c)), closes [#363](https://github.com/sct/overseerr/issues/363)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** add crew related movies/shows to person details page ([12127a7](https://github.com/sct/overseerr/commit/12127a77633f0e92ae88cbafd49581296f559c33))
|
||||
* **frontend:** add full crew page for movies/shows ([604ba2a](https://github.com/sct/overseerr/commit/604ba2a92f1d59489e7fc6dfc011347f8595c123))
|
||||
* default user permissions added to settings ([e7ee85c](https://github.com/sct/overseerr/commit/e7ee85c29b5d25c6bff58717eae5e62de4dcef0c)), closes [#388](https://github.com/sct/overseerr/issues/388)
|
||||
* import users from plex ([#428](https://github.com/sct/overseerr/issues/428)) ([7e8f361](https://github.com/sct/overseerr/commit/7e8f361af711001cfc4dcc06a384b76f9846f90f)), closes [#281](https://github.com/sct/overseerr/issues/281)
|
||||
* **frontend:** add prioritized crew under overview ([6753d9d](https://github.com/sct/overseerr/commit/6753d9daaafb18672f14fd86f2c1675dcec39b13)), closes [#406](https://github.com/sct/overseerr/issues/406)
|
||||
* **notifications:** added ability to send test notifications ([44a3054](https://github.com/sct/overseerr/commit/44a305426f3e9829c167a4a73095d0d248641f47)), closes [#309](https://github.com/sct/overseerr/issues/309)
|
||||
|
||||
|
||||
### Reverts
|
||||
|
||||
* **deps:** revert react-use-clipboard to 1.0.2 ([7083ddf](https://github.com/sct/overseerr/commit/7083ddf18121716e3442acab3506c395fdc351ac))
|
||||
|
||||
# [1.11.0](https://github.com/sct/overseerr/compare/v1.10.0...v1.11.0) (2020-12-20)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** add language picker to setup/login ([ff2ab29](https://github.com/sct/overseerr/commit/ff2ab29491a80c421525b9a394d6fbbf54914dc2))
|
||||
* **frontend:** add support overseerr block to about page ([c128898](https://github.com/sct/overseerr/commit/c128898206d6cbb482de4d8dca53f70b87e4911a))
|
||||
* **frontend:** releases added to about page ([b7f5739](https://github.com/sct/overseerr/commit/b7f573903500cc8a62e39afd787bc1da8c09d88b)), closes [#303](https://github.com/sct/overseerr/issues/303)
|
||||
* **lang:** add support for Italian, Portuguese (Brazil) and Serbian ([108dfc4](https://github.com/sct/overseerr/commit/108dfc4afd31388cb6c9e07deccd168ade8b1574))
|
||||
* **lang:** add support for swedish language ([c9fe6cb](https://github.com/sct/overseerr/commit/c9fe6cb0b7ea984d8e4e1cb3f284935c9da7cc2b))
|
||||
* **lang:** translations update from Weblate ([#400](https://github.com/sct/overseerr/issues/400)) ([1bd0e64](https://github.com/sct/overseerr/commit/1bd0e646e313ddf77ef331e818e03401fbf64a72))
|
||||
* **lang:** translations update from Weblate ([#403](https://github.com/sct/overseerr/issues/403)) ([3778ad8](https://github.com/sct/overseerr/commit/3778ad829c0897de178212b3bde4c0d3b5089161))
|
||||
|
||||
# [1.10.0](https://github.com/sct/overseerr/compare/v1.9.1...v1.10.0) (2020-12-19)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **email:** fix link to Overseerr in email templates ([816fec1](https://github.com/sct/overseerr/commit/816fec1a83a53edb3b65c3e5e7d0e6e1bd49726d)), closes [#392](https://github.com/sct/overseerr/issues/392)
|
||||
* **frontend:** adjust padding of search box so placeholder text fits on mobile ([3601d44](https://github.com/sct/overseerr/commit/3601d442db32d3f98f7b050365c11ea8ef9bc4ae)), closes [#393](https://github.com/sct/overseerr/issues/393)
|
||||
* **frontend:** changed request block for slideover on mobile UI ([#387](https://github.com/sct/overseerr/issues/387)) ([549567a](https://github.com/sct/overseerr/commit/549567a7e9db01933546d9970fc06f17218dfab1))
|
||||
* **frontend:** hide Request More button if all current seasons are available ([2a4dd52](https://github.com/sct/overseerr/commit/2a4dd52275007e48f946c3b9e29f1d78da57bdaa)), closes [#343](https://github.com/sct/overseerr/issues/343)
|
||||
* **frontend:** try not to render broken rottentomatoes data ([a0c5608](https://github.com/sct/overseerr/commit/a0c5608aa0b6c7a4294300589efa9a662163ce48))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translations update from Weblate ([#391](https://github.com/sct/overseerr/issues/391)) ([5f71fb7](https://github.com/sct/overseerr/commit/5f71fb7ee280714275d2ac045c472fcdddd5a2ea))
|
||||
* add missing tzdata package to image ([53bede6](https://github.com/sct/overseerr/commit/53bede692d4f0e940dededa63015fe1908129914)), closes [#394](https://github.com/sct/overseerr/issues/394)
|
||||
* **frontend:** add external links to movie and tv detail pages ([a0024a0](https://github.com/sct/overseerr/commit/a0024a0cbe717d78f53413bb78644c829f143c4d))
|
||||
* **lang:** translations update from Weblate ([#380](https://github.com/sct/overseerr/issues/380)) ([8408e19](https://github.com/sct/overseerr/commit/8408e19568b2f239c57e11e2946c75f193d1c22e))
|
||||
|
||||
## [1.9.1](https://github.com/sct/overseerr/compare/v1.9.0...v1.9.1) (2020-12-18)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* change default internal port to 5055 ([#389](https://github.com/sct/overseerr/issues/389)) ([5e5ba40](https://github.com/sct/overseerr/commit/5e5ba4050563f07bff367d2fb31ed7e7fca4291e))
|
||||
|
||||
# [1.9.0](https://github.com/sct/overseerr/compare/v1.8.0...v1.9.0) (2020-12-18)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* api key regeneration ([6beac73](https://github.com/sct/overseerr/commit/6beac736efcf7b9102e02e43b75d91a9a158cd22))
|
||||
* **api:** add movie keyword search ([f88c4a6](https://github.com/sct/overseerr/commit/f88c4a6d4a49f8f3451ba6c85153677f33b7f5f6))
|
||||
* **frontend:** add studio/networks to movie/tv details ([4b6ad8a](https://github.com/sct/overseerr/commit/4b6ad8a3871957db4192b603abf38404250cea5d)), closes [#370](https://github.com/sct/overseerr/issues/370)
|
||||
* **frontend:** added user deletion to the user list ([727fa06](https://github.com/sct/overseerr/commit/727fa06c18febb2a97ca219cc6bf0277ff462acd)), closes [#348](https://github.com/sct/overseerr/issues/348)
|
||||
* **holiday:** special seasonal slider added to discover :) ([908f635](https://github.com/sct/overseerr/commit/908f63557ca03a1da8b16809ffa2c3acd782d94e))
|
||||
* allow to listen server on specific host interface ([#381](https://github.com/sct/overseerr/issues/381)) ([086183b](https://github.com/sct/overseerr/commit/086183b5636aa8d075d01fe59492c3eab0d1345b)), closes [#273](https://github.com/sct/overseerr/issues/273)
|
||||
* anime profile support ([#384](https://github.com/sct/overseerr/issues/384)) ([0972f40](https://github.com/sct/overseerr/commit/0972f40a4e1fb3b5f02b07ae46b997d71aab9bfb)), closes [#266](https://github.com/sct/overseerr/issues/266)
|
||||
|
||||
# [1.8.0](https://github.com/sct/overseerr/compare/v1.7.0...v1.8.0) (2020-12-17)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** translations update from Weblate ([#336](https://github.com/sct/overseerr/issues/336)) ([ee84f74](https://github.com/sct/overseerr/commit/ee84f74f8a3558875b41daa539f42d00b949898a))
|
||||
|
||||
# [1.7.0](https://github.com/sct/overseerr/compare/v1.6.0...v1.7.0) (2020-12-17)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **email:** do not pass auth object to transport if no auth data present ([d5eb4d8](https://github.com/sct/overseerr/commit/d5eb4d8d438a159266b2de66b6bcdd9440a0c8ef)), closes [#312](https://github.com/sct/overseerr/issues/312)
|
||||
* **frontend:** add http/https prefix to hostname fields for plex/radarr/sonarr ([ce0266f](https://github.com/sct/overseerr/commit/ce0266f74ea3979b291ff962271a928682892788)), closes [#357](https://github.com/sct/overseerr/issues/357)
|
||||
* **frontend:** clarify that radarr/sonnarr servers must be tested before profiles/folders appear ([fc12ab8](https://github.com/sct/overseerr/commit/fc12ab84d9482eb3a11f117f8cab6fd48a9401cd)), closes [#326](https://github.com/sct/overseerr/issues/326) [#328](https://github.com/sct/overseerr/issues/328)
|
||||
* **frontend:** correctly show an unauthorized error when a user fails to login ([18925de](https://github.com/sct/overseerr/commit/18925decafdac518f52a354c594cc378d2529022)), closes [#322](https://github.com/sct/overseerr/issues/322)
|
||||
* **frontend:** fix tv shows failing to open when firstAirDate is undefined ([c21fa5b](https://github.com/sct/overseerr/commit/c21fa5b5350abdd8e03c077fde7246fa398e176e)), closes [#347](https://github.com/sct/overseerr/issues/347)
|
||||
* **frontend:** make minimum availability required for Radarr servers ([2fe53ec](https://github.com/sct/overseerr/commit/2fe53ec5a8534e75c7d0cef31a8b46065111e0a7)), closes [#345](https://github.com/sct/overseerr/issues/345)
|
||||
* **plex-sync:** bundle duplicate ratingKeys to speed up recently added sync ([67146c3](https://github.com/sct/overseerr/commit/67146c33ef7f28d520ba2c50b32673d43f4525c8)), closes [#360](https://github.com/sct/overseerr/issues/360)
|
||||
* **sonarr.ts, mediarequest.ts:** add missing seasonFolder option ([#358](https://github.com/sct/overseerr/issues/358)) ([e9c899c](https://github.com/sct/overseerr/commit/e9c899ce419d149dde2ad9a0f7d5a2f2545b3ebf))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** show alert when there are no default radarr/sonarr servers ([0d088e0](https://github.com/sct/overseerr/commit/0d088e085e68d39455fda21d1fd08ebcaef2c06b)), closes [#344](https://github.com/sct/overseerr/issues/344)
|
||||
|
||||
# [1.6.0](https://github.com/sct/overseerr/compare/v1.5.0...v1.6.0) (2020-12-16)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** accept the api key to perform actions on the api with X-API-Key header ([33f8831](https://github.com/sct/overseerr/commit/33f8831e880dc7fd3f69d951246cada5c6c0ffe7))
|
||||
* **api:** filter out libraries that do not have any metadata agent or are not movie/show ([01c179f](https://github.com/sct/overseerr/commit/01c179f762e686a1e5a3d4dab3a5bea53425b575))
|
||||
* **api:** only run recently added sync on enabled libraries ([e08fa35](https://github.com/sct/overseerr/commit/e08fa35548bb8644afa8df3124e6f9cc3a2c8f4a)), closes [#259](https://github.com/sct/overseerr/issues/259)
|
||||
* **api:** set plex libraries to disabled if the name changes ([675060b](https://github.com/sct/overseerr/commit/675060bcdf23acbfd4de2900a65f95e74f4966a5)), closes [#324](https://github.com/sct/overseerr/issues/324)
|
||||
* **frontend:** adds a tip to plex setup to clarify that syncing runs in the background ([df4ac83](https://github.com/sct/overseerr/commit/df4ac8361f82971ee845f3be217408a9123a0bf3)), closes [#325](https://github.com/sct/overseerr/issues/325)
|
||||
* **frontend:** aligned movie and tv details ([#331](https://github.com/sct/overseerr/issues/331)) ([db0a5c4](https://github.com/sct/overseerr/commit/db0a5c44f678e76eee7f5582381016306d1f46a2))
|
||||
* **frontend:** close sidebar when clicking outside ([#333](https://github.com/sct/overseerr/issues/333)) ([6d7907e](https://github.com/sct/overseerr/commit/6d7907e844a909993d185759d660632f55aeaa35))
|
||||
* spelling mistake on the word 'requested' fixed ([#319](https://github.com/sct/overseerr/issues/319)) ([961d110](https://github.com/sct/overseerr/commit/961d1107208069a6fc820a1ba97ffda7336677cb))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add version to startup logs ([2948f93](https://github.com/sct/overseerr/commit/2948f9360eb484d1d6c0740a840135ca97e7240a))
|
||||
* **frontend:** temporary logs page to clear up confusion about it 404ing ([d9788c4](https://github.com/sct/overseerr/commit/d9788c4aa9f87e2eda3f7e3f1adc985f16039552)), closes [#272](https://github.com/sct/overseerr/issues/272)
|
||||
* **lang:** add support for Spanish language ([6cd2049](https://github.com/sct/overseerr/commit/6cd20491d2a0ceb995c4744eeb92a6e2f57a4893))
|
||||
* **lang:** Translations update from Weblate ([#291](https://github.com/sct/overseerr/issues/291)) ([fddbb3c](https://github.com/sct/overseerr/commit/fddbb3cdfe3d50b2835c248556139c769dc2b805))
|
||||
|
||||
# [1.5.0](https://github.com/sct/overseerr/compare/v1.4.0...v1.5.0) (2020-12-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** require package.json directly so typescript doesnt compile it into dist folder ([b9faa64](https://github.com/sct/overseerr/commit/b9faa6486b35aa865019aa8af9d307531054bc1d))
|
||||
* **frontend:** add validation for Radarr/Sonarr server name ([b5988f9](https://github.com/sct/overseerr/commit/b5988f9a5ff274e97f208c2726abe76c22c858ee))
|
||||
* **frontend:** only show alpha notice to admins ([ff61895](https://github.com/sct/overseerr/commit/ff618956b5d9cf933d867ea979b612c3d8a6f30b))
|
||||
* add support for ssl when connecting to plex ([3ba09d0](https://github.com/sct/overseerr/commit/3ba09d07eb0367c41603cd55e7ff41c66fb641c4)), closes [#275](https://github.com/sct/overseerr/issues/275)
|
||||
* **services:** improve logging for when Radarr movie already exists ([#285](https://github.com/sct/overseerr/issues/285)) ([f998873](https://github.com/sct/overseerr/commit/f998873fc5669a547901f2733c9c785d744d27ca)), closes [#260](https://github.com/sct/overseerr/issues/260)
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** add i18n strings for new about page ([900827b](https://github.com/sct/overseerr/commit/900827be97845688e4bea72a8c5d9611a3e9d069))
|
||||
* about page initial version ([3f2a04c](https://github.com/sct/overseerr/commit/3f2a04c881bf06b73a952181fa463af84454b0dd))
|
||||
|
||||
# [1.4.0](https://github.com/sct/overseerr/compare/v1.3.2...v1.4.0) (2020-12-15)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* changing parameter name to use correct 'port' [#276](https://github.com/sct/overseerr/issues/276) ([#277](https://github.com/sct/overseerr/issues/277)) ([6d08b10](https://github.com/sct/overseerr/commit/6d08b108200177ca3068c852e60a0df75ce2232a))
|
||||
* **services:** include radarr/sonarr baseUrl when adding media ([78af1a3](https://github.com/sct/overseerr/commit/78af1a3e6d00a5645a05e7bf3cf56a59439b6cc9))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** Translations update from Weblate ([#240](https://github.com/sct/overseerr/issues/240)) ([e17c637](https://github.com/sct/overseerr/commit/e17c63748362b6a480693e003ef5eec614dcec43))
|
||||
|
||||
## [1.3.2](https://github.com/sct/overseerr/compare/v1.3.1...v1.3.2) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** convert plex port to a number before posting to the api ([8cb05c4](https://github.com/sct/overseerr/commit/8cb05c413a15a4b74e37ece5e24367d115995b32))
|
||||
* **frontend:** converts email smtp port to a number before posting to the api ([2098a2d](https://github.com/sct/overseerr/commit/2098a2d3d2981fd2ae54392aec3ef81327f2858e)), closes [#251](https://github.com/sct/overseerr/issues/251)
|
||||
* **frontend:** encode special characters in search input to prevent crashing router ([15013d6](https://github.com/sct/overseerr/commit/15013d6c5dbff15704c7c30d261d68a265e7f2d7)), closes [#252](https://github.com/sct/overseerr/issues/252)
|
||||
* **plex sync:** catch errors that occur during processMovie ([edbbccf](https://github.com/sct/overseerr/commit/edbbccf3ae623430294f1a5c3fd2728dbd42e555)), closes [#244](https://github.com/sct/overseerr/issues/244) [#246](https://github.com/sct/overseerr/issues/246) [#250](https://github.com/sct/overseerr/issues/250)
|
||||
* **services:** improve logging for adding movies to Radarr ([6c1ee83](https://github.com/sct/overseerr/commit/6c1ee830a183f89bb1fe96a181a7d61684e23b22))
|
||||
* **services:** radarr/sonarr will use the correct default server ([0658b79](https://github.com/sct/overseerr/commit/0658b7943e1ab25816db9da34d4c9ea808d9203d))
|
||||
|
||||
## [1.3.1](https://github.com/sct/overseerr/compare/v1.3.0...v1.3.1) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** also convert activeProfileId to a number for radarr/sonarr submissions ([7bf924f](https://github.com/sct/overseerr/commit/7bf924f7e94a0e0834f41b4ec067ed277c652766))
|
||||
* **frontend:** also convert ports to numbers when saving radarr/sonarr servers ([c53dc3b](https://github.com/sct/overseerr/commit/c53dc3b15da522c6e6ab76bbc9d15008a8a9fb9d))
|
||||
* **frontend:** new radarr/sonarr ports will be converted to a number before posting ([92c9001](https://github.com/sct/overseerr/commit/92c9001c9d1f2cbd272a5897ea1157d2cadbce2d))
|
||||
|
||||
# [1.3.0](https://github.com/sct/overseerr/compare/v1.2.0...v1.3.0) (2020-12-14)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** correctly generate clientId on first startup ([5f09e83](https://github.com/sct/overseerr/commit/5f09e83ed870336638d3e9d94fcf55ead928e737))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **frontend:** add full cast page for movies and series ([051f1b3](https://github.com/sct/overseerr/commit/051f1b3e899bf749e632743e5c8d45a02b621998))
|
||||
* **lang:** translated using Weblate (Dutch) ([1ab3a4b](https://github.com/sct/overseerr/commit/1ab3a4b80a081d7e4a201f1290cd270ed5b38ac7))
|
||||
* **lang:** translated using Weblate (English) ([0949c9b](https://github.com/sct/overseerr/commit/0949c9b334b3a4b6c342517a157a9e2b7596f2f0))
|
||||
* **lang:** translated using Weblate (French) ([f943701](https://github.com/sct/overseerr/commit/f943701e13c7f0de5a711302597858cc898b16e2))
|
||||
* **lang:** translated using Weblate (French) ([30d04ce](https://github.com/sct/overseerr/commit/30d04ce35adc21070cce37ab10384154afda191b))
|
||||
* **lang:** translated using Weblate (German) ([7bf9add](https://github.com/sct/overseerr/commit/7bf9addd13a707aac23b64ef3f1733e491d40a4e))
|
||||
* **lang:** translated using Weblate (German) ([b6e60a4](https://github.com/sct/overseerr/commit/b6e60a412b30907aea751a4cf1ce0cc8230f9814))
|
||||
* **lang:** translated using Weblate (Japanese) ([08e968f](https://github.com/sct/overseerr/commit/08e968fd0097ec7b2a65de064ed5b07e7c49ef39))
|
||||
* **lang:** translated using Weblate (Norwegian Bokmål) ([83efb0e](https://github.com/sct/overseerr/commit/83efb0e3d4d96b6a2d2ebdd85d36c9d78c1717b2))
|
||||
* **lang:** translated using Weblate (Russian) ([0d8e0d0](https://github.com/sct/overseerr/commit/0d8e0d0352f72fdb65ee8f054371eae08c39fe33))
|
||||
|
||||
# [1.2.0](https://github.com/sct/overseerr/compare/v1.1.0...v1.2.0) (2020-12-11)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **frontend:** person cards now show correctly in ListView's ([ccb9855](https://github.com/sct/overseerr/commit/ccb98553f104c1aebd33796b7090cc9bbe964bd7))
|
||||
* **frontend:** properly remove site overlay when closing modals ([3fa7ff9](https://github.com/sct/overseerr/commit/3fa7ff9858d14d132151f3329164d55d74638f53))
|
||||
* **frontend:** switch to using Transition component for modals ([b16fbaf](https://github.com/sct/overseerr/commit/b16fbafa1f3d5e105c0a4ba6f1d66aa064019636)), closes [#220](https://github.com/sct/overseerr/issues/220)
|
||||
* fix missing personid in Discover ([d8060af](https://github.com/sct/overseerr/commit/d8060afe02574337f51b88cab0a0f824976ac721))
|
||||
* missing personId in ListView component ([6502feb](https://github.com/sct/overseerr/commit/6502feb1a5be3c6daab33230814fe74632c87f7e))
|
||||
* **frontend:** update overflow issues with seasons + email ([#217](https://github.com/sct/overseerr/issues/217)) ([2d0afb2](https://github.com/sct/overseerr/commit/2d0afb29d37798a626e3f182571ccce43d80063c)), closes [#216](https://github.com/sct/overseerr/issues/216)
|
||||
* **lang:** fix missing i18n string for agent enabled in email notification page ([42788ad](https://github.com/sct/overseerr/commit/42788adb75f7d23e68327688b1c542dd047e9609))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* **lang:** update language files ([8cd067b](https://github.com/sct/overseerr/commit/8cd067b6e9df1a3c8f4056789436a31177703986))
|
||||
* person details page ([d6eb3ae](https://github.com/sct/overseerr/commit/d6eb3ae64ef46bd62145010d3029e272676487c3))
|
||||
* **lang:** add nb-NO and de language support to app ([d38b28d](https://github.com/sct/overseerr/commit/d38b28d2061b38366989ff412957a5dee5766c6f))
|
||||
* **lang:** add support for dutch language ([df94db0](https://github.com/sct/overseerr/commit/df94db050bf68a925118e0ce865d27178b702f9e))
|
||||
* **lang:** add support for russian languge ([8d8e750](https://github.com/sct/overseerr/commit/8d8e7509826514eebc859374d2e1ab212cc442d1))
|
||||
* **lang:** added translation using Weblate (Russian) ([887f5dd](https://github.com/sct/overseerr/commit/887f5dd487b61676029652d99cbc5b40213aa22e))
|
||||
* **lang:** translated using Weblate (French) ([30a8934](https://github.com/sct/overseerr/commit/30a8934626fa2d47e95b5925d7e4227a0d0aa728))
|
||||
* **lang:** translated using Weblate (German) ([44dbb74](https://github.com/sct/overseerr/commit/44dbb745b6216ce19fab4740520785c6414cf367))
|
||||
* **lang:** translated using Weblate (Japanese) ([a494507](https://github.com/sct/overseerr/commit/a494507dfeafb0cfd2bd66fb01138522e0e80737))
|
||||
* **lang:** translated using Weblate (Russian) ([86cadb8](https://github.com/sct/overseerr/commit/86cadb8283fcab8745b4c09f8429fd9e46708813))
|
||||
* **lang:** translations update from Weblate ([#201](https://github.com/sct/overseerr/issues/201)) ([b0c663b](https://github.com/sct/overseerr/commit/b0c663baccd994e234b4d41d86486c3af4906344))
|
||||
|
||||
# [1.1.0](https://github.com/sct/overseerr/compare/v1.0.0...v1.1.0) (2020-12-08)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* fix a few misc unused imports and useless assignments/conditionals ([8e6daf7](https://github.com/sct/overseerr/commit/8e6daf7bd271ce5bebf4a00f5bb1144bd6b60aa5))
|
||||
* **frontend:** dont show delete button in request list for users without correct permission ([83fde46](https://github.com/sct/overseerr/commit/83fde46a59c6f1910806a6106b5526b8adbc386c))
|
||||
* **frontend:** push updated i18n locale files ([b4002d7](https://github.com/sct/overseerr/commit/b4002d71323a04e7991198cedc263660e872df8d))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* generate real api key ([a839370](https://github.com/sct/overseerr/commit/a8393707fec85a9262af5ba8c03d205190b2235b))
|
||||
* **frontend:** add i18n strings for request list and request item ([6c4022f](https://github.com/sct/overseerr/commit/6c4022fb236583ad20d4c4c6693c1339e165b4af))
|
||||
* **frontend:** initial version of the requests page (no filtering/sorting) ([1ba027b](https://github.com/sct/overseerr/commit/1ba027b4357e078c3f177d9d07208049f0c1ce65))
|
||||
* **frontend:** only load request/tmdb cards when in the browser view ([2d51efd](https://github.com/sct/overseerr/commit/2d51efd71612ec969b83c62d6aa0dac6df9391a3))
|
||||
|
||||
# 1.0.0 (2020-12-06)
|
||||
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* **api:** fix scheduling for plex full sync (maybe) ([7287a6a](https://github.com/sct/overseerr/commit/7287a6a95703b23acc0c4f6eb3beb9ec2295e33f))
|
||||
* **frontend:** always show request modal option for tv ([2b46268](https://github.com/sct/overseerr/commit/2b462688243531b4be620a942f59defd4e0534d0))
|
||||
* **frontend:** canceled movie request should set parent movie status back to unknown ([#198](https://github.com/sct/overseerr/issues/198)) ([139871f](https://github.com/sct/overseerr/commit/139871f218812a15f742aa66408db12704e0b9b5))
|
||||
* **frontend:** close request modals when complete ([85ae499](https://github.com/sct/overseerr/commit/85ae4998f0ba8d4869b9b244f2c440b9df1310d2))
|
||||
* **frontend:** dont show runtime if there is no runtime data ([e0c39ae](https://github.com/sct/overseerr/commit/e0c39aeca119b822f2a54ff05a97f91780ddd052))
|
||||
* **frontend:** fix missing data for request modal title i18n ([a56fd16](https://github.com/sct/overseerr/commit/a56fd16ab6638d4649fe9f8b9d75e7cae7742f73))
|
||||
* **frontend:** fix missing import for ReactNode type in Slider ([b26a234](https://github.com/sct/overseerr/commit/b26a2347e7b0f7ff8720a204d9faefd501ba886c))
|
||||
* **frontend:** fix modal design and rename some text for adding servers ([46d99b0](https://github.com/sct/overseerr/commit/46d99b02b1c992c7b8dde2150217ed9ce326b7a5))
|
||||
* **frontend:** fix opening popups on safari ([364d9d1](https://github.com/sct/overseerr/commit/364d9d105ca3690fcd5f635485d7c025353bb9f1))
|
||||
* **frontend:** fix request card placeholder sizes for mobile ([ef62c67](https://github.com/sct/overseerr/commit/ef62c67480ed52d753ea6db8205f035b2e9da272))
|
||||
* **frontend:** show a badge on requestcard for partially available status ([59056c4](https://github.com/sct/overseerr/commit/59056c44f942a37df536ff947b5faccc27f32246))
|
||||
* dont cross import SyncStatus type ([e032e38](https://github.com/sct/overseerr/commit/e032e385a5253d215490255c676f42ee48f39428))
|
||||
* fix type import from server side crashing build process ([89be56d](https://github.com/sct/overseerr/commit/89be56d8403ebc60c411e7cb357593edd9c79bb2))
|
||||
* **frontend:** fix title detail background image to be centered ([b92f64f](https://github.com/sct/overseerr/commit/b92f64fa6e167bc89168d8f5c0f2eb12efa0b6f0))
|
||||
* **frontend:** fixed similar/recommendations showing when empty ([#180](https://github.com/sct/overseerr/issues/180)) ([a3ca9b4](https://github.com/sct/overseerr/commit/a3ca9b40c552e6cc5effc2f57f7562ff6f723e42))
|
||||
* **frontend:** have tvDetail use the new RequestModal ([6aca826](https://github.com/sct/overseerr/commit/6aca82607b97d4a4ad74e2ea843d52fba4689e6a))
|
||||
* **frontend:** reinitalize plex form after data loads ([97e3036](https://github.com/sct/overseerr/commit/97e30367fb5d2d27efc42c1d76b0d051b6f1da76))
|
||||
* **frontend:** remove requestId from tilecard request modal component ([61b6152](https://github.com/sct/overseerr/commit/61b6152e8915c99585b944756a61d33b8c8a0307))
|
||||
* **frontend:** run initial props for children components after getting the user ([fdf9f38](https://github.com/sct/overseerr/commit/fdf9f38776b6d4c08b3505c03b354639cebb011f))
|
||||
* **frontend:** when there were no results in the list view, it would call fetch more infinitely ([c0ce87b](https://github.com/sct/overseerr/commit/c0ce87b6f65bf0ab1301c7ca61090d779709529f))
|
||||
* fixed an issue with eslint-prettier on windows ([#32](https://github.com/sct/overseerr/issues/32)) ([b673ea1](https://github.com/sct/overseerr/commit/b673ea1b18ca0f432996bb9e4e5d148af0247170))
|
||||
* fixes next.js build to not include server files ([de8ee9b](https://github.com/sct/overseerr/commit/de8ee9ba85e0160b0b472cab44f92c01796efec8))
|
||||
|
||||
|
||||
### Features
|
||||
|
||||
* add migration for delete cascades on season requests/seasons ([c688cf6](https://github.com/sct/overseerr/commit/c688cf60c710f0cf0b2da5ba6b0c18a2d137e7f9))
|
||||
* **api:** email notification agent ([0962392](https://github.com/sct/overseerr/commit/0962392e3930c7fdcb3164b9143cc8faca38bdfa))
|
||||
* **frontend:** add french language file ([cd6d8a8](https://github.com/sct/overseerr/commit/cd6d8a8216e7ae183b046d26cd22f3c1dc1d2b35))
|
||||
* **frontend:** add translatable strings for request card ([0d2f360](https://github.com/sct/overseerr/commit/0d2f360c22cd9bb50ae04f00a25e5fcc6c21bcdd))
|
||||
* **frontend:** added more localized strings ([659a601](https://github.com/sct/overseerr/commit/659a6018777718f7a90141307678d8dadcfd77f8))
|
||||
* actually include email templates in built server files ([a28a8b3](https://github.com/sct/overseerr/commit/a28a8b37b0afc79583e4a7191a91f73ff6d3adad))
|
||||
* add application url config to main settings ui ([a359672](https://github.com/sct/overseerr/commit/a359672ebafffef742858814f0faa918e0341aa3))
|
||||
* add filtering for requests api ([cb9ae25](https://github.com/sct/overseerr/commit/cb9ae25d94f21e97113dfea3ca45c7002089e344))
|
||||
* add trending to discover page ([ff8b9d8](https://github.com/sct/overseerr/commit/ff8b9d8e7ed228a153c2da4d237f7a4f99a79321))
|
||||
* force setup if app is not initialized ([a99705f](https://github.com/sct/overseerr/commit/a99705f6a5674b436ae28cbc558f4ee6e99ac910))
|
||||
* initial user list (no edit/delete yet) and job schedules ([24a0423](https://github.com/sct/overseerr/commit/24a0423f3b14303cfb0e83aef6e9e3bb273c5ba9))
|
||||
* manage series slideover added (and approve/decline/delete hooked up) ([236c4e5](https://github.com/sct/overseerr/commit/236c4e5e6126d2424a4badc08b7f7e6d1d70f401))
|
||||
* media delete option in manage media slideover ([250f484](https://github.com/sct/overseerr/commit/250f48492c95d74e40d95d3f026d2952157bc6e1))
|
||||
* other email notifications for approved/available ([0d73d88](https://github.com/sct/overseerr/commit/0d73d88f35b03e993f305873dc72672003c7d9e5))
|
||||
* radarr edit/create modal/backend functionality ([c4ac357](https://github.com/sct/overseerr/commit/c4ac357ef4cdd7a2c610260db46a4f0c325cd785))
|
||||
* season creation migration ([978f92a](https://github.com/sct/overseerr/commit/978f92a1c589ac404a3cb1103a68a8a5ffb0dd7d))
|
||||
* sonarr edit/delete modal ([3204326](https://github.com/sct/overseerr/commit/320432657e6ccf4d255238098e03590f28267bdb))
|
||||
* throw 404 when movie/tv show doesnt exist ([0601b44](https://github.com/sct/overseerr/commit/0601b446873e2eaf042044dd6a995b713586b0cc))
|
||||
* **api:** sonarr api wrapper / send to sonarr ([9385592](https://github.com/sct/overseerr/commit/9385592362eeba1dba05c5aa8fc7a2de1d054d74))
|
||||
* **frontend:** add header styling to movie/tv recommendation and similar list views ([f5f2545](https://github.com/sct/overseerr/commit/f5f2545520a43daa23e1276d24ff60d794ebbc6e))
|
||||
* **frontend:** add links to detail pages from new request card ([6ad3384](https://github.com/sct/overseerr/commit/6ad3384a78f7bcb03f409cce8b35cc61d634d6b2))
|
||||
* **frontend:** new design for request card ([93738e1](https://github.com/sct/overseerr/commit/93738e154c41fd11d5c6cf3d35573daf54ead471))
|
||||
* **frontend:** update favicon ([886389a](https://github.com/sct/overseerr/commit/886389a361da54c616da3bdfeee9a85e9d12bcf3))
|
||||
* notification framework ([d8e542e](https://github.com/sct/overseerr/commit/d8e542e5fe2ed76dcb20fb6dfc5f59430cd4245d))
|
||||
* notifications for media_available and media_approved ([a6c5e65](https://github.com/sct/overseerr/commit/a6c5e65bbfc196545471e99fe2e5b7194f9dd387))
|
||||
* rotten tomatoes scores on movie/tv details pages ([1694f60](https://github.com/sct/overseerr/commit/1694f60e8aa475ceeb7f170a783ec0ba70bd4bce))
|
||||
* upcoming movies on discover ([67290dd](https://github.com/sct/overseerr/commit/67290dd502571a22dcf8559ac07f42e855275bd0))
|
||||
* upcoming/trending list views and larger title cards ([94eaaf9](https://github.com/sct/overseerr/commit/94eaaf96b4302a832c52ccb72009b3593452c779))
|
||||
* upgrade tailwindcss to 2.0.1 ([fb5c791](https://github.com/sct/overseerr/commit/fb5c791b0b6b7593a472bf01713999a001f92dc7))
|
||||
* user edit functionality (managing permissions) ([185ac26](https://github.com/sct/overseerr/commit/185ac2648fd21c4bf9692ac5ac055e9c740065ca))
|
||||
* **api:** plex tv sync and recently added sync ([1390cc1](https://github.com/sct/overseerr/commit/1390cc1f130bb3975996e84b12ac833f55f2f753))
|
||||
* **frontend:** allow permission check for showing nav items ([0b239f0](https://github.com/sct/overseerr/commit/0b239f0bdfb1394897bce5c50b0d112abfbb4ad7))
|
||||
* **frontend:** alpha notice ([33da7e9](https://github.com/sct/overseerr/commit/33da7e9df3a2546b0f208bd3b1d1f268e343cead))
|
||||
* **frontend:** buttonWithDropdown component added (no hookups yet) ([4975841](https://github.com/sct/overseerr/commit/4975841b5d4ba4ed1ba8cacaa5a063eeb3b8c311))
|
||||
* **frontend:** cancel movie request modal ([1f9cbbf](https://github.com/sct/overseerr/commit/1f9cbbfdf1ac98e54de5b8777c52c7bfc69c7e20))
|
||||
* **frontend:** improved settings menu design for mobile ([16221a4](https://github.com/sct/overseerr/commit/16221a46a7d57c77f53aa0186263aa27267d9863))
|
||||
* **frontend:** initial Settings design ([8742da0](https://github.com/sct/overseerr/commit/8742da0ebb92d2f78309a998de0f67e788e14376))
|
||||
* **frontend:** plex library scan ([1bc3f7b](https://github.com/sct/overseerr/commit/1bc3f7be4b07211563a1e254c28ce51e1bc337a2))
|
||||
* **frontend:** plex settings page ([47714b6](https://github.com/sct/overseerr/commit/47714b698cf4351c1ee38bdf0b672d9f0baed03a))
|
||||
* **frontend:** radarr delete modal ([877a518](https://github.com/sct/overseerr/commit/877a5184158fb4aa371fa2ea2107032543c9aa37))
|
||||
* **frontend:** recently added on discover ([06dc606](https://github.com/sct/overseerr/commit/06dc606bcfeb50b7be1c35ac180c10738bade458))
|
||||
* **frontend:** slideover initial work ([14b9cb6](https://github.com/sct/overseerr/commit/14b9cb610c0dcfef939ebec328f371e1cdfb689d))
|
||||
* tv request modal status hookup ([5f8114f](https://github.com/sct/overseerr/commit/5f8114f730b067eb710704952824057e7b5b8fbf))
|
||||
* **.editorconfig:** add .editorconfig ([b982066](https://github.com/sct/overseerr/commit/b982066327525156f8dd0d32818d3fe7cb28f9c8))
|
||||
* **api:** add external ids to movie/tv response ([4aa7431](https://github.com/sct/overseerr/commit/4aa74319e0adcc19041239e57a00bc40fb127826))
|
||||
* **api:** add movie details endpoint ([b176148](https://github.com/sct/overseerr/commit/b1761484cb2861329763d51a868f37dd3098760d))
|
||||
* **api:** add tmdb discover api wrapper ([#67](https://github.com/sct/overseerr/issues/67)) ([839448f](https://github.com/sct/overseerr/commit/839448fcc8cc14ea83092af82e2ba3d0d92c9b73))
|
||||
* **api:** allow plex logins from users who have access to the server ([5147140](https://github.com/sct/overseerr/commit/514714071dfe4be04e607fe6412f5b3f0ef74dd4))
|
||||
* **api:** decouple media requests from media info ([8577db1](https://github.com/sct/overseerr/commit/8577db1be16f099d92c6649bbfb15f15e09a2f73))
|
||||
* **api:** discover endpoint for movie/tv ([#73](https://github.com/sct/overseerr/issues/73)) ([258bb93](https://github.com/sct/overseerr/commit/258bb93be2acc2ca32eaaefb617a5c326c5943ba))
|
||||
* **api:** initial implementation of the auth system ([#30](https://github.com/sct/overseerr/issues/30)) ([5343f35](https://github.com/sct/overseerr/commit/5343f35e5b572fe366a8712b24bd735de30e6170))
|
||||
* **api:** plex Sync (Movies) ([1be8b18](https://github.com/sct/overseerr/commit/1be8b183617c3a44ab8d4454a64b43dfe1d877fe))
|
||||
* **api:** public settings route ([#57](https://github.com/sct/overseerr/issues/57)) ([c0166e7](https://github.com/sct/overseerr/commit/c0166e7ecb5df110a4167f33338ed6406bf47f41))
|
||||
* **api:** radarr api wrapper / send to radarr when requests approved ([#93](https://github.com/sct/overseerr/issues/93)) ([48d62c3](https://github.com/sct/overseerr/commit/48d62c3178488d0d51831155ddd35cc31867db2b))
|
||||
* **api:** request api ([#80](https://github.com/sct/overseerr/issues/80)) ([f4c2c47](https://github.com/sct/overseerr/commit/f4c2c47e569e7faea7f99664966cb98b321ce952))
|
||||
* **api:** tmdb api wrapper / multi search route ([#62](https://github.com/sct/overseerr/issues/62)) ([c702c17](https://github.com/sct/overseerr/commit/c702c17cee00a52b23f685206e2d5d0c2eddf5a2))
|
||||
* **api:** tmdb trending api wrapper ([#68](https://github.com/sct/overseerr/issues/68)) ([ba34e54](https://github.com/sct/overseerr/commit/ba34e54d77d142d211df58d6ce9f53b6e673e004))
|
||||
* **api:** tv details endpoint ([a3beeed](https://github.com/sct/overseerr/commit/a3beeede7e72e99c7595673a27e38611ca4bb0cd))
|
||||
* **api:** validate plex when settings are saved ([8f6247d](https://github.com/sct/overseerr/commit/8f6247d82160704a3cfb76262696957b27641e87))
|
||||
* **api-user:** add basic User Entity and basic routing to fetch all users ([d902ef7](https://github.com/sct/overseerr/commit/d902ef72770712f2f71f33c09bca9ba99a30fc64))
|
||||
* **components/plexloginbutton:** added PlexLoginButton ([0abf743](https://github.com/sct/overseerr/commit/0abf743b17c664b58da18bdbf176f4a55ddc4179))
|
||||
* **extensions.json:** added recommended extensions for VSCode ([5dc9b51](https://github.com/sct/overseerr/commit/5dc9b510b8049516ad889c9d76a2f84daa0d2718))
|
||||
* **frontend:** add cancel request modal for titlecards ([f22f8c5](https://github.com/sct/overseerr/commit/f22f8c5d734be5cc0b1dcca869458a7321cd43a2))
|
||||
* **frontend:** approve/decline request well added to movie detail ([8f21358](https://github.com/sct/overseerr/commit/8f21358f797ed55923d90ba43acf1126856e9dfd))
|
||||
* **frontend:** basic discover page (only movies) ([#74](https://github.com/sct/overseerr/issues/74)) ([bbfe349](https://github.com/sct/overseerr/commit/bbfe349b52d308620796b37aaf986a0ed1ff0006))
|
||||
* **frontend:** design updates for responsive titlecards ([31809d9](https://github.com/sct/overseerr/commit/31809d952c8bafde3f63e2c1d952cc013149940e))
|
||||
* **frontend:** discover tv/movies full page ([be0003a](https://github.com/sct/overseerr/commit/be0003a85dc4e91799e85019aeb1110bd524a026))
|
||||
* **frontend:** initial search functionality ([#78](https://github.com/sct/overseerr/issues/78)) ([342d1a3](https://github.com/sct/overseerr/commit/342d1a3c75b32b172a51ca7d82fdfde8510abedf))
|
||||
* **frontend:** loading spinner ([de84658](https://github.com/sct/overseerr/commit/de84658b48985e24b0f92a1690387f6d59d0bc16))
|
||||
* **frontend:** logo updates ([5a43ec5](https://github.com/sct/overseerr/commit/5a43ec5405855deb244e8085484a9d2b743caba6))
|
||||
* **frontend:** modal component and basic request hookup ([#91](https://github.com/sct/overseerr/issues/91)) ([626099a](https://github.com/sct/overseerr/commit/626099a2c98fb30d0cb53d8ccf79a6bf75a00059))
|
||||
* **frontend:** new dashboard concept ([#82](https://github.com/sct/overseerr/issues/82)) ([eae38bb](https://github.com/sct/overseerr/commit/eae38bb9ec8588856f319387d2f262d7ee3f7e9c))
|
||||
* **frontend:** refresh indicator for titlecards / toasts ([4638fae](https://github.com/sct/overseerr/commit/4638fae336edc62a539796b3f55277a238683603))
|
||||
* **frontend:** request card / recent requests ([371e433](https://github.com/sct/overseerr/commit/371e43356d2c057e52368c32ffe2af1744311d91))
|
||||
* **frontend:** title detail (movie) initial version ([73ce24a](https://github.com/sct/overseerr/commit/73ce24a37bda3713e8cedc44e1ed065bdbc4ee4f))
|
||||
* **frontend/api:** beginning of new request modal ([2bf7e10](https://github.com/sct/overseerr/commit/2bf7e10e32718b36799be2feb0a7f9ff54d85744))
|
||||
* **frontend/api:** cast included with movie request and cast list on detail page ([04252f8](https://github.com/sct/overseerr/commit/04252f88bbdf51949923586feda582f86ac668ce))
|
||||
* **frontend/api:** i18n support ([9131254](https://github.com/sct/overseerr/commit/9131254f3371f12a17de44b6fa8f9bfb0e5c002e))
|
||||
* **frontend/api:** movie recommendations/similar request and frontend detail page update ([6398e36](https://github.com/sct/overseerr/commit/6398e3645a1e4ddbb9de9f4fda0a0659b4cac4d0))
|
||||
* **frontend/api:** tv details page ([02cbb5b](https://github.com/sct/overseerr/commit/02cbb5b030a3af5d62ab6c4cafdd4d800b4f61f4))
|
||||
* **frontend/api:** tv request modal (no status. only request) ([608b966](https://github.com/sct/overseerr/commit/608b96600a926adf16331b36e77789afa5d67069))
|
||||
* logout route/sign out button ([#54](https://github.com/sct/overseerr/issues/54)) ([cb9098f](https://github.com/sct/overseerr/commit/cb9098f457f79b71734959fd924b6c72ca77d61d))
|
||||
* user avatars from plex ([#53](https://github.com/sct/overseerr/issues/53)) ([e6349c1](https://github.com/sct/overseerr/commit/e6349c13a0eb0489289aa7663fcc64fa7d2906e6))
|
||||
* **layout:** created Layout component ([1f497e8](https://github.com/sct/overseerr/commit/1f497e8913146ceb9748d667e638141b2ca4612a))
|
||||
* **login component/route:** add: Login Component and Route ([6e47be2](https://github.com/sct/overseerr/commit/6e47be2fa865bcd51582ce30ebee6fd820c5f9dd))
|
||||
* **login route conditional:** on login route, do not display layout ([7d179ae](https://github.com/sct/overseerr/commit/7d179ae3b42d8ffae5e1b6e266038793260f1bbe))
|
||||
* **pass pageprops to loginpage:** pass page props to loginPage ([1597188](https://github.com/sct/overseerr/commit/159718891fb363001c650ac8b7e1446a1520ce4a))
|
||||
* **plex/utils:** added Plex OAuth class ([72f9624](https://github.com/sct/overseerr/commit/72f9624f1db721fe0324b7be9f0f811d2ae02389))
|
||||
* bootstrap the basic app structure ([89a6017](https://github.com/sct/overseerr/commit/89a6017c7f6f7637fe249ac0d667a652f44e02bb))
|
||||
@@ -904,6 +904,8 @@ components:
|
||||
$ref: '#/components/schemas/Season'
|
||||
status:
|
||||
type: string
|
||||
tagline:
|
||||
type: string
|
||||
type:
|
||||
type: string
|
||||
voteAverage:
|
||||
@@ -4737,6 +4739,12 @@ paths:
|
||||
description: Returns a list of genres in a JSON array.
|
||||
tags:
|
||||
- tmdb
|
||||
parameters:
|
||||
- in: query
|
||||
name: language
|
||||
schema:
|
||||
type: string
|
||||
example: en
|
||||
responses:
|
||||
'200':
|
||||
description: Results
|
||||
@@ -4759,6 +4767,12 @@ paths:
|
||||
description: Returns a list of genres in a JSON array.
|
||||
tags:
|
||||
- tmdb
|
||||
parameters:
|
||||
- in: query
|
||||
name: language
|
||||
schema:
|
||||
type: string
|
||||
example: en
|
||||
responses:
|
||||
'200':
|
||||
description: Results
|
||||
|
||||
35
package.json
35
package.json
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "overseerr",
|
||||
"version": "0.1.0",
|
||||
"version": "1.21.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"dev": "nodemon -e ts --watch server --watch overseerr-api.yml -e .json,.ts,.yml -x ts-node --files --project server/tsconfig.json server/index.ts",
|
||||
@@ -20,6 +20,7 @@
|
||||
"@headlessui/react": "^0.3.1",
|
||||
"@supercharge/request-ip": "^1.1.2",
|
||||
"@svgr/webpack": "^5.5.0",
|
||||
"@tanem/react-nprogress": "^3.0.57",
|
||||
"ace-builds": "^1.4.12",
|
||||
"axios": "^0.21.1",
|
||||
"bcrypt": "^5.0.1",
|
||||
@@ -42,6 +43,7 @@
|
||||
"node-schedule": "^2.0.0",
|
||||
"nodemailer": "^6.5.0",
|
||||
"nookies": "^2.5.2",
|
||||
"openpgp": "^5.0.0-1",
|
||||
"plex-api": "^5.3.1",
|
||||
"pug": "^3.0.2",
|
||||
"react": "17.0.1",
|
||||
@@ -89,9 +91,9 @@
|
||||
"@types/express": "^4.17.11",
|
||||
"@types/express-session": "^1.17.3",
|
||||
"@types/lodash": "^4.14.168",
|
||||
"@types/node": "^14.14.33",
|
||||
"@types/node": "^14.14.34",
|
||||
"@types/node-schedule": "^1.3.1",
|
||||
"@types/nodemailer": "^6.4.0",
|
||||
"@types/nodemailer": "^6.4.1",
|
||||
"@types/react": "^17.0.3",
|
||||
"@types/react-dom": "^17.0.2",
|
||||
"@types/react-toast-notifications": "^2.4.0",
|
||||
@@ -124,8 +126,8 @@
|
||||
"postcss": "^8.2.8",
|
||||
"postcss-preset-env": "^6.7.0",
|
||||
"prettier": "^2.2.1",
|
||||
"semantic-release": "^17.4.1",
|
||||
"semantic-release-docker": "^2.2.0",
|
||||
"semantic-release": "^17.4.2",
|
||||
"semantic-release-docker-buildx": "^1.0.1",
|
||||
"tailwindcss": "npm:@tailwindcss/postcss7-compat",
|
||||
"ts-node": "^9.1.1",
|
||||
"typescript": "^4.2.3"
|
||||
@@ -186,13 +188,7 @@
|
||||
"message": "chore(release): ${nextRelease.version}"
|
||||
}
|
||||
],
|
||||
[
|
||||
"@semantic-release/exec",
|
||||
{
|
||||
"prepareCmd": "docker build --build-arg COMMIT_TAG=$GITHUB_SHA -t sctx/overseerr ."
|
||||
}
|
||||
],
|
||||
"semantic-release-docker",
|
||||
"semantic-release-docker-buildx",
|
||||
[
|
||||
"@semantic-release/github",
|
||||
{
|
||||
@@ -206,8 +202,19 @@
|
||||
"npmPublish": false,
|
||||
"publish": [
|
||||
{
|
||||
"path": "semantic-release-docker",
|
||||
"name": "sctx/overseerr"
|
||||
"path": "semantic-release-docker-buildx",
|
||||
"buildArgs": {
|
||||
"COMMIT_TAG": "$GITHUB_SHA"
|
||||
},
|
||||
"imageNames": [
|
||||
"sctx/overseerr",
|
||||
"ghcr.io/sct/overseerr"
|
||||
],
|
||||
"platforms": [
|
||||
"linux/amd64",
|
||||
"linux/arm64",
|
||||
"linux/arm/v7"
|
||||
]
|
||||
},
|
||||
"@semantic-release/github"
|
||||
]
|
||||
|
||||
@@ -254,6 +254,7 @@ export interface TmdbTvDetails {
|
||||
}[];
|
||||
seasons: TmdbTvSeasonResult[];
|
||||
status: string;
|
||||
tagline?: string;
|
||||
type: string;
|
||||
vote_average: number;
|
||||
vote_count: number;
|
||||
|
||||
@@ -37,4 +37,7 @@ export class UserSettings {
|
||||
|
||||
@Column({ nullable: true })
|
||||
public originalLanguage?: string;
|
||||
|
||||
@Column({ nullable: true })
|
||||
public pgpKey?: string;
|
||||
}
|
||||
|
||||
@@ -10,4 +10,5 @@ export interface UserSettingsNotificationsResponse {
|
||||
discordId?: string;
|
||||
telegramChatId?: string;
|
||||
telegramSendSilently?: boolean;
|
||||
pgpKey?: string;
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import nodemailer from 'nodemailer';
|
||||
import Email from 'email-templates';
|
||||
import { getSettings } from '../settings';
|
||||
import { openpgpEncrypt } from './openpgpEncrypt';
|
||||
class PreparedEmail extends Email {
|
||||
public constructor() {
|
||||
public constructor(pgpKey?: string) {
|
||||
const settings = getSettings().notifications.agents.email;
|
||||
|
||||
const transport = nodemailer.createTransport({
|
||||
@@ -22,6 +23,16 @@ class PreparedEmail extends Email {
|
||||
}
|
||||
: undefined,
|
||||
});
|
||||
if (pgpKey) {
|
||||
transport.use(
|
||||
'stream',
|
||||
openpgpEncrypt({
|
||||
signingKey: settings.options.pgpPrivateKey,
|
||||
password: settings.options.pgpPassword,
|
||||
encryptionKeys: [pgpKey],
|
||||
})
|
||||
);
|
||||
}
|
||||
super({
|
||||
message: {
|
||||
from: {
|
||||
|
||||
181
server/lib/email/openpgpEncrypt.ts
Normal file
181
server/lib/email/openpgpEncrypt.ts
Normal file
@@ -0,0 +1,181 @@
|
||||
import * as openpgp from 'openpgp';
|
||||
import { Transform, TransformCallback } from 'stream';
|
||||
import crypto from 'crypto';
|
||||
|
||||
interface EncryptorOptions {
|
||||
signingKey?: string;
|
||||
password?: string;
|
||||
encryptionKeys: string[];
|
||||
}
|
||||
|
||||
class PGPEncryptor extends Transform {
|
||||
private _messageChunks: Uint8Array[] = [];
|
||||
private _messageLength = 0;
|
||||
private _signingKey?: string;
|
||||
private _password?: string;
|
||||
|
||||
private _encryptionKeys: string[];
|
||||
|
||||
constructor(options: EncryptorOptions) {
|
||||
super();
|
||||
this._signingKey = options.signingKey;
|
||||
this._password = options.password;
|
||||
this._encryptionKeys = options.encryptionKeys;
|
||||
}
|
||||
|
||||
// just save the whole message
|
||||
_transform = (
|
||||
chunk: any,
|
||||
_encoding: BufferEncoding,
|
||||
callback: TransformCallback
|
||||
): void => {
|
||||
this._messageChunks.push(chunk);
|
||||
this._messageLength += chunk.length;
|
||||
callback();
|
||||
};
|
||||
|
||||
// Actually do stuff
|
||||
_flush = async (callback: TransformCallback): Promise<void> => {
|
||||
// Reconstruct message as buffer
|
||||
const message = Buffer.concat(this._messageChunks, this._messageLength);
|
||||
const validPublicKeys = await Promise.all(
|
||||
this._encryptionKeys.map((armoredKey) => openpgp.readKey({ armoredKey }))
|
||||
);
|
||||
let privateKey: openpgp.Key | undefined;
|
||||
|
||||
// Just return the message if there is no one to encrypt for
|
||||
if (!validPublicKeys.length) {
|
||||
this.push(message);
|
||||
return callback();
|
||||
}
|
||||
|
||||
// Only sign the message if private key and password exist
|
||||
if (this._signingKey && this._password) {
|
||||
privateKey = await openpgp.readKey({
|
||||
armoredKey: this._signingKey,
|
||||
});
|
||||
await privateKey.decrypt(this._password);
|
||||
}
|
||||
|
||||
const emailPartDelimiter = '\r\n\r\n';
|
||||
const messageParts = message.toString().split(emailPartDelimiter);
|
||||
|
||||
/**
|
||||
* In this loop original headers are split up into two parts,
|
||||
* one for the email that is sent
|
||||
* and one for the encrypted content
|
||||
*/
|
||||
const header = messageParts.shift() as string;
|
||||
const emailHeaders: string[][] = [];
|
||||
const contentHeaders: string[][] = [];
|
||||
const linesInHeader = header.split('\r\n');
|
||||
let previousHeader: string[] = [];
|
||||
for (let i = 0; i < linesInHeader.length; i++) {
|
||||
const line = linesInHeader[i];
|
||||
/**
|
||||
* If it is a multi-line header (current line starts with whitespace)
|
||||
* or it's the first line in the iteration
|
||||
* add the current line with previous header and move on
|
||||
*/
|
||||
if (/^\s/.test(line) || i === 0) {
|
||||
previousHeader.push(line);
|
||||
continue;
|
||||
}
|
||||
|
||||
/**
|
||||
* This is done to prevent the last header
|
||||
* from being missed
|
||||
*/
|
||||
if (i === linesInHeader.length - 1) {
|
||||
previousHeader.push(line);
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to seperate the actual content headers
|
||||
* so that we can add it as a header for the encrypted content
|
||||
* So that the content will be displayed properly after decryption
|
||||
*/
|
||||
if (
|
||||
/^(content-type|content-transfer-encoding):/i.test(previousHeader[0])
|
||||
) {
|
||||
contentHeaders.push(previousHeader);
|
||||
} else {
|
||||
emailHeaders.push(previousHeader);
|
||||
}
|
||||
previousHeader = [line];
|
||||
}
|
||||
|
||||
// Generate a new boundary for the email content
|
||||
const boundary = 'nm_' + crypto.randomBytes(14).toString('hex');
|
||||
/**
|
||||
* Concatenate everything into single strings
|
||||
* and add pgp headers to the email headers
|
||||
*/
|
||||
const emailHeadersRaw =
|
||||
emailHeaders.map((line) => line.join('\r\n')).join('\r\n') +
|
||||
'\r\n' +
|
||||
'Content-Type: multipart/encrypted; protocol="application/pgp-encrypted";' +
|
||||
'\r\n' +
|
||||
' boundary="' +
|
||||
boundary +
|
||||
'"' +
|
||||
'\r\n' +
|
||||
'Content-Description: OpenPGP encrypted message' +
|
||||
'\r\n' +
|
||||
'Content-Transfer-Encoding: 7bit';
|
||||
const contentHeadersRaw = contentHeaders
|
||||
.map((line) => line.join('\r\n'))
|
||||
.join('\r\n');
|
||||
|
||||
const encryptedMessage = await openpgp.encrypt({
|
||||
message: openpgp.Message.fromText(
|
||||
contentHeadersRaw +
|
||||
emailPartDelimiter +
|
||||
messageParts.join(emailPartDelimiter)
|
||||
),
|
||||
publicKeys: validPublicKeys,
|
||||
privateKeys: privateKey,
|
||||
});
|
||||
|
||||
const body =
|
||||
'--' +
|
||||
boundary +
|
||||
'\r\n' +
|
||||
'Content-Type: application/pgp-encrypted\r\n' +
|
||||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||||
'\r\n' +
|
||||
'Version: 1\r\n' +
|
||||
'\r\n' +
|
||||
'--' +
|
||||
boundary +
|
||||
'\r\n' +
|
||||
'Content-Type: application/octet-stream; name=encrypted.asc\r\n' +
|
||||
'Content-Disposition: inline; filename=encrypted.asc\r\n' +
|
||||
'Content-Transfer-Encoding: 7bit\r\n' +
|
||||
'\r\n' +
|
||||
encryptedMessage +
|
||||
'\r\n--' +
|
||||
boundary +
|
||||
'--\r\n';
|
||||
|
||||
this.push(Buffer.from(emailHeadersRaw + emailPartDelimiter + body));
|
||||
callback();
|
||||
};
|
||||
}
|
||||
|
||||
export const openpgpEncrypt = (options: EncryptorOptions) => {
|
||||
return function (mail: any, callback: () => unknown): void {
|
||||
if (!options.encryptionKeys.length) {
|
||||
setImmediate(callback);
|
||||
}
|
||||
mail.message.transform(
|
||||
() =>
|
||||
new PGPEncryptor({
|
||||
signingKey: options.signingKey,
|
||||
password: options.password,
|
||||
encryptionKeys: options.encryptionKeys,
|
||||
})
|
||||
);
|
||||
setImmediate(callback);
|
||||
};
|
||||
};
|
||||
@@ -156,15 +156,14 @@ class DiscordAgent
|
||||
break;
|
||||
}
|
||||
|
||||
if (settings.main.applicationUrl && payload.media) {
|
||||
fields.push({
|
||||
name: `Open in ${settings.main.applicationTitle}`,
|
||||
value: `${settings.main.applicationUrl}/${payload.media?.mediaType}/${payload.media?.tmdbId}`,
|
||||
});
|
||||
}
|
||||
const url =
|
||||
settings.main.applicationUrl && payload.media
|
||||
? `${settings.main.applicationUrl}/${payload.media.mediaType}/${payload.media.tmdbId}`
|
||||
: undefined;
|
||||
|
||||
return {
|
||||
title: payload.subject,
|
||||
url,
|
||||
description: payload.message,
|
||||
color,
|
||||
timestamp: new Date().toISOString(),
|
||||
|
||||
@@ -47,7 +47,7 @@ class EmailAgent
|
||||
users
|
||||
.filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS))
|
||||
.forEach((user) => {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
email.send({
|
||||
template: path.join(
|
||||
@@ -97,7 +97,7 @@ class EmailAgent
|
||||
users
|
||||
.filter((user) => user.hasPermission(Permission.MANAGE_REQUESTS))
|
||||
.forEach((user) => {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
email.send({
|
||||
template: path.join(
|
||||
@@ -142,7 +142,7 @@ class EmailAgent
|
||||
// This is getting main settings for the whole app
|
||||
const { applicationUrl, applicationTitle } = getSettings().main;
|
||||
try {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
await email.send({
|
||||
template: path.join(
|
||||
@@ -234,7 +234,7 @@ class EmailAgent
|
||||
// This is getting main settings for the whole app
|
||||
const { applicationUrl, applicationTitle } = getSettings().main;
|
||||
try {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
await email.send({
|
||||
template: path.join(
|
||||
@@ -276,7 +276,7 @@ class EmailAgent
|
||||
// This is getting main settings for the whole app
|
||||
const { applicationUrl, applicationTitle } = getSettings().main;
|
||||
try {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
await email.send({
|
||||
template: path.join(
|
||||
@@ -318,7 +318,7 @@ class EmailAgent
|
||||
// This is getting main settings for the whole app
|
||||
const { applicationUrl, applicationTitle } = getSettings().main;
|
||||
try {
|
||||
const email = new PreparedEmail();
|
||||
const email = new PreparedEmail(payload.notifyUser.settings?.pgpKey);
|
||||
|
||||
await email.send({
|
||||
template: path.join(__dirname, '../../../templates/email/test-email'),
|
||||
|
||||
@@ -117,6 +117,8 @@ export interface NotificationAgentEmail extends NotificationAgentConfig {
|
||||
authPass?: string;
|
||||
allowSelfSigned: boolean;
|
||||
senderName: string;
|
||||
pgpPrivateKey?: string;
|
||||
pgpPassword?: string;
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
31
server/migration/1615333940450-AddPGPToUserSettings.ts
Normal file
31
server/migration/1615333940450-AddPGPToUserSettings.ts
Normal file
@@ -0,0 +1,31 @@
|
||||
import { MigrationInterface, QueryRunner } from 'typeorm';
|
||||
|
||||
export class AddPGPToUserSettings1615333940450 implements MigrationInterface {
|
||||
name = 'AddPGPToUserSettings1615333940450';
|
||||
|
||||
public async up(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "temporary_user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "enableNotifications" boolean NOT NULL DEFAULT (1), "discordId" varchar, "userId" integer, "region" varchar, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, "pgpKey" varchar, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "temporary_user_settings"("id", "enableNotifications", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently") SELECT "id", "enableNotifications", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently" FROM "user_settings"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "user_settings"`);
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "temporary_user_settings" RENAME TO "user_settings"`
|
||||
);
|
||||
}
|
||||
|
||||
public async down(queryRunner: QueryRunner): Promise<void> {
|
||||
await queryRunner.query(
|
||||
`ALTER TABLE "user_settings" RENAME TO "temporary_user_settings"`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`CREATE TABLE "user_settings" ("id" integer PRIMARY KEY AUTOINCREMENT NOT NULL, "enableNotifications" boolean NOT NULL DEFAULT (1), "discordId" varchar, "userId" integer, "region" varchar, "originalLanguage" varchar, "telegramChatId" varchar, "telegramSendSilently" boolean, CONSTRAINT "UQ_986a2b6d3c05eb4091bb8066f78" UNIQUE ("userId"), CONSTRAINT "FK_986a2b6d3c05eb4091bb8066f78" FOREIGN KEY ("userId") REFERENCES "user" ("id") ON DELETE CASCADE ON UPDATE NO ACTION)`
|
||||
);
|
||||
await queryRunner.query(
|
||||
`INSERT INTO "user_settings"("id", "enableNotifications", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently") SELECT "id", "enableNotifications", "discordId", "userId", "region", "originalLanguage", "telegramChatId", "telegramSendSilently" FROM "temporary_user_settings"`
|
||||
);
|
||||
await queryRunner.query(`DROP TABLE "temporary_user_settings"`);
|
||||
}
|
||||
}
|
||||
@@ -91,6 +91,7 @@ export interface TvDetails {
|
||||
spokenLanguages: SpokenLanguage[];
|
||||
seasons: Season[];
|
||||
status: string;
|
||||
tagline?: string;
|
||||
type: string;
|
||||
voteAverage: number;
|
||||
voteCount: number;
|
||||
@@ -174,6 +175,7 @@ export const mapTvDetails = (
|
||||
originCountry: show.origin_country,
|
||||
originalLanguage: show.original_language,
|
||||
originalName: show.original_name,
|
||||
tagline: show.tagline,
|
||||
overview: show.overview,
|
||||
popularity: show.popularity,
|
||||
productionCompanies: show.production_companies.map((company) => ({
|
||||
|
||||
@@ -95,7 +95,9 @@ router.get<{ id: string }>('/network/:id', async (req, res) => {
|
||||
router.get('/genres/movie', isAuthenticated(), async (req, res) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
|
||||
const genres = await tmdb.getMovieGenres();
|
||||
const genres = await tmdb.getMovieGenres({
|
||||
language: req.query.language as string,
|
||||
});
|
||||
|
||||
return res.status(200).json(genres);
|
||||
});
|
||||
@@ -103,7 +105,9 @@ router.get('/genres/movie', isAuthenticated(), async (req, res) => {
|
||||
router.get('/genres/tv', isAuthenticated(), async (req, res) => {
|
||||
const tmdb = new TheMovieDb();
|
||||
|
||||
const genres = await tmdb.getTvGenres();
|
||||
const genres = await tmdb.getTvGenres({
|
||||
language: req.query.language as string,
|
||||
});
|
||||
|
||||
return res.status(200).json(genres);
|
||||
});
|
||||
|
||||
@@ -73,6 +73,14 @@ userSettingsRoutes.post<
|
||||
return next({ status: 404, message: 'User not found.' });
|
||||
}
|
||||
|
||||
// "Owner" user settings cannot be modified by other users
|
||||
if (user.id === 1 && req.user?.id !== 1) {
|
||||
return next({
|
||||
status: 403,
|
||||
message: "You do not have permission to modify this user's settings.",
|
||||
});
|
||||
}
|
||||
|
||||
user.username = req.body.username;
|
||||
if (!user.settings) {
|
||||
user.settings = new UserSettings({
|
||||
@@ -217,6 +225,7 @@ userSettingsRoutes.get<{ id: string }, UserSettingsNotificationsResponse>(
|
||||
discordId: user.settings?.discordId,
|
||||
telegramChatId: user.settings?.telegramChatId,
|
||||
telegramSendSilently: user?.settings?.telegramSendSilently,
|
||||
pgpKey: user?.settings?.pgpKey,
|
||||
});
|
||||
} catch (e) {
|
||||
next({ status: 500, message: e.message });
|
||||
@@ -240,6 +249,14 @@ userSettingsRoutes.post<
|
||||
return next({ status: 404, message: 'User not found.' });
|
||||
}
|
||||
|
||||
// "Owner" user settings cannot be modified by other users
|
||||
if (user.id === 1 && req.user?.id !== 1) {
|
||||
return next({
|
||||
status: 403,
|
||||
message: "You do not have permission to modify this user's settings.",
|
||||
});
|
||||
}
|
||||
|
||||
if (!user.settings) {
|
||||
user.settings = new UserSettings({
|
||||
user: req.user,
|
||||
@@ -247,12 +264,14 @@ userSettingsRoutes.post<
|
||||
discordId: req.body.discordId,
|
||||
telegramChatId: req.body.telegramChatId,
|
||||
telegramSendSilently: req.body.telegramSendSilently,
|
||||
pgpKey: req.body.pgpKey,
|
||||
});
|
||||
} else {
|
||||
user.settings.enableNotifications = req.body.enableNotifications;
|
||||
user.settings.discordId = req.body.discordId;
|
||||
user.settings.telegramChatId = req.body.telegramChatId;
|
||||
user.settings.telegramSendSilently = req.body.telegramSendSilently;
|
||||
user.settings.pgpKey = req.body.pgpKey;
|
||||
}
|
||||
|
||||
userRepository.save(user);
|
||||
@@ -262,6 +281,7 @@ userSettingsRoutes.post<
|
||||
discordId: user.settings.discordId,
|
||||
telegramChatId: user.settings.telegramChatId,
|
||||
telegramSendSilently: user.settings.telegramSendSilently,
|
||||
pgpKey: user.settings.pgpKey,
|
||||
});
|
||||
} catch (e) {
|
||||
next({ status: 500, message: e.message });
|
||||
@@ -309,8 +329,8 @@ userSettingsRoutes.post<
|
||||
return next({ status: 404, message: 'User not found.' });
|
||||
}
|
||||
|
||||
// Only let the owner user modify themselves
|
||||
if (user.id === 1 && req.user?.id !== 1) {
|
||||
// "Owner" user permissions cannot be modified, and users cannot set their own permissions
|
||||
if (user.id === 1 || req.user?.id === user.id) {
|
||||
return next({
|
||||
status: 403,
|
||||
message: 'You do not have permission to modify this user',
|
||||
|
||||
@@ -19,12 +19,14 @@ import Transition from '../Transition';
|
||||
import PageTitle from '../Common/PageTitle';
|
||||
import { useUser, Permission } from '../../hooks/useUser';
|
||||
import useSettings from '../../hooks/useSettings';
|
||||
import Link from 'next/link';
|
||||
import { uniq } from 'lodash';
|
||||
|
||||
const messages = defineMessages({
|
||||
overviewunavailable: 'Overview unavailable.',
|
||||
overview: 'Overview',
|
||||
movies: 'Movies',
|
||||
numberofmovies: 'Number of Movies: {count}',
|
||||
numberofmovies: '{count} Movies',
|
||||
requesting: 'Requesting…',
|
||||
request: 'Request',
|
||||
requestcollection: 'Request Collection',
|
||||
@@ -62,6 +64,10 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
}
|
||||
);
|
||||
|
||||
const { data: genres } = useSWR<{ id: number; name: string }[]>(
|
||||
`/api/v1/genres/movie?language=${locale}`
|
||||
);
|
||||
|
||||
if (!data && !error) {
|
||||
return <LoadingSpinner />;
|
||||
}
|
||||
@@ -105,6 +111,17 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
collectionStatus4k = MediaStatus.PARTIALLY_AVAILABLE;
|
||||
}
|
||||
|
||||
const hasRequestable =
|
||||
data.parts.filter(
|
||||
(part) => !part.mediaInfo || part.mediaInfo.status === MediaStatus.UNKNOWN
|
||||
).length > 0;
|
||||
|
||||
const hasRequestable4k =
|
||||
data.parts.filter(
|
||||
(part) =>
|
||||
!part.mediaInfo || part.mediaInfo.status4k === MediaStatus.UNKNOWN
|
||||
).length > 0;
|
||||
|
||||
const requestableParts = data.parts.filter(
|
||||
(part) =>
|
||||
!part.mediaInfo ||
|
||||
@@ -147,9 +164,43 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
}
|
||||
};
|
||||
|
||||
const collectionAttributes: React.ReactNode[] = [];
|
||||
|
||||
collectionAttributes.push(
|
||||
intl.formatMessage(messages.numberofmovies, {
|
||||
count: data.parts.length,
|
||||
})
|
||||
);
|
||||
|
||||
if (genres && data.parts.some((part) => part.genreIds.length)) {
|
||||
collectionAttributes.push(
|
||||
uniq(
|
||||
data.parts.reduce(
|
||||
(genresList: number[], curr) => genresList.concat(curr.genreIds),
|
||||
[]
|
||||
)
|
||||
)
|
||||
.map((genreId) => (
|
||||
<Link
|
||||
href={`/discover/movies/genre/${genreId}`}
|
||||
key={`genre-${genreId}`}
|
||||
>
|
||||
<a className="hover:underline">
|
||||
{genres.find((g) => g.id === genreId)?.name}
|
||||
</a>
|
||||
</Link>
|
||||
))
|
||||
.reduce((prev, curr) => (
|
||||
<>
|
||||
{prev}, {curr}
|
||||
</>
|
||||
))
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<div
|
||||
className="px-4 pt-16 -mx-4 -mt-16 bg-center bg-cover"
|
||||
className="media-page"
|
||||
style={{
|
||||
height: 493,
|
||||
backgroundImage: `linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath})`,
|
||||
@@ -216,24 +267,20 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
</ul>
|
||||
</Modal>
|
||||
</Transition>
|
||||
<div className="flex flex-col items-center pt-4 lg:flex-row lg:items-end">
|
||||
<div className="lg:mr-4">
|
||||
<img
|
||||
src={`//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`}
|
||||
alt=""
|
||||
className="w-32 rounded shadow md:rounded-lg md:shadow-2xl md:w-44 lg:w-52"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 mt-4 text-center text-white lg:mr-4 lg:mt-0 lg:text-left">
|
||||
<div className="mb-2 space-x-2">
|
||||
<span className="ml-2 lg:ml-0">
|
||||
<StatusBadge
|
||||
status={collectionStatus}
|
||||
inProgress={data.parts.some(
|
||||
(part) => (part.mediaInfo?.downloadStatus ?? []).length > 0
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
<div className="media-header">
|
||||
<img
|
||||
src={`//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`}
|
||||
alt=""
|
||||
className="media-poster"
|
||||
/>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={collectionStatus}
|
||||
inProgress={data.parts.some(
|
||||
(part) => (part.mediaInfo?.downloadStatus ?? []).length > 0
|
||||
)}
|
||||
/>
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
@@ -241,43 +288,83 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
type: 'or',
|
||||
}
|
||||
) && (
|
||||
<span>
|
||||
<StatusBadge
|
||||
status={collectionStatus4k}
|
||||
is4k
|
||||
inProgress={data.parts.some(
|
||||
(part) =>
|
||||
(part.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
)}
|
||||
/>
|
||||
</span>
|
||||
<StatusBadge
|
||||
status={collectionStatus4k}
|
||||
is4k
|
||||
inProgress={data.parts.some(
|
||||
(part) =>
|
||||
(part.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-2xl md:text-4xl">{data.name}</h1>
|
||||
<span className="mt-1 text-xs lg:text-base lg:mt-0">
|
||||
{intl.formatMessage(messages.numberofmovies, {
|
||||
count: data.parts.length,
|
||||
})}
|
||||
<h1>{data.name}</h1>
|
||||
<span className="media-attributes">
|
||||
{collectionAttributes.length > 0 &&
|
||||
collectionAttributes
|
||||
.map((t, k) => <span key={k}>{t}</span>)
|
||||
.reduce((prev, curr) => (
|
||||
<>
|
||||
{prev} | {curr}
|
||||
</>
|
||||
))}
|
||||
</span>
|
||||
</div>
|
||||
<div className="relative z-10 flex flex-wrap justify-center flex-shrink-0 mt-4 sm:justify-end sm:flex-nowrap lg:mt-0">
|
||||
<div className="media-actions">
|
||||
{hasPermission(Permission.REQUEST) &&
|
||||
(collectionStatus !== MediaStatus.AVAILABLE ||
|
||||
(hasRequestable ||
|
||||
(settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
collectionStatus4k !== MediaStatus.AVAILABLE)) && (
|
||||
<div className="mb-3 sm:mb-0">
|
||||
<ButtonWithDropdown
|
||||
buttonType="primary"
|
||||
onClick={() => {
|
||||
setRequestModal(true);
|
||||
setIs4k(collectionStatus === MediaStatus.AVAILABLE);
|
||||
}}
|
||||
text={
|
||||
<>
|
||||
hasRequestable4k)) && (
|
||||
<ButtonWithDropdown
|
||||
buttonType="primary"
|
||||
onClick={() => {
|
||||
setRequestModal(true);
|
||||
setIs4k(!hasRequestable);
|
||||
}}
|
||||
text={
|
||||
<>
|
||||
<svg
|
||||
className="w-4 mr-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
||||
/>
|
||||
</svg>
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
hasRequestable
|
||||
? messages.requestcollection
|
||||
: messages.requestcollection4k
|
||||
)}
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
hasRequestable &&
|
||||
hasRequestable4k && (
|
||||
<ButtonWithDropdown.Item
|
||||
buttonType="primary"
|
||||
onClick={() => {
|
||||
setRequestModal(true);
|
||||
setIs4k(true);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="w-4 mr-1"
|
||||
fill="none"
|
||||
@@ -293,70 +380,27 @@ const CollectionDetails: React.FC<CollectionDetailsProps> = ({
|
||||
/>
|
||||
</svg>
|
||||
<span>
|
||||
{intl.formatMessage(
|
||||
collectionStatus === MediaStatus.AVAILABLE
|
||||
? messages.requestcollection4k
|
||||
: messages.requestcollection
|
||||
)}
|
||||
{intl.formatMessage(messages.requestcollection4k)}
|
||||
</span>
|
||||
</>
|
||||
}
|
||||
>
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
{ type: 'or' }
|
||||
) &&
|
||||
collectionStatus !== MediaStatus.AVAILABLE &&
|
||||
collectionStatus4k !== MediaStatus.AVAILABLE && (
|
||||
<ButtonWithDropdown.Item
|
||||
buttonType="primary"
|
||||
onClick={() => {
|
||||
setRequestModal(true);
|
||||
setIs4k(true);
|
||||
}}
|
||||
>
|
||||
<svg
|
||||
className="w-4 mr-1"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M4 16v1a3 3 0 003 3h10a3 3 0 003-3v-1m-4-4l-4 4m0 0l-4-4m4 4V4"
|
||||
/>
|
||||
</svg>
|
||||
<span>
|
||||
{intl.formatMessage(messages.requestcollection4k)}
|
||||
</span>
|
||||
</ButtonWithDropdown.Item>
|
||||
)}
|
||||
</ButtonWithDropdown>
|
||||
</div>
|
||||
</ButtonWithDropdown.Item>
|
||||
)}
|
||||
</ButtonWithDropdown>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col pt-8 pb-4 text-white md:flex-row">
|
||||
<div className="flex-1 md:mr-8">
|
||||
<h2 className="text-xl md:text-2xl">
|
||||
{intl.formatMessage(messages.overview)}
|
||||
</h2>
|
||||
<p className="pt-2 text-sm md:text-base">
|
||||
<div className="media-overview">
|
||||
<div className="flex-1">
|
||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||
<p>
|
||||
{data.overview
|
||||
? data.overview
|
||||
: intl.formatMessage(messages.overviewunavailable)}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mt-6 mb-4 md:flex md:items-center md:justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="inline-flex items-center text-xl leading-7 text-white sm:text-2xl sm:leading-9 sm:truncate">
|
||||
<span>{intl.formatMessage(messages.movies)}</span>
|
||||
</div>
|
||||
<div className="slider-header">
|
||||
<div className="slider-title">
|
||||
<span>{intl.formatMessage(messages.movies)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<Slider
|
||||
|
||||
@@ -45,37 +45,37 @@ function Button<P extends ElementTypes = 'button'>(
|
||||
ref?: React.Ref<Element<P>>
|
||||
): JSX.Element {
|
||||
const buttonStyle = [
|
||||
'inline-flex items-center justify-center border border-transparent leading-5 font-medium rounded-md focus:outline-none transition ease-in-out duration-150 cursor-pointer',
|
||||
'inline-flex items-center justify-center border border-transparent leading-5 font-medium rounded-md focus:outline-none transition ease-in-out duration-150 cursor-pointer disabled:opacity-50',
|
||||
];
|
||||
switch (buttonType) {
|
||||
case 'primary':
|
||||
buttonStyle.push(
|
||||
'text-white bg-indigo-600 hover:bg-indigo-500 focus:border-indigo-700 focus:ring-indigo active:bg-indigo-700 disabled:opacity-50'
|
||||
'text-white bg-indigo-600 border-indigo-600 hover:bg-indigo-500 hover:border-indigo-500 focus:border-indigo-700 focus:ring-indigo active:bg-indigo-700 active:border-indigo-700'
|
||||
);
|
||||
break;
|
||||
case 'danger':
|
||||
buttonStyle.push(
|
||||
'text-white bg-red-600 hover:bg-red-500 focus:border-red-700 focus:ring-red active:bg-red-700 disabled:opacity-50'
|
||||
'text-white bg-red-600 border-red-600 hover:bg-red-500 hover:border-red-500 focus:border-red-700 focus:ring-red active:bg-red-700 active:border-red-700'
|
||||
);
|
||||
break;
|
||||
case 'warning':
|
||||
buttonStyle.push(
|
||||
'text-white bg-yellow-500 hover:bg-yellow-400 focus:border-yellow-700 focus:ring-yellow active:bg-yellow-700 disabled:opacity-50'
|
||||
'text-white bg-yellow-500 border-yellow-500 hover:bg-yellow-400 hover:border-yellow-400 focus:border-yellow-700 focus:ring-yellow active:bg-yellow-700 active:border-yellow-700'
|
||||
);
|
||||
break;
|
||||
case 'success':
|
||||
buttonStyle.push(
|
||||
'text-white bg-green-400 hover:bg-green-300 focus:border-green-700 focus:ring-green active:bg-green-700 disabled:opacity-50'
|
||||
'text-white bg-green-400 border-green-400 hover:bg-green-300 hover:border-green-300 focus:border-green-700 focus:ring-green active:bg-green-700 active:border-green-700'
|
||||
);
|
||||
break;
|
||||
case 'ghost':
|
||||
buttonStyle.push(
|
||||
'text-white bg-transaprent border border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100 disabled:opacity-50'
|
||||
'text-white bg-transaprent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100'
|
||||
);
|
||||
break;
|
||||
default:
|
||||
buttonStyle.push(
|
||||
'leading-5 font-medium rounded-md text-gray-200 bg-gray-500 hover:bg-gray-400 group-hover:bg-gray-400 hover:text-white group-hover:text-white focus:border-blue-300 focus:ring-blue active:text-gray-200 active:bg-gray-400 disabled:opacity-50'
|
||||
'text-gray-200 bg-gray-500 border-gray-500 hover:text-white hover:bg-gray-400 hover:border-gray-400 group-hover:text-white group-hover:bg-gray-400 group-hover:border-gray-400 focus:border-blue-300 focus:ring-blue active:text-gray-200 active:bg-gray-400 active:border-gray-400'
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -59,24 +59,23 @@ const ButtonWithDropdown: React.FC<ButtonWithDropdownProps> = ({
|
||||
useClickOutside(buttonRef, () => setIsOpen(false));
|
||||
|
||||
const styleClasses = {
|
||||
mainButtonClasses: '',
|
||||
dropdownSideButtonClasses: '',
|
||||
mainButtonClasses: 'text-white border',
|
||||
dropdownSideButtonClasses: 'border',
|
||||
dropdownClasses: '',
|
||||
};
|
||||
|
||||
switch (buttonType) {
|
||||
case 'ghost':
|
||||
styleClasses.mainButtonClasses =
|
||||
'text-white bg-transparent border border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100';
|
||||
styleClasses.dropdownSideButtonClasses =
|
||||
'bg-transparent border border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100';
|
||||
styleClasses.mainButtonClasses +=
|
||||
' bg-transparent border-gray-600 hover:border-gray-200 focus:border-gray-100 active:border-gray-100';
|
||||
styleClasses.dropdownSideButtonClasses = styleClasses.mainButtonClasses;
|
||||
styleClasses.dropdownClasses = 'bg-gray-700';
|
||||
break;
|
||||
default:
|
||||
styleClasses.mainButtonClasses =
|
||||
'text-white bg-indigo-600 hover:text-white hover:bg-indigo-500 active:bg-indigo-700 focus:ring-blue';
|
||||
styleClasses.dropdownSideButtonClasses =
|
||||
'bg-indigo-700 border border-indigo-600 hover:bg-indigo-500 active:bg-indigo-700 focus:ring-blue';
|
||||
styleClasses.mainButtonClasses +=
|
||||
' bg-indigo-600 border-indigo-600 hover:bg-indigo-500 hover:border-indigo-500 active:bg-indigo-700 active:border-indigo-700 focus:ring-blue';
|
||||
styleClasses.dropdownSideButtonClasses +=
|
||||
' bg-indigo-700 border-indigo-600 hover:bg-indigo-500 active:bg-indigo-700 focus:ring-blue';
|
||||
styleClasses.dropdownClasses = 'bg-indigo-600';
|
||||
}
|
||||
|
||||
|
||||
@@ -24,11 +24,11 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
||||
plexUrl,
|
||||
}) => {
|
||||
return (
|
||||
<div className="flex items-center justify-end">
|
||||
<div className="flex items-center justify-center w-full space-x-5">
|
||||
{plexUrl && (
|
||||
<a
|
||||
href={plexUrl}
|
||||
className="w-8 mx-2 transition duration-300 opacity-50 hover:opacity-100"
|
||||
className="w-12 transition duration-300 opacity-50 hover:opacity-100"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
@@ -38,7 +38,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
||||
{tmdbId && (
|
||||
<a
|
||||
href={`https://www.themoviedb.org/${mediaType}/${tmdbId}`}
|
||||
className="w-8 mx-2 transition duration-300 opacity-50 hover:opacity-100"
|
||||
className="w-8 transition duration-300 opacity-50 hover:opacity-100"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
@@ -48,7 +48,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
||||
{tvdbId && mediaType === MediaType.TV && (
|
||||
<a
|
||||
href={`http://www.thetvdb.com/?tab=series&id=${tvdbId}`}
|
||||
className="w-8 mx-2 transition duration-300 opacity-50 hover:opacity-100"
|
||||
className="transition duration-300 opacity-50 w-9 hover:opacity-100"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
@@ -58,7 +58,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
||||
{imdbId && (
|
||||
<a
|
||||
href={`https://www.imdb.com/title/${imdbId}`}
|
||||
className="w-8 mx-2 transition duration-300 opacity-50 hover:opacity-100"
|
||||
className="w-8 transition duration-300 opacity-50 hover:opacity-100"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
@@ -68,7 +68,7 @@ const ExternalLinkBlock: React.FC<ExternalLinkBlockProps> = ({
|
||||
{rtUrl && (
|
||||
<a
|
||||
href={`${rtUrl}`}
|
||||
className="mx-2 transition duration-300 opacity-50 w-14 hover:opacity-100"
|
||||
className="transition duration-300 opacity-50 w-14 hover:opacity-100"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
>
|
||||
|
||||
73
src/components/LoadingBar/index.tsx
Normal file
73
src/components/LoadingBar/index.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
import { NProgress } from '@tanem/react-nprogress';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import ReactDOM from 'react-dom';
|
||||
import { useRouter } from 'next/router';
|
||||
|
||||
interface BarProps {
|
||||
progress: number;
|
||||
isFinished: boolean;
|
||||
}
|
||||
|
||||
const Bar = ({ progress, isFinished }: BarProps) => {
|
||||
return (
|
||||
<div
|
||||
className={`fixed top-0 left-0 z-50 w-full transition-opacity ease-out duration-400 ${
|
||||
isFinished ? 'opacity-0' : 'opacity-100'
|
||||
}`}
|
||||
>
|
||||
<div
|
||||
className="duration-300 bg-indigo-400 transition-width"
|
||||
style={{
|
||||
height: '3px',
|
||||
width: `${progress * 100}%`,
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const NProgressBar = ({ loading }: { loading: boolean }) => (
|
||||
<NProgress isAnimating={loading}>
|
||||
{({ isFinished, progress }) => (
|
||||
<Bar progress={progress} isFinished={isFinished} />
|
||||
)}
|
||||
</NProgress>
|
||||
);
|
||||
|
||||
const MemoizedNProgress = React.memo(NProgressBar);
|
||||
|
||||
const LoadingBar = (): React.ReactPortal | null => {
|
||||
const [mounted, setMounted] = useState(false);
|
||||
const [loading, setLoading] = useState(false);
|
||||
const router = useRouter();
|
||||
useEffect(() => {
|
||||
setMounted(true);
|
||||
}, []);
|
||||
|
||||
useEffect(() => {
|
||||
const handleLoading = () => {
|
||||
setLoading(true);
|
||||
};
|
||||
const handleFinishedLoading = () => {
|
||||
setLoading(false);
|
||||
};
|
||||
router.events.on('routeChangeStart', handleLoading);
|
||||
router.events.on('routeChangeComplete', handleFinishedLoading);
|
||||
router.events.on('routeChangeError', handleFinishedLoading);
|
||||
|
||||
return () => {
|
||||
router.events.off('routeChangeStart', handleLoading);
|
||||
router.events.off('routeChangeComplete', handleFinishedLoading);
|
||||
router.events.off('routeChangeError', handleFinishedLoading);
|
||||
};
|
||||
}, [router]);
|
||||
|
||||
return mounted
|
||||
? ReactDOM.createPortal(
|
||||
<MemoizedNProgress loading={loading} />,
|
||||
document.body
|
||||
)
|
||||
: null;
|
||||
};
|
||||
|
||||
export default LoadingBar;
|
||||
@@ -1,10 +1,5 @@
|
||||
import React, { useState, useContext, useMemo } from 'react';
|
||||
import {
|
||||
defineMessages,
|
||||
FormattedNumber,
|
||||
FormattedDate,
|
||||
useIntl,
|
||||
} from 'react-intl';
|
||||
import { defineMessages, FormattedNumber, useIntl } from 'react-intl';
|
||||
import type { MovieDetails as MovieDetailsType } from '../../../server/models/Movie';
|
||||
import useSWR from 'swr';
|
||||
import { useRouter } from 'next/router';
|
||||
@@ -205,7 +200,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="px-4 pt-16 -mx-4 -mt-16 bg-center bg-cover"
|
||||
className="media-page"
|
||||
style={{
|
||||
height: 493,
|
||||
backgroundImage: `linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath})`,
|
||||
@@ -384,27 +379,23 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
<div className="flex flex-col items-center pt-4 lg:flex-row lg:items-end">
|
||||
<div className="lg:mr-4">
|
||||
<img
|
||||
src={
|
||||
data.posterPath
|
||||
? `//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`
|
||||
: '/images/overseerr_poster_not_found.png'
|
||||
}
|
||||
alt=""
|
||||
className="w-32 rounded shadow md:rounded-lg md:shadow-2xl md:w-44 lg:w-52"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 mt-4 text-center text-white lg:mr-4 lg:mt-0 lg:text-left">
|
||||
<div className="mb-2 space-x-2">
|
||||
<span className="ml-2 lg:ml-0">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
plexUrl={data.mediaInfo?.plexUrl}
|
||||
/>
|
||||
</span>
|
||||
<div className="media-header">
|
||||
<img
|
||||
src={
|
||||
data.posterPath
|
||||
? `//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`
|
||||
: '/images/overseerr_poster_not_found.png'
|
||||
}
|
||||
alt=""
|
||||
className="media-poster"
|
||||
/>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
plexUrl={data.mediaInfo?.plexUrl}
|
||||
/>
|
||||
{settings.currentSettings.movie4kEnabled &&
|
||||
hasPermission(
|
||||
[Permission.REQUEST_4K, Permission.REQUEST_4K_MOVIE],
|
||||
@@ -412,25 +403,25 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
type: 'or',
|
||||
}
|
||||
) && (
|
||||
<span>
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status4k}
|
||||
is4k
|
||||
inProgress={
|
||||
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
}
|
||||
plexUrl4k={data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
</span>
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status4k}
|
||||
is4k
|
||||
inProgress={
|
||||
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
}
|
||||
plexUrl4k={data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-2xl lg:text-4xl">
|
||||
<h1>
|
||||
{data.title}{' '}
|
||||
{data.releaseDate && (
|
||||
<span className="text-2xl">({data.releaseDate.slice(0, 4)})</span>
|
||||
<span className="media-year">
|
||||
({data.releaseDate.slice(0, 4)})
|
||||
</span>
|
||||
)}
|
||||
</h1>
|
||||
<span className="mt-1 text-xs lg:text-base lg:mt-0">
|
||||
<span className="media-attributes">
|
||||
{movieAttributes.length > 0 &&
|
||||
movieAttributes
|
||||
.map((t, k) => <span key={k}>{t}</span>)
|
||||
@@ -441,27 +432,23 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
))}
|
||||
</span>
|
||||
</div>
|
||||
<div className="relative z-10 flex flex-wrap justify-center flex-shrink-0 mt-4 sm:justify-end sm:flex-nowrap lg:mt-0">
|
||||
<div className="mb-3 sm:mb-0">
|
||||
<PlayButton links={mediaLinks} />
|
||||
</div>
|
||||
<div className="mb-3 sm:mb-0">
|
||||
<RequestButton
|
||||
mediaType="movie"
|
||||
media={data.mediaInfo}
|
||||
tmdbId={data.id}
|
||||
onUpdate={() => revalidate()}
|
||||
/>
|
||||
</div>
|
||||
<div className="media-actions">
|
||||
<PlayButton links={mediaLinks} />
|
||||
<RequestButton
|
||||
mediaType="movie"
|
||||
media={data.mediaInfo}
|
||||
tmdbId={data.id}
|
||||
onUpdate={() => revalidate()}
|
||||
/>
|
||||
{hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<Button
|
||||
buttonType="default"
|
||||
className="mb-3 ml-2 first:ml-0 sm:mb-0"
|
||||
className="ml-2 first:ml-0"
|
||||
onClick={() => setShowManager(true)}
|
||||
>
|
||||
<svg
|
||||
className="w-5"
|
||||
style={{ height: 20 }}
|
||||
style={{ height: 18 }}
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -484,27 +471,21 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col pt-8 pb-4 text-white md:flex-row">
|
||||
<div className="flex-1 md:mr-8">
|
||||
<h2 className="text-xl md:text-2xl">
|
||||
{intl.formatMessage(messages.overview)}
|
||||
</h2>
|
||||
<p className="pt-2 text-sm md:text-base">
|
||||
<div className="media-overview">
|
||||
<div className="media-overview-left">
|
||||
<div className="tagline">{data.tagline}</div>
|
||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||
<p>
|
||||
{data.overview
|
||||
? data.overview
|
||||
: intl.formatMessage(messages.overviewunavailable)}
|
||||
</p>
|
||||
<ul className="grid grid-cols-2 gap-6 mt-6 sm:grid-cols-3">
|
||||
<ul className="media-crew">
|
||||
{sortedCrew.slice(0, 6).map((person) => (
|
||||
<li
|
||||
className="flex flex-col col-span-1"
|
||||
key={`crew-${person.job}-${person.id}`}
|
||||
>
|
||||
<span className="font-bold">{person.job}</span>
|
||||
<li key={`crew-${person.job}-${person.id}`}>
|
||||
<span>{person.job}</span>
|
||||
<Link href={`/person/${person.id}`}>
|
||||
<a className="text-gray-400 transition duration-300 hover:text-underline hover:text-gray-100">
|
||||
{person.name}
|
||||
</a>
|
||||
<a className="crew-name">{person.name}</a>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
@@ -533,7 +514,7 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full mt-8 md:w-80 md:mt-0">
|
||||
<div className="media-overview-right">
|
||||
{data.collection && (
|
||||
<div className="mb-6">
|
||||
<Link href={`/collection/${data.collection.id}`}>
|
||||
@@ -555,80 +536,65 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
<div className="bg-gray-900 border border-gray-800 rounded-lg shadow">
|
||||
<div className="media-facts">
|
||||
{(!!data.voteCount ||
|
||||
(ratingData?.criticsRating && !!ratingData?.criticsScore) ||
|
||||
(ratingData?.audienceRating && !!ratingData?.audienceScore)) && (
|
||||
<div className="flex items-center justify-center px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<div className="media-ratings">
|
||||
{ratingData?.criticsRating && !!ratingData?.criticsScore && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
<span className="media-rating">
|
||||
{ratingData.criticsRating === 'Rotten' ? (
|
||||
<RTRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTFresh className="w-6 mr-1" />
|
||||
)}
|
||||
</span>
|
||||
<span className="mr-4 text-sm text-gray-400 last:mr-0">
|
||||
{ratingData.criticsScore}%
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{ratingData?.audienceRating && !!ratingData?.audienceScore && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
<span className="media-rating">
|
||||
{ratingData.audienceRating === 'Spilled' ? (
|
||||
<RTAudRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTAudFresh className="w-6 mr-1" />
|
||||
)}
|
||||
</span>
|
||||
<span className="mr-4 text-sm text-gray-400 last:mr-0">
|
||||
{ratingData.audienceScore}%
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
{!!data.voteCount && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
<span className="media-rating">
|
||||
<TmdbLogo className="w-6 mr-2" />
|
||||
</span>
|
||||
<span className="text-sm text-gray-400">
|
||||
{data.voteAverage}/10
|
||||
</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.status)}</span>
|
||||
<span className="media-fact-value">{data.status}</span>
|
||||
</div>
|
||||
{data.releaseDate && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.releasedate)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<FormattedDate
|
||||
value={new Date(data.releaseDate)}
|
||||
year="numeric"
|
||||
month="long"
|
||||
day="numeric"
|
||||
/>
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.releasedate)}</span>
|
||||
<span className="media-fact-value">
|
||||
{intl.formatDate(data.releaseDate, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.status)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
{data.status}
|
||||
</span>
|
||||
</div>
|
||||
{data.revenue > 0 && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.revenue)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.revenue)}</span>
|
||||
<span className="media-fact-value">
|
||||
<FormattedNumber
|
||||
currency="USD"
|
||||
style="currency"
|
||||
@@ -638,11 +604,9 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
)}
|
||||
{data.budget > 0 && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.budget)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.budget)}</span>
|
||||
<span className="media-fact-value">
|
||||
<FormattedNumber
|
||||
currency="USD"
|
||||
style="currency"
|
||||
@@ -652,11 +616,9 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
)}
|
||||
{data.originalLanguage && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.originallanguage)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.originallanguage)}</span>
|
||||
<span className="media-fact-value">
|
||||
<Link
|
||||
href={`/discover/movies/language/${data.originalLanguage}`}
|
||||
>
|
||||
@@ -674,13 +636,13 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</div>
|
||||
)}
|
||||
{data.productionCompanies.length > 0 && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
{intl.formatMessage(messages.studio, {
|
||||
studioCount: data.productionCompanies.length,
|
||||
})}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<span className="media-fact-value">
|
||||
{data.productionCompanies.map((s) => {
|
||||
return (
|
||||
<Link
|
||||
@@ -694,43 +656,41 @@ const MovieDetails: React.FC<MovieDetailsProps> = ({ movie }) => {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<ExternalLinkBlock
|
||||
mediaType="movie"
|
||||
tmdbId={data.id}
|
||||
tvdbId={data.externalIds.tvdbId}
|
||||
imdbId={data.externalIds.imdbId}
|
||||
rtUrl={ratingData?.url}
|
||||
plexUrl={data.mediaInfo?.plexUrl ?? data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
<div className="media-fact">
|
||||
<ExternalLinkBlock
|
||||
mediaType="movie"
|
||||
tmdbId={data.id}
|
||||
tvdbId={data.externalIds.tvdbId}
|
||||
imdbId={data.externalIds.imdbId}
|
||||
rtUrl={ratingData?.url}
|
||||
plexUrl={data.mediaInfo?.plexUrl ?? data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{data.credits.cast.length > 0 && (
|
||||
<>
|
||||
<div className="mt-6 mb-4 md:flex md:items-center md:justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link href="/movie/[movieId]/cast" as={`/movie/${data.id}/cast`}>
|
||||
<a className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="slider-header">
|
||||
<Link href="/movie/[movieId]/cast" as={`/movie/${data.id}/cast`}>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="cast"
|
||||
|
||||
@@ -128,7 +128,7 @@ const PermissionOption: React.FC<PermissionOptionProps> = ({
|
||||
/>
|
||||
</div>
|
||||
<div className="ml-3 text-sm leading-6">
|
||||
<label htmlFor={option.id} className="block font-medium">
|
||||
<label htmlFor={option.id} className="block font-medium text-white">
|
||||
<div className="flex flex-col">
|
||||
<span>{option.name}</span>
|
||||
<span className="text-gray-500">{option.description}</span>
|
||||
|
||||
@@ -15,8 +15,8 @@ import { groupBy } from 'lodash';
|
||||
import PageTitle from '../Common/PageTitle';
|
||||
|
||||
const messages = defineMessages({
|
||||
appearsin: 'Appears in',
|
||||
crewmember: 'Crew Member',
|
||||
appearsin: 'Appearances',
|
||||
crewmember: 'Crew',
|
||||
ascharacter: 'as {character}',
|
||||
nobiography: 'No biography available.',
|
||||
});
|
||||
@@ -85,11 +85,9 @@ const PersonDetails: React.FC = () => {
|
||||
|
||||
const cast = (sortedCast ?? []).length > 0 && (
|
||||
<>
|
||||
<div className="relative z-10 mt-6 mb-4 md:flex md:items-center md:justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
|
||||
<span>{intl.formatMessage(messages.appearsin)}</span>
|
||||
</div>
|
||||
<div className="slider-header">
|
||||
<div className="slider-title">
|
||||
<span>{intl.formatMessage(messages.appearsin)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="cardList">
|
||||
@@ -127,11 +125,9 @@ const PersonDetails: React.FC = () => {
|
||||
|
||||
const crew = (sortedCrew ?? []).length > 0 && (
|
||||
<>
|
||||
<div className="relative z-10 mt-6 mb-4 md:flex md:items-center md:justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<div className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
|
||||
<span>{intl.formatMessage(messages.crewmember)}</span>
|
||||
</div>
|
||||
<div className="slider-header">
|
||||
<div className="slider-title">
|
||||
<span>{intl.formatMessage(messages.crewmember)}</span>
|
||||
</div>
|
||||
</div>
|
||||
<ul className="cardList">
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import React, { useState } from 'react';
|
||||
import type { MediaRequest } from '../../../server/entity/MediaRequest';
|
||||
import { FormattedDate, useIntl, defineMessages } from 'react-intl';
|
||||
import { useIntl, defineMessages } from 'react-intl';
|
||||
import Badge from '../Common/Badge';
|
||||
import { MediaRequestStatus } from '../../../server/constants/media';
|
||||
import Button from '../Common/Button';
|
||||
@@ -228,7 +228,11 @@ const RequestBlock: React.FC<RequestBlockProps> = ({ request, onUpdate }) => {
|
||||
/>
|
||||
</svg>
|
||||
<span>
|
||||
<FormattedDate value={request.createdAt} />
|
||||
{intl.formatDate(request.createdAt, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -256,7 +256,11 @@ const RequestItem: React.FC<RequestItemProps> = ({
|
||||
{intl.formatMessage(messages.requested)}
|
||||
</span>
|
||||
<span className="text-gray-300">
|
||||
{intl.formatDate(requestData.createdAt)}
|
||||
{intl.formatDate(requestData.createdAt, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
<div className="card-field">
|
||||
|
||||
@@ -18,12 +18,11 @@ const messages = defineMessages({
|
||||
qualityprofile: 'Quality Profile',
|
||||
rootfolder: 'Root Folder',
|
||||
animenote: '* This series is an anime.',
|
||||
default: '(Default)',
|
||||
loadingprofiles: 'Loading profiles…',
|
||||
loadingfolders: 'Loading folders…',
|
||||
default: '{name} (Default)',
|
||||
folder: '{path} ({space})',
|
||||
requestas: 'Request As',
|
||||
languageprofile: 'Language Profile',
|
||||
loadinglanguages: 'Loading languages…',
|
||||
loading: 'Loading…',
|
||||
});
|
||||
|
||||
export type RequestOverrides = {
|
||||
@@ -266,7 +265,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
<>
|
||||
<div className="flex flex-col items-center justify-between md:flex-row">
|
||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:pr-4 md:mb-0">
|
||||
<label htmlFor="server" className="text-label">
|
||||
<label htmlFor="server">
|
||||
{intl.formatMessage(messages.destinationserver)}
|
||||
</label>
|
||||
<select
|
||||
@@ -279,16 +278,17 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
>
|
||||
{data.map((server) => (
|
||||
<option key={`server-list-${server.id}`} value={server.id}>
|
||||
{server.name}
|
||||
{server.isDefault && server.is4k === is4k
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
: ''}
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: server.name,
|
||||
})
|
||||
: server.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:pr-4 md:mb-0">
|
||||
<label htmlFor="profile" className="text-label">
|
||||
<label htmlFor="profile">
|
||||
{intl.formatMessage(messages.qualityprofile)}
|
||||
</label>
|
||||
<select
|
||||
@@ -298,10 +298,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
onChange={(e) => setSelectedProfile(Number(e.target.value))}
|
||||
onBlur={(e) => setSelectedProfile(Number(e.target.value))}
|
||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
||||
disabled={isValidating || !serverData}
|
||||
>
|
||||
{isValidating && (
|
||||
{(isValidating || !serverData) && (
|
||||
<option value="">
|
||||
{intl.formatMessage(messages.loadingprofiles)}
|
||||
{intl.formatMessage(messages.loading)}
|
||||
</option>
|
||||
)}
|
||||
{!isValidating &&
|
||||
@@ -311,14 +312,17 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
key={`profile-list${profile.id}`}
|
||||
value={profile.id}
|
||||
>
|
||||
{profile.name}
|
||||
{isAnime &&
|
||||
serverData.server.activeAnimeProfileId === profile.id
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: profile.name,
|
||||
})
|
||||
: !isAnime &&
|
||||
serverData.server.activeProfileId === profile.id
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
: ''}
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: profile.name,
|
||||
})
|
||||
: profile.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -328,7 +332,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
type === 'tv' ? 'md:pr-4' : ''
|
||||
}`}
|
||||
>
|
||||
<label htmlFor="folder" className="text-label">
|
||||
<label htmlFor="folder">
|
||||
{intl.formatMessage(messages.rootfolder)}
|
||||
</label>
|
||||
<select
|
||||
@@ -338,10 +342,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
onChange={(e) => setSelectedFolder(e.target.value)}
|
||||
onBlur={(e) => setSelectedFolder(e.target.value)}
|
||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
||||
disabled={isValidating || !serverData}
|
||||
>
|
||||
{isValidating && (
|
||||
{(isValidating || !serverData) && (
|
||||
<option value="">
|
||||
{intl.formatMessage(messages.loadingfolders)}
|
||||
{intl.formatMessage(messages.loading)}
|
||||
</option>
|
||||
)}
|
||||
{!isValidating &&
|
||||
@@ -351,21 +356,33 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
key={`folder-list${folder.id}`}
|
||||
value={folder.path}
|
||||
>
|
||||
{folder.path} ({formatBytes(folder.freeSpace ?? 0)})
|
||||
{isAnime &&
|
||||
serverData.server.activeAnimeDirectory === folder.path
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: intl.formatMessage(messages.folder, {
|
||||
path: folder.path,
|
||||
space: formatBytes(folder.freeSpace ?? 0),
|
||||
}),
|
||||
})
|
||||
: !isAnime &&
|
||||
serverData.server.activeDirectory === folder.path
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
: ''}
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: intl.formatMessage(messages.folder, {
|
||||
path: folder.path,
|
||||
space: formatBytes(folder.freeSpace ?? 0),
|
||||
}),
|
||||
})
|
||||
: intl.formatMessage(messages.folder, {
|
||||
path: folder.path,
|
||||
space: formatBytes(folder.freeSpace ?? 0),
|
||||
})}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
</div>
|
||||
{type === 'tv' && (
|
||||
<div className="flex-grow flex-shrink-0 w-full mb-2 md:w-1/4 md:mb-0">
|
||||
<label htmlFor="language" className="text-label">
|
||||
<label htmlFor="language">
|
||||
{intl.formatMessage(messages.languageprofile)}
|
||||
</label>
|
||||
<select
|
||||
@@ -379,10 +396,11 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
setSelectedLanguage(parseInt(e.target.value))
|
||||
}
|
||||
className="block w-full py-2 pl-3 pr-10 mt-1 text-base leading-6 text-white transition duration-150 ease-in-out bg-gray-800 border-gray-700 rounded-md form-select focus:outline-none focus:ring-blue focus:border-blue-300 sm:text-sm sm:leading-5"
|
||||
disabled={isValidating || !serverData}
|
||||
>
|
||||
{isValidating && (
|
||||
{(isValidating || !serverData) && (
|
||||
<option value="">
|
||||
{intl.formatMessage(messages.loadinglanguages)}
|
||||
{intl.formatMessage(messages.loading)}
|
||||
</option>
|
||||
)}
|
||||
{!isValidating &&
|
||||
@@ -392,16 +410,19 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
key={`folder-list${language.id}`}
|
||||
value={language.id}
|
||||
>
|
||||
{language.name}
|
||||
{isAnime &&
|
||||
serverData.server.activeAnimeLanguageProfileId ===
|
||||
language.id
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: language.name,
|
||||
})
|
||||
: !isAnime &&
|
||||
serverData.server.activeLanguageProfileId ===
|
||||
language.id
|
||||
? ` ${intl.formatMessage(messages.default)}`
|
||||
: ''}
|
||||
? intl.formatMessage(messages.default, {
|
||||
name: language.name,
|
||||
})
|
||||
: language.name}
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
@@ -412,7 +433,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
)}
|
||||
{hasPermission([Permission.MANAGE_REQUESTS, Permission.MANAGE_USERS]) &&
|
||||
selectedUser && (
|
||||
<div className="mt-0 sm:mt-2">
|
||||
<div className="first:mt-0 sm:mt-4">
|
||||
<Listbox
|
||||
as="div"
|
||||
value={selectedUser}
|
||||
@@ -421,7 +442,7 @@ const AdvancedRequester: React.FC<AdvancedRequesterProps> = ({
|
||||
>
|
||||
{({ open }) => (
|
||||
<>
|
||||
<Listbox.Label className="text-label">
|
||||
<Listbox.Label>
|
||||
{intl.formatMessage(messages.requestas)}
|
||||
</Listbox.Label>
|
||||
<div className="relative">
|
||||
|
||||
@@ -9,6 +9,8 @@ import * as Yup from 'yup';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
import NotificationTypeSelector from '../../NotificationTypeSelector';
|
||||
import Alert from '../../Common/Alert';
|
||||
import Badge from '../../Common/Badge';
|
||||
import globalMessages from '../../../i18n/globalMessages';
|
||||
|
||||
const messages = defineMessages({
|
||||
save: 'Save Changes',
|
||||
@@ -39,8 +41,27 @@ const messages = defineMessages({
|
||||
emailNotificationTypesAlertDescriptionPt2:
|
||||
'<strong>Media Approved</strong>, <strong>Media Declined</strong>, and <strong>Media Available</strong>\
|
||||
email notifications are sent to the user who submitted the request.',
|
||||
pgpPrivateKey: '<PgpLink>PGP</PgpLink> Private Key',
|
||||
pgpPrivateKeyTip:
|
||||
'Sign encrypted email messages (PGP password is also required)',
|
||||
pgpPassword: '<PgpLink>PGP</PgpLink> Password',
|
||||
pgpPasswordTip:
|
||||
'Sign encrypted email messages (PGP private key is also required)',
|
||||
});
|
||||
|
||||
export function PgpLink(msg: string): JSX.Element {
|
||||
return (
|
||||
<a
|
||||
href="https://www.openpgp.org/"
|
||||
target="_blank"
|
||||
rel="noreferrer"
|
||||
className="text-gray-100 underline transition duration-300 hover:text-white"
|
||||
>
|
||||
{msg}
|
||||
</a>
|
||||
);
|
||||
}
|
||||
|
||||
const NotificationsEmail: React.FC = () => {
|
||||
const intl = useIntl();
|
||||
const { addToast } = useToasts();
|
||||
@@ -77,6 +98,8 @@ const NotificationsEmail: React.FC = () => {
|
||||
authPass: data.options.authPass,
|
||||
allowSelfSigned: data.options.allowSelfSigned,
|
||||
senderName: data.options.senderName,
|
||||
pgpPrivateKey: data.options.pgpPrivateKey,
|
||||
pgpPassword: data.options.pgpPassword,
|
||||
}}
|
||||
validationSchema={NotificationsEmailSchema}
|
||||
onSubmit={async (values) => {
|
||||
@@ -93,6 +116,8 @@ const NotificationsEmail: React.FC = () => {
|
||||
authPass: values.authPass,
|
||||
allowSelfSigned: values.allowSelfSigned,
|
||||
senderName: values.senderName,
|
||||
pgpPrivateKey: values.pgpPrivateKey,
|
||||
pgpPassword: values.pgpPassword,
|
||||
},
|
||||
});
|
||||
addToast(intl.formatMessage(messages.emailsettingssaved), {
|
||||
@@ -122,6 +147,8 @@ const NotificationsEmail: React.FC = () => {
|
||||
authUser: values.authUser,
|
||||
authPass: values.authPass,
|
||||
senderName: values.senderName,
|
||||
pgpPrivateKey: values.pgpPrivateKey,
|
||||
pgpPassword: values.pgpPassword,
|
||||
},
|
||||
});
|
||||
|
||||
@@ -291,6 +318,56 @@ const NotificationsEmail: React.FC = () => {
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="pgpPrivateKey" className="text-label">
|
||||
<span className="mr-2">
|
||||
{intl.formatMessage(messages.pgpPrivateKey, {
|
||||
PgpLink: PgpLink,
|
||||
})}
|
||||
</span>
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.advanced)}
|
||||
</Badge>
|
||||
<span className="label-tip">
|
||||
{intl.formatMessage(messages.pgpPrivateKeyTip)}
|
||||
</span>
|
||||
</label>
|
||||
<div className="form-input">
|
||||
<div className="form-input-field">
|
||||
<Field
|
||||
id="pgpPrivateKey"
|
||||
name="pgpPrivateKey"
|
||||
as="textarea"
|
||||
rows="3"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="pgpPassword" className="text-label">
|
||||
<span className="mr-2">
|
||||
{intl.formatMessage(messages.pgpPassword, {
|
||||
PgpLink: PgpLink,
|
||||
})}
|
||||
</span>
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.advanced)}
|
||||
</Badge>
|
||||
<span className="label-tip">
|
||||
{intl.formatMessage(messages.pgpPasswordTip)}
|
||||
</span>
|
||||
</label>
|
||||
<div className="form-input">
|
||||
<div className="form-input-field">
|
||||
<Field
|
||||
id="pgpPassword"
|
||||
name="pgpPassword"
|
||||
type="password"
|
||||
autoComplete="off"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
role="group"
|
||||
aria-labelledby="group-label"
|
||||
|
||||
@@ -41,13 +41,13 @@ const NotificationsPushover: React.FC = () => {
|
||||
accessToken: Yup.string()
|
||||
.required(intl.formatMessage(messages.validationAccessTokenRequired))
|
||||
.matches(
|
||||
/^a[A-Za-z0-9]{29}$/,
|
||||
/^[a-z\d]{30}$/i,
|
||||
intl.formatMessage(messages.validationAccessTokenRequired)
|
||||
),
|
||||
userToken: Yup.string()
|
||||
.required(intl.formatMessage(messages.validationUserTokenRequired))
|
||||
.matches(
|
||||
/^[ug][A-Za-z0-9]{29}$/,
|
||||
/^[a-z\d]{30}$/i,
|
||||
intl.formatMessage(messages.validationUserTokenRequired)
|
||||
),
|
||||
});
|
||||
|
||||
@@ -18,7 +18,7 @@ const messages = defineMessages({
|
||||
botAPI: 'Bot Authentication Token',
|
||||
chatId: 'Chat ID',
|
||||
validationBotAPIRequired: 'You must provide a bot authentication token',
|
||||
validationChatIdRequired: 'You must provide a chat ID',
|
||||
validationChatIdRequired: 'You must provide a valid chat ID',
|
||||
telegramsettingssaved: 'Telegram notification settings saved successfully!',
|
||||
telegramsettingsfailed: 'Telegram notification settings failed to save.',
|
||||
testsent: 'Test notification sent!',
|
||||
|
||||
@@ -279,7 +279,7 @@ const SettingsServices: React.FC = () => {
|
||||
<p>{intl.formatMessage(messages.nodefaultdescription)}</p>
|
||||
</Alert>
|
||||
)}
|
||||
<ul className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<ul className="grid max-w-6xl grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3">
|
||||
{radarrData.map((radarr) => (
|
||||
<ServerInstance
|
||||
key={`radarr-config-${radarr.id}`}
|
||||
@@ -350,7 +350,7 @@ const SettingsServices: React.FC = () => {
|
||||
<p>{intl.formatMessage(messages.nodefaultdescription)}</p>
|
||||
</Alert>
|
||||
)}
|
||||
<ul className="grid grid-cols-1 gap-6 sm:grid-cols-2 lg:grid-cols-3">
|
||||
<ul className="grid max-w-6xl grid-cols-1 gap-6 lg:grid-cols-2 xl:grid-cols-3">
|
||||
{sonarrData.map((sonarr) => (
|
||||
<ServerInstance
|
||||
key={`sonarr-config-${sonarr.id}`}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import React, { useState, useContext, useMemo } from 'react';
|
||||
import { FormattedDate, defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import useSWR from 'swr';
|
||||
import { useRouter } from 'next/router';
|
||||
import Button from '../Common/Button';
|
||||
@@ -60,7 +60,7 @@ const messages = defineMessages({
|
||||
If this item exists in your Plex library, the media information will be recreated during the next scan.',
|
||||
approve: 'Approve',
|
||||
decline: 'Decline',
|
||||
showtype: 'Show Type',
|
||||
showtype: 'Series Type',
|
||||
anime: 'Anime',
|
||||
network: '{networkCount, plural, one {Network} other {Networks}}',
|
||||
viewfullcrew: 'View Full Crew',
|
||||
@@ -74,6 +74,8 @@ const messages = defineMessages({
|
||||
mark4kavailable: 'Mark 4K as Available',
|
||||
allseasonsmarkedavailable: '* All seasons will be marked as available.',
|
||||
seasons: '{seasonCount, plural, one {# Season} other {# Seasons}}',
|
||||
episodeRuntime: 'Episode Runtime',
|
||||
episodeRuntimeMinutes: '{runtime} minutes',
|
||||
});
|
||||
|
||||
interface TvDetailsProps {
|
||||
@@ -223,7 +225,7 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
|
||||
return (
|
||||
<div
|
||||
className="px-4 pt-16 -mx-4 -mt-16 bg-center bg-cover"
|
||||
className="media-page"
|
||||
style={{
|
||||
height: 493,
|
||||
backgroundImage: `linear-gradient(180deg, rgba(17, 24, 39, 0.47) 0%, rgba(17, 24, 39, 1) 100%), url(//image.tmdb.org/t/p/w1920_and_h800_multi_faces/${data.backdropPath})`,
|
||||
@@ -415,52 +417,46 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</div>
|
||||
)}
|
||||
</SlideOver>
|
||||
<div className="flex flex-col items-center pt-4 lg:flex-row lg:items-end">
|
||||
<div className="lg:mr-4">
|
||||
<img
|
||||
src={
|
||||
data.posterPath
|
||||
? `//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`
|
||||
: '/images/overseerr_poster_not_found.png'
|
||||
}
|
||||
alt=""
|
||||
className="w-32 rounded shadow md:rounded-lg md:shadow-2xl md:w-44 lg:w-52"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-col flex-1 mt-4 text-center text-white lg:mr-4 lg:mt-0 lg:text-left">
|
||||
<div className="mb-2 space-x-2">
|
||||
<span className="ml-2 lg:ml-0">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
plexUrl={data.mediaInfo?.plexUrl}
|
||||
/>
|
||||
</span>
|
||||
<div className="media-header">
|
||||
<img
|
||||
src={
|
||||
data.posterPath
|
||||
? `//image.tmdb.org/t/p/w600_and_h900_bestv2${data.posterPath}`
|
||||
: '/images/overseerr_poster_not_found.png'
|
||||
}
|
||||
alt=""
|
||||
className="media-poster"
|
||||
/>
|
||||
<div className="media-title">
|
||||
<div className="media-status">
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status}
|
||||
inProgress={(data.mediaInfo?.downloadStatus ?? []).length > 0}
|
||||
plexUrl={data.mediaInfo?.plexUrl}
|
||||
/>
|
||||
{settings.currentSettings.series4kEnabled &&
|
||||
hasPermission([Permission.REQUEST_4K, Permission.REQUEST_4K_TV], {
|
||||
type: 'or',
|
||||
}) && (
|
||||
<span>
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status4k}
|
||||
is4k
|
||||
inProgress={
|
||||
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
}
|
||||
plexUrl4k={data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
</span>
|
||||
<StatusBadge
|
||||
status={data.mediaInfo?.status4k}
|
||||
is4k
|
||||
inProgress={
|
||||
(data.mediaInfo?.downloadStatus4k ?? []).length > 0
|
||||
}
|
||||
plexUrl4k={data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
<h1 className="text-2xl lg:text-4xl">
|
||||
<h1>
|
||||
{data.name}{' '}
|
||||
{data.firstAirDate && (
|
||||
<span className="text-2xl">
|
||||
<span className="media-year">
|
||||
({data.firstAirDate.slice(0, 4)})
|
||||
</span>
|
||||
)}
|
||||
</h1>
|
||||
<span className="mt-1 text-xs lg:text-base lg:mt-0">
|
||||
<span className="media-attributes">
|
||||
{seriesAttributes.length > 0 &&
|
||||
seriesAttributes
|
||||
.map((t, k) => <span key={k}>{t}</span>)
|
||||
@@ -471,29 +467,24 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
))}
|
||||
</span>
|
||||
</div>
|
||||
<div className="relative z-10 flex flex-wrap justify-center flex-shrink-0 mt-4 sm:justify-end sm:flex-nowrap lg:mt-0">
|
||||
<div className="mb-3 sm:mb-0">
|
||||
<PlayButton links={mediaLinks} />
|
||||
</div>
|
||||
<div className="mb-3 sm:mb-0">
|
||||
<RequestButton
|
||||
mediaType="tv"
|
||||
onUpdate={() => revalidate()}
|
||||
tmdbId={data?.id}
|
||||
media={data?.mediaInfo}
|
||||
isShowComplete={isComplete}
|
||||
is4kShowComplete={is4kComplete}
|
||||
/>
|
||||
</div>
|
||||
<div className="media-actions">
|
||||
<PlayButton links={mediaLinks} />
|
||||
<RequestButton
|
||||
mediaType="tv"
|
||||
onUpdate={() => revalidate()}
|
||||
tmdbId={data?.id}
|
||||
media={data?.mediaInfo}
|
||||
isShowComplete={isComplete}
|
||||
is4kShowComplete={is4kComplete}
|
||||
/>
|
||||
{hasPermission(Permission.MANAGE_REQUESTS) && (
|
||||
<Button
|
||||
buttonType="default"
|
||||
className="mb-3 ml-2 first:ml-0 sm:mb-0"
|
||||
className="ml-2 first:ml-0"
|
||||
onClick={() => setShowManager(true)}
|
||||
>
|
||||
<svg
|
||||
className="w-5"
|
||||
style={{ height: 20 }}
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
@@ -516,17 +507,16 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col pt-8 pb-4 text-white md:flex-row">
|
||||
<div className="flex-1 md:mr-8">
|
||||
<h2 className="text-xl md:text-2xl">
|
||||
{intl.formatMessage(messages.overview)}
|
||||
</h2>
|
||||
<p className="pt-2 text-sm md:text-base">
|
||||
<div className="media-overview">
|
||||
<div className="media-overview-left">
|
||||
<div className="tagline">{data.tagline}</div>
|
||||
<h2>{intl.formatMessage(messages.overview)}</h2>
|
||||
<p>
|
||||
{data.overview
|
||||
? data.overview
|
||||
: intl.formatMessage(messages.overviewunavailable)}
|
||||
</p>
|
||||
<ul className="grid grid-cols-2 gap-6 mt-6 sm:grid-cols-3">
|
||||
<ul className="media-crew">
|
||||
{(data.createdBy.length > 0
|
||||
? [
|
||||
...data.createdBy.map(
|
||||
@@ -542,15 +532,10 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
)
|
||||
.slice(0, 6)
|
||||
.map((person) => (
|
||||
<li
|
||||
className="flex flex-col col-span-1"
|
||||
key={`crew-${person.job}-${person.id}`}
|
||||
>
|
||||
<span className="font-bold">{person.job}</span>
|
||||
<li key={`crew-${person.job}-${person.id}`}>
|
||||
<span>{person.job}</span>
|
||||
<Link href={`/person/${person.id}`}>
|
||||
<a className="text-gray-400 transition duration-300 hover:text-underline hover:text-gray-100">
|
||||
{person.name}
|
||||
</a>
|
||||
<a className="crew-name">{person.name}</a>
|
||||
</Link>
|
||||
</li>
|
||||
))}
|
||||
@@ -579,108 +564,92 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="w-full mt-8 md:w-80 md:mt-0">
|
||||
<div className="bg-gray-900 border border-gray-800 rounded-lg shadow">
|
||||
<div className="media-overview-right">
|
||||
<div className="media-facts">
|
||||
{(!!data.voteCount ||
|
||||
(ratingData?.criticsRating && !!ratingData?.criticsScore) ||
|
||||
(ratingData?.audienceRating && !!ratingData?.audienceScore)) && (
|
||||
<div className="flex items-center justify-center px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<div className="media-ratings">
|
||||
{ratingData?.criticsRating && !!ratingData?.criticsScore && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
{ratingData.criticsRating === 'Rotten' ? (
|
||||
<RTRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTFresh className="w-6 mr-1" />
|
||||
)}
|
||||
</span>
|
||||
<span className="mr-4 text-sm text-gray-400 last:mr-0">
|
||||
{ratingData.criticsScore}%
|
||||
</span>
|
||||
</>
|
||||
<span className="media-rating">
|
||||
{ratingData.criticsRating === 'Rotten' ? (
|
||||
<RTRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTFresh className="w-6 mr-1" />
|
||||
)}
|
||||
{ratingData.criticsScore}%
|
||||
</span>
|
||||
)}
|
||||
{ratingData?.audienceRating && !!ratingData?.audienceScore && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
{ratingData.audienceRating === 'Spilled' ? (
|
||||
<RTAudRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTAudFresh className="w-6 mr-1" />
|
||||
)}
|
||||
</span>
|
||||
<span className="mr-4 text-sm text-gray-400 last:mr-0">
|
||||
{ratingData.audienceScore}%
|
||||
</span>
|
||||
</>
|
||||
<span className="media-rating">
|
||||
{ratingData.audienceRating === 'Spilled' ? (
|
||||
<RTAudRotten className="w-6 mr-1" />
|
||||
) : (
|
||||
<RTAudFresh className="w-6 mr-1" />
|
||||
)}
|
||||
{ratingData.audienceScore}%
|
||||
</span>
|
||||
)}
|
||||
{!!data.voteCount && (
|
||||
<>
|
||||
<span className="text-sm">
|
||||
<TmdbLogo className="w-6 mr-2" />
|
||||
</span>
|
||||
<span className="text-sm text-gray-400">
|
||||
{data.voteAverage}/10
|
||||
</span>
|
||||
</>
|
||||
<span className="media-rating">
|
||||
<TmdbLogo className="w-6 mr-2" />
|
||||
{data.voteAverage}/10
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
)}
|
||||
{data.keywords.some(
|
||||
(keyword) => keyword.id === ANIME_KEYWORD_ID
|
||||
) && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.showtype)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.showtype)}</span>
|
||||
<span className="media-fact-value">
|
||||
{intl.formatMessage(messages.anime)}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.status)}</span>
|
||||
<span className="media-fact-value">{data.status}</span>
|
||||
</div>
|
||||
{data.firstAirDate && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.firstAirDate)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<FormattedDate
|
||||
value={new Date(data.firstAirDate)}
|
||||
year="numeric"
|
||||
month="long"
|
||||
day="numeric"
|
||||
/>
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.firstAirDate)}</span>
|
||||
<span className="media-fact-value">
|
||||
{intl.formatDate(data.firstAirDate, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
{data.nextEpisodeToAir && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.nextAirDate)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<FormattedDate
|
||||
value={new Date(data.nextEpisodeToAir?.airDate)}
|
||||
year="numeric"
|
||||
month="long"
|
||||
day="numeric"
|
||||
/>
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.nextAirDate)}</span>
|
||||
<span className="media-fact-value">
|
||||
{intl.formatDate(data.nextEpisodeToAir.airDate, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.status)}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
{data.status}
|
||||
</span>
|
||||
</div>
|
||||
{data.originalLanguage && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
{intl.formatMessage(messages.originallanguage)}
|
||||
{data.episodeRunTime.length > 0 && (
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.episodeRuntime)}</span>
|
||||
<span className="media-fact-value">
|
||||
{intl.formatMessage(messages.episodeRuntimeMinutes, {
|
||||
runtime: data.episodeRunTime[0],
|
||||
})}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
</div>
|
||||
)}
|
||||
{data.originalLanguage && (
|
||||
<div className="media-fact">
|
||||
<span>{intl.formatMessage(messages.originallanguage)}</span>
|
||||
<span className="media-fact-value">
|
||||
<Link href={`/discover/tv/language/${data.originalLanguage}`}>
|
||||
<a className="hover:underline">
|
||||
{intl.formatDisplayName(data.originalLanguage, {
|
||||
@@ -696,13 +665,13 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</div>
|
||||
)}
|
||||
{data.networks.length > 0 && (
|
||||
<div className="flex px-4 py-2 border-b border-gray-800 last:border-b-0">
|
||||
<span className="text-sm">
|
||||
<div className="media-fact">
|
||||
<span>
|
||||
{intl.formatMessage(messages.network, {
|
||||
networkCount: data.networks.length,
|
||||
})}
|
||||
</span>
|
||||
<span className="flex-1 text-sm text-right text-gray-400">
|
||||
<span className="media-fact-value">
|
||||
{data.networks
|
||||
.map((n) => (
|
||||
<Link
|
||||
@@ -720,43 +689,41 @@ const TvDetails: React.FC<TvDetailsProps> = ({ tv }) => {
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-4">
|
||||
<ExternalLinkBlock
|
||||
mediaType="tv"
|
||||
tmdbId={data.id}
|
||||
tvdbId={data.externalIds.tvdbId}
|
||||
imdbId={data.externalIds.imdbId}
|
||||
rtUrl={ratingData?.url}
|
||||
plexUrl={data.mediaInfo?.plexUrl ?? data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
<div className="media-fact">
|
||||
<ExternalLinkBlock
|
||||
mediaType="tv"
|
||||
tmdbId={data.id}
|
||||
tvdbId={data.externalIds.tvdbId}
|
||||
imdbId={data.externalIds.imdbId}
|
||||
rtUrl={ratingData?.url}
|
||||
plexUrl={data.mediaInfo?.plexUrl ?? data.mediaInfo?.plexUrl4k}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{data.credits.cast.length > 0 && (
|
||||
<>
|
||||
<div className="mt-6 mb-4 md:flex md:items-center md:justify-between">
|
||||
<div className="flex-1 min-w-0">
|
||||
<Link href="/tv/[tvId]/cast" as={`/tv/${data.id}/cast`}>
|
||||
<a className="inline-flex items-center text-xl leading-7 text-gray-300 hover:text-white sm:text-2xl sm:leading-9 sm:truncate">
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<div className="slider-header">
|
||||
<Link href="/tv/[tvId]/cast" as={`/tv/${data.id}/cast`}>
|
||||
<a className="slider-title">
|
||||
<span>{intl.formatMessage(messages.cast)}</span>
|
||||
<svg
|
||||
className="w-6 h-6 ml-2"
|
||||
fill="none"
|
||||
stroke="currentColor"
|
||||
viewBox="0 0 24 24"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
strokeLinecap="round"
|
||||
strokeLinejoin="round"
|
||||
strokeWidth={2}
|
||||
d="M13 9l3 3m0 0l-3 3m3-3H8m13 0a9 9 0 11-18 0 9 9 0 0118 0z"
|
||||
/>
|
||||
</svg>
|
||||
</a>
|
||||
</Link>
|
||||
</div>
|
||||
<Slider
|
||||
sliderKey="cast"
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useEffect, useState } from 'react';
|
||||
import PermissionEdit from '../PermissionEdit';
|
||||
import Modal from '../Common/Modal';
|
||||
import { User, useUser } from '../../hooks/useUser';
|
||||
import { defineMessages, FormattedMessage, useIntl } from 'react-intl';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import axios from 'axios';
|
||||
import { useToasts } from 'react-toast-notifications';
|
||||
|
||||
@@ -19,8 +19,7 @@ const messages = defineMessages({
|
||||
save: 'Save Changes',
|
||||
saving: 'Saving…',
|
||||
userfail: 'Something went wrong while saving the user.',
|
||||
permissions: 'Permissions',
|
||||
edituser: 'Edit User',
|
||||
edituser: 'Edit User Permissions',
|
||||
});
|
||||
|
||||
const BulkEditModal: React.FC<BulkEditProps> = ({
|
||||
@@ -93,27 +92,12 @@ const BulkEditModal: React.FC<BulkEditProps> = ({
|
||||
okText={intl.formatMessage(messages.save)}
|
||||
onCancel={onCancel}
|
||||
>
|
||||
<div className="mt-6 mb-6">
|
||||
<div role="group" aria-labelledby="group-label">
|
||||
<div className="form-row">
|
||||
<div>
|
||||
<div id="group-label" className="group-label">
|
||||
<FormattedMessage {...messages.permissions} />
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-input">
|
||||
<div className="max-w-lg">
|
||||
<PermissionEdit
|
||||
actingUser={currentUser}
|
||||
currentPermission={currentPermission}
|
||||
onUpdate={(newPermission) =>
|
||||
setCurrentPermission(newPermission)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="mb-6">
|
||||
<PermissionEdit
|
||||
actingUser={currentUser}
|
||||
currentPermission={currentPermission}
|
||||
onUpdate={(newPermission) => setCurrentPermission(newPermission)}
|
||||
/>
|
||||
</div>
|
||||
</Modal>
|
||||
);
|
||||
|
||||
@@ -2,7 +2,7 @@ import React, { useState } from 'react';
|
||||
import useSWR from 'swr';
|
||||
import LoadingSpinner from '../Common/LoadingSpinner';
|
||||
import Badge from '../Common/Badge';
|
||||
import { FormattedDate, defineMessages, useIntl } from 'react-intl';
|
||||
import { defineMessages, useIntl } from 'react-intl';
|
||||
import Button from '../Common/Button';
|
||||
import { hasPermission } from '../../../server/lib/permissions';
|
||||
import { Permission, User, UserType, useUser } from '../../hooks/useUser';
|
||||
@@ -551,14 +551,23 @@ const UserList: React.FC = () => {
|
||||
: intl.formatMessage(messages.user)}
|
||||
</Table.TD>
|
||||
<Table.TD>
|
||||
<FormattedDate value={user.createdAt} />
|
||||
{intl.formatDate(user.createdAt, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</Table.TD>
|
||||
<Table.TD>
|
||||
<FormattedDate value={user.updatedAt} />
|
||||
{intl.formatDate(user.updatedAt, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
})}
|
||||
</Table.TD>
|
||||
<Table.TD alignText="right">
|
||||
<Button
|
||||
buttonType="warning"
|
||||
disabled={user.id === 1 && currentUser?.id !== 1}
|
||||
className="mr-2"
|
||||
onClick={() =>
|
||||
router.push(
|
||||
@@ -571,7 +580,11 @@ const UserList: React.FC = () => {
|
||||
</Button>
|
||||
<Button
|
||||
buttonType="danger"
|
||||
disabled={hasPermission(Permission.ADMIN, user.permissions)}
|
||||
disabled={
|
||||
user.id === 1 ||
|
||||
(currentUser?.id !== 1 &&
|
||||
hasPermission(Permission.ADMIN, user.permissions))
|
||||
}
|
||||
onClick={() => setDeleteModal({ isOpen: true, user })}
|
||||
>
|
||||
{intl.formatMessage(messages.delete)}
|
||||
|
||||
@@ -27,7 +27,11 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
||||
|
||||
const subtextItems: React.ReactNode[] = [
|
||||
intl.formatMessage(messages.joindate, {
|
||||
joindate: intl.formatDate(user.createdAt),
|
||||
joindate: intl.formatDate(user.createdAt, {
|
||||
year: 'numeric',
|
||||
month: 'long',
|
||||
day: 'numeric',
|
||||
}),
|
||||
}),
|
||||
intl.formatMessage(messages.requests, {
|
||||
requestCount: user.requestCount,
|
||||
@@ -39,7 +43,7 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="relative z-40 mt-6 mb-12 md:flex md:items-end md:justify-between md:space-x-5">
|
||||
<div className="relative z-40 mt-6 mb-12 lg:flex lg:items-end lg:justify-between lg:space-x-5">
|
||||
<div className="flex items-end space-x-5 justify-items-end">
|
||||
<div className="flex-shrink-0">
|
||||
<div className="relative">
|
||||
@@ -80,9 +84,9 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="flex flex-col-reverse mt-6 space-y-4 space-y-reverse justify-stretch sm:flex-row-reverse sm:justify-end sm:space-x-reverse sm:space-y-0 sm:space-x-3 md:mt-0 md:flex-row md:space-x-3">
|
||||
<div className="flex flex-col-reverse mt-6 space-y-4 space-y-reverse justify-stretch lg:flex-row lg:justify-end lg:space-x-reverse lg:space-y-0 lg:space-x-3">
|
||||
{(loggedInUser?.id === user.id ||
|
||||
hasPermission(Permission.MANAGE_USERS)) &&
|
||||
(user.id !== 1 && hasPermission(Permission.MANAGE_USERS))) &&
|
||||
!isSettingsPage ? (
|
||||
<Link
|
||||
href={
|
||||
@@ -109,28 +113,30 @@ const ProfileHeader: React.FC<ProfileHeaderProps> = ({
|
||||
</Button>
|
||||
</Link>
|
||||
) : (
|
||||
<Link
|
||||
href={
|
||||
loggedInUser?.id === user.id ? `/profile` : `/users/${user.id}`
|
||||
}
|
||||
passHref
|
||||
>
|
||||
<Button as="a">
|
||||
<svg
|
||||
className="w-5 h-5 mr-1"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{intl.formatMessage(messages.profile)}
|
||||
</Button>
|
||||
</Link>
|
||||
isSettingsPage && (
|
||||
<Link
|
||||
href={
|
||||
loggedInUser?.id === user.id ? `/profile` : `/users/${user.id}`
|
||||
}
|
||||
passHref
|
||||
>
|
||||
<Button as="a">
|
||||
<svg
|
||||
className="w-5 h-5 mr-1"
|
||||
fill="currentColor"
|
||||
viewBox="0 0 20 20"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
>
|
||||
<path
|
||||
fillRule="evenodd"
|
||||
d="M10 9a3 3 0 100-6 3 3 0 000 6zm-7 9a7 7 0 1114 0H3z"
|
||||
clipRule="evenodd"
|
||||
/>
|
||||
</svg>
|
||||
{intl.formatMessage(messages.profile)}
|
||||
</Button>
|
||||
</Link>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -11,6 +11,9 @@ import Button from '../../../Common/Button';
|
||||
import LoadingSpinner from '../../../Common/LoadingSpinner';
|
||||
import { UserSettingsNotificationsResponse } from '../../../../../server/interfaces/api/userSettingsInterfaces';
|
||||
import * as Yup from 'yup';
|
||||
import Badge from '../../../Common/Badge';
|
||||
import globalMessages from '../../../../i18n/globalMessages';
|
||||
import { PgpLink } from '../../../Settings/Notifications/NotificationsEmail';
|
||||
|
||||
const messages = defineMessages({
|
||||
notificationsettings: 'Notification Settings',
|
||||
@@ -32,6 +35,8 @@ const messages = defineMessages({
|
||||
localuser: 'Local User',
|
||||
toastSettingsSuccess: 'Settings successfully saved!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
pgpKey: '<PgpLink>PGP</PgpLink> Public Key',
|
||||
pgpKeyTip: 'Encrypt email messages',
|
||||
});
|
||||
|
||||
const UserNotificationSettings: React.FC = () => {
|
||||
@@ -76,6 +81,7 @@ const UserNotificationSettings: React.FC = () => {
|
||||
discordId: data?.discordId,
|
||||
telegramChatId: data?.telegramChatId,
|
||||
telegramSendSilently: data?.telegramSendSilently,
|
||||
pgpKey: data?.pgpKey,
|
||||
}}
|
||||
validationSchema={UserNotificationSettingsSchema}
|
||||
enableReinitialize
|
||||
@@ -88,6 +94,7 @@ const UserNotificationSettings: React.FC = () => {
|
||||
discordId: values.discordId,
|
||||
telegramChatId: values.telegramChatId,
|
||||
telegramSendSilently: values.telegramSendSilently,
|
||||
pgpKey: values.pgpKey,
|
||||
}
|
||||
);
|
||||
|
||||
@@ -123,6 +130,29 @@ const UserNotificationSettings: React.FC = () => {
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="pgpKey" className="text-label">
|
||||
<span className="mr-2">
|
||||
{intl.formatMessage(messages.pgpKey, {
|
||||
PgpLink: PgpLink,
|
||||
})}
|
||||
</span>
|
||||
<Badge badgeType="danger">
|
||||
{intl.formatMessage(globalMessages.advanced)}
|
||||
</Badge>
|
||||
<span className="label-tip">
|
||||
{intl.formatMessage(messages.pgpKeyTip)}
|
||||
</span>
|
||||
</label>
|
||||
<div className="form-input">
|
||||
<div className="form-input-field">
|
||||
<Field id="pgpKey" name="pgpKey" as="textarea" rows="3" />
|
||||
</div>
|
||||
{errors.pgpKey && touched.pgpKey && (
|
||||
<div className="error">{errors.pgpKey}</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
<div className="form-row">
|
||||
<label htmlFor="discordId" className="text-label">
|
||||
<span>{intl.formatMessage(messages.discordId)}</span>
|
||||
|
||||
@@ -10,6 +10,7 @@ import Error from '../../../../pages/_error';
|
||||
import Button from '../../../Common/Button';
|
||||
import LoadingSpinner from '../../../Common/LoadingSpinner';
|
||||
import PermissionEdit from '../../../PermissionEdit';
|
||||
import Alert from '../../../Common/Alert';
|
||||
|
||||
const messages = defineMessages({
|
||||
displayName: 'Display Name',
|
||||
@@ -20,6 +21,8 @@ const messages = defineMessages({
|
||||
toastSettingsSuccess: 'Settings successfully saved!',
|
||||
toastSettingsFailure: 'Something went wrong while saving settings.',
|
||||
permissions: 'Permissions',
|
||||
unauthorized: 'Unauthorized',
|
||||
unauthorizedDescription: 'You cannot modify your own permissions.',
|
||||
});
|
||||
|
||||
const UserPermissions: React.FC = () => {
|
||||
@@ -40,6 +43,21 @@ const UserPermissions: React.FC = () => {
|
||||
return <Error statusCode={500} />;
|
||||
}
|
||||
|
||||
if (currentUser?.id !== 1 && currentUser?.id === user?.id) {
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6">
|
||||
<h3 className="heading">
|
||||
{intl.formatMessage(messages.permissions)}
|
||||
</h3>
|
||||
</div>
|
||||
<Alert title={intl.formatMessage(messages.unauthorized)} type="error">
|
||||
{intl.formatMessage(messages.unauthorizedDescription)}
|
||||
</Alert>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<>
|
||||
<div className="mb-6">
|
||||
@@ -74,28 +92,15 @@ const UserPermissions: React.FC = () => {
|
||||
{({ isSubmitting, setFieldValue, values }) => {
|
||||
return (
|
||||
<Form className="section">
|
||||
<div
|
||||
role="group"
|
||||
aria-labelledby="group-label"
|
||||
className="form-group"
|
||||
>
|
||||
<div className="form-row">
|
||||
<span id="group-label" className="group-label">
|
||||
{intl.formatMessage(messages.permissions)}
|
||||
</span>
|
||||
<div className="form-input">
|
||||
<div className="max-w-lg">
|
||||
<PermissionEdit
|
||||
actingUser={currentUser}
|
||||
currentUser={user}
|
||||
currentPermission={values.currentPermissions ?? 0}
|
||||
onUpdate={(newPermission) =>
|
||||
setFieldValue('currentPermissions', newPermission)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="max-w-3xl">
|
||||
<PermissionEdit
|
||||
actingUser={currentUser}
|
||||
currentUser={user}
|
||||
currentPermission={values.currentPermissions ?? 0}
|
||||
onUpdate={(newPermission) =>
|
||||
setFieldValue('currentPermissions', newPermission)
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
<div className="actions">
|
||||
<div className="flex justify-end">
|
||||
|
||||
@@ -9,6 +9,7 @@ import LoadingSpinner from '../../Common/LoadingSpinner';
|
||||
import PageTitle from '../../Common/PageTitle';
|
||||
import ProfileHeader from '../ProfileHeader';
|
||||
import useSettings from '../../../hooks/useSettings';
|
||||
import Alert from '../../Common/Alert';
|
||||
|
||||
const messages = defineMessages({
|
||||
settings: 'User Settings',
|
||||
@@ -16,6 +17,9 @@ const messages = defineMessages({
|
||||
menuChangePass: 'Password',
|
||||
menuNotifications: 'Notifications',
|
||||
menuPermissions: 'Permissions',
|
||||
unauthorized: 'Unauthorized',
|
||||
unauthorizedDescription:
|
||||
"You do not have permission to modify this user's settings.",
|
||||
});
|
||||
|
||||
interface SettingsRoute {
|
||||
@@ -24,6 +28,7 @@ interface SettingsRoute {
|
||||
regex: RegExp;
|
||||
requiredPermission?: Permission | Permission[];
|
||||
permissionType?: { type: 'and' | 'or' };
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
const UserSettings: React.FC = ({ children }) => {
|
||||
@@ -51,6 +56,15 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
text: intl.formatMessage(messages.menuChangePass),
|
||||
route: '/settings/password',
|
||||
regex: /\/settings\/password/,
|
||||
hidden:
|
||||
(!settings.currentSettings.localLogin &&
|
||||
!hasPermission(
|
||||
Permission.MANAGE_SETTINGS,
|
||||
currentUser?.permissions ?? 0
|
||||
)) ||
|
||||
(currentUser?.id !== 1 &&
|
||||
currentUser?.id !== user?.id &&
|
||||
hasPermission(Permission.ADMIN, user?.permissions ?? 0)),
|
||||
},
|
||||
{
|
||||
text: intl.formatMessage(messages.menuNotifications),
|
||||
@@ -62,6 +76,7 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
route: '/settings/permissions',
|
||||
regex: /\/settings\/permissions/,
|
||||
requiredPermission: Permission.MANAGE_USERS,
|
||||
hidden: currentUser?.id !== 1 && currentUser?.id === user.id,
|
||||
},
|
||||
];
|
||||
|
||||
@@ -76,20 +91,6 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
regex: RegExp;
|
||||
isMobile?: boolean;
|
||||
}> = ({ children, route, regex, isMobile = false }) => {
|
||||
if (
|
||||
route === '/settings/password' &&
|
||||
((!settings.currentSettings.localLogin &&
|
||||
!hasPermission(
|
||||
Permission.MANAGE_SETTINGS,
|
||||
currentUser?.permissions ?? 0
|
||||
)) ||
|
||||
(currentUser?.id !== 1 &&
|
||||
currentUser?.id !== user?.id &&
|
||||
hasPermission(Permission.ADMIN, user?.permissions ?? 0)))
|
||||
) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const finalRoute = router.asPath.includes('/profile')
|
||||
? `/profile${route}`
|
||||
: `/users/${user.id}${route}`;
|
||||
@@ -111,6 +112,20 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
);
|
||||
};
|
||||
|
||||
if (currentUser?.id !== 1 && user.id === 1) {
|
||||
return (
|
||||
<>
|
||||
<PageTitle title={intl.formatMessage(messages.settings)} />
|
||||
<ProfileHeader user={user} isSettingsPage />
|
||||
<div className="mt-6">
|
||||
<Alert title={intl.formatMessage(messages.unauthorized)} type="error">
|
||||
{intl.formatMessage(messages.unauthorizedDescription)}
|
||||
</Alert>
|
||||
</div>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
const currentRoute = settingsRoutes.find(
|
||||
(route) => !!router.pathname.match(route.regex)
|
||||
)?.route;
|
||||
@@ -136,14 +151,16 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
aria-label="Selected tab"
|
||||
>
|
||||
{settingsRoutes
|
||||
.filter((route) =>
|
||||
route.requiredPermission
|
||||
? hasPermission(
|
||||
route.requiredPermission,
|
||||
currentUser?.permissions ?? 0,
|
||||
route.permissionType
|
||||
)
|
||||
: true
|
||||
.filter(
|
||||
(route) =>
|
||||
!route.hidden &&
|
||||
(route.requiredPermission
|
||||
? hasPermission(
|
||||
route.requiredPermission,
|
||||
currentUser?.permissions ?? 0,
|
||||
route.permissionType
|
||||
)
|
||||
: true)
|
||||
)
|
||||
.map((route, index) => (
|
||||
<SettingsLink
|
||||
@@ -161,14 +178,16 @@ const UserSettings: React.FC = ({ children }) => {
|
||||
<div className="border-b border-gray-600">
|
||||
<nav className="flex -mb-px">
|
||||
{settingsRoutes
|
||||
.filter((route) =>
|
||||
route.requiredPermission
|
||||
? hasPermission(
|
||||
route.requiredPermission,
|
||||
currentUser?.permissions ?? 0,
|
||||
route.permissionType
|
||||
)
|
||||
: true
|
||||
.filter(
|
||||
(route) =>
|
||||
!route.hidden &&
|
||||
(route.requiredPermission
|
||||
? hasPermission(
|
||||
route.requiredPermission,
|
||||
currentUser?.permissions ?? 0,
|
||||
route.permissionType
|
||||
)
|
||||
: true)
|
||||
)
|
||||
.map((route, index) => (
|
||||
<SettingsLink
|
||||
|
||||
@@ -16,6 +16,7 @@ import { defineMessages, useIntl } from 'react-intl';
|
||||
|
||||
const messages = defineMessages({
|
||||
recentrequests: 'Recent Requests',
|
||||
norequests: 'No Requests',
|
||||
});
|
||||
|
||||
type MediaTitle = MovieDetails | TvDetails;
|
||||
@@ -95,7 +96,7 @@ const UserProfile: React.FC = () => {
|
||||
/>
|
||||
))}
|
||||
placeholder={<RequestCard.Placeholder />}
|
||||
emptyMessage={'No Requests'}
|
||||
emptyMessage={intl.formatMessage(messages.norequests)}
|
||||
/>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
"components.AppDataWarning.dockerVolumeMissing": "Docker Volume Mount Missing",
|
||||
"components.AppDataWarning.dockerVolumeMissingDescription": "The <code>{appDataPath}</code> volume mount was not configured properly. All data will be cleared when the container is stopped or restarted.",
|
||||
"components.CollectionDetails.movies": "Movies",
|
||||
"components.CollectionDetails.numberofmovies": "Number of Movies: {count}",
|
||||
"components.CollectionDetails.numberofmovies": "{count} Movies",
|
||||
"components.CollectionDetails.overview": "Overview",
|
||||
"components.CollectionDetails.overviewunavailable": "Overview unavailable.",
|
||||
"components.CollectionDetails.request": "Request",
|
||||
@@ -141,9 +141,9 @@
|
||||
"components.PermissionEdit.viewrequestsDescription": "Grants permission to view other users' requests.",
|
||||
"components.PermissionEdit.vote": "Vote",
|
||||
"components.PermissionEdit.voteDescription": "Grants permission to vote on requests (voting not yet implemented).",
|
||||
"components.PersonDetails.appearsin": "Appears in",
|
||||
"components.PersonDetails.appearsin": "Appearances",
|
||||
"components.PersonDetails.ascharacter": "as {character}",
|
||||
"components.PersonDetails.crewmember": "Crew Member",
|
||||
"components.PersonDetails.crewmember": "Crew",
|
||||
"components.PersonDetails.nobiography": "No biography available.",
|
||||
"components.PlexLoginButton.loading": "Loading…",
|
||||
"components.PlexLoginButton.signingin": "Signing in…",
|
||||
@@ -197,12 +197,11 @@
|
||||
"components.RequestList.sortModified": "Last Modified",
|
||||
"components.RequestModal.AdvancedRequester.advancedoptions": "Advanced Options",
|
||||
"components.RequestModal.AdvancedRequester.animenote": "* This series is an anime.",
|
||||
"components.RequestModal.AdvancedRequester.default": "(Default)",
|
||||
"components.RequestModal.AdvancedRequester.default": "{name} (Default)",
|
||||
"components.RequestModal.AdvancedRequester.destinationserver": "Destination Server",
|
||||
"components.RequestModal.AdvancedRequester.folder": "{path} ({space})",
|
||||
"components.RequestModal.AdvancedRequester.languageprofile": "Language Profile",
|
||||
"components.RequestModal.AdvancedRequester.loadingfolders": "Loading folders…",
|
||||
"components.RequestModal.AdvancedRequester.loadinglanguages": "Loading languages…",
|
||||
"components.RequestModal.AdvancedRequester.loadingprofiles": "Loading profiles…",
|
||||
"components.RequestModal.AdvancedRequester.loading": "Loading…",
|
||||
"components.RequestModal.AdvancedRequester.qualityprofile": "Quality Profile",
|
||||
"components.RequestModal.AdvancedRequester.requestas": "Request As",
|
||||
"components.RequestModal.AdvancedRequester.rootfolder": "Root Folder",
|
||||
@@ -328,6 +327,10 @@
|
||||
"components.Settings.Notifications.emailsettingssaved": "Email notification settings saved successfully!",
|
||||
"components.Settings.Notifications.enableSsl": "Enable SSL",
|
||||
"components.Settings.Notifications.notificationtypes": "Notification Types",
|
||||
"components.Settings.Notifications.pgpPassword": "<PgpLink>PGP</PgpLink> Password",
|
||||
"components.Settings.Notifications.pgpPasswordTip": "Sign encrypted email messages (PGP private key is also required)",
|
||||
"components.Settings.Notifications.pgpPrivateKey": "<PgpLink>PGP</PgpLink> Private Key",
|
||||
"components.Settings.Notifications.pgpPrivateKeyTip": "Sign encrypted email messages (PGP password is also required)",
|
||||
"components.Settings.Notifications.save": "Save Changes",
|
||||
"components.Settings.Notifications.saving": "Saving…",
|
||||
"components.Settings.Notifications.sendSilently": "Send Silently",
|
||||
@@ -343,7 +346,7 @@
|
||||
"components.Settings.Notifications.test": "Test",
|
||||
"components.Settings.Notifications.testsent": "Test notification sent!",
|
||||
"components.Settings.Notifications.validationBotAPIRequired": "You must provide a bot authentication token",
|
||||
"components.Settings.Notifications.validationChatIdRequired": "You must provide a chat ID",
|
||||
"components.Settings.Notifications.validationChatIdRequired": "You must provide a valid chat ID",
|
||||
"components.Settings.Notifications.validationEmail": "You must provide a valid email address",
|
||||
"components.Settings.Notifications.validationSmtpHostRequired": "You must provide an SMTP host",
|
||||
"components.Settings.Notifications.validationSmtpPortRequired": "You must provide an SMTP port",
|
||||
@@ -629,6 +632,8 @@
|
||||
"components.TvDetails.cast": "Cast",
|
||||
"components.TvDetails.decline": "Decline",
|
||||
"components.TvDetails.downloadstatus": "Download Status",
|
||||
"components.TvDetails.episodeRuntime": "Episode Runtime",
|
||||
"components.TvDetails.episodeRuntimeMinutes": "{runtime} minutes",
|
||||
"components.TvDetails.firstAirDate": "First Air Date",
|
||||
"components.TvDetails.manageModalClearMedia": "Clear All Media Data",
|
||||
"components.TvDetails.manageModalClearMediaWarning": "* This will irreversibly remove all data for this TV series, including any requests. If this item exists in your Plex library, the media information will be recreated during the next scan.",
|
||||
@@ -650,7 +655,7 @@
|
||||
"components.TvDetails.recommendations": "Recommendations",
|
||||
"components.TvDetails.recommendationssubtext": "If you liked {title}, you might also like…",
|
||||
"components.TvDetails.seasons": "{seasonCount, plural, one {# Season} other {# Seasons}}",
|
||||
"components.TvDetails.showtype": "Show Type",
|
||||
"components.TvDetails.showtype": "Series Type",
|
||||
"components.TvDetails.similar": "Similar Series",
|
||||
"components.TvDetails.similarsubtext": "Other series similar to {title}",
|
||||
"components.TvDetails.status": "Status",
|
||||
@@ -671,7 +676,7 @@
|
||||
"components.UserList.deleteconfirm": "Are you sure you want to delete this user? All existing request data from this user will be removed.",
|
||||
"components.UserList.deleteuser": "Delete User",
|
||||
"components.UserList.edit": "Edit",
|
||||
"components.UserList.edituser": "Edit User",
|
||||
"components.UserList.edituser": "Edit User Permissions",
|
||||
"components.UserList.email": "Email Address",
|
||||
"components.UserList.importedfromplex": "{userCount, plural, =0 {No new users} one {# new user} other {# new users}} imported from Plex",
|
||||
"components.UserList.importfromplex": "Import Users from Plex",
|
||||
@@ -683,7 +688,6 @@
|
||||
"components.UserList.password": "Password",
|
||||
"components.UserList.passwordinfo": "Password Information",
|
||||
"components.UserList.passwordinfodescription": "Email notifications need to be configured and enabled in order to automatically generate passwords.",
|
||||
"components.UserList.permissions": "Permissions",
|
||||
"components.UserList.plexuser": "Plex User",
|
||||
"components.UserList.previous": "Previous",
|
||||
"components.UserList.resultsperpage": "Display {pageSize} results per page",
|
||||
@@ -736,6 +740,8 @@
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.enableNotifications": "Enable Notifications",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.localuser": "Local User",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.notificationsettings": "Notification Settings",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.pgpKey": "<PgpLink>PGP</PgpLink> Public Key",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.pgpKeyTip": "Encrypt email messages",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.plexuser": "Plex User",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.save": "Save Changes",
|
||||
"components.UserProfile.UserSettings.UserNotificationSettings.saving": "Saving…",
|
||||
@@ -773,11 +779,16 @@
|
||||
"components.UserProfile.UserSettings.UserPermissions.saving": "Saving…",
|
||||
"components.UserProfile.UserSettings.UserPermissions.toastSettingsFailure": "Something went wrong while saving settings.",
|
||||
"components.UserProfile.UserSettings.UserPermissions.toastSettingsSuccess": "Settings successfully saved!",
|
||||
"components.UserProfile.UserSettings.UserPermissions.unauthorized": "Unauthorized",
|
||||
"components.UserProfile.UserSettings.UserPermissions.unauthorizedDescription": "You cannot modify your own permissions.",
|
||||
"components.UserProfile.UserSettings.menuChangePass": "Password",
|
||||
"components.UserProfile.UserSettings.menuGeneralSettings": "General Settings",
|
||||
"components.UserProfile.UserSettings.menuNotifications": "Notifications",
|
||||
"components.UserProfile.UserSettings.menuPermissions": "Permissions",
|
||||
"components.UserProfile.UserSettings.settings": "User Settings",
|
||||
"components.UserProfile.UserSettings.unauthorized": "Unauthorized",
|
||||
"components.UserProfile.UserSettings.unauthorizedDescription": "You do not have permission to modify this user's settings.",
|
||||
"components.UserProfile.norequests": "No Requests",
|
||||
"components.UserProfile.recentrequests": "Recent Requests",
|
||||
"i18n.advanced": "Advanced",
|
||||
"i18n.approve": "Approve",
|
||||
|
||||
@@ -16,6 +16,7 @@ import { InteractionProvider } from '../context/InteractionContext';
|
||||
import StatusChecker from '../components/StatusChacker';
|
||||
import { PublicSettingsResponse } from '../../server/interfaces/api/settingsInterfaces';
|
||||
import { SettingsProvider } from '../context/SettingsContext';
|
||||
import LoadingBar from '../components/LoadingBar';
|
||||
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||
const loadLocaleData = (locale: AvailableLocales): Promise<any> => {
|
||||
@@ -113,6 +114,7 @@ const CoreApp: Omit<NextAppComponentType, 'origGetInitialProps'> = ({
|
||||
defaultLocale="en"
|
||||
messages={loadedMessages}
|
||||
>
|
||||
<LoadingBar />
|
||||
<SettingsProvider currentSettings={currentSettings}>
|
||||
<InteractionProvider>
|
||||
<ToastProvider components={{ Toast }}>
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
@tailwind screens;
|
||||
|
||||
body {
|
||||
@apply bg-gray-900;
|
||||
@@ -30,7 +31,7 @@ ul.cardList > li {
|
||||
}
|
||||
|
||||
.slider-header {
|
||||
@apply flex mt-6 mb-4;
|
||||
@apply relative flex mt-6 mb-4;
|
||||
}
|
||||
|
||||
.slider-title {
|
||||
@@ -41,17 +42,100 @@ a.slider-title {
|
||||
@apply hover:text-white;
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
.media-page {
|
||||
@apply px-4 pt-16 -mx-4 -mt-16 bg-center bg-cover;
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
.media-header {
|
||||
@apply flex flex-col items-center pt-4 xl:flex-row xl:items-end;
|
||||
}
|
||||
|
||||
.toast {
|
||||
width: 360px;
|
||||
.media-poster {
|
||||
@apply w-32 rounded shadow md:rounded-lg md:shadow-2xl md:w-44 xl:w-52 xl:mr-4;
|
||||
}
|
||||
|
||||
.media-status {
|
||||
@apply mb-2 space-x-2;
|
||||
}
|
||||
|
||||
.media-title {
|
||||
@apply flex flex-col flex-1 mt-4 text-center text-white xl:mr-4 xl:mt-0 xl:text-left;
|
||||
}
|
||||
|
||||
.media-title > h1 {
|
||||
@apply text-2xl xl:text-4xl;
|
||||
}
|
||||
|
||||
h1 > .media-year {
|
||||
@apply text-2xl;
|
||||
}
|
||||
|
||||
.media-attributes {
|
||||
@apply mt-1 text-xs sm:text-sm xl:text-base xl:mt-0;
|
||||
}
|
||||
|
||||
.media-actions {
|
||||
@apply relative z-10 flex flex-wrap items-center justify-center flex-shrink-0 mt-4 sm:justify-end sm:flex-nowrap xl:mt-0;
|
||||
}
|
||||
|
||||
.media-actions > * {
|
||||
@apply mb-3 sm:mb-0;
|
||||
}
|
||||
|
||||
.media-overview {
|
||||
@apply flex flex-col pt-8 pb-4 text-white lg:flex-row;
|
||||
}
|
||||
|
||||
.media-overview-left {
|
||||
@apply flex-1 lg:mr-8;
|
||||
}
|
||||
|
||||
.tagline {
|
||||
@apply mb-4 text-xl italic text-gray-400 lg:text-2xl;
|
||||
}
|
||||
|
||||
.media-overview h2 {
|
||||
@apply text-xl sm:text-2xl;
|
||||
}
|
||||
|
||||
.media-overview p {
|
||||
@apply pt-2 text-sm text-gray-400 lg:text-base;
|
||||
}
|
||||
|
||||
ul.media-crew {
|
||||
@apply grid grid-cols-2 gap-6 mt-6 sm:grid-cols-3;
|
||||
}
|
||||
|
||||
ul.media-crew > li {
|
||||
@apply flex flex-col col-span-1 font-bold;
|
||||
}
|
||||
|
||||
a.crew-name {
|
||||
@apply font-normal text-gray-400 transition duration-300 hover:underline hover:text-gray-100;
|
||||
}
|
||||
|
||||
.media-overview-right {
|
||||
@apply w-full mt-8 lg:w-80 lg:mt-0;
|
||||
}
|
||||
|
||||
.media-facts {
|
||||
@apply text-sm bg-gray-900 border border-gray-700 rounded-lg shadow;
|
||||
}
|
||||
|
||||
.media-fact {
|
||||
@apply flex px-4 py-2 border-b border-gray-700 last:border-b-0;
|
||||
}
|
||||
|
||||
.media-fact-value {
|
||||
@apply flex-1 text-sm text-right text-gray-400;
|
||||
}
|
||||
|
||||
.media-ratings {
|
||||
@apply flex items-center justify-center px-4 py-2 border-b border-gray-700 last:border-b-0;
|
||||
}
|
||||
|
||||
.media-rating {
|
||||
@apply flex items-center mr-4 last:mr-0;
|
||||
}
|
||||
|
||||
.error-message {
|
||||
@@ -94,6 +178,10 @@ img.avatar-sm {
|
||||
@apply flex max-w-lg rounded-md shadow-sm;
|
||||
}
|
||||
|
||||
textarea {
|
||||
@apply flex-1 block w-full min-w-0 text-white transition duration-150 ease-in-out bg-gray-700 border border-gray-500 rounded-md form-input sm:text-sm sm:leading-5;
|
||||
}
|
||||
|
||||
.label-required {
|
||||
@apply text-red-500;
|
||||
}
|
||||
@@ -106,12 +194,20 @@ img.avatar-sm {
|
||||
@apply pt-5 mt-8 text-white border-t border-gray-700;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
@apply w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md;
|
||||
label {
|
||||
@apply block mb-1 text-sm font-medium leading-5 text-gray-400;
|
||||
}
|
||||
|
||||
.checkbox-label {
|
||||
@apply block mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-1;
|
||||
label.checkbox-label {
|
||||
@apply sm:mt-1;
|
||||
}
|
||||
|
||||
label.text-label {
|
||||
@apply sm:mt-2;
|
||||
}
|
||||
|
||||
input[type='checkbox'] {
|
||||
@apply w-6 h-6 text-indigo-600 transition duration-150 ease-in-out rounded-md;
|
||||
}
|
||||
|
||||
input[type='text'],
|
||||
@@ -138,11 +234,6 @@ select.short {
|
||||
.protocol {
|
||||
@apply inline-flex items-center px-3 text-gray-100 bg-gray-600 border border-r-0 border-gray-500 cursor-default rounded-l-md sm:text-sm;
|
||||
}
|
||||
|
||||
.text-label {
|
||||
@apply block mb-1 text-sm font-medium leading-5 text-gray-400 sm:mt-2;
|
||||
}
|
||||
|
||||
.error {
|
||||
@apply mt-2 text-sm text-red-500;
|
||||
}
|
||||
@@ -155,11 +246,24 @@ select.short {
|
||||
@apply block mb-1 text-sm font-medium leading-6 text-gray-400;
|
||||
}
|
||||
|
||||
.toast {
|
||||
width: 360px;
|
||||
}
|
||||
|
||||
/* Used for animating height */
|
||||
.extra-max-height {
|
||||
max-height: 100rem;
|
||||
}
|
||||
|
||||
.hide-scrollbar {
|
||||
-ms-overflow-style: none; /* IE and Edge */
|
||||
scrollbar-width: none; /* Firefox */
|
||||
}
|
||||
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
}
|
||||
|
||||
/* Hide scrollbar for Chrome, Safari and Opera */
|
||||
.hide-scrollbar::-webkit-scrollbar {
|
||||
display: none;
|
||||
|
||||
@@ -7,6 +7,7 @@ module.exports = {
|
||||
extend: {
|
||||
transitionProperty: {
|
||||
'max-height': 'max-height',
|
||||
width: 'width',
|
||||
},
|
||||
fontFamily: {
|
||||
sans: ['Inter var', ...defaultTheme.fontFamily.sans],
|
||||
@@ -61,7 +62,7 @@ module.exports = {
|
||||
padding: ['first', 'last', 'responsive'],
|
||||
borderWidth: ['first', 'last'],
|
||||
margin: ['first', 'last', 'responsive'],
|
||||
boxShadow: ['group-focus'],
|
||||
boxShadow: ['group-focus', 'responsive'],
|
||||
opacity: ['disabled', 'hover', 'group-hover'],
|
||||
ringColor: ['focus', 'focus-within', 'hover', 'active'],
|
||||
scale: ['hover', 'focus', 'group-hover'],
|
||||
|
||||
353
yarn.lock
353
yarn.lock
@@ -1034,6 +1034,13 @@
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/runtime@^7.1.2", "@babel/runtime@^7.12.18":
|
||||
version "7.13.10"
|
||||
resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.13.10.tgz#47d42a57b6095f4468da440388fdbad8bebf0d7d"
|
||||
integrity sha512-4QPkjJq6Ns3V/RgpEahRk+AGfL0eO6RHHtTWoNNr5mO49G6B5+X6d6THgWEAvTrznU5xYpbAlVKRYcsCgh/Akw==
|
||||
dependencies:
|
||||
regenerator-runtime "^0.13.4"
|
||||
|
||||
"@babel/template@^7.10.4":
|
||||
version "7.10.4"
|
||||
resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278"
|
||||
@@ -2004,6 +2011,16 @@
|
||||
lodash.merge "^4.6.2"
|
||||
lodash.uniq "^4.5.0"
|
||||
|
||||
"@tanem/react-nprogress@^3.0.57":
|
||||
version "3.0.57"
|
||||
resolved "https://registry.yarnpkg.com/@tanem/react-nprogress/-/react-nprogress-3.0.57.tgz#926f0477574659dcbaa4d892743a11dac675c81b"
|
||||
integrity sha512-hYNDAENoAQK3LttNs4IfWF4ByLoAaxJ/rxBTXeTR+x4kk5lLdRBqR0rcU6XrX0oyx+mXLqJk5IXterui6usBfg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.12.18"
|
||||
hoist-non-react-statics "^3.3.2"
|
||||
prop-types "^15.7.2"
|
||||
react-use "^15.3.8"
|
||||
|
||||
"@tootallnate/once@1":
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/@tootallnate/once/-/once-1.1.2.tgz#ccb91445360179a04e7fe6aff78c00ffc1eeaf82"
|
||||
@@ -2191,6 +2208,11 @@
|
||||
resolved "https://registry.yarnpkg.com/@types/html-to-text/-/html-to-text-5.1.2.tgz#59a723cce41b573b7fa606414e2ceaa886038098"
|
||||
integrity sha512-56PHFwRe18fmZ+UsN6GqUaoKfalOwFzxaBMRA2O5URde3d5mxdH1HvnIV7LSugCiO8JWlRdSL2L3xJXykCTKVg==
|
||||
|
||||
"@types/js-cookie@2.2.6":
|
||||
version "2.2.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/js-cookie/-/js-cookie-2.2.6.tgz#f1a1cb35aff47bc5cfb05cb0c441ca91e914c26f"
|
||||
integrity sha512-+oY0FDTO2GYKEV0YPvSshGq9t7YozVkgvXLty7zogQNuCxBhT9/3INX9Q7H1aRZ4SUDRXAKlJuA4EA5nTt7SNw==
|
||||
|
||||
"@types/json-schema@*", "@types/json-schema@^7.0.5", "@types/json-schema@^7.0.6":
|
||||
version "7.0.6"
|
||||
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.6.tgz#f4c7ec43e81b319a9815115031709f26987891f0"
|
||||
@@ -2247,25 +2269,15 @@
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
"@types/node@*":
|
||||
version "14.10.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.10.0.tgz#15815dff82c8dc30827f6b1286f865902945095a"
|
||||
integrity sha512-SOIyrdADB4cq6eY1F+9iU48iIomFAPltu11LCvA9PKcyEwHadjCFzNVPotAR+oEJA0bCP4Xvvgy+vwu1ZjVh8g==
|
||||
"@types/node@*", "@types/node@>= 8", "@types/node@^14.14.34":
|
||||
version "14.14.34"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.34.tgz#07935194fc049069a1c56c0c274265abeddf88da"
|
||||
integrity sha512-dBPaxocOK6UVyvhbnpFIj2W+S+1cBTkHQbFQfeeJhoKFbzYcVUGHvddeWPSucKATb3F0+pgDq0i6ghEaZjsugA==
|
||||
|
||||
"@types/node@>= 8":
|
||||
version "14.14.10"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.10.tgz#5958a82e41863cfc71f2307b3748e3491ba03785"
|
||||
integrity sha512-J32dgx2hw8vXrSbu4ZlVhn1Nm3GbeCFNw2FWL8S5QKucHGY0cyNwjdQdO+KMBZ4wpmC7KhLCiNsdk1RFRIYUQQ==
|
||||
|
||||
"@types/node@^14.14.33":
|
||||
version "14.14.33"
|
||||
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.33.tgz#9e4f8c64345522e4e8ce77b334a8aaa64e2b6c78"
|
||||
integrity sha512-oJqcTrgPUF29oUP8AsUqbXGJNuPutsetaa9kTQAQce5Lx5dTYWV02ScBiT/k1BX/Z7pKeqedmvp39Wu4zR7N7g==
|
||||
|
||||
"@types/nodemailer@*", "@types/nodemailer@^6.4.0":
|
||||
version "6.4.0"
|
||||
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.0.tgz#d8c039be3ed685c4719a026455555be82c124b74"
|
||||
integrity sha512-KY7bFWB0MahRZvVW4CuW83qcCDny59pJJ0MQ5ifvfcjNwPlIT0vW4uARO4u1gtkYnWdhSvURegecY/tzcukJcA==
|
||||
"@types/nodemailer@*", "@types/nodemailer@^6.4.1":
|
||||
version "6.4.1"
|
||||
resolved "https://registry.yarnpkg.com/@types/nodemailer/-/nodemailer-6.4.1.tgz#31f96f4410632f781d3613bd1f4293649e423f75"
|
||||
integrity sha512-8081UY/0XTTDpuGqCnDc8IY+Q3DSg604wB3dBH0CaZlj4nZWHWuxtZ3NRZ9c9WUrz1Vfm6wioAUnqL3bsh49uQ==
|
||||
dependencies:
|
||||
"@types/node" "*"
|
||||
|
||||
@@ -2643,6 +2655,11 @@
|
||||
"@webassemblyjs/wast-parser" "1.9.0"
|
||||
"@xtuc/long" "4.2.2"
|
||||
|
||||
"@xobotyi/scrollbar-width@1.9.5":
|
||||
version "1.9.5"
|
||||
resolved "https://registry.yarnpkg.com/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz#80224a6919272f405b87913ca13b92929bdf3c4d"
|
||||
integrity sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==
|
||||
|
||||
"@xtuc/ieee754@^1.2.0":
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/@xtuc/ieee754/-/ieee754-1.2.0.tgz#eef014a3145ae477a1cbc00cd1e552336dceb790"
|
||||
@@ -3050,7 +3067,7 @@ asap@^2.0.0, asap@~2.0.3:
|
||||
resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.6.tgz#e50347611d7e690943208bbdafebcbc2fb866d46"
|
||||
integrity sha1-5QNHYR1+aQlDIIu9r+vLwvuGbUY=
|
||||
|
||||
asn1.js@^5.2.0:
|
||||
asn1.js@^5.0.0, asn1.js@^5.2.0:
|
||||
version "5.4.1"
|
||||
resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-5.4.1.tgz#11a980b84ebb91781ce35b0fdc2ee294e3783f07"
|
||||
integrity sha512-+I//4cYPccV8LdmBLiX8CYvf9Sp3vQsrqu2QNXRcrbiWvcx/UdlFiqUJJzxRQxgsZmvhXhn4cSKeSmoFjVdupA==
|
||||
@@ -4602,7 +4619,7 @@ copy-descriptor@^0.1.0:
|
||||
resolved "https://registry.yarnpkg.com/copy-descriptor/-/copy-descriptor-0.1.1.tgz#676f6eb3c39997c2ee1ac3a924fd6124748f578d"
|
||||
integrity sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=
|
||||
|
||||
copy-to-clipboard@^3.3.1:
|
||||
copy-to-clipboard@^3.2.0, copy-to-clipboard@^3.3.1:
|
||||
version "3.3.1"
|
||||
resolved "https://registry.yarnpkg.com/copy-to-clipboard/-/copy-to-clipboard-3.3.1.tgz#115aa1a9998ffab6196f93076ad6da3b913662ae"
|
||||
integrity sha512-i13qo6kIHTTpCm8/Wup+0b1mVWETvu2kIMzKoK8FpkLkFxlt0znUAHcMzox+T8sPlqtZXq3CulEjQHsYiGFJUw==
|
||||
@@ -4749,17 +4766,6 @@ cross-spawn@^5.0.1:
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^6.0.0:
|
||||
version "6.0.5"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-6.0.5.tgz#4a5ec7c64dfae22c3a14124dbacdee846d80cbc4"
|
||||
integrity sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==
|
||||
dependencies:
|
||||
nice-try "^1.0.4"
|
||||
path-key "^2.0.1"
|
||||
semver "^5.5.0"
|
||||
shebang-command "^1.2.0"
|
||||
which "^1.2.9"
|
||||
|
||||
cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3:
|
||||
version "7.0.3"
|
||||
resolved "https://registry.yarnpkg.com/cross-spawn/-/cross-spawn-7.0.3.tgz#f73a85b9d5d41d045551c177e2882d4ac85728a6"
|
||||
@@ -4820,6 +4826,14 @@ css-has-pseudo@^0.10.0:
|
||||
postcss "^7.0.6"
|
||||
postcss-selector-parser "^5.0.0-rc.4"
|
||||
|
||||
css-in-js-utils@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/css-in-js-utils/-/css-in-js-utils-2.0.1.tgz#3b472b398787291b47cfe3e44fecfdd9e914ba99"
|
||||
integrity sha512-PJF0SpJT+WdbVVt0AOYp9C8GnuruRlL/UFW7932nLWmFLQTaWEzTBQEx7/hn4BuV+WON75iAViSUJLiU3PKbpA==
|
||||
dependencies:
|
||||
hyphenate-style-name "^1.0.2"
|
||||
isobject "^3.0.1"
|
||||
|
||||
css-loader@4.3.0:
|
||||
version "4.3.0"
|
||||
resolved "https://registry.yarnpkg.com/css-loader/-/css-loader-4.3.0.tgz#c888af64b2a5b2e85462c72c0f4a85c7e2e0821e"
|
||||
@@ -4886,6 +4900,14 @@ css-tree@1.0.0-alpha.39:
|
||||
mdn-data "2.0.6"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-tree@^1.1.2:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.2.tgz#9ae393b5dafd7dae8a622475caec78d3d8fbd7b5"
|
||||
integrity sha512-wCoWush5Aeo48GLhfHPbmvZs59Z+M7k5+B1xDnXbdWNcEF423DoFdqSWE0PM5aNk5nI5cp1q7ms36zGApY/sKQ==
|
||||
dependencies:
|
||||
mdn-data "2.0.14"
|
||||
source-map "^0.6.1"
|
||||
|
||||
css-unit-converter@^1.1.1:
|
||||
version "1.1.2"
|
||||
resolved "https://registry.yarnpkg.com/css-unit-converter/-/css-unit-converter-1.1.2.tgz#4c77f5a1954e6dbff60695ecb214e3270436ab21"
|
||||
@@ -4980,6 +5002,11 @@ csstype@^3.0.2:
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.2.tgz#ee5ff8f208c8cd613b389f7b222c9801ca62b3f7"
|
||||
integrity sha512-ofovWglpqoqbfLNOTBNZLSbMuGrblAf1efvvArGKOZMBrIoJeu5UsAipQolkijtyQx5MtAzT/J9IHj/CEY1mJw==
|
||||
|
||||
csstype@^3.0.6:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.0.7.tgz#2a5fb75e1015e84dd15692f71e89a1450290950b"
|
||||
integrity sha512-KxnUB0ZMlnUWCsx2Z8MUsr6qV6ja1w9ArPErJaJaF8a5SOWoHLIszeCTKGRGRgtLgYrs1E8CHkNSP1VZTTPc9g==
|
||||
|
||||
csurf@^1.11.0:
|
||||
version "1.11.0"
|
||||
resolved "https://registry.yarnpkg.com/csurf/-/csurf-1.11.0.tgz#ab0c3c6634634192bd3d6f4b861be20800eeb61a"
|
||||
@@ -5079,34 +5106,20 @@ debug@3.1.0:
|
||||
dependencies:
|
||||
ms "2.0.0"
|
||||
|
||||
debug@4, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1:
|
||||
version "4.1.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791"
|
||||
integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^3.1.0:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^3.2.6:
|
||||
version "3.2.6"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.6.tgz#e83d17de16d8a7efb7717edbe5fb10135eee629b"
|
||||
integrity sha512-mel+jf7nrtEl5Pn1Qx46zARXKDpBbvzezse7p7LqINmdoIk8PYP5SySaxEmYv6TZ0JyEKA1hsCId6DIhgITtWQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debug@^4.0.0, debug@^4.2.0, debug@^4.3.1:
|
||||
debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.2.0, debug@^4.3.1:
|
||||
version "4.3.1"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee"
|
||||
integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==
|
||||
dependencies:
|
||||
ms "2.1.2"
|
||||
|
||||
debug@^3.1.0, debug@^3.2.6:
|
||||
version "3.2.7"
|
||||
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
|
||||
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
|
||||
dependencies:
|
||||
ms "^2.1.1"
|
||||
|
||||
debuglog@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492"
|
||||
@@ -5729,6 +5742,13 @@ error-ex@^1.2.0, error-ex@^1.3.1:
|
||||
dependencies:
|
||||
is-arrayish "^0.2.1"
|
||||
|
||||
error-stack-parser@^2.0.6:
|
||||
version "2.0.6"
|
||||
resolved "https://registry.yarnpkg.com/error-stack-parser/-/error-stack-parser-2.0.6.tgz#5a99a707bd7a4c58a797902d48d82803ede6aad8"
|
||||
integrity sha512-d51brTeqC+BHlwF0BhPtcYgF5nlzf9ZZ0ZIUQNZpc9ZB9qw5IJ2diTrBY9jlCJkTLITYPjmiX6OWCwH+fuyNgQ==
|
||||
dependencies:
|
||||
stackframe "^1.1.1"
|
||||
|
||||
es-abstract@^1.17.0, es-abstract@^1.17.0-next.1, es-abstract@^1.17.2, es-abstract@^1.17.5:
|
||||
version "1.17.6"
|
||||
resolved "https://registry.yarnpkg.com/es-abstract/-/es-abstract-1.17.6.tgz#9142071707857b2cacc7b89ecb670316c3e2d52a"
|
||||
@@ -6056,19 +6076,6 @@ evp_bytestokey@^1.0.0, evp_bytestokey@^1.0.3:
|
||||
md5.js "^1.3.4"
|
||||
safe-buffer "^5.1.1"
|
||||
|
||||
execa@^0.10.0:
|
||||
version "0.10.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-0.10.0.tgz#ff456a8f53f90f8eccc71a96d11bdfc7f082cb50"
|
||||
integrity sha512-7XOMnz8Ynx1gGo/3hyV9loYNPWM94jG3+3T3Y8tsfSstFmETmENCMU/A/zj8Lyaj1lkgEepKepvd6240tBRvlw==
|
||||
dependencies:
|
||||
cross-spawn "^6.0.0"
|
||||
get-stream "^3.0.0"
|
||||
is-stream "^1.1.0"
|
||||
npm-run-path "^2.0.0"
|
||||
p-finally "^1.0.0"
|
||||
signal-exit "^3.0.0"
|
||||
strip-eof "^1.0.0"
|
||||
|
||||
execa@^0.7.0:
|
||||
version "0.7.0"
|
||||
resolved "https://registry.yarnpkg.com/execa/-/execa-0.7.0.tgz#944becd34cc41ee32a63a9faf27ad5a65fc59777"
|
||||
@@ -6286,7 +6293,7 @@ extsprintf@^1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
|
||||
integrity sha1-4mifjzVvrWLMplo6kcXfX5VRaS8=
|
||||
|
||||
fast-deep-equal@^3.1.1:
|
||||
fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3:
|
||||
version "3.1.3"
|
||||
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz#3a7d56b559d6cbc3eb512325244e619a65c6c525"
|
||||
integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==
|
||||
@@ -6328,6 +6335,16 @@ fast-safe-stringify@^2.0.4:
|
||||
resolved "https://registry.yarnpkg.com/fast-safe-stringify/-/fast-safe-stringify-2.0.7.tgz#124aa885899261f68aedb42a7c080de9da608743"
|
||||
integrity sha512-Utm6CdzT+6xsDk2m8S6uL8VHxNwI6Jub+e9NYTcAms28T84pTa25GJQV9j0CY0N1rM8hK4x6grpF2BQf+2qwVA==
|
||||
|
||||
fast-shallow-equal@^1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fast-shallow-equal/-/fast-shallow-equal-1.0.0.tgz#d4dcaf6472440dcefa6f88b98e3251e27f25628b"
|
||||
integrity sha512-HPtaa38cPgWvaCFmRNhlc6NG7pv6NUHqjPgVAkWGoB9mQMwYB27/K0CvOM5Czy+qpT3e8XJ6Q4aPAnzpNpzNaw==
|
||||
|
||||
fastest-stable-stringify@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/fastest-stable-stringify/-/fastest-stable-stringify-2.0.2.tgz#3757a6774f6ec8de40c4e86ec28ea02417214c76"
|
||||
integrity sha512-bijHueCGd0LqqNK9b5oCMHc0MluJAx0cwqASgbWMvkO01lCYgIhacVRLcaDz3QnyYIRNJRDwMb41VuT6pHJ91Q==
|
||||
|
||||
fastq@^1.6.0:
|
||||
version "1.8.0"
|
||||
resolved "https://registry.yarnpkg.com/fastq/-/fastq-1.8.0.tgz#550e1f9f59bbc65fe185cb6a9b4d95357107f481"
|
||||
@@ -7152,13 +7169,20 @@ hosted-git-info@^2.1.4, hosted-git-info@^2.7.1, hosted-git-info@^2.8.8:
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.8.8.tgz#7539bd4bc1e0e0a895815a2e0262420b12858488"
|
||||
integrity sha512-f/wzC2QaWBs7t9IYqB4T3sR1xviIViXJRJTWBlx2Gf3g0Xi5vI7Yy4koXQ1c9OYDGHN9sBy1DQ2AB8fqZBWhUg==
|
||||
|
||||
hosted-git-info@^3.0.0, hosted-git-info@^3.0.6:
|
||||
hosted-git-info@^3.0.6:
|
||||
version "3.0.7"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-3.0.7.tgz#a30727385ea85acfcee94e0aad9e368c792e036c"
|
||||
integrity sha512-fWqc0IcuXs+BmE9orLDyVykAG9GJtGLGuZAAqgcckPgv5xad4AcXGIv8galtQvlwutxSlaMcdw7BUtq2EIvqCQ==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
hosted-git-info@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-4.0.0.tgz#9f06639a90beff66cacae6e77f8387b431d61ddc"
|
||||
integrity sha512-fqhGdjk4av7mT9fU/B01dUtZ+WZSc/XEXMoLXDVZukiQRXxeHSSz3AqbeWRJHtF8EQYHlAgB1NSAHU0Cm7aqZA==
|
||||
dependencies:
|
||||
lru-cache "^6.0.0"
|
||||
|
||||
html-tags@^3.1.0:
|
||||
version "3.1.0"
|
||||
resolved "https://registry.yarnpkg.com/html-tags/-/html-tags-3.1.0.tgz#7b5e6f7e665e9fb41f30007ed9e0d41e97fb2140"
|
||||
@@ -7329,6 +7353,11 @@ husky@4.3.8:
|
||||
slash "^3.0.0"
|
||||
which-pm-runs "^1.0.0"
|
||||
|
||||
hyphenate-style-name@^1.0.2:
|
||||
version "1.0.4"
|
||||
resolved "https://registry.yarnpkg.com/hyphenate-style-name/-/hyphenate-style-name-1.0.4.tgz#691879af8e220aea5750e8827db4ef62a54e361d"
|
||||
integrity sha512-ygGZLjmXfPHj+ZWh6LwbC37l43MhfztxetbFCoYTM2VjkIUpeHgSNn7QIyVFj7YQ1Wl9Cbw5sholVJPzWvC2MQ==
|
||||
|
||||
i18n-locales@^0.0.4:
|
||||
version "0.0.4"
|
||||
resolved "https://registry.yarnpkg.com/i18n-locales/-/i18n-locales-0.0.4.tgz#95d6505f6563f870f68860c23d35f82bd805cbf5"
|
||||
@@ -7500,6 +7529,13 @@ init-package-json@^1.10.3:
|
||||
validate-npm-package-license "^3.0.1"
|
||||
validate-npm-package-name "^3.0.0"
|
||||
|
||||
inline-style-prefixer@^6.0.0:
|
||||
version "6.0.0"
|
||||
resolved "https://registry.yarnpkg.com/inline-style-prefixer/-/inline-style-prefixer-6.0.0.tgz#f73d5dbf2855733d6b153a4d24b7b47a73e9770b"
|
||||
integrity sha512-XTHvRUS4ZJNzC1GixJRmOlWSS45fSt+DJoyQC9ytj0WxQfcgofQtDtyKKYxHUqEsWCs+LIWftPF1ie7+i012Fg==
|
||||
dependencies:
|
||||
css-in-js-utils "^2.0.0"
|
||||
|
||||
inquirer@6.5.2:
|
||||
version "6.5.2"
|
||||
resolved "https://registry.yarnpkg.com/inquirer/-/inquirer-6.5.2.tgz#ad50942375d036d327ff528c08bd5fab089928ca"
|
||||
@@ -8051,6 +8087,11 @@ jest-worker@24.9.0:
|
||||
merge-stream "^2.0.0"
|
||||
supports-color "^6.1.0"
|
||||
|
||||
js-cookie@^2.2.1:
|
||||
version "2.2.1"
|
||||
resolved "https://registry.yarnpkg.com/js-cookie/-/js-cookie-2.2.1.tgz#69e106dc5d5806894562902aa5baec3744e9b2b8"
|
||||
integrity sha512-HvdH2LzI/EAZcUwA8+0nKNtWHqS+ZmijLA30RwZA0bo7ToCckjK5MkGhjED9KoRcXO6BaGI3I9UIzSA1FKFPOQ==
|
||||
|
||||
js-stringify@^1.0.2:
|
||||
version "1.0.2"
|
||||
resolved "https://registry.yarnpkg.com/js-stringify/-/js-stringify-1.0.2.tgz#1736fddfd9724f28a3682adc6230ae7e4e9679db"
|
||||
@@ -8772,12 +8813,7 @@ lodash.zipobject@^4.1.3:
|
||||
resolved "https://registry.yarnpkg.com/lodash.zipobject/-/lodash.zipobject-4.1.3.tgz#b399f5aba8ff62a746f6979bf20b214f964dbef8"
|
||||
integrity sha1-s5n1q6j/YqdG9peb8gshT5ZNvvg=
|
||||
|
||||
lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.4:
|
||||
version "4.17.20"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52"
|
||||
integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA==
|
||||
|
||||
lodash@^4.17.21:
|
||||
lodash@^4.0.0, lodash@^4.15.0, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@^4.17.4:
|
||||
version "4.17.21"
|
||||
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.21.tgz#679591c564c3bffaae8454cf0b3df370c3d6911c"
|
||||
integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==
|
||||
@@ -9027,6 +9063,11 @@ mdast-util-to-string@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz#b8cfe6a713e1091cb5b728fc48885a4767f8b97b"
|
||||
integrity sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==
|
||||
|
||||
mdn-data@2.0.14:
|
||||
version "2.0.14"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
|
||||
integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
|
||||
|
||||
mdn-data@2.0.4:
|
||||
version "2.0.4"
|
||||
resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.4.tgz#699b3c38ac6f1d728091a64650b65d388502fd5b"
|
||||
@@ -9483,6 +9524,20 @@ nan@^2.12.1:
|
||||
resolved "https://registry.yarnpkg.com/nan/-/nan-2.14.2.tgz#f5376400695168f4cc694ac9393d0c9585eeea19"
|
||||
integrity sha512-M2ufzIiINKCuDfBSAUr1vWQ+vuVcA9kqx8JJUsbQi6yf1uGRyb7HfpdfUr5qLXf3B/t8dPvcjhKMmlfnP47EzQ==
|
||||
|
||||
nano-css@^5.2.1:
|
||||
version "5.3.1"
|
||||
resolved "https://registry.yarnpkg.com/nano-css/-/nano-css-5.3.1.tgz#b709383e07ad3be61f64edffacb9d98250b87a1f"
|
||||
integrity sha512-ENPIyNzANQRyYVvb62ajDd7PAyIgS2LIUnT9ewih4yrXSZX4hKoUwssy8WjUH++kEOA5wUTMgNnV7ko5n34kUA==
|
||||
dependencies:
|
||||
css-tree "^1.1.2"
|
||||
csstype "^3.0.6"
|
||||
fastest-stable-stringify "^2.0.2"
|
||||
inline-style-prefixer "^6.0.0"
|
||||
rtl-css-js "^1.14.0"
|
||||
sourcemap-codec "^1.4.8"
|
||||
stacktrace-js "^2.0.2"
|
||||
stylis "^4.0.6"
|
||||
|
||||
nanoclone@^0.2.1:
|
||||
version "0.2.1"
|
||||
resolved "https://registry.yarnpkg.com/nanoclone/-/nanoclone-0.2.1.tgz#dd4090f8f1a110d26bb32c49ed2f5b9235209ed4"
|
||||
@@ -9613,11 +9668,6 @@ next@10.0.3:
|
||||
optionalDependencies:
|
||||
sharp "0.26.2"
|
||||
|
||||
nice-try@^1.0.4:
|
||||
version "1.0.5"
|
||||
resolved "https://registry.yarnpkg.com/nice-try/-/nice-try-1.0.5.tgz#a3378a7696ce7d223e88fc9b764bd7ef1089e366"
|
||||
integrity sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==
|
||||
|
||||
node-abi@^2.7.0:
|
||||
version "2.19.3"
|
||||
resolved "https://registry.yarnpkg.com/node-abi/-/node-abi-2.19.3.tgz#252f5dcab12dad1b5503b2d27eddd4733930282d"
|
||||
@@ -10339,6 +10389,13 @@ opener@^1.5.1:
|
||||
resolved "https://registry.yarnpkg.com/opener/-/opener-1.5.2.tgz#5d37e1f35077b9dcac4301372271afdeb2a13598"
|
||||
integrity sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==
|
||||
|
||||
openpgp@^5.0.0-1:
|
||||
version "5.0.0-1"
|
||||
resolved "https://registry.yarnpkg.com/openpgp/-/openpgp-5.0.0-1.tgz#28456d930895483770f099e373045e3ce9dbf9f9"
|
||||
integrity sha512-yfmRStdmOQPZbNbvwyQrqjLOTGW4QO0/aok/Vt08Zhf4UB9w0tGA5c6zBxDefxq+SmXlqEsmdNu+AtYx5G8D6A==
|
||||
dependencies:
|
||||
asn1.js "^5.0.0"
|
||||
|
||||
optionator@^0.9.1:
|
||||
version "0.9.1"
|
||||
resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.9.1.tgz#4f236a6373dae0566a6d43e1326674f50c291499"
|
||||
@@ -10698,7 +10755,7 @@ path-is-inside@^1.0.1, path-is-inside@^1.0.2, path-is-inside@~1.0.2:
|
||||
resolved "https://registry.yarnpkg.com/path-is-inside/-/path-is-inside-1.0.2.tgz#365417dede44430d1c11af61027facf074bdfc53"
|
||||
integrity sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=
|
||||
|
||||
path-key@^2.0.0, path-key@^2.0.1:
|
||||
path-key@^2.0.0:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/path-key/-/path-key-2.0.1.tgz#411cadb574c5a140d3a4b1910d40d80cc9f40b40"
|
||||
integrity sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=
|
||||
@@ -11897,6 +11954,11 @@ react-truncate-markup@^5.1.0:
|
||||
prop-types "^15.6.0"
|
||||
resize-observer-polyfill "1.5.x"
|
||||
|
||||
react-universal-interface@^0.6.2:
|
||||
version "0.6.2"
|
||||
resolved "https://registry.yarnpkg.com/react-universal-interface/-/react-universal-interface-0.6.2.tgz#5e8d438a01729a4dbbcbeeceb0b86be146fe2b3b"
|
||||
integrity sha512-dg8yXdcQmvgR13RIlZbTRQOoUrDciFVoSBZILwjE2LFISxZZ8loVJKAkuzswl5js8BHda79bIb2b84ehU8IjXw==
|
||||
|
||||
react-use-clipboard@1.0.7:
|
||||
version "1.0.7"
|
||||
resolved "https://registry.yarnpkg.com/react-use-clipboard/-/react-use-clipboard-1.0.7.tgz#34cccdfb4f17f5e6522e38f2cee62d05f605597a"
|
||||
@@ -11904,6 +11966,26 @@ react-use-clipboard@1.0.7:
|
||||
dependencies:
|
||||
copy-to-clipboard "^3.3.1"
|
||||
|
||||
react-use@^15.3.8:
|
||||
version "15.3.8"
|
||||
resolved "https://registry.yarnpkg.com/react-use/-/react-use-15.3.8.tgz#ca839ac7fb3d696e5ccbeabbc8dadc2698969d30"
|
||||
integrity sha512-GeGcrmGuUvZrY5wER3Lnph9DSYhZt5nEjped4eKDq8BRGr2CnLf9bDQWG9RFc7oCPphnscUUdOovzq0E5F2c6Q==
|
||||
dependencies:
|
||||
"@types/js-cookie" "2.2.6"
|
||||
"@xobotyi/scrollbar-width" "1.9.5"
|
||||
copy-to-clipboard "^3.2.0"
|
||||
fast-deep-equal "^3.1.3"
|
||||
fast-shallow-equal "^1.0.0"
|
||||
js-cookie "^2.2.1"
|
||||
nano-css "^5.2.1"
|
||||
react-universal-interface "^0.6.2"
|
||||
resize-observer-polyfill "^1.5.1"
|
||||
screenfull "^5.0.0"
|
||||
set-harmonic-interval "^1.0.1"
|
||||
throttle-debounce "^2.1.0"
|
||||
ts-easing "^0.2.0"
|
||||
tslib "^2.0.0"
|
||||
|
||||
react@17.0.1:
|
||||
version "17.0.1"
|
||||
resolved "https://registry.yarnpkg.com/react/-/react-17.0.1.tgz#6e0600416bd57574e3f86d92edba3d9008726127"
|
||||
@@ -12301,7 +12383,7 @@ require-main-filename@^2.0.0:
|
||||
resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b"
|
||||
integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==
|
||||
|
||||
resize-observer-polyfill@1.5.x:
|
||||
resize-observer-polyfill@1.5.x, resize-observer-polyfill@^1.5.1:
|
||||
version "1.5.1"
|
||||
resolved "https://registry.yarnpkg.com/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz#0e9020dd3d21024458d4ebd27e23e40269810464"
|
||||
integrity sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==
|
||||
@@ -12450,6 +12532,13 @@ rndm@1.2.0:
|
||||
resolved "https://registry.yarnpkg.com/rndm/-/rndm-1.2.0.tgz#f33fe9cfb52bbfd520aa18323bc65db110a1b76c"
|
||||
integrity sha1-8z/pz7Urv9UgqhgyO8ZdsRCht2w=
|
||||
|
||||
rtl-css-js@^1.14.0:
|
||||
version "1.14.0"
|
||||
resolved "https://registry.yarnpkg.com/rtl-css-js/-/rtl-css-js-1.14.0.tgz#daa4f192a92509e292a0519f4b255e6e3c076b7d"
|
||||
integrity sha512-Dl5xDTeN3e7scU1cWX8c9b6/Nqz3u/HgR4gePc1kWXYiQWVQbKCEyK6+Hxve9LbcJ5EieHy1J9nJCN3grTtGwg==
|
||||
dependencies:
|
||||
"@babel/runtime" "^7.1.2"
|
||||
|
||||
run-async@^2.2.0:
|
||||
version "2.4.1"
|
||||
resolved "https://registry.yarnpkg.com/run-async/-/run-async-2.4.1.tgz#8440eccf99ea3e70bd409d49aab88e10c189a455"
|
||||
@@ -12559,6 +12648,11 @@ schema-utils@^1.0.0:
|
||||
ajv-errors "^1.0.0"
|
||||
ajv-keywords "^3.1.0"
|
||||
|
||||
screenfull@^5.0.0:
|
||||
version "5.1.0"
|
||||
resolved "https://registry.yarnpkg.com/screenfull/-/screenfull-5.1.0.tgz#85c13c70f4ead4c1b8a935c70010dfdcd2c0e5c8"
|
||||
integrity sha512-dYaNuOdzr+kc6J6CFcBrzkLCfyGcMg+gWkJ8us93IQ7y1cevhQAugFsaCdMHb6lw8KV3xPzSxzH7zM1dQap9mA==
|
||||
|
||||
secure-random-password@^0.2.2:
|
||||
version "0.2.2"
|
||||
resolved "https://registry.yarnpkg.com/secure-random-password/-/secure-random-password-0.2.2.tgz#eb043bcada24bc372bc98457845222b2a96d2058"
|
||||
@@ -12571,18 +12665,17 @@ secure-random@^1.1.2:
|
||||
resolved "https://registry.yarnpkg.com/secure-random/-/secure-random-1.1.2.tgz#ed103b460a851632d420d46448b2a900a41e7f7c"
|
||||
integrity sha512-H2bdSKERKdBV1SwoqYm6C0y+9EA94v6SUBOWO8kDndc4NoUih7Dv6Tsgma7zO1lv27wIvjlD0ZpMQk7um5dheQ==
|
||||
|
||||
semantic-release-docker@^2.2.0:
|
||||
version "2.2.0"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release-docker/-/semantic-release-docker-2.2.0.tgz#9a5e1c8b4fe2b85063e1dc64e15550e7bf26c26f"
|
||||
integrity sha512-p5pZuyD05ax2OIJY3MTa9ekPbnR7hw3Pzv79sDELx4/MwHdkxjoLNsbNHnH4RNfgyRYGUfnS3R0CnYv3e713FQ==
|
||||
semantic-release-docker-buildx@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release-docker-buildx/-/semantic-release-docker-buildx-1.0.1.tgz#9d63ee60638905bd4caba6e15190f091de4ded67"
|
||||
integrity sha512-DU5OCNM2cDpjM1Gr83jJnPgxryQysPno9cvDbs0AY8NwUL/nZc5mZn59UZB9BjHtSKsjKX1pgRb0bFd7LWJOOQ==
|
||||
dependencies:
|
||||
"@semantic-release/error" "^2.1.0"
|
||||
execa "^0.10.0"
|
||||
execa "^5.0.0"
|
||||
|
||||
semantic-release@^17.4.1:
|
||||
version "17.4.1"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.4.1.tgz#71b89a772452f8cd3bbd55bbf99287630be1c81f"
|
||||
integrity sha512-o/Rjk0HCBUWEYxN99Vq04Th+XtRQAxbC+FN+pBQ49wpqQ5NW/cfwhfw0qyxeTEhbchQ/1/KGMPWqD4/rRScAag==
|
||||
semantic-release@^17.4.2:
|
||||
version "17.4.2"
|
||||
resolved "https://registry.yarnpkg.com/semantic-release/-/semantic-release-17.4.2.tgz#b5147b5a629c227b7074ad4cc89920a14cb08c96"
|
||||
integrity sha512-TPLWuoe2L2DmgnQEh+OLWW5V1T+ZAa1xWuHXsuPAWEko0BqSdLPl+5+BlQ+D5Bp27S5gDJ1//Y1tgbmvUhnOCw==
|
||||
dependencies:
|
||||
"@semantic-release/commit-analyzer" "^8.0.0"
|
||||
"@semantic-release/error" "^2.2.0"
|
||||
@@ -12599,7 +12692,7 @@ semantic-release@^17.4.1:
|
||||
get-stream "^6.0.0"
|
||||
git-log-parser "^1.2.0"
|
||||
hook-std "^2.0.0"
|
||||
hosted-git-info "^3.0.0"
|
||||
hosted-git-info "^4.0.0"
|
||||
lodash "^4.17.15"
|
||||
marked "^2.0.0"
|
||||
marked-terminal "^4.1.1"
|
||||
@@ -12647,7 +12740,7 @@ semver@7.0.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e"
|
||||
integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A==
|
||||
|
||||
semver@7.3.4, semver@^7.1.2, semver@^7.3.4:
|
||||
semver@7.3.4, semver@^7.1.2, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4:
|
||||
version "7.3.4"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.4.tgz#27aaa7d2e4ca76452f98d3add093a72c943edc97"
|
||||
integrity sha512-tCfb2WLjqFAtXn4KEdxIhalnRtoKFN7nAwj0B3ZXCbQloV2tq5eDbcTmT68JJD3nRJq24/XgxtQKFIpQdtvmVw==
|
||||
@@ -12659,11 +12752,6 @@ semver@^6.0.0, semver@^6.2.0, semver@^6.3.0:
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
|
||||
integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
|
||||
|
||||
semver@^7.2.1, semver@^7.3.2:
|
||||
version "7.3.2"
|
||||
resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.2.tgz#604962b052b81ed0786aae84389ffba70ffd3938"
|
||||
integrity sha512-OrOb32TeeambH6UrhtShmF7CRDqhL6/5XpPNp2DuRH6+9QLw/orhp72j87v8Qa1ScDkvrrBNpZcDejAirJmfXQ==
|
||||
|
||||
send@0.17.1:
|
||||
version "0.17.1"
|
||||
resolved "https://registry.yarnpkg.com/send/-/send-0.17.1.tgz#c1d8b059f7900f7466dd4938bdc44e11ddb376c8"
|
||||
@@ -12710,6 +12798,11 @@ set-cookie-parser@^2.4.6:
|
||||
resolved "https://registry.yarnpkg.com/set-cookie-parser/-/set-cookie-parser-2.4.6.tgz#43bdea028b9e6f176474ee5298e758b4a44799c3"
|
||||
integrity sha512-mNCnTUF0OYPwYzSHbdRdCfNNHqrne+HS5tS5xNb6yJbdP9wInV0q5xPLE0EyfV/Q3tImo3y/OXpD8Jn0Jtnjrg==
|
||||
|
||||
set-harmonic-interval@^1.0.1:
|
||||
version "1.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-harmonic-interval/-/set-harmonic-interval-1.0.1.tgz#e1773705539cdfb80ce1c3d99e7f298bb3995249"
|
||||
integrity sha512-AhICkFV84tBP1aWqPwLZqFvAwqEoVA9kxNMniGEUvzOlm4vLmOFLiTT3UZ6bziJTy4bOVpzWGTfSCbmaayGx8g==
|
||||
|
||||
set-value@^2.0.0, set-value@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/set-value/-/set-value-2.0.1.tgz#a18d40530e6f07de4228c7defe4227af8cad005b"
|
||||
@@ -12984,6 +13077,11 @@ source-map-url@^0.4.0:
|
||||
resolved "https://registry.yarnpkg.com/source-map-url/-/source-map-url-0.4.0.tgz#3e935d7ddd73631b97659956d55128e87b5084a3"
|
||||
integrity sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=
|
||||
|
||||
source-map@0.5.6:
|
||||
version "0.5.6"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412"
|
||||
integrity sha1-dc449SvwczxafwwRjYEzSiu19BI=
|
||||
|
||||
source-map@0.6.1, source-map@^0.6.0, source-map@^0.6.1, source-map@~0.6.1:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
|
||||
@@ -13006,6 +13104,11 @@ source-map@^0.5.0, source-map@^0.5.6, source-map@^0.5.7:
|
||||
resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.7.tgz#8a039d2d1021d22d1ea14c80d8ea468ba2ef3fcc"
|
||||
integrity sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=
|
||||
|
||||
sourcemap-codec@^1.4.8:
|
||||
version "1.4.8"
|
||||
resolved "https://registry.yarnpkg.com/sourcemap-codec/-/sourcemap-codec-1.4.8.tgz#ea804bd94857402e6992d05a38ef1ae35a9ab4c4"
|
||||
integrity sha512-9NykojV5Uih4lgo5So5dtw+f0JgJX30KCNI8gwhz2J9A15wD0Ml6tjHKwf6fTSa6fAdVBdZeNOs9eJ71qCk8vA==
|
||||
|
||||
spawn-error-forwarder@~1.0.0:
|
||||
version "1.0.0"
|
||||
resolved "https://registry.yarnpkg.com/spawn-error-forwarder/-/spawn-error-forwarder-1.0.0.tgz#1afd94738e999b0346d7b9fc373be55e07577029"
|
||||
@@ -13117,11 +13220,40 @@ stable@^0.1.8:
|
||||
resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
|
||||
integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
|
||||
|
||||
stack-generator@^2.0.5:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/stack-generator/-/stack-generator-2.0.5.tgz#fb00e5b4ee97de603e0773ea78ce944d81596c36"
|
||||
integrity sha512-/t1ebrbHkrLrDuNMdeAcsvynWgoH/i4o8EGGfX7dEYDoTXOYVAkEpFdtshlvabzc6JlJ8Kf9YdFEoz7JkzGN9Q==
|
||||
dependencies:
|
||||
stackframe "^1.1.1"
|
||||
|
||||
stack-trace@0.0.x:
|
||||
version "0.0.10"
|
||||
resolved "https://registry.yarnpkg.com/stack-trace/-/stack-trace-0.0.10.tgz#547c70b347e8d32b4e108ea1a2a159e5fdde19c0"
|
||||
integrity sha1-VHxws0fo0ytOEI6hoqFZ5f3eGcA=
|
||||
|
||||
stackframe@^1.1.1:
|
||||
version "1.2.0"
|
||||
resolved "https://registry.yarnpkg.com/stackframe/-/stackframe-1.2.0.tgz#52429492d63c62eb989804c11552e3d22e779303"
|
||||
integrity sha512-GrdeshiRmS1YLMYgzF16olf2jJ/IzxXY9lhKOskuVziubpTYcYqyOwYeJKzQkwy7uN0fYSsbsC4RQaXf9LCrYA==
|
||||
|
||||
stacktrace-gps@^3.0.4:
|
||||
version "3.0.4"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-gps/-/stacktrace-gps-3.0.4.tgz#7688dc2fc09ffb3a13165ebe0dbcaf41bcf0c69a"
|
||||
integrity sha512-qIr8x41yZVSldqdqe6jciXEaSCKw1U8XTXpjDuy0ki/apyTn/r3w9hDAAQOhZdxvsC93H+WwwEu5cq5VemzYeg==
|
||||
dependencies:
|
||||
source-map "0.5.6"
|
||||
stackframe "^1.1.1"
|
||||
|
||||
stacktrace-js@^2.0.2:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-js/-/stacktrace-js-2.0.2.tgz#4ca93ea9f494752d55709a081d400fdaebee897b"
|
||||
integrity sha512-Je5vBeY4S1r/RnLydLl0TBTi3F2qdfWmYsGvtfZgEI+SCprPppaIhQf5nGcal4gI4cGpCV/duLcAzT1np6sQqg==
|
||||
dependencies:
|
||||
error-stack-parser "^2.0.6"
|
||||
stack-generator "^2.0.5"
|
||||
stacktrace-gps "^3.0.4"
|
||||
|
||||
stacktrace-parser@0.1.10:
|
||||
version "0.1.10"
|
||||
resolved "https://registry.yarnpkg.com/stacktrace-parser/-/stacktrace-parser-0.1.10.tgz#29fb0cae4e0d0b85155879402857a1639eb6051a"
|
||||
@@ -13421,6 +13553,11 @@ stylis@3.5.4:
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-3.5.4.tgz#f665f25f5e299cf3d64654ab949a57c768b73fbe"
|
||||
integrity sha512-8/3pSmthWM7lsPBKv7NXkzn2Uc9W7NotcwGNpJaa3k7WMM1XDCA4MgT5k/8BIexd5ydZdboXtU90XH9Ec4Bv/Q==
|
||||
|
||||
stylis@^4.0.6:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/stylis/-/stylis-4.0.7.tgz#412a90c28079417f3d27c028035095e4232d2904"
|
||||
integrity sha512-OFFeUXFgwnGOKvEXaSv0D0KQ5ADP0n6g3SVONx6I/85JzNZ3u50FRwB3lVIk1QO2HNdI75tbVzc4Z66Gdp9voA==
|
||||
|
||||
supports-color@^2.0.0:
|
||||
version "2.0.0"
|
||||
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
|
||||
@@ -13682,6 +13819,11 @@ thenify-all@^1.0.0:
|
||||
dependencies:
|
||||
any-promise "^1.0.0"
|
||||
|
||||
throttle-debounce@^2.1.0:
|
||||
version "2.3.0"
|
||||
resolved "https://registry.yarnpkg.com/throttle-debounce/-/throttle-debounce-2.3.0.tgz#fd31865e66502071e411817e241465b3e9c372e2"
|
||||
integrity sha512-H7oLPV0P7+jgvrk+6mwwwBDmxTaxnu9HMXmloNLXwnNO0ZxZ31Orah2n8lU1eMPvsaowP2CX+USCgyovXfdOFQ==
|
||||
|
||||
through2@^2.0.0, through2@^2.0.1, through2@^2.0.2, through2@~2.0.0:
|
||||
version "2.0.5"
|
||||
resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.5.tgz#01c1e39eb31d07cb7d03a96a70823260b23132cd"
|
||||
@@ -13868,6 +14010,11 @@ trough@^1.0.0:
|
||||
resolved "https://registry.yarnpkg.com/trough/-/trough-1.0.5.tgz#b8b639cefad7d0bb2abd37d433ff8293efa5f406"
|
||||
integrity sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==
|
||||
|
||||
ts-easing@^0.2.0:
|
||||
version "0.2.0"
|
||||
resolved "https://registry.yarnpkg.com/ts-easing/-/ts-easing-0.2.0.tgz#c8a8a35025105566588d87dbda05dd7fbfa5a4ec"
|
||||
integrity sha512-Z86EW+fFFh/IFB1fqQ3/+7Zpf9t2ebOAxNI/V6Wo7r5gqiqtxmgTlQ1qbqQcjLKYeSHPTsEmvlJUDg/EuL0uHQ==
|
||||
|
||||
ts-node@^9.1.1:
|
||||
version "9.1.1"
|
||||
resolved "https://registry.yarnpkg.com/ts-node/-/ts-node-9.1.1.tgz#51a9a450a3e959401bda5f004a72d54b936d376d"
|
||||
@@ -13890,16 +14037,16 @@ tslib@^1.10.0, tslib@^1.13.0, tslib@^1.8.1, tslib@^1.9.0:
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00"
|
||||
integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==
|
||||
|
||||
tslib@^2.0.0, tslib@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
||||
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
||||
|
||||
tslib@^2.0.1:
|
||||
version "2.0.2"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.0.2.tgz#462295631185db44b21b1ea3615b63cd1c038242"
|
||||
integrity sha512-wAH28hcEKwna96/UacuWaVspVLkg4x1aDM9JlzqaQTOFczCktkVAb5fmXChgandR1EraDPs2w8P+ozM+oafwxg==
|
||||
|
||||
tslib@^2.1.0:
|
||||
version "2.1.0"
|
||||
resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a"
|
||||
integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A==
|
||||
|
||||
tsscmp@1.0.6:
|
||||
version "1.0.6"
|
||||
resolved "https://registry.yarnpkg.com/tsscmp/-/tsscmp-1.0.6.tgz#85b99583ac3589ec4bfef825b5000aa911d605eb"
|
||||
|
||||
Reference in New Issue
Block a user