Merge branch 'details-in-card-and-add-dialog-title-change'
@@ -8,7 +8,8 @@
|
||||
> `http://192.168.78.4:8090` - correct
|
||||
>
|
||||
> `http://192.168.78.4:8090/` - wrong
|
||||
3. `yarn start`
|
||||
3. in `.env` file add TMDB api key
|
||||
4. `yarn start`
|
||||
|
||||
### Eslint
|
||||
> Prettier will fix the code every time the code is saved
|
||||
|
||||
@@ -7,7 +7,6 @@
|
||||
"@material-ui/icons": "^4.11.2",
|
||||
"axios": "^0.21.1",
|
||||
"clsx": "^1.1.1",
|
||||
"fontsource-roboto": "^4.0.0",
|
||||
"i18next": "^20.3.1",
|
||||
"i18next-browser-languagedetector": "^6.1.1",
|
||||
"lodash": "^4.17.21",
|
||||
|
||||
BIN
web/public/android-chrome-192x192.png
Normal file
|
After Width: | Height: | Size: 30 KiB |
BIN
web/public/android-chrome-512x512.png
Normal file
|
After Width: | Height: | Size: 111 KiB |
BIN
web/public/apple-touch-icon.png
Normal file
|
After Width: | Height: | Size: 28 KiB |
9
web/public/browserconfig.xml
Normal file
@@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<browserconfig>
|
||||
<msapplication>
|
||||
<tile>
|
||||
<square150x150logo src="/mstile-150x150.png"/>
|
||||
<TileColor>#da532c</TileColor>
|
||||
</tile>
|
||||
</msapplication>
|
||||
</browserconfig>
|
||||
BIN
web/public/favicon-16x16.png
Normal file
|
After Width: | Height: | Size: 1.3 KiB |
BIN
web/public/favicon-32x32.png
Normal file
|
After Width: | Height: | Size: 3.0 KiB |
BIN
web/public/favicon.ico
Normal file
|
After Width: | Height: | Size: 15 KiB |
BIN
web/public/mstile-150x150.png
Normal file
|
After Width: | Height: | Size: 19 KiB |
265
web/public/safari-pinned-tab.svg
Normal file
@@ -0,0 +1,265 @@
|
||||
<?xml version="1.0" standalone="no"?>
|
||||
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 20010904//EN"
|
||||
"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd">
|
||||
<svg version="1.0" xmlns="http://www.w3.org/2000/svg"
|
||||
width="1200.000000pt" height="1200.000000pt" viewBox="0 0 1200.000000 1200.000000"
|
||||
preserveAspectRatio="xMidYMid meet">
|
||||
<metadata>
|
||||
Created by potrace 1.14, written by Peter Selinger 2001-2017
|
||||
</metadata>
|
||||
<g transform="translate(0.000000,1200.000000) scale(0.100000,-0.100000)"
|
||||
fill="#000000" stroke="none">
|
||||
<path d="M5719 11396 c-2 -2 -58 -7 -124 -10 -66 -4 -127 -9 -135 -11 -8 -2
|
||||
-42 -7 -75 -10 -703 -70 -1491 -334 -2125 -710 -473 -281 -931 -656 -1281
|
||||
-1051 -95 -106 -113 -127 -175 -204 -565 -701 -934 -1492 -1110 -2385 -4 -19
|
||||
-31 -182 -39 -235 -10 -60 -35 -293 -42 -385 -16 -198 -8 -823 12 -923 2 -11
|
||||
7 -53 10 -94 4 -40 8 -75 10 -78 2 -3 6 -36 10 -75 3 -38 8 -72 10 -75 1 -3 6
|
||||
-27 9 -54 4 -28 14 -82 22 -120 9 -39 18 -84 21 -101 2 -16 25 -111 50 -210
|
||||
146 -582 397 -1146 736 -1655 78 -117 230 -326 287 -393 10 -12 44 -53 76 -92
|
||||
130 -156 353 -388 494 -515 265 -237 517 -428 803 -605 107 -67 154 -101 145
|
||||
-107 -7 -4 -9 -8 -4 -8 5 0 -1 -11 -14 -25 -13 -14 -19 -25 -14 -25 5 0 1 -5
|
||||
-9 -11 -9 -6 -15 -14 -12 -19 3 -4 -2 -11 -11 -14 -9 -4 -14 -13 -10 -21 3 -9
|
||||
0 -15 -9 -15 -8 0 -14 -3 -13 -8 3 -11 -23 -55 -43 -73 -10 -9 -15 -19 -11
|
||||
-23 4 -4 -1 -12 -11 -17 -9 -6 -15 -14 -12 -19 3 -4 -2 -11 -11 -14 -8 -3 -13
|
||||
-10 -9 -15 3 -6 -3 -14 -12 -20 -10 -6 -13 -11 -8 -11 6 0 3 -5 -5 -10 -8 -5
|
||||
-15 -15 -15 -22 -1 -7 -6 -12 -12 -11 -6 1 -9 -6 -5 -19 3 -14 1 -19 -6 -14
|
||||
-8 5 -12 -2 -12 -18 0 -14 3 -26 8 -26 12 1 72 59 72 70 0 6 4 9 9 6 5 -3 19
|
||||
10 32 28 13 19 27 32 31 30 4 -3 8 -1 8 4 0 15 208 221 216 214 4 -4 4 1 1 11
|
||||
-4 11 -3 16 3 12 6 -3 10 -1 10 4 0 21 34 10 168 -57 580 -289 1207 -469 1869
|
||||
-537 154 -15 252 -19 518 -20 297 0 430 6 595 26 47 5 103 12 125 15 194 22
|
||||
496 81 690 135 39 11 86 24 105 29 346 96 782 278 1127 471 1188 665 2073
|
||||
1735 2502 3027 97 292 181 648 216 912 3 25 8 56 10 70 4 23 13 104 21 190 14
|
||||
145 19 283 19 530 0 334 -8 458 -46 730 -25 183 -28 204 -46 285 -8 39 -17 84
|
||||
-20 100 -2 17 -14 66 -25 110 -11 44 -22 90 -24 103 -3 13 -24 92 -49 175
|
||||
-181 624 -470 1200 -869 1732 -49 66 -92 122 -95 125 -4 3 -22 25 -41 50 -19
|
||||
25 -49 61 -66 80 -17 19 -55 62 -84 95 -293 335 -743 718 -1130 962 -91 57
|
||||
-305 183 -362 212 -21 11 -25 18 -18 31 5 10 7 20 3 23 -3 4 2 9 11 13 9 3 14
|
||||
10 11 14 -3 4 2 11 11 14 8 3 13 10 10 15 -3 5 1 12 10 15 8 3 12 10 9 16 -3
|
||||
5 -1 10 4 10 6 0 10 3 9 8 -4 10 68 123 75 116 3 -3 5 1 4 8 -1 32 4 49 13 43
|
||||
5 -3 12 6 16 20 3 14 10 25 15 25 5 0 8 6 7 13 -2 6 2 11 8 10 7 -1 10 6 7 17
|
||||
-3 11 0 20 6 20 6 0 11 9 11 19 0 14 -6 19 -20 18 -11 -1 -20 -5 -20 -10 0 -4
|
||||
-4 -6 -9 -3 -5 3 -8 -2 -7 -12 0 -9 -5 -16 -11 -14 -7 1 -13 -3 -13 -10 0 -11
|
||||
-24 -38 -152 -169 -32 -33 -58 -64 -58 -69 0 -6 -4 -10 -8 -10 -5 0 -17 -7
|
||||
-28 -16 -10 -8 -13 -12 -5 -8 10 5 12 3 7 -5 -5 -7 -15 -10 -23 -7 -8 3 -11 2
|
||||
-8 -4 3 -5 -2 -18 -11 -28 -16 -19 -19 -18 -148 39 -72 33 -140 64 -151 69
|
||||
-144 67 -624 228 -757 254 -13 2 -70 16 -128 30 -198 47 -471 91 -690 112 -36
|
||||
3 -85 8 -110 11 -56 6 -686 14 -691 9z m602 -1203 c13 -16 12 -17 -3 -4 -10 7
|
||||
-18 15 -18 17 0 8 8 3 21 -13z m844 -102 c3 -5 2 -12 -3 -15 -5 -3 -9 1 -9 9
|
||||
0 17 3 19 12 6z m-644 -98 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3
|
||||
21 -13z m-1670 -70 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m-201 -3 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z
|
||||
m320 0 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11
|
||||
-10z m50 -74 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m425 -75 c3 -5 2 -12 -3 -15 -5 -3 -9 1 -9 9 0 17 3 19 12 6z m125 5 c0 -2 -8
|
||||
-10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-520 -18 c0 -4 -4 -8
|
||||
-9 -8 -6 0 -12 4 -15 8 -3 5 1 9 9 9 8 0 15 -4 15 -9z m3157 -3 c0 -8 -4 -12
|
||||
-9 -9 -5 3 -6 10 -3 15 9 13 12 11 12 -6z m-2526 -42 c13 -16 12 -17 -3 -4
|
||||
-10 7 -18 15 -18 17 0 8 8 3 21 -13z m-551 -153 c0 -5 -5 -10 -11 -10 -5 0 -7
|
||||
5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m330 6 c0 -2 -8 -10 -17 -17 -16 -13
|
||||
-17 -12 -4 4 13 16 21 21 21 13z m2385 -14 c-3 -3 -11 0 -18 7 -9 10 -8 11 6
|
||||
5 10 -3 15 -9 12 -12z m481 -27 c-1 -8 -5 -17 -8 -21 -5 -4 -4 16 1 34 3 9 9
|
||||
-1 7 -13z m-3202 -131 c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16 0 14 7 11 14 -7z
|
||||
m606 -258 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-1769 -23 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m219 11
|
||||
c0 -8 -19 -13 -24 -6 -3 5 1 9 9 9 8 0 15 -2 15 -3z m1341 -51 c13 -16 12 -17
|
||||
-3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m2880 0 c13 -16 12 -17 -3 -4 -10
|
||||
7 -18 15 -18 17 0 8 8 3 21 -13z m-4760 -40 c13 -16 12 -17 -3 -4 -10 7 -18
|
||||
15 -18 17 0 8 8 3 21 -13z m530 -30 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17
|
||||
0 8 8 3 21 -13z m2079 -43 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4
|
||||
10 6 0 11 -4 11 -10z m1671 -47 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8
|
||||
8 3 21 -13z m-3791 -17 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m730 -10 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m-2089 -163 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m1840 0 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m160 0 c13
|
||||
-16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m160 0 c13 -16 12 -17
|
||||
-3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m160 0 c13 -16 12 -17 -3 -4 -10 7
|
||||
-18 15 -18 17 0 8 8 3 21 -13z m3480 -40 c13 -16 12 -17 -3 -4 -10 7 -18 15
|
||||
-18 17 0 8 8 3 21 -13z m-81 -37 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6
|
||||
5 11 10 11 6 0 10 -2 10 -4z m475 -134 c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5 10
|
||||
-3 15 -9 12 -12z m46 -29 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3
|
||||
21 -13z m-1637 -1 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9 9 3 4 7 8 9 8 2 0 6 -4 9
|
||||
-8z m-1443 -39 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m3289 3 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m240 0
|
||||
c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-2139 -53 c13
|
||||
-16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1169 -73 c0 -5 -2 -10
|
||||
-4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m320 0 c0 -5 -2
|
||||
-10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m640 0 c0 -5
|
||||
-5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m-89 -47 c13
|
||||
-16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-387 -71 c3 -5 -1 -9
|
||||
-9 -9 -8 0 -12 4 -9 9 3 4 7 8 9 8 2 0 6 -4 9 -8z m-5893 -55 c-10 -9 -11 -8
|
||||
-5 6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z m169 19 c0 -3 -4 -8 -10 -11 -5 -3
|
||||
-10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m311 -13 c13 -16 12 -17 -3 -4
|
||||
-10 7 -18 15 -18 17 0 8 8 3 21 -13z m334 7 c-3 -5 -12 -10 -18 -10 -7 0 -6 4
|
||||
3 10 19 12 23 12 15 0z m3685 -74 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4
|
||||
13 16 21 21 21 13z m748 -51 c-3 -3 -9 2 -12 12 -6 14 -5 15 5 6 7 -7 10 -15
|
||||
7 -18z m323 8 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m-641 -3 c0 -5 -4 -10 -10 -10 -5 0 -10 5 -10 10 0 6 5 10 10 10 6 0 10 -4 10
|
||||
-10z m1641 -37 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m-201 -3 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z
|
||||
m370 -74 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-6930 -82 c0 -8 -19 -13 -24 -6 -3 5 1 9 9 9 8 0 15 -2 15 -3z m880 2 c0 -2
|
||||
-7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25 14 25 6z m325 -5 c-9 -8 -36 -10 -30
|
||||
-2 2 4 11 8 20 8 8 0 13 -3 10 -6z m280 -1 c3 -6 -1 -7 -9 -4 -18 7 -21 14 -7
|
||||
14 6 0 13 -4 16 -10z m4270 1 c3 -5 2 -12 -3 -15 -5 -3 -9 1 -9 9 0 17 3 19
|
||||
12 6z m-6545 -35 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m1951 -43 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m4230 -10 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-4991
|
||||
-17 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m80 -56 c0
|
||||
-5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m320 0
|
||||
c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m210 6
|
||||
c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m110 -6 c0 -5
|
||||
-5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m3130 6 c0 -2
|
||||
-8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1115 -5 c-9 -8 -36
|
||||
-10 -30 -2 2 4 11 8 20 8 8 0 13 -3 10 -6z m-6124 -78 c13 -16 12 -17 -3 -4
|
||||
-10 7 -18 15 -18 17 0 8 8 3 21 -13z m679 -27 c0 -2 -8 -10 -17 -17 -16 -13
|
||||
-17 -12 -4 4 13 16 21 21 21 13z m561 -13 c13 -16 12 -17 -3 -4 -10 7 -18 15
|
||||
-18 17 0 8 8 3 21 -13z m5399 -27 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4
|
||||
13 16 21 21 21 13z m-120 -12 c0 -8 -19 -13 -24 -6 -3 5 1 9 9 9 8 0 15 -2 15
|
||||
-3z m400 -2 c0 -5 -7 -9 -15 -9 -8 0 -12 4 -9 9 3 4 9 8 15 8 5 0 9 -4 9 -8z
|
||||
m325 -1 c-9 -8 -36 -10 -30 -2 2 4 11 8 20 8 8 0 13 -3 10 -6z m-5915 -35 c0
|
||||
-2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m5421 -13 c13 -16
|
||||
12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m130 -30 c13 -16 12 -17 -3
|
||||
-4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-5006 -83 c3 -5 1 -10 -4 -10 -6 0
|
||||
-11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m5925 -120 c0 -5 -2 -10 -4 -10
|
||||
-3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-7683 -35 c0 -8 -4 -12
|
||||
-9 -9 -5 3 -6 10 -3 15 9 13 12 11 12 -6z m7008 -5 c3 -6 -1 -7 -9 -4 -18 7
|
||||
-21 14 -7 14 6 0 13 -4 16 -10z m510 -160 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11
|
||||
10 0 6 2 10 4 10 3 0 8 -4 11 -10z m320 -8 c-3 -3 -11 0 -18 7 -9 10 -8 11 6
|
||||
5 10 -3 15 -9 12 -12z m-7844 -39 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21
|
||||
2 0 10 -8 17 -17z m5680 0 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3
|
||||
21 -13z m-186 -113 c-3 -5 -12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z
|
||||
m285 -34 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-5970 -30 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m1481 -53 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-1446
|
||||
-43 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z
|
||||
m116 -7 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m209 7
|
||||
c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m5551
|
||||
-87 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-4511 -17 c0
|
||||
-2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-839 -53 c13 -16
|
||||
12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m6676 2 c0 -8 -4 -12 -9
|
||||
-9 -5 3 -6 10 -3 15 9 13 12 11 12 -6z m-5762 -4 c3 -5 2 -12 -3 -15 -5 -3 -9
|
||||
1 -9 9 0 17 3 19 12 6z m-705 -35 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4
|
||||
13 16 21 21 21 13z m6560 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16
|
||||
21 21 21 13z m-4376 -55 c-2 -3 -12 3 -22 13 -16 17 -16 18 5 5 12 -7 20 -15
|
||||
17 -18z m4886 25 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m-5440 -90 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10
|
||||
-2 10 -4z m4290 -40 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21
|
||||
21 13z m541 -13 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m650 -70 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-5566
|
||||
-51 c-3 -3 -11 0 -18 7 -9 10 -8 11 6 5 10 -3 15 -9 12 -12z m3245 6 c0 -4 -4
|
||||
-8 -9 -8 -6 0 -12 4 -15 8 -3 5 1 9 9 9 8 0 15 -4 15 -9z m-5889 -85 c13 -16
|
||||
12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m5329 11 c0 -8 -19 -13 -24
|
||||
-6 -3 5 1 9 9 9 8 0 15 -2 15 -3z m1040 -28 c0 -2 -8 -10 -17 -17 -16 -13 -17
|
||||
-12 -4 4 13 16 21 21 21 13z m-2960 -16 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10
|
||||
3 6 8 10 11 10 2 0 4 -4 4 -10z m3040 -40 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11
|
||||
10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-4329 -53 c-10 -9 -11 -8 -5 6 3 10 9
|
||||
15 12 12 3 -3 0 -11 -7 -18z m4330 -64 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18
|
||||
17 0 8 8 3 21 -13z m-5928 -78 c-3 -9 -8 -14 -10 -11 -3 3 -2 9 2 15 9 16 15
|
||||
13 8 -4z m-482 -12 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z
|
||||
m5924 7 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z
|
||||
m1685 -64 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-7605 -56 c3 -5 1 -10 -4 -10 -6 0 -11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11
|
||||
-10z m965 0 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4
|
||||
-10z m6720 0 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4
|
||||
11 -10z m320 0 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4
|
||||
4 -10z m320 6 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10
|
||||
-2 10 -4z m-8230 -40 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21
|
||||
21 13z m1760 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-1694 -52 c1 -9 0 -13 -4 -10 -3 4 -7 14 -8 22 -1 9 0 13 4 10 3 -4 7 -14 8
|
||||
-22z m2560 11 c-1 -8 -5 -17 -8 -21 -5 -4 -4 16 1 34 3 9 9 -1 7 -13z m-2476
|
||||
-29 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m7441 -13
|
||||
c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-6730 -90 c13 -16
|
||||
12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1779 13 c0 -2 -8 -10 -17
|
||||
-17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-2520 -40 c0 -2 -8 -10 -17 -17
|
||||
-16 -13 -17 -12 -4 4 13 16 21 21 21 13z m745 -86 c3 -5 1 -10 -4 -10 -6 0
|
||||
-11 5 -11 10 0 6 2 10 4 10 3 0 8 -4 11 -10z m-804 -47 c13 -16 12 -17 -3 -4
|
||||
-10 7 -18 15 -18 17 0 8 8 3 21 -13z m899 13 c0 -2 -8 -10 -17 -17 -16 -13
|
||||
-17 -12 -4 4 13 16 21 21 21 13z m4541 -19 c-10 -9 -11 -8 -5 6 3 10 9 15 12
|
||||
12 3 -3 0 -11 -7 -18z m-3711 -11 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4
|
||||
13 16 21 21 21 13z m791 -23 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8
|
||||
3 21 -13z m2894 7 c3 -6 -1 -7 -9 -4 -18 7 -21 14 -7 14 6 0 13 -4 16 -10z
|
||||
m146 -7 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m99 13 c0
|
||||
-2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1030 -86 c0 -5
|
||||
-2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m1320 6 c0
|
||||
-3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m320 0
|
||||
c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z
|
||||
m-1679 -123 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m639
|
||||
13 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-720 -50
|
||||
c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z
|
||||
m-639 -83 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m553 -9
|
||||
c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16 0 14 7 11 14 -7z m1446 -18 c0 -2 -8
|
||||
-10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-2350 -50 c0 -2 -8 -10
|
||||
-17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m1750 -70 c0 -2 -8 -10 -17
|
||||
-17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-559 -93 c13 -16 12 -17 -3 -4
|
||||
-10 7 -18 15 -18 17 0 8 8 3 21 -13z m-597 -1 c3 -5 -1 -9 -9 -9 -8 0 -12 4
|
||||
-9 9 3 4 7 8 9 8 2 0 6 -4 9 -8z m396 -2 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4
|
||||
10 3 6 8 10 11 10 2 0 4 -4 4 -10z m320 0 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11
|
||||
10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m50 -74 c0 -2 -8 -10 -17 -17 -16 -13
|
||||
-17 -12 -4 4 13 16 21 21 21 13z m-1690 -50 c0 -2 -8 -10 -17 -17 -16 -13 -17
|
||||
-12 -4 4 13 16 21 21 21 13z m-3640 -32 c0 -8 -19 -13 -24 -6 -3 5 1 9 9 9 8
|
||||
0 15 -2 15 -3z m634 -42 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9 9 3 4 7 8 9 8 2 0 6
|
||||
-4 9 -8z m4326 -122 c0 -5 -5 -10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0
|
||||
4 -4 4 -10z m-6160 -104 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m1120 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m-230 -90 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m3231 -43 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1020
|
||||
-160 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-4310 -10
|
||||
c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17 -17z m3086 -68 c0 -8
|
||||
-4 -12 -9 -9 -5 3 -6 10 -3 15 9 13 12 11 12 -6z m3040 0 c0 -8 -4 -12 -9 -9
|
||||
-5 3 -6 10 -3 15 9 13 12 11 12 -6z m-323 -3 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9
|
||||
9 3 4 7 8 9 8 2 0 6 -4 9 -8z m-1273 -119 c13 -16 12 -17 -3 -4 -10 7 -18 15
|
||||
-18 17 0 8 8 3 21 -13z m1590 -90 c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0
|
||||
8 8 3 21 -13z m-6911 -17 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21
|
||||
21 21 13z m7235 -85 c3 -5 2 -12 -3 -15 -5 -3 -9 1 -9 9 0 17 3 19 12 6z
|
||||
m-310 -11 c-3 -5 -12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m-6555
|
||||
-34 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m4581 -53
|
||||
c13 -16 12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-4106 -33 c-3 -5
|
||||
-12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m-485 -40 c0 -5 -5 -10 -11
|
||||
-10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m320 0 c0 -5 -2 -10 -4
|
||||
-10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z m-409 -47 c13 -16 12
|
||||
-17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m4739 13 c0 -2 -8 -10 -17 -17
|
||||
-16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-3610 -70 c0 -2 -8 -10 -17 -17 -16
|
||||
-13 -17 -12 -4 4 13 16 21 21 21 13z m-245 -55 c3 -5 2 -12 -3 -15 -5 -3 -9 1
|
||||
-9 9 0 17 3 19 12 6z m4165 5 c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25
|
||||
14 25 6z m-3609 -53 c13 -16 12 -17 -3 -4 -17 13 -22 21 -14 21 2 0 10 -8 17
|
||||
-17z m4975 -115 c3 -4 -1 -5 -10 -4 -8 1 -18 5 -22 8 -3 4 1 5 10 4 8 -1 18
|
||||
-5 22 -8z m-5215 -51 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12 3 -3 0 -11 -7 -18z
|
||||
m339 19 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m4155
|
||||
-6 c-3 -5 -12 -10 -18 -10 -7 0 -6 4 3 10 19 12 23 12 15 0z m635 4 c0 -8 -19
|
||||
-13 -24 -6 -3 5 1 9 9 9 8 0 15 -2 15 -3z m-645 -113 c3 -5 2 -12 -3 -15 -5
|
||||
-3 -9 1 -9 9 0 17 3 19 12 6z m-4804 -24 c-10 -9 -11 -8 -5 6 3 10 9 15 12 12
|
||||
3 -3 0 -11 -7 -18z m654 13 c3 -6 -1 -7 -9 -4 -18 7 -21 14 -7 14 6 0 13 -4
|
||||
16 -10z m1835 -104 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m680 -120 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-1560 -10 c0 -3 -4 -8 -10 -11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2
|
||||
10 -4z m3120 -30 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21
|
||||
13z m-1842 -61 c-3 -3 -9 2 -12 12 -6 14 -5 15 5 6 7 -7 10 -15 7 -18z m-2998
|
||||
5 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4 11 -10z
|
||||
m120 4 c0 -8 -19 -13 -24 -6 -3 5 1 9 9 9 8 0 15 -2 15 -3z m2991 -11 c13 -16
|
||||
12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m1603 1 c3 -8 2 -12 -4 -9
|
||||
-6 3 -10 10 -10 16 0 14 7 11 14 -7z m-2994 -18 c0 -2 -8 -10 -17 -17 -16 -13
|
||||
-17 -12 -4 4 13 16 21 21 21 13z m-1763 -51 c0 -8 -4 -15 -9 -15 -10 0 -11 14
|
||||
-1 23 9 10 10 9 10 -8z m640 -160 c0 -8 -4 -12 -9 -9 -5 3 -6 10 -3 15 9 13
|
||||
12 11 12 -6z m723 1 c0 -2 -7 -7 -16 -10 -8 -3 -12 -2 -9 4 6 10 25 14 25 6z
|
||||
m1676 -92 c1 -9 0 -13 -4 -10 -3 4 -7 14 -8 22 -1 9 0 13 4 10 3 -4 7 -14 8
|
||||
-22z m-2561 7 c3 -5 2 -12 -3 -15 -5 -3 -9 1 -9 9 0 17 3 19 12 6z m95 -35 c0
|
||||
-2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m4080 0 c0 -2 -8
|
||||
-10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-650 -70 c0 -2 -8 -10
|
||||
-17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z m-3520 -10 c0 -3 -4 -8 -10
|
||||
-11 -5 -3 -10 -1 -10 4 0 6 5 11 10 11 6 0 10 -2 10 -4z m4160 -46 c0 -5 -5
|
||||
-10 -11 -10 -5 0 -7 5 -4 10 3 6 8 10 11 10 2 0 4 -4 4 -10z m-49 -87 c13 -16
|
||||
12 -17 -3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-510 -30 c13 -16 12 -17
|
||||
-3 -4 -10 7 -18 15 -18 17 0 8 8 3 21 -13z m-2841 -27 c0 -2 -8 -10 -17 -17
|
||||
-16 -13 -17 -12 -4 4 13 16 21 21 21 13z m561 -13 c13 -16 12 -17 -3 -4 -17
|
||||
13 -22 21 -14 21 2 0 10 -8 17 -17z m1120 0 c13 -16 12 -17 -3 -4 -17 13 -22
|
||||
21 -14 21 2 0 10 -8 17 -17z m-207 -1 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9 9 3 4
|
||||
7 8 9 8 2 0 6 -4 9 -8z m320 -8 c3 -8 2 -12 -4 -9 -6 3 -10 10 -10 16 0 14 7
|
||||
11 14 -7z m-1024 -28 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21
|
||||
21 13z m2160 0 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-1400 -40 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m1394 -84 c3 -5 -1 -9 -9 -9 -8 0 -12 4 -9 9 3 4 7 8 9 8 2 0 6 -4 9 -8z
|
||||
m-714 -36 c0 -2 -8 -10 -17 -17 -16 -13 -17 -12 -4 4 13 16 21 21 21 13z
|
||||
m-530 -126 c0 -5 -2 -10 -4 -10 -3 0 -8 5 -11 10 -3 6 -1 10 4 10 6 0 11 -4
|
||||
11 -10z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 19 KiB |
19
web/public/site.webmanifest
Normal file
@@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "",
|
||||
"short_name": "",
|
||||
"icons": [
|
||||
{
|
||||
"src": "/android-chrome-192x192.png",
|
||||
"sizes": "192x192",
|
||||
"type": "image/png"
|
||||
},
|
||||
{
|
||||
"src": "/android-chrome-512x512.png",
|
||||
"sizes": "512x512",
|
||||
"type": "image/png"
|
||||
}
|
||||
],
|
||||
"theme_color": "#ffffff",
|
||||
"background_color": "#ffffff",
|
||||
"display": "standalone"
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useState } from 'react'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import Dialog from '@material-ui/core/Dialog'
|
||||
import { torrentsHost, torrentUploadHost } from 'utils/Hosts'
|
||||
@@ -9,6 +9,9 @@ import useChangeLanguage from 'utils/useChangeLanguage'
|
||||
import { useMediaQuery } from '@material-ui/core'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import usePreviousState from 'utils/usePreviousState'
|
||||
import { useQuery } from 'react-query'
|
||||
import { getTorrents } from 'utils/Utils'
|
||||
import parseTorrent from 'parse-torrent'
|
||||
|
||||
import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers'
|
||||
import { ButtonWrapper, Content, Header } from './style'
|
||||
@@ -23,31 +26,75 @@ export default function AddDialog({
|
||||
poster: originalPoster,
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
const isEditMode = !!originalHash
|
||||
const [torrentSource, setTorrentSource] = useState(originalHash || '')
|
||||
const [title, setTitle] = useState(originalTitle || '')
|
||||
const [originalTorrentTitle, setOriginalTorrentTitle] = useState('')
|
||||
const [parsedTitle, setParsedTitle] = useState('')
|
||||
const [posterUrl, setPosterUrl] = useState(originalPoster || '')
|
||||
const [isPosterUrlCorrect, setIsPosterUrlCorrect] = useState(false)
|
||||
const [isTorrentSourceCorrect, setIsTorrentSourceCorrect] = useState(false)
|
||||
const [isHashAlreadyExists, setIsHashAlreadyExists] = useState(false)
|
||||
const [posterList, setPosterList] = useState()
|
||||
const [isUserInteractedWithPoster, setIsUserInteractedWithPoster] = useState(false)
|
||||
const [isUserInteractedWithPoster, setIsUserInteractedWithPoster] = useState(isEditMode)
|
||||
const [currentLang] = useChangeLanguage()
|
||||
const [selectedFile, setSelectedFile] = useState()
|
||||
const [posterSearchLanguage, setPosterSearchLanguage] = useState(currentLang === 'ru' ? 'ru' : 'en')
|
||||
const [isLoadingButton, setIsLoadingButton] = useState(false)
|
||||
const [skipDebounce, setSkipDebounce] = useState(false)
|
||||
const [isEditMode, setIsEditMode] = useState(false)
|
||||
const [isCustomTitleEnabled, setIsCustomTitleEnabled] = useState(false)
|
||||
|
||||
const { data: torrents } = useQuery('torrents', getTorrents, {
|
||||
retry: 1,
|
||||
refetchInterval: 1000,
|
||||
})
|
||||
|
||||
useEffect(() => {
|
||||
const allHashes = torrents.map(({ hash }) => hash)
|
||||
|
||||
parseTorrent.remote(selectedFile || torrentSource, (err, { infoHash } = {}) => {
|
||||
setIsHashAlreadyExists(allHashes.includes(infoHash))
|
||||
})
|
||||
}, [selectedFile, torrentSource, torrents])
|
||||
|
||||
const fullScreen = useMediaQuery('@media (max-width:930px)')
|
||||
|
||||
const updateTitleFromSource = useCallback(() => {
|
||||
parseTorrentTitle(selectedFile || torrentSource, ({ parsedTitle, originalName }) => {
|
||||
if (!originalName) return
|
||||
|
||||
setSkipDebounce(true)
|
||||
setTitle('')
|
||||
setIsCustomTitleEnabled(false)
|
||||
setOriginalTorrentTitle(originalName)
|
||||
setParsedTitle(parsedTitle)
|
||||
})
|
||||
}, [selectedFile, torrentSource])
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedFile && !torrentSource) {
|
||||
setTitle('')
|
||||
setOriginalTorrentTitle('')
|
||||
setParsedTitle('')
|
||||
setIsCustomTitleEnabled(false)
|
||||
setPosterList()
|
||||
removePoster()
|
||||
setIsUserInteractedWithPoster(false)
|
||||
}
|
||||
}, [selectedFile, torrentSource])
|
||||
|
||||
const removePoster = () => {
|
||||
setIsPosterUrlCorrect(false)
|
||||
setPosterUrl('')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (originalHash) {
|
||||
setIsEditMode(true)
|
||||
|
||||
checkImageURL(posterUrl).then(correctImage => {
|
||||
correctImage ? setIsPosterUrlCorrect(true) : removePoster()
|
||||
})
|
||||
}
|
||||
// This is needed only on mount
|
||||
// This is needed only on mount. Do not remove line below
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, [])
|
||||
|
||||
@@ -85,54 +132,51 @@ export default function AddDialog({
|
||||
|
||||
const delayedPosterSearch = useMemo(() => debounce(posterSearch, 700), [posterSearch])
|
||||
|
||||
const prevTitleState = usePreviousState(title)
|
||||
const prevTorrentSourceState = usePreviousState(torrentSource)
|
||||
|
||||
useEffect(() => {
|
||||
// if torrentSource is updated then we are checking that source is valid and getting title from the source
|
||||
const torrentSourceChanged = torrentSource !== prevTorrentSourceState
|
||||
|
||||
const isCorrectSource = chechTorrentSource(torrentSource)
|
||||
if (!isCorrectSource) return setIsTorrentSourceCorrect(false)
|
||||
|
||||
setIsTorrentSourceCorrect(true)
|
||||
|
||||
if (torrentSourceChanged) {
|
||||
parseTorrentTitle(selectedFile || torrentSource, newTitle => {
|
||||
if (!newTitle) return
|
||||
// if torrentSource is updated then we are getting title from the source
|
||||
const torrentSourceChanged = torrentSource !== prevTorrentSourceState
|
||||
if (!torrentSourceChanged) return
|
||||
|
||||
setSkipDebounce(true)
|
||||
setTitle(newTitle)
|
||||
})
|
||||
}
|
||||
}, [prevTorrentSourceState, selectedFile, torrentSource])
|
||||
updateTitleFromSource()
|
||||
}, [prevTorrentSourceState, selectedFile, torrentSource, updateTitleFromSource])
|
||||
|
||||
const prevTitleState = usePreviousState(title)
|
||||
|
||||
useEffect(() => {
|
||||
// if title exists and title was changed then search poster.
|
||||
const titleChanged = title !== prevTitleState
|
||||
if (!titleChanged) return
|
||||
if (!titleChanged && !parsedTitle) return
|
||||
|
||||
if (skipDebounce) {
|
||||
posterSearch(title, posterSearchLanguage)
|
||||
posterSearch(title || parsedTitle, posterSearchLanguage)
|
||||
setSkipDebounce(false)
|
||||
} else if (!title) {
|
||||
if (parsedTitle) {
|
||||
posterSearch(parsedTitle, posterSearchLanguage)
|
||||
} else {
|
||||
delayedPosterSearch.cancel()
|
||||
!isUserInteractedWithPoster && removePoster()
|
||||
}
|
||||
} else {
|
||||
title === '' ? removePoster() : delayedPosterSearch(title, posterSearchLanguage)
|
||||
delayedPosterSearch(title, posterSearchLanguage)
|
||||
}
|
||||
}, [title, prevTitleState, delayedPosterSearch, posterSearch, posterSearchLanguage, skipDebounce])
|
||||
|
||||
const removePoster = () => {
|
||||
setIsPosterUrlCorrect(false)
|
||||
setPosterUrl('')
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
if (!selectedFile && !torrentSource) {
|
||||
setTitle('')
|
||||
setPosterList()
|
||||
removePoster()
|
||||
setIsUserInteractedWithPoster(false)
|
||||
}
|
||||
}, [selectedFile, torrentSource])
|
||||
}, [
|
||||
title,
|
||||
parsedTitle,
|
||||
prevTitleState,
|
||||
delayedPosterSearch,
|
||||
posterSearch,
|
||||
posterSearchLanguage,
|
||||
skipDebounce,
|
||||
isUserInteractedWithPoster,
|
||||
])
|
||||
|
||||
const handleSave = () => {
|
||||
setIsLoadingButton(true)
|
||||
@@ -142,7 +186,7 @@ export default function AddDialog({
|
||||
.post(torrentsHost(), {
|
||||
action: 'set',
|
||||
hash: originalHash,
|
||||
title: title === '' ? originalName : title,
|
||||
title: title || originalName,
|
||||
poster: posterUrl,
|
||||
})
|
||||
.finally(handleClose)
|
||||
@@ -185,13 +229,16 @@ export default function AddDialog({
|
||||
)}
|
||||
|
||||
<RightSideComponent
|
||||
originalTorrentTitle={originalTorrentTitle}
|
||||
setTitle={setTitle}
|
||||
setPosterUrl={setPosterUrl}
|
||||
setIsPosterUrlCorrect={setIsPosterUrlCorrect}
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setPosterList={setPosterList}
|
||||
isTorrentSourceCorrect={isTorrentSourceCorrect}
|
||||
isHashAlreadyExists={isHashAlreadyExists}
|
||||
title={title}
|
||||
parsedTitle={parsedTitle}
|
||||
posterUrl={posterUrl}
|
||||
isPosterUrlCorrect={isPosterUrlCorrect}
|
||||
posterList={posterList}
|
||||
@@ -200,7 +247,11 @@ export default function AddDialog({
|
||||
setPosterSearchLanguage={setPosterSearchLanguage}
|
||||
posterSearch={posterSearch}
|
||||
removePoster={removePoster}
|
||||
updateTitleFromSource={updateTitleFromSource}
|
||||
torrentSource={torrentSource}
|
||||
isCustomTitleEnabled={isCustomTitleEnabled}
|
||||
setIsCustomTitleEnabled={setIsCustomTitleEnabled}
|
||||
isEditMode={isEditMode}
|
||||
/>
|
||||
</Content>
|
||||
|
||||
@@ -212,7 +263,7 @@ export default function AddDialog({
|
||||
<Button
|
||||
variant='contained'
|
||||
style={{ minWidth: '110px' }}
|
||||
disabled={!torrentSource}
|
||||
disabled={!torrentSource || (isHashAlreadyExists && !isEditMode) || !isTorrentSourceCorrect}
|
||||
onClick={handleSave}
|
||||
color='primary'
|
||||
>
|
||||
|
||||
@@ -50,8 +50,8 @@ export default function LeftSideComponent({
|
||||
onChange={handleTorrentSourceChange}
|
||||
value={torrentSource}
|
||||
margin='dense'
|
||||
label={t('TorrentSourceLink')}
|
||||
helperText={t('TorrentSourceOptions')}
|
||||
label={t('AddDialog.TorrentSourceLink')}
|
||||
helperText={t('AddDialog.TorrentSourceOptions')}
|
||||
type='text'
|
||||
fullWidth
|
||||
onFocus={() => setIsTorrentSourceActive(true)}
|
||||
@@ -74,11 +74,11 @@ export default function LeftSideComponent({
|
||||
) : (
|
||||
<LeftSideBottomSectionNoFile isDragActive={isDragActive} {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<div>{t('AppendFile.Or')}</div>
|
||||
<div>{t('AddDialog.AppendFile.Or')}</div>
|
||||
|
||||
<IconWrapper>
|
||||
<AddItemIcon color='primary' />
|
||||
<div>{t('AppendFile.ClickOrDrag')}</div>
|
||||
<div>{t('AddDialog.AppendFile.ClickOrDrag')}</div>
|
||||
</IconWrapper>
|
||||
</LeftSideBottomSectionNoFile>
|
||||
)}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NoImageIcon } from 'icons'
|
||||
import { TextField } from '@material-ui/core'
|
||||
import { IconButton, InputAdornment, TextField } from '@material-ui/core'
|
||||
import { CheckBox as CheckBoxIcon } from '@material-ui/icons'
|
||||
|
||||
import {
|
||||
ClearPosterButton,
|
||||
@@ -21,7 +22,9 @@ export default function RightSideComponent({
|
||||
setIsUserInteractedWithPoster,
|
||||
setPosterList,
|
||||
isTorrentSourceCorrect,
|
||||
isHashAlreadyExists,
|
||||
title,
|
||||
parsedTitle,
|
||||
posterUrl,
|
||||
isPosterUrlCorrect,
|
||||
posterList,
|
||||
@@ -31,6 +34,11 @@ export default function RightSideComponent({
|
||||
posterSearch,
|
||||
removePoster,
|
||||
torrentSource,
|
||||
originalTorrentTitle,
|
||||
updateTitleFromSource,
|
||||
isCustomTitleEnabled,
|
||||
setIsCustomTitleEnabled,
|
||||
isEditMode,
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -49,13 +57,61 @@ export default function RightSideComponent({
|
||||
|
||||
return (
|
||||
<RightSide>
|
||||
<RightSideContainer isHidden={!isTorrentSourceCorrect}>
|
||||
<TextField onChange={handleTitleChange} value={title} margin='dense' label={t('Title')} type='text' fullWidth />
|
||||
<RightSideContainer isHidden={!isTorrentSourceCorrect || (isHashAlreadyExists && !isEditMode)}>
|
||||
{originalTorrentTitle ? (
|
||||
<>
|
||||
<TextField
|
||||
value={originalTorrentTitle}
|
||||
margin='dense'
|
||||
label={t('AddDialog.OriginalTorrentTitle')}
|
||||
type='text'
|
||||
fullWidth
|
||||
disabled={isCustomTitleEnabled}
|
||||
InputProps={{ readOnly: true }}
|
||||
/>
|
||||
<TextField
|
||||
onChange={handleTitleChange}
|
||||
onFocus={() => setIsCustomTitleEnabled(true)}
|
||||
onBlur={({ target: { value } }) => !value && setIsCustomTitleEnabled(false)}
|
||||
value={title}
|
||||
margin='dense'
|
||||
label={t('AddDialog.CustomTorrentTitle')}
|
||||
type='text'
|
||||
fullWidth
|
||||
InputProps={{
|
||||
endAdornment: (
|
||||
<InputAdornment position='end'>
|
||||
<IconButton
|
||||
style={{ padding: '0 0 0 7px' }}
|
||||
onClick={() => {
|
||||
setTitle('')
|
||||
setIsCustomTitleEnabled(!isCustomTitleEnabled)
|
||||
updateTitleFromSource()
|
||||
setIsUserInteractedWithPoster(false)
|
||||
}}
|
||||
>
|
||||
<CheckBoxIcon style={{ color: isCustomTitleEnabled ? 'green' : 'gray' }} />
|
||||
</IconButton>
|
||||
</InputAdornment>
|
||||
),
|
||||
}}
|
||||
/>
|
||||
</>
|
||||
) : (
|
||||
<TextField
|
||||
onChange={handleTitleChange}
|
||||
value={title}
|
||||
margin='dense'
|
||||
label={t('AddDialog.TitleBlank')}
|
||||
type='text'
|
||||
fullWidth
|
||||
/>
|
||||
)}
|
||||
<TextField
|
||||
onChange={handlePosterUrlChange}
|
||||
value={posterUrl}
|
||||
margin='dense'
|
||||
label={t('AddPosterLinkInput')}
|
||||
label={t('AddDialog.AddPosterLinkInput')}
|
||||
type='url'
|
||||
fullWidth
|
||||
/>
|
||||
@@ -81,7 +137,9 @@ export default function RightSideComponent({
|
||||
onClick={() => {
|
||||
const newLanguage = posterSearchLanguage === 'en' ? 'ru' : 'en'
|
||||
setPosterSearchLanguage(newLanguage)
|
||||
posterSearch(title, newLanguage, { shouldRefreshMainPoster: true })
|
||||
posterSearch(isCustomTitleEnabled ? title : originalTorrentTitle ? parsedTitle : title, newLanguage, {
|
||||
shouldRefreshMainPoster: true,
|
||||
})
|
||||
}}
|
||||
showbutton={+isPosterUrlCorrect}
|
||||
color='primary'
|
||||
@@ -108,11 +166,15 @@ export default function RightSideComponent({
|
||||
</RightSideContainer>
|
||||
|
||||
<RightSideContainer
|
||||
isError={torrentSource && !isTorrentSourceCorrect}
|
||||
isError={torrentSource && (!isTorrentSourceCorrect || isHashAlreadyExists)}
|
||||
notificationMessage={
|
||||
!torrentSource ? t('AddTorrentSourceNotification') : !isTorrentSourceCorrect && t('WrongTorrentSource')
|
||||
!torrentSource
|
||||
? t('AddDialog.AddTorrentSourceNotification')
|
||||
: !isTorrentSourceCorrect
|
||||
? t('AddDialog.WrongTorrentSource')
|
||||
: isHashAlreadyExists && t('AddDialog.HashExists')
|
||||
}
|
||||
isHidden={isTorrentSourceCorrect}
|
||||
isHidden={isEditMode || (isTorrentSourceCorrect && !isHashAlreadyExists)}
|
||||
/>
|
||||
</RightSide>
|
||||
)
|
||||
|
||||
@@ -32,14 +32,14 @@ export const checkImageURL = async url => {
|
||||
}
|
||||
|
||||
const magnetRegex = /^magnet:\?xt=urn:[a-z0-9].*/i
|
||||
const hashRegex = /^\b[0-9a-f]{32}\b$|^\b[0-9a-f]{40}\b$|^\b[0-9a-f]{64}\b$/i
|
||||
export const hashRegex = /^\b[0-9a-f]{32}\b$|^\b[0-9a-f]{40}\b$|^\b[0-9a-f]{64}\b$/i
|
||||
const torrentRegex = /^.*\.(torrent)$/i
|
||||
export const chechTorrentSource = source =>
|
||||
source.match(hashRegex) !== null || source.match(magnetRegex) !== null || source.match(torrentRegex) !== null
|
||||
|
||||
export const parseTorrentTitle = (parsingSource, callback) => {
|
||||
parseTorrent.remote(parsingSource, (err, { name, files } = {}) => {
|
||||
if (!name || err) return callback(null)
|
||||
if (!name || err) return callback({ parsedTitle: null, originalName: null })
|
||||
|
||||
const torrentName = ptt.parse(name).title
|
||||
const nameOfFileInsideTorrent = files ? ptt.parse(files[0].name).title : null
|
||||
@@ -50,6 +50,6 @@ export const parseTorrentTitle = (parsingSource, callback) => {
|
||||
newTitle = torrentName.length < nameOfFileInsideTorrent.length ? torrentName : nameOfFileInsideTorrent
|
||||
}
|
||||
|
||||
callback(newTitle)
|
||||
callback({ parsedTitle: newTitle, originalName: name })
|
||||
})
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ export const Header = styled.div`
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
font-size: 20px;
|
||||
color: #fff;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);
|
||||
padding: 15px 24px;
|
||||
position: relative;
|
||||
@@ -14,6 +14,7 @@ export const Header = styled.div`
|
||||
|
||||
export const Content = styled.div`
|
||||
${({ isEditMode }) => css`
|
||||
height: 550px;
|
||||
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||
flex: 1;
|
||||
display: grid;
|
||||
@@ -29,6 +30,10 @@ export const Content = styled.div`
|
||||
@media (max-width: 930px) {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
align-content: start;
|
||||
}
|
||||
`}
|
||||
`
|
||||
|
||||
@@ -38,7 +43,7 @@ export const RightSide = styled.div`
|
||||
|
||||
export const RightSideContainer = styled.div`
|
||||
${({ isHidden, notificationMessage, isError }) => css`
|
||||
height: 455px;
|
||||
height: 530px;
|
||||
|
||||
${notificationMessage &&
|
||||
css`
|
||||
@@ -54,7 +59,7 @@ export const RightSideContainer = styled.div`
|
||||
background: ${isError ? '#cda184' : '#84cda7'};
|
||||
padding: 10px 15px;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
top: 52%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, -50%);
|
||||
border-radius: 5px;
|
||||
@@ -65,6 +70,10 @@ export const RightSideContainer = styled.div`
|
||||
css`
|
||||
display: none;
|
||||
`};
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: 170px;
|
||||
}
|
||||
`}
|
||||
`
|
||||
export const LeftSide = styled.div`
|
||||
@@ -88,7 +97,7 @@ export const LeftSideBottomSectionNoFile = styled.div`
|
||||
${({ isDragActive }) => isDragActive && `border: 4px dashed green`};
|
||||
|
||||
justify-items: center;
|
||||
grid-template-rows: 100px 1fr;
|
||||
grid-template-rows: 130px 1fr;
|
||||
cursor: pointer;
|
||||
|
||||
:hover {
|
||||
@@ -104,6 +113,15 @@ export const LeftSideBottomSectionNoFile = styled.div`
|
||||
place-items: center;
|
||||
grid-template-rows: 40% 1fr;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: 170px;
|
||||
grid-template-rows: 1fr;
|
||||
|
||||
> div:first-of-type {
|
||||
display: none;
|
||||
}
|
||||
}
|
||||
`
|
||||
|
||||
export const LeftSideBottomSectionFileSelected = styled.div`
|
||||
@@ -113,6 +131,10 @@ export const LeftSideBottomSectionFileSelected = styled.div`
|
||||
@media (max-width: 930px) {
|
||||
height: 400px;
|
||||
}
|
||||
|
||||
@media (max-width: 500px) {
|
||||
height: 170px;
|
||||
}
|
||||
`
|
||||
|
||||
export const TorrentIconWrapper = styled.div`
|
||||
@@ -281,7 +303,7 @@ export const PosterLanguageSwitch = styled.div`
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #e1f4eb;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
cursor: pointer;
|
||||
transition: all 0.3s;
|
||||
|
||||
|
||||
@@ -1,12 +1,10 @@
|
||||
import { playlistAllHost } from 'utils/Hosts'
|
||||
import Divider from '@material-ui/core/Divider'
|
||||
import ListItem from '@material-ui/core/ListItem'
|
||||
import ListItemIcon from '@material-ui/core/ListItemIcon'
|
||||
import ListItemText from '@material-ui/core/ListItemText'
|
||||
import { CreditCard as CreditCardIcon, List as ListIcon, Language as LanguageIcon } from '@material-ui/icons'
|
||||
import { CreditCard as CreditCardIcon } from '@material-ui/icons'
|
||||
import List from '@material-ui/core/List'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import useChangeLanguage from 'utils/useChangeLanguage'
|
||||
import AddDialogButton from 'components/Add'
|
||||
import SettingsDialog from 'components/Settings'
|
||||
import RemoveAll from 'components/RemoveAll'
|
||||
@@ -16,7 +14,6 @@ import CloseServer from 'components/CloseServer'
|
||||
import { AppSidebarStyle } from './style'
|
||||
|
||||
export default function Sidebar({ isDrawerOpen, setIsDonationDialogOpen }) {
|
||||
const [currentLang, changeLang] = useChangeLanguage()
|
||||
const { t } = useTranslation()
|
||||
|
||||
return (
|
||||
@@ -24,12 +21,6 @@ export default function Sidebar({ isDrawerOpen, setIsDonationDialogOpen }) {
|
||||
<List>
|
||||
<AddDialogButton />
|
||||
<RemoveAll />
|
||||
<ListItem button component='a' target='_blank' href={playlistAllHost()}>
|
||||
<ListItemIcon>
|
||||
<ListIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t('PlaylistAll')} />
|
||||
</ListItem>
|
||||
</List>
|
||||
|
||||
<Divider />
|
||||
@@ -37,20 +28,14 @@ export default function Sidebar({ isDrawerOpen, setIsDonationDialogOpen }) {
|
||||
<List>
|
||||
<SettingsDialog />
|
||||
|
||||
<ListItem button onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}>
|
||||
<ListItemIcon>
|
||||
<LanguageIcon />
|
||||
</ListItemIcon>
|
||||
<ListItemText primary={t('ChooseLanguage')} />
|
||||
</ListItem>
|
||||
|
||||
<AboutDialog />
|
||||
<CloseServer />
|
||||
</List>
|
||||
|
||||
<Divider />
|
||||
|
||||
<List>
|
||||
<AboutDialog />
|
||||
|
||||
<ListItem button onClick={() => setIsDonationDialogOpen(true)}>
|
||||
<ListItemIcon>
|
||||
<CreditCardIcon />
|
||||
|
||||
@@ -10,19 +10,22 @@ import axios from 'axios'
|
||||
import TorrentList from 'components/TorrentList'
|
||||
import DonateSnackbar from 'components/Donate'
|
||||
import DonateDialog from 'components/Donate/DonateDialog'
|
||||
import useChangeLanguage from 'utils/useChangeLanguage'
|
||||
|
||||
import { AppWrapper, AppHeader } from './style'
|
||||
import { AppWrapper, AppHeader, LanguageSwitch } from './style'
|
||||
import Sidebar from './Sidebar'
|
||||
|
||||
const baseTheme = createMuiTheme({
|
||||
overrides: { MuiCssBaseline: { '@global': { html: { WebkitFontSmoothing: 'auto' } } } },
|
||||
palette: { primary: { main: '#00a572' }, secondary: { main: '#ffa724' }, tonalOffset: 0.2 },
|
||||
typography: { fontFamily: 'Open Sans, sans-serif' },
|
||||
})
|
||||
|
||||
export default function App() {
|
||||
const [isDrawerOpen, setIsDrawerOpen] = useState(false)
|
||||
const [isDonationDialogOpen, setIsDonationDialogOpen] = useState(false)
|
||||
const [torrServerVersion, setTorrServerVersion] = useState('')
|
||||
const [currentLang, changeLang] = useChangeLanguage()
|
||||
|
||||
useEffect(() => {
|
||||
axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data))
|
||||
@@ -48,6 +51,12 @@ export default function App() {
|
||||
<Typography variant='h6' noWrap>
|
||||
TorrServer {torrServerVersion}
|
||||
</Typography>
|
||||
|
||||
<div style={{ justifySelf: 'end' }}>
|
||||
<LanguageSwitch onClick={() => (currentLang === 'en' ? changeLang('ru') : changeLang('en'))}>
|
||||
{currentLang === 'en' ? 'RU' : 'EN'}
|
||||
</LanguageSwitch>
|
||||
</div>
|
||||
</AppHeader>
|
||||
|
||||
<Sidebar isDrawerOpen={isDrawerOpen} setIsDonationDialogOpen={setIsDonationDialogOpen} />
|
||||
|
||||
@@ -21,8 +21,10 @@ export const AppHeader = styled.div`
|
||||
background: #00a572;
|
||||
color: rgba(0, 0, 0, 0.87);
|
||||
grid-area: head;
|
||||
display: flex;
|
||||
display: grid;
|
||||
grid-auto-flow: column;
|
||||
align-items: center;
|
||||
grid-template-columns: repeat(2, max-content) 1fr;
|
||||
box-shadow: 0px 2px 4px -1px rgb(0 0 0 / 20%), 0px 4px 5px 0px rgb(0 0 0 / 14%), 0px 1px 10px 0px rgb(0 0 0 / 12%);
|
||||
padding: 0 24px;
|
||||
z-index: 3;
|
||||
@@ -63,3 +65,26 @@ export const TorrentListWrapper = styled.div`
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
`
|
||||
|
||||
export const LanguageSwitch = styled.div`
|
||||
cursor: pointer;
|
||||
border-radius: 50%;
|
||||
background: #56b887;
|
||||
height: 35px;
|
||||
width: 35px;
|
||||
transition: all 0.2s;
|
||||
font-weight: 600;
|
||||
display: grid;
|
||||
place-items: center;
|
||||
color: #44795e;
|
||||
|
||||
:hover {
|
||||
background: #7ec9a3;
|
||||
}
|
||||
|
||||
@media (max-width: 700px) {
|
||||
height: 28px;
|
||||
width: 28px;
|
||||
font-size: 12px;
|
||||
}
|
||||
`
|
||||
|
||||
@@ -4,9 +4,9 @@ export const pieceSizeForMiniMap = 23
|
||||
export const gapBetweenPieces = 3
|
||||
export const miniCacheMaxHeight = 340
|
||||
|
||||
export const defaultBorderColor = '#eef2f4'
|
||||
export const defaultBorderColor = '#dbf2e8'
|
||||
export const defaultBackgroundColor = '#fff'
|
||||
export const completeColor = '#00a572'
|
||||
export const progressColor = '#ffa724'
|
||||
export const activeColor = '#000'
|
||||
export const rangeColor = '#9a9aff'
|
||||
export const rangeColor = '#ffa724'
|
||||
|
||||
@@ -62,5 +62,5 @@ export const SnakeWrapper = styled.div`
|
||||
|
||||
export const PercentagePiece = styled.div`
|
||||
background: ${completeColor};
|
||||
height: ${({ percentage }) => (percentage / 100) * 12}px;
|
||||
height: ${({ percentage }) => percentage}%;
|
||||
`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { NoImageIcon } from 'icons'
|
||||
import { humanizeSize, shortenText } from 'utils/Utils'
|
||||
import { humanizeSize, removeRedundantCharacters } from 'utils/Utils'
|
||||
import { useEffect, useState } from 'react'
|
||||
import { Button, ButtonGroup } from '@material-ui/core'
|
||||
import ptt from 'parse-torrent-title'
|
||||
@@ -102,18 +102,27 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
||||
const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false
|
||||
|
||||
const getParsedTitle = () => {
|
||||
const newNameStrings = []
|
||||
const newNameStringArr = []
|
||||
|
||||
const torrentParsedName = name && ptt.parse(name)
|
||||
|
||||
if (title !== name) {
|
||||
newNameStrings.push(title)
|
||||
} else if (torrentParsedName?.title) newNameStrings.push(torrentParsedName?.title)
|
||||
newNameStringArr.push(removeRedundantCharacters(title))
|
||||
} else if (torrentParsedName?.title) newNameStringArr.push(removeRedundantCharacters(torrentParsedName?.title))
|
||||
|
||||
if (torrentParsedName?.year) newNameStrings.push(torrentParsedName?.year)
|
||||
if (torrentParsedName?.resolution) newNameStrings.push(torrentParsedName?.resolution)
|
||||
// These 2 checks are needed to get year and resolution from torrent name if title does not have this info
|
||||
if (torrentParsedName?.year && !newNameStringArr[0].includes(torrentParsedName?.year))
|
||||
newNameStringArr.push(torrentParsedName?.year)
|
||||
if (torrentParsedName?.resolution && !newNameStringArr[0].includes(torrentParsedName?.resolution))
|
||||
newNameStringArr.push(torrentParsedName?.resolution)
|
||||
|
||||
return newNameStrings.join('. ')
|
||||
const newNameString = newNameStringArr.join('. ')
|
||||
|
||||
// removeRedundantCharacters is returning ".." if it was "..."
|
||||
const lastDotShouldBeAdded =
|
||||
newNameString[newNameString.length - 1] === '.' && newNameString[newNameString.length - 2] === '.'
|
||||
|
||||
return lastDotShouldBeAdded ? `${newNameString}.` : newNameString
|
||||
}
|
||||
|
||||
return (
|
||||
@@ -145,12 +154,19 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
||||
|
||||
<div>
|
||||
{title && name !== title ? (
|
||||
<>
|
||||
<SectionTitle>{shortenText(getParsedTitle(), 55)}</SectionTitle>
|
||||
<SectionSubName mb={20}>{shortenText(ptt.parse(name).title, 110)}</SectionSubName>
|
||||
</>
|
||||
getParsedTitle().length > 90 ? (
|
||||
<>
|
||||
<SectionTitle>{ptt.parse(name).title}</SectionTitle>
|
||||
<SectionSubName mb={20}>{getParsedTitle()}</SectionSubName>
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<SectionTitle>{getParsedTitle()}</SectionTitle>
|
||||
<SectionSubName mb={20}>{ptt.parse(name).title}</SectionSubName>
|
||||
</>
|
||||
)
|
||||
) : (
|
||||
<SectionTitle mb={20}>{shortenText(getParsedTitle(), 55)}</SectionTitle>
|
||||
<SectionTitle mb={20}>{getParsedTitle()}</SectionTitle>
|
||||
)}
|
||||
|
||||
<WidgetWrapper>
|
||||
|
||||
@@ -113,7 +113,7 @@ export const SectionTitle = styled.div`
|
||||
${({ mb }) => css`
|
||||
${mb && `margin-bottom: ${mb}px`};
|
||||
font-size: 35px;
|
||||
font-weight: 200;
|
||||
font-weight: 300;
|
||||
line-height: 1;
|
||||
word-break: break-word;
|
||||
|
||||
@@ -187,7 +187,7 @@ export const WidgetFieldTitle = styled.div`
|
||||
text-transform: uppercase;
|
||||
font-size: 11px;
|
||||
margin-bottom: 2px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
`
|
||||
|
||||
export const WidgetFieldIcon = styled.div`
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
import 'fontsource-roboto'
|
||||
import { forwardRef, memo, useState } from 'react'
|
||||
import {
|
||||
UnfoldMore as UnfoldMoreIcon,
|
||||
@@ -6,7 +5,7 @@ import {
|
||||
Close as CloseIcon,
|
||||
Delete as DeleteIcon,
|
||||
} from '@material-ui/icons'
|
||||
import { getPeerString, humanizeSize, shortenText } from 'utils/Utils'
|
||||
import { getPeerString, humanizeSize, removeRedundantCharacters } from 'utils/Utils'
|
||||
import { torrentsHost } from 'utils/Hosts'
|
||||
import { NoImageIcon } from 'icons'
|
||||
import DialogTorrentDetailsContent from 'components/DialogTorrentDetailsContent'
|
||||
@@ -40,7 +39,21 @@ const Torrent = ({ torrent }) => {
|
||||
const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })
|
||||
const deleteTorrent = () => axios.post(torrentsHost(), { action: 'rem', hash })
|
||||
|
||||
const parsedTitle = (title || name) && ptt.parse(title || name).title
|
||||
const getParsedTitle = () => {
|
||||
const parse = key => ptt.parse(title || '')?.[key] || ptt.parse(name || '')?.[key]
|
||||
|
||||
const titleStrings = []
|
||||
|
||||
let parsedTitle = removeRedundantCharacters(parse('title'))
|
||||
const parsedYear = parse('year')
|
||||
const parsedResolution = parse('resolution')
|
||||
if (parsedTitle) titleStrings.push(parsedTitle)
|
||||
if (parsedYear) titleStrings.push(`(${parsedYear})`)
|
||||
if (parsedResolution) titleStrings.push(`[${parsedResolution}]`)
|
||||
parsedTitle = titleStrings.join(' ')
|
||||
return { parsedTitle }
|
||||
}
|
||||
const { parsedTitle } = getParsedTitle()
|
||||
|
||||
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
|
||||
const handleClickOpenEditDialog = () => setIsEditDialogOpen(true)
|
||||
@@ -78,7 +91,7 @@ const Torrent = ({ torrent }) => {
|
||||
<TorrentCardDescription>
|
||||
<div className='description-title-wrapper'>
|
||||
<div className='description-section-name'>{t('Name')}</div>
|
||||
<div className='description-torrent-title'>{shortenText(parsedTitle, 100)}</div>
|
||||
<div className='description-torrent-title'>{parsedTitle}</div>
|
||||
</div>
|
||||
|
||||
<div className='description-statistics-wrapper'>
|
||||
|
||||
@@ -87,10 +87,6 @@ export const TorrentCardDescription = styled.div`
|
||||
gap: 3px;
|
||||
}
|
||||
|
||||
@media (max-width: 770px) {
|
||||
grid-template-rows: 56% 1fr;
|
||||
}
|
||||
|
||||
.description-title-wrapper {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
@@ -99,7 +95,7 @@ export const TorrentCardDescription = styled.div`
|
||||
.description-section-name {
|
||||
text-transform: uppercase;
|
||||
font-size: 10px;
|
||||
font-weight: 500;
|
||||
font-weight: 600;
|
||||
letter-spacing: 0.4px;
|
||||
color: #216e47;
|
||||
|
||||
@@ -170,7 +166,6 @@ export const StyledButton = styled.button`
|
||||
background: #268757;
|
||||
color: #fff;
|
||||
font-size: 0.9rem;
|
||||
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
|
||||
letter-spacing: 0.009em;
|
||||
padding: 0 12px;
|
||||
svg {
|
||||
|
||||
@@ -1,21 +1,11 @@
|
||||
import { useState } from 'react'
|
||||
import { Typography } from '@material-ui/core'
|
||||
import { torrentsHost } from 'utils/Hosts'
|
||||
import TorrentCard from 'components/TorrentCard'
|
||||
import axios from 'axios'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import { TorrentListWrapper, CenteredGrid } from 'components/App/style'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useQuery } from 'react-query'
|
||||
|
||||
const getTorrents = async () => {
|
||||
try {
|
||||
const { data } = await axios.post(torrentsHost(), { action: 'list' })
|
||||
return data
|
||||
} catch (error) {
|
||||
throw new Error(null)
|
||||
}
|
||||
}
|
||||
import { getTorrents } from 'utils/Utils'
|
||||
|
||||
export default function TorrentList() {
|
||||
const { t } = useTranslation()
|
||||
|
||||
@@ -1,13 +1,20 @@
|
||||
body {
|
||||
*,
|
||||
*::before,
|
||||
*::after {
|
||||
margin: 0;
|
||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',
|
||||
'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',
|
||||
sans-serif;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
padding: 0;
|
||||
box-sizing: inherit;
|
||||
}
|
||||
|
||||
code {
|
||||
font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',
|
||||
monospace;
|
||||
body {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
box-sizing: border-box;
|
||||
-webkit-font-smoothing: antialiased;
|
||||
-moz-osx-font-smoothing: grayscale;
|
||||
letter-spacing: -0.1px;
|
||||
}
|
||||
|
||||
button {
|
||||
font-family: "Open Sans", sans-serif;
|
||||
letter-spacing: -0.1px;
|
||||
}
|
||||
@@ -2,21 +2,29 @@
|
||||
"About": "About",
|
||||
"Actions": "Actions",
|
||||
"Add": "Add",
|
||||
"AddDialog": {
|
||||
"AddPosterLinkInput": "Poster link",
|
||||
"AddTorrentSourceNotification": "First add your torrent source",
|
||||
"AppendFile": {
|
||||
"Or": "OR",
|
||||
"ClickOrDrag": "CLICK / DRAG & DROP (.torrent)"
|
||||
},
|
||||
"CustomTorrentTitle": "Custom title (optional)",
|
||||
"HashExists": "This torrent is already in database",
|
||||
"OriginalTorrentTitle": "Original torrent title",
|
||||
"TitleBlank": "Title (blank for orig. torrent title)",
|
||||
"TorrentSourceLink": "Torrent source link",
|
||||
"TorrentSourceOptions": "magnet / hash / .torrent file link",
|
||||
"WrongTorrentSource": "Wrong torrent source"
|
||||
},
|
||||
"AddFromLink": "Add from Link",
|
||||
"AddNewTorrent": "Add new torrent",
|
||||
"AddPosterLinkInput": "Poster link",
|
||||
"AddRetrackers": "Add retrackers",
|
||||
"AddTorrentSourceNotification": "First add your torrent source",
|
||||
"AppendFile": {
|
||||
"Or": "OR",
|
||||
"ClickOrDrag": "CLICK / DRAG & DROP (.torrent)"
|
||||
},
|
||||
"Buffer": "Preload Buffer / Cache",
|
||||
"BufferNote": "Enable “Preload Buffer” in settings to see cache loading progress",
|
||||
"Cache": "Cache",
|
||||
"CacheSize": "Cache Size (Megabytes)",
|
||||
"Cancel": "Cancel",
|
||||
"ChooseLanguage": "Russian",
|
||||
"Clear": "Clear",
|
||||
"Close": "Close",
|
||||
"CloseServer?": "Do you want to turn off server?",
|
||||
@@ -63,7 +71,6 @@
|
||||
"PEX": "PEX (Peer Exchange)",
|
||||
"PiecesCount": "Pieces count",
|
||||
"PiecesLength": "Pieces length",
|
||||
"PlaylistAll": "Playlist All",
|
||||
"Preload": "Preload",
|
||||
"PreloadBuffer": "Preload Buffer",
|
||||
"ReaderReadAHead": "Reader Read Ahead (5-100%)",
|
||||
@@ -86,7 +93,6 @@
|
||||
"Support": "Support",
|
||||
"TCP": "TCP (Transmission Control Protocol)",
|
||||
"ThanksToEveryone": "Thanks to everyone who tested and helped.",
|
||||
"Title": "Title",
|
||||
"TorrentAdded": "Added",
|
||||
"TorrentClosed": "Сlosed",
|
||||
"TorrentContent": "Torrent Content",
|
||||
@@ -96,8 +102,6 @@
|
||||
"TorrentInDb": "In DB",
|
||||
"TorrentPreload": "Preload",
|
||||
"TorrentSize": "Torrent size",
|
||||
"TorrentSourceLink": "Torrent source link",
|
||||
"TorrentSourceOptions": "magnet / hash / .torrent file link",
|
||||
"TorrentsSavePath": "Torrents Save Path",
|
||||
"TorrentState": "Torrent State",
|
||||
"TorrentStatus": "Torrent Status",
|
||||
@@ -111,6 +115,5 @@
|
||||
"UseDisk": "Use Disk for Cache",
|
||||
"UseDiskDesc": "Better use external media on flash-based devices",
|
||||
"UTP": "μTP (Micro Transport Protocol)",
|
||||
"Viewed": "Viewed",
|
||||
"WrongTorrentSource": "Wrong torrent source"
|
||||
"Viewed": "Viewed"
|
||||
}
|
||||
@@ -2,21 +2,29 @@
|
||||
"About": "О сервере",
|
||||
"Actions": "Действия",
|
||||
"Add": "Добавить",
|
||||
"AddDialog": {
|
||||
"AddPosterLinkInput": "Ссылка на постер",
|
||||
"AddTorrentSourceNotification": "Сначала добавьте torrent-источник",
|
||||
"AppendFile": {
|
||||
"Or": "ИЛИ",
|
||||
"ClickOrDrag": "НАЖМИТЕ / ПЕРЕТАЩИТЕ ФАЙЛ (.torrent)"
|
||||
},
|
||||
"CustomTorrentTitle": "Cвое имя (не обязательно)",
|
||||
"HashExists": "Этот торрент уже есть в базе данных",
|
||||
"OriginalTorrentTitle": "Оригинальное имя торрента",
|
||||
"TitleBlank": "Имя (пустое - ориг. имя торрента)",
|
||||
"TorrentSourceLink": "Ссылка на источник торрента",
|
||||
"TorrentSourceOptions": "magnet-ссылка / хеш / ссылка на .torrent файл",
|
||||
"WrongTorrentSource": "Неправильный torrent-источник"
|
||||
},
|
||||
"AddFromLink": "Добавить",
|
||||
"AddNewTorrent": "Добавить новый торрент",
|
||||
"AddPosterLinkInput": "Ссылка на постер",
|
||||
"AddRetrackers": "Добавлять",
|
||||
"AddTorrentSourceNotification": "Сначала добавьте torrent-источник",
|
||||
"AppendFile": {
|
||||
"Or": "ИЛИ",
|
||||
"ClickOrDrag": "НАЖМИТЕ / ПЕРЕТАЩИТЕ ФАЙЛ (.torrent)"
|
||||
},
|
||||
"Buffer": "Предзагрузка / Кеш",
|
||||
"BufferNote": "Включите «Наполнять кеш перед началом воспроизведения» в настройках для показа заполнения кеша",
|
||||
"Cache": "Кеш",
|
||||
"CacheSize": "Размер кеша (Мегабайты)",
|
||||
"Cancel": "Отмена",
|
||||
"ChooseLanguage": "Английский",
|
||||
"Clear": "Очистить",
|
||||
"Close": "Закрыть",
|
||||
"CloseServer?": "Хотите выключить сервер?",
|
||||
@@ -58,12 +66,11 @@
|
||||
"Offline": "Сервер не доступен",
|
||||
"OK": "OK",
|
||||
"OpenLink": "Открыть",
|
||||
"Peers": "Подкл./Пиры",
|
||||
"Peers": "Пиры",
|
||||
"PeersListenPort": "Порт для входящих подключений",
|
||||
"PEX": "PEX (Peer Exchange)",
|
||||
"PiecesCount": "Кол-во блоков",
|
||||
"PiecesLength": "Размер блока",
|
||||
"PlaylistAll": "Плейлист всех",
|
||||
"Preload": "Предзагр.",
|
||||
"PreloadBuffer": "Наполнять кеш перед началом воспроизведения",
|
||||
"ReaderReadAHead": "Кеш предзагрузки (5-100%, рек. 95%)",
|
||||
@@ -86,7 +93,6 @@
|
||||
"Support": "Поддержать",
|
||||
"TCP": "TCP (Transmission Control Protocol)",
|
||||
"ThanksToEveryone": "Спасибо всем, кто тестировал и помогал!",
|
||||
"Title": "Название",
|
||||
"TorrentAdded": "Добавлен",
|
||||
"TorrentClosed": "Закрыт",
|
||||
"TorrentContent": "Содержимое торрента",
|
||||
@@ -96,8 +102,6 @@
|
||||
"TorrentInDb": "Торрент в БД",
|
||||
"TorrentPreload": "Предзагрузка",
|
||||
"TorrentSize": "Размер торрента",
|
||||
"TorrentSourceLink": "Ссылка на источник торрента",
|
||||
"TorrentSourceOptions": "magnet-ссылка / хеш / ссылка на .torrent файл",
|
||||
"TorrentsSavePath": "Путь хранения кеша",
|
||||
"TorrentState": "Данные торрента",
|
||||
"TorrentStatus": "Состояние торрента",
|
||||
@@ -111,6 +115,5 @@
|
||||
"UseDisk": "Использовать диск для кеша",
|
||||
"UseDiskDesc": "Рекомендуется использовать внешние носители на устройствах с flash-памятью",
|
||||
"UTP": "μTP (Micro Transport Protocol)",
|
||||
"Viewed": "Просм.",
|
||||
"WrongTorrentSource": "Неправильный torrent-источник"
|
||||
"Viewed": "Просм."
|
||||
}
|
||||
@@ -10,7 +10,6 @@ export const settingsHost = () => `${torrserverHost}/settings`
|
||||
export const streamHost = () => `${torrserverHost}/stream`
|
||||
export const shutdownHost = () => `${torrserverHost}/shutdown`
|
||||
export const echoHost = () => `${torrserverHost}/echo`
|
||||
export const playlistAllHost = () => `${torrserverHost}/playlistall/all.m3u`
|
||||
export const playlistTorrHost = () => `${torrserverHost}/stream`
|
||||
|
||||
export const getTorrServerHost = () => torrserverHost
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import axios from 'axios'
|
||||
|
||||
import { torrentsHost } from './Hosts'
|
||||
|
||||
export function humanizeSize(size) {
|
||||
if (!size) return ''
|
||||
const i = Math.floor(Math.log(size) / Math.log(1024))
|
||||
return `${(size / Math.pow(1024, i)).toFixed(2) * 1} ${['B', 'kB', 'MB', 'GB', 'TB'][i]}`
|
||||
return `${(size / Math.pow(1024, i)).toFixed(2) * 1} ${['B', 'KB', 'MB', 'GB', 'TB'][i]}`
|
||||
}
|
||||
|
||||
export function getPeerString(torrent) {
|
||||
@@ -10,4 +14,43 @@ export function getPeerString(torrent) {
|
||||
}
|
||||
|
||||
export const shortenText = (text, sympolAmount) =>
|
||||
text ? text.slice(0, sympolAmount) + (text.length > sympolAmount ? '...' : '') : ''
|
||||
text ? text.slice(0, sympolAmount) + (text.length > sympolAmount ? '…' : '') : ''
|
||||
|
||||
export const removeRedundantCharacters = string => {
|
||||
let newString = string
|
||||
const brackets = [
|
||||
['(', ')'],
|
||||
['[', ']'],
|
||||
['{', '}'],
|
||||
]
|
||||
|
||||
brackets.forEach(el => {
|
||||
const leftBracketRegexFormula = `\\${el[0]}`
|
||||
const leftBracketRegex = new RegExp(leftBracketRegexFormula, 'g')
|
||||
const leftBracketAmount = [...newString.matchAll(leftBracketRegex)].length
|
||||
const rightBracketRegexFormula = `\\${el[1]}`
|
||||
const rightBracketRegex = new RegExp(rightBracketRegexFormula, 'g')
|
||||
const rightBracketAmount = [...newString.matchAll(rightBracketRegex)].length
|
||||
|
||||
if (leftBracketAmount !== rightBracketAmount) {
|
||||
const removeFormula = `(\\${el[0]})(?!.*\\1).*`
|
||||
const removeRegex = new RegExp(removeFormula, 'g')
|
||||
newString = newString.replace(removeRegex, '')
|
||||
}
|
||||
})
|
||||
|
||||
const hasThreeDotsAtTheEnd = !!newString.match(/\.{3}$/g)
|
||||
|
||||
const trimmedString = newString.replace(/[\\.| ]+$/g, '').trim()
|
||||
|
||||
return hasThreeDotsAtTheEnd ? `${trimmedString}..` : trimmedString
|
||||
}
|
||||
|
||||
export const getTorrents = async () => {
|
||||
try {
|
||||
const { data } = await axios.post(torrentsHost(), { action: 'list' })
|
||||
return data
|
||||
} catch (error) {
|
||||
throw new Error(null)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5808,11 +5808,6 @@ follow-redirects@^1.0.0, follow-redirects@^1.10.0:
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.14.1.tgz#d9114ded0a1cfdd334e164e6662ad02bfd91ff43"
|
||||
integrity sha512-HWqDgT7ZEkqRzBvc2s64vSZ/hfOceEol3ac/7tKwzuvEyWx3/4UegXh5oBOIotkGsObyk3xznnSRVADBgWSQVg==
|
||||
|
||||
fontsource-roboto@^4.0.0:
|
||||
version "4.0.0"
|
||||
resolved "https://registry.yarnpkg.com/fontsource-roboto/-/fontsource-roboto-4.0.0.tgz#35eacd4fb8d90199053c0eec9b34a57fb79cd820"
|
||||
integrity sha512-zD6L8nvdWRcwSgp4ojxFchG+MPj8kXXQKDEAH9bfhbxy+lkpvpC1WgAK0lCa4dwobv+hvAe0uyHaawcgH7WH/g==
|
||||
|
||||
for-each@^0.3.3:
|
||||
version "0.3.3"
|
||||
resolved "https://registry.yarnpkg.com/for-each/-/for-each-0.3.3.tgz#69b447e88a0a5d32c3e7084f3f1710034b21376e"
|
||||
|
||||