Move wipe to server side. Add UI unsafe buttons (#355)

* move 'remove all' function to server side ('wipe')

* add UnsafeButton to RemoveAll and CloseServer webui
This commit is contained in:
Alexey D. Filimonov
2024-02-15 09:14:58 +03:00
committed by GitHub
parent d1b29bd848
commit 5e71af9751
4 changed files with 55 additions and 19 deletions

View File

@@ -72,6 +72,10 @@ func torrents(c *gin.Context) {
{ {
dropTorrent(req, c) dropTorrent(req, c)
} }
case "wipe":
{
wipeTorrents(req, c)
}
} }
} }
@@ -184,3 +188,16 @@ func dropTorrent(req torrReqJS, c *gin.Context) {
torr.DropTorrent(req.Hash) torr.DropTorrent(req.Hash)
c.Status(200) c.Status(200)
} }
func wipeTorrents(req torrReqJS, c *gin.Context) {
torrents := torr.ListTorrent()
for _, t := range torrents {
torr.RemTorrent(t.TorrentSpec.InfoHash.HexString())
}
// TODO: remove (copied todo from remTorrent())
if set.BTsets.EnableDLNA {
dlna.Stop()
dlna.Start()
}
c.Status(200)
}

View File

@@ -1,11 +1,12 @@
import { useState } from 'react' import { useState } from 'react'
import { Button, DialogActions, DialogTitle, ListItemIcon, ListItemText } from '@material-ui/core' import { Button, DialogActions, DialogTitle, ListItemIcon, ListItemText } from '@material-ui/core'
import { StyledDialog, StyledMenuButtonWrapper } from 'style/CustomMaterialUiStyles' 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 { shutdownHost } from 'utils/Hosts'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import { isStandaloneApp } from 'utils/Utils' import { isStandaloneApp } from 'utils/Utils'
import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick' import useOnStandaloneAppOutsideClick from 'utils/useOnStandaloneAppOutsideClick'
import UnsafeButton from './UnsafeButton'
export default function CloseServer({ isOffline, isLoading }) { export default function CloseServer({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()
@@ -41,7 +42,9 @@ export default function CloseServer({ isOffline, isLoading }) {
{t('Cancel')} {t('Cancel')}
</Button> </Button>
<Button <UnsafeButton
timeout={5}
startIcon={<PowerOffIcon />}
variant='contained' variant='contained'
onClick={() => { onClick={() => {
fetch(shutdownHost()) fetch(shutdownHost())
@@ -51,7 +54,7 @@ export default function CloseServer({ isOffline, isLoading }) {
autoFocus autoFocus
> >
{t('TurnOff')} {t('TurnOff')}
</Button> </UnsafeButton>
</DialogActions> </DialogActions>
</StyledDialog> </StyledDialog>
</> </>

View File

@@ -6,29 +6,17 @@ import DeleteIcon from '@material-ui/icons/Delete'
import { useState } from 'react' import { useState } from 'react'
import { torrentsHost } from 'utils/Hosts' import { torrentsHost } from 'utils/Hosts'
import { useTranslation } from 'react-i18next' import { useTranslation } from 'react-i18next'
import UnsafeButton from './UnsafeButton'
const fnRemoveAll = () => { const fnRemoveAll = () => {
fetch(torrentsHost(), { fetch(torrentsHost(), {
method: 'post', method: 'post',
body: JSON.stringify({ action: 'list' }), body: JSON.stringify({ action: 'wipe' }),
headers: { headers: {
Accept: 'application/json, text/plain, */*', Accept: 'application/json, text/plain, */*',
'Content-Type': 'application/json', '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 }) { export default function RemoveAll({ isOffline, isLoading }) {
@@ -54,7 +42,9 @@ export default function RemoveAll({ isOffline, isLoading }) {
{t('Cancel')} {t('Cancel')}
</Button> </Button>
<Button <UnsafeButton
timeout={5}
startIcon={<DeleteIcon />}
variant='contained' variant='contained'
onClick={() => { onClick={() => {
fnRemoveAll() fnRemoveAll()
@@ -64,7 +54,7 @@ export default function RemoveAll({ isOffline, isLoading }) {
autoFocus autoFocus
> >
{t('OK')} {t('OK')}
</Button> </UnsafeButton>
</DialogActions> </DialogActions>
</Dialog> </Dialog>
</> </>

View File

@@ -0,0 +1,26 @@
import { Button } from '@material-ui/core';
import { useEffect, useRef, 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)
}, [timeLeft])
return (
<Button disabled={buttonDisabled} {...props}>
{children} {getTimerText()}
</Button>
)
}