mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 13:36:09 +05:00
Merge branch 'master' into 230-torrents-category
This commit is contained in:
@@ -85,13 +85,16 @@ export default function AboutDialog() {
|
||||
<LinkComponent name='tw1cker' link='https://github.com/Nemiroff' />
|
||||
<LinkComponent name='SpAwN_LMG' link='https://github.com/spawnlmg' />
|
||||
<LinkComponent name='damiva' link='https://github.com/damiva' />
|
||||
<LinkComponent name='Vladlenas' link='https://github.com/vladlenas' />
|
||||
<LinkComponent name='Anton Potekhin' link='https://github.com/Anton111111' />
|
||||
<LinkComponent name='FaintGhost' link='https://github.com/FaintGhost' />
|
||||
<LinkComponent name='TopperBG' link='https://github.com/TopperBG' />
|
||||
<LinkComponent name='FaintGhost' link='https://github.com/FaintGhost' />
|
||||
<LinkComponent name='lieranderl' link='https://github.com/lieranderl' />
|
||||
<LinkComponent name='Evgeni' link='https://github.com/lieranderl' />
|
||||
<LinkComponent name='cocool97' link='https://github.com/cocool97' />
|
||||
<LinkComponent name='shadeov' link='https://github.com/shadeov' />
|
||||
<LinkComponent name='Pavel' link='https://github.com/butaford' />
|
||||
<LinkComponent name='Alexey Filimonov' link='https://github.com/filimonic' />
|
||||
<LinkComponent name='Viacheslav Evseev' link='https://github.com/leporel' />
|
||||
</div>
|
||||
</Section>
|
||||
</div>
|
||||
|
||||
@@ -39,7 +39,11 @@ export default function LeftSideComponent({
|
||||
}
|
||||
|
||||
const [isTorrentSourceActive, setIsTorrentSourceActive] = useState(false)
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: handleCapture, accept: '.torrent' })
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({
|
||||
onDrop: handleCapture,
|
||||
accept: '.torrent',
|
||||
multiple: false,
|
||||
})
|
||||
|
||||
const handleTorrentSourceChange = ({ target: { value } }) => setTorrentSource(value)
|
||||
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
import { useState } from 'react'
|
||||
import { Button, DialogActions, DialogTitle, ListItemIcon, ListItemText } from '@material-ui/core'
|
||||
import { StyledDialog, StyledMenuButtonWrapper } from 'style/CustomMaterialUiStyles'
|
||||
import { PowerSettingsNew as PowerSettingsNewIcon } from '@material-ui/icons'
|
||||
import { PowerSettingsNew as PowerSettingsNewIcon, PowerOff as PowerOffIcon } from '@material-ui/icons'
|
||||
import { shutdownHost } from 'utils/Hosts'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { isStandaloneApp } from 'utils/Utils'
|
||||
import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick'
|
||||
|
||||
import UnsafeButton from './UnsafeButton'
|
||||
|
||||
export default function CloseServer({ isOffline, isLoading }) {
|
||||
const { t } = useTranslation()
|
||||
const [open, setOpen] = useState(false)
|
||||
@@ -41,7 +43,9 @@ export default function CloseServer({ isOffline, isLoading }) {
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
<UnsafeButton
|
||||
timeout={5}
|
||||
startIcon={<PowerOffIcon />}
|
||||
variant='contained'
|
||||
onClick={() => {
|
||||
fetch(shutdownHost())
|
||||
@@ -51,7 +55,7 @@ export default function CloseServer({ isOffline, isLoading }) {
|
||||
autoFocus
|
||||
>
|
||||
{t('TurnOff')}
|
||||
</Button>
|
||||
</UnsafeButton>
|
||||
</DialogActions>
|
||||
</StyledDialog>
|
||||
</>
|
||||
|
||||
@@ -12,6 +12,7 @@ const playableExtList = [
|
||||
'avchd',
|
||||
'avi',
|
||||
'drc',
|
||||
'dv',
|
||||
'flv',
|
||||
'iso',
|
||||
'm2v',
|
||||
@@ -27,9 +28,9 @@ const playableExtList = [
|
||||
'mpeg',
|
||||
'mpg',
|
||||
'mpv',
|
||||
'mts',
|
||||
'mxf',
|
||||
'nsv',
|
||||
'ogg',
|
||||
'ogv',
|
||||
'ts',
|
||||
'qt',
|
||||
@@ -46,6 +47,9 @@ const playableExtList = [
|
||||
'aiff',
|
||||
'ape',
|
||||
'au',
|
||||
'dsd',
|
||||
'dff',
|
||||
'dsf',
|
||||
'flac',
|
||||
'gsm',
|
||||
'it',
|
||||
@@ -55,11 +59,15 @@ const playableExtList = [
|
||||
'mod',
|
||||
'mp3',
|
||||
'mpa',
|
||||
'oga',
|
||||
'ogg',
|
||||
'opus',
|
||||
'pls',
|
||||
'ra',
|
||||
's3m',
|
||||
'sid',
|
||||
'wav',
|
||||
'weba',
|
||||
'wma',
|
||||
'xm',
|
||||
]
|
||||
|
||||
@@ -52,7 +52,7 @@ export const PeersWidget = ({ data }) => {
|
||||
return (
|
||||
<StatisticsField
|
||||
title={t('Peers')}
|
||||
value={getPeerString(data) || '0 · 0 / 0'}
|
||||
value={getPeerString(data) || '0 / 0 · 0'}
|
||||
iconBg={iconBGColor}
|
||||
valueBg={valueBGColor}
|
||||
icon={SwapVerticalCircleIcon}
|
||||
|
||||
@@ -7,28 +7,17 @@ import { useState } from 'react'
|
||||
import { torrentsHost } from 'utils/Hosts'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
|
||||
import UnsafeButton from './UnsafeButton'
|
||||
|
||||
const fnRemoveAll = () => {
|
||||
fetch(torrentsHost(), {
|
||||
method: 'post',
|
||||
body: JSON.stringify({ action: 'list' }),
|
||||
body: JSON.stringify({ action: 'wipe' }),
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
.then(res => res.json())
|
||||
.then(json => {
|
||||
json.forEach(torr => {
|
||||
fetch(torrentsHost(), {
|
||||
method: 'post',
|
||||
body: JSON.stringify({ action: 'rem', hash: torr.hash }),
|
||||
headers: {
|
||||
Accept: 'application/json, text/plain, */*',
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
export default function RemoveAll({ isOffline, isLoading }) {
|
||||
@@ -54,7 +43,9 @@ export default function RemoveAll({ isOffline, isLoading }) {
|
||||
{t('Cancel')}
|
||||
</Button>
|
||||
|
||||
<Button
|
||||
<UnsafeButton
|
||||
timeout={5}
|
||||
startIcon={<DeleteIcon />}
|
||||
variant='contained'
|
||||
onClick={() => {
|
||||
fnRemoveAll()
|
||||
@@ -64,7 +55,7 @@ export default function RemoveAll({ isOffline, isLoading }) {
|
||||
autoFocus
|
||||
>
|
||||
{t('OK')}
|
||||
</Button>
|
||||
</UnsafeButton>
|
||||
</DialogActions>
|
||||
</Dialog>
|
||||
</>
|
||||
|
||||
@@ -16,10 +16,11 @@ export default function AddFirstTorrent() {
|
||||
<>
|
||||
<IconWrapper onClick={() => handleClickOpen(true)} isButton>
|
||||
<lord-icon
|
||||
src='https://cdn.lordicon.com/bbnkwdur.json'
|
||||
src='https://cdn.lordicon.com/jkzgajyr.json'
|
||||
trigger='loop'
|
||||
colors={`primary:#121331,secondary:${primary}`}
|
||||
stroke='26'
|
||||
delay='2000'
|
||||
colors={`primary:#575757,secondary:${primary}`}
|
||||
stroke='light'
|
||||
scale='60'
|
||||
/>
|
||||
<div className='icon-label'>{t('NoTorrentsAdded')}</div>
|
||||
|
||||
29
web/src/components/UnsafeButton.jsx
Normal file
29
web/src/components/UnsafeButton.jsx
Normal file
@@ -0,0 +1,29 @@
|
||||
import { Button } from '@material-ui/core'
|
||||
import { useEffect, useState } from 'react'
|
||||
|
||||
export default function UnsafeButton({ timeout, children, disabled, ...props }) {
|
||||
const [timeLeft, setTimeLeft] = useState(timeout || 7)
|
||||
const [buttonDisabled, setButtonDisabled] = useState(disabled || timeLeft > 0)
|
||||
const handleTimerTick = () => {
|
||||
const newTimeLeft = timeLeft - 1
|
||||
setTimeLeft(newTimeLeft)
|
||||
if (newTimeLeft <= 0) {
|
||||
setButtonDisabled(disabled)
|
||||
}
|
||||
}
|
||||
const getTimerText = () => (!disabled && timeLeft > 0 ? ` (${timeLeft})` : '')
|
||||
useEffect(() => {
|
||||
if (disabled || !timeLeft) {
|
||||
return
|
||||
}
|
||||
const intervalId = setInterval(handleTimerTick, 1000)
|
||||
return () => clearInterval(intervalId)
|
||||
// eslint-disable-next-line
|
||||
}, [timeLeft])
|
||||
|
||||
return (
|
||||
<Button disabled={buttonDisabled} {...props}>
|
||||
{children} {getTimerText()}
|
||||
</Button>
|
||||
)
|
||||
}
|
||||
@@ -72,7 +72,7 @@
|
||||
"Offline": "Извън линия",
|
||||
"OK": "OK",
|
||||
"OpenLink": "Отвори линк",
|
||||
"Peers": "Пиъри",
|
||||
"Peers": "Пиъри·Сийдъри",
|
||||
"PiecesCount": "Брой парчета",
|
||||
"PiecesLength": "Дължина на парчетата",
|
||||
"Playlist": "Плейлист",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"Offline": "Offline",
|
||||
"OK": "OK",
|
||||
"OpenLink": "Open link",
|
||||
"Peers": "Peers",
|
||||
"Peers": "Peers·Seeds",
|
||||
"PiecesCount": "Pieces count",
|
||||
"PiecesLength": "Pieces length",
|
||||
"Playlist": "Playlist",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"Offline": "Сервер недоступен",
|
||||
"OK": "OK",
|
||||
"OpenLink": "Открыть",
|
||||
"Peers": "Пиры",
|
||||
"Peers": "Пиры·Сиды",
|
||||
"PiecesCount": "Кол-во блоков",
|
||||
"PiecesLength": "Размер блока",
|
||||
"Playlist": "Плейлист",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"Offline": "Сервер не доступний",
|
||||
"OK": "OK",
|
||||
"OpenLink": "Відкрити",
|
||||
"Peers": "Піри",
|
||||
"Peers": "Піри·Сіди",
|
||||
"PiecesCount": "К-сть блоків",
|
||||
"PiecesLength": "Розмір блоку",
|
||||
"Playlist": "Плейлист",
|
||||
|
||||
@@ -72,7 +72,7 @@
|
||||
"Offline": "离线",
|
||||
"OK": "确定",
|
||||
"OpenLink": "打开链接",
|
||||
"Peers": "Peers",
|
||||
"Peers": "Peers·Seeds",
|
||||
"PiecesCount": "块数量",
|
||||
"PiecesLength": "块长度",
|
||||
"Playlist": "播放列表",
|
||||
|
||||
@@ -20,8 +20,9 @@ export function humanizeSpeed(speed) {
|
||||
}
|
||||
|
||||
export function getPeerString(torrent) {
|
||||
if (!torrent || !torrent.connected_seeders) return null
|
||||
return `${torrent.connected_seeders} · ${torrent.active_peers} / ${torrent.total_peers}`
|
||||
if (!torrent || !torrent.active_peers) return null
|
||||
const seeders = typeof torrent.connected_seeders !== 'undefined' ? torrent.connected_seeders : 0
|
||||
return `${torrent.active_peers} / ${torrent.total_peers} · ${seeders}`
|
||||
}
|
||||
|
||||
export const shortenText = (text, sympolAmount) =>
|
||||
|
||||
@@ -5230,13 +5230,14 @@ es-to-primitive@^1.2.1:
|
||||
is-date-object "^1.0.1"
|
||||
is-symbol "^1.0.2"
|
||||
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50:
|
||||
version "0.10.62"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.62.tgz#5e6adc19a6da524bf3d1e02bbc8960e5eb49a9a5"
|
||||
integrity sha512-BHLqn0klhEpnOKSrzn/Xsz2UIW8j+cGmo9JLzr8BiUapV8hPL9+FliFqjwr9ngW7jWdnxv6eO+/LqyhJVqgrjA==
|
||||
es5-ext@^0.10.35, es5-ext@^0.10.46, es5-ext@^0.10.50, es5-ext@^0.10.62, es5-ext@~0.10.14:
|
||||
version "0.10.63"
|
||||
resolved "https://registry.yarnpkg.com/es5-ext/-/es5-ext-0.10.63.tgz#9c222a63b6a332ac80b1e373b426af723b895bd6"
|
||||
integrity sha512-hUCZd2Byj/mNKjfP9jXrdVZ62B8KuA/VoK7X8nUh5qT+AxDmcbvZz041oDVZdbIN1qW6XY9VDNwzkvKnZvK2TQ==
|
||||
dependencies:
|
||||
es6-iterator "^2.0.3"
|
||||
es6-symbol "^3.1.3"
|
||||
esniff "^2.0.1"
|
||||
next-tick "^1.1.0"
|
||||
|
||||
es6-iterator@2.0.3, es6-iterator@^2.0.1, es6-iterator@^2.0.3:
|
||||
@@ -5559,6 +5560,16 @@ eslint@^7.11.0, eslint@^7.27.0:
|
||||
text-table "^0.2.0"
|
||||
v8-compile-cache "^2.0.3"
|
||||
|
||||
esniff@^2.0.1:
|
||||
version "2.0.1"
|
||||
resolved "https://registry.yarnpkg.com/esniff/-/esniff-2.0.1.tgz#a4d4b43a5c71c7ec51c51098c1d8a29081f9b308"
|
||||
integrity sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg==
|
||||
dependencies:
|
||||
d "^1.0.1"
|
||||
es5-ext "^0.10.62"
|
||||
event-emitter "^0.3.5"
|
||||
type "^2.7.2"
|
||||
|
||||
espree@^7.3.0, espree@^7.3.1:
|
||||
version "7.3.1"
|
||||
resolved "https://registry.yarnpkg.com/espree/-/espree-7.3.1.tgz#f2df330b752c6f55019f8bd89b7660039c1bbbb6"
|
||||
@@ -5622,6 +5633,14 @@ etag@~1.8.1:
|
||||
resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.1.tgz#41ae2eeb65efa62268aebfea83ac7d79299b0887"
|
||||
integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg==
|
||||
|
||||
event-emitter@^0.3.5:
|
||||
version "0.3.5"
|
||||
resolved "https://registry.yarnpkg.com/event-emitter/-/event-emitter-0.3.5.tgz#df8c69eef1647923c7157b9ce83840610b02cc39"
|
||||
integrity sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==
|
||||
dependencies:
|
||||
d "1"
|
||||
es5-ext "~0.10.14"
|
||||
|
||||
eventemitter3@^4.0.0:
|
||||
version "4.0.7"
|
||||
resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-4.0.7.tgz#2de9b68f6528d5644ef5c59526a1b4a07306169f"
|
||||
@@ -6037,9 +6056,9 @@ flush-write-stream@^1.0.0, flush-write-stream@^1.0.2:
|
||||
readable-stream "^2.3.6"
|
||||
|
||||
follow-redirects@^1.0.0, follow-redirects@^1.15.0:
|
||||
version "1.15.3"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.3.tgz#fe2f3ef2690afce7e82ed0b44db08165b207123a"
|
||||
integrity sha512-1VzOtuEM8pC9SFU1E+8KfTjZyMztRsgEfwQl44z8A25uy13jSzTj6dyK2Df52iV0vgHCfBwLhDWevLn95w5v6Q==
|
||||
version "1.15.4"
|
||||
resolved "https://registry.yarnpkg.com/follow-redirects/-/follow-redirects-1.15.4.tgz#cdc7d308bf6493126b17ea2191ea0ccf3e535adf"
|
||||
integrity sha512-Cr4D/5wlrb0z9dgERpUL3LrmPKVDsETIJhaCMeDfuFYcqa5bldGV6wBsAN6X/vxlXQtFBMrXdXxdL8CbDTGniw==
|
||||
|
||||
for-each@^0.3.3:
|
||||
version "0.3.3"
|
||||
@@ -7063,9 +7082,9 @@ ip-regex@^2.1.0:
|
||||
integrity sha512-58yWmlHpp7VYfcdTwMTvwMmqx/Elfxjd9RXTDyMsbL7lLWmhMylLEqiYVLKuLzOZqVgiWXD9MfR62Vv89VRxkw==
|
||||
|
||||
ip@^1.1.0, ip@^1.1.5:
|
||||
version "1.1.8"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.8.tgz#ae05948f6b075435ed3307acce04629da8cdbf48"
|
||||
integrity sha512-PuExPYUiu6qMBQb4l06ecm6T6ujzhmh+MeJcW9wa89PoAz5pvd4zPgN5WJV104mb6S2T1AwNIAaB70JNrLQWhg==
|
||||
version "1.1.9"
|
||||
resolved "https://registry.yarnpkg.com/ip/-/ip-1.1.9.tgz#8dfbcc99a754d07f425310b86a99546b1151e396"
|
||||
integrity sha512-cyRxvOEpNHNtchU3Ln9KC/auJgup87llfQpQ+t5ghoC/UhL16SWzbueiCsdTnWmqAWl7LadfuwhlqmtOaqMHdQ==
|
||||
|
||||
ipaddr.js@1.9.1, ipaddr.js@^1.9.0:
|
||||
version "1.9.1"
|
||||
|
||||
Reference in New Issue
Block a user