diff --git a/server/web/api/torrents.go b/server/web/api/torrents.go
index d94a28a..34cef2a 100644
--- a/server/web/api/torrents.go
+++ b/server/web/api/torrents.go
@@ -72,6 +72,10 @@ func torrents(c *gin.Context) {
{
dropTorrent(req, c)
}
+ case "wipe":
+ {
+ wipeTorrents(req, c)
+ }
}
}
@@ -184,3 +188,16 @@ func dropTorrent(req torrReqJS, c *gin.Context) {
torr.DropTorrent(req.Hash)
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)
+}
diff --git a/web/src/components/CloseServer.jsx b/web/src/components/CloseServer.jsx
index 160c1d9..f652c4f 100644
--- a/web/src/components/CloseServer.jsx
+++ b/web/src/components/CloseServer.jsx
@@ -1,11 +1,12 @@
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()
@@ -41,7 +42,9 @@ export default function CloseServer({ isOffline, isLoading }) {
{t('Cancel')}
- }
variant='contained'
onClick={() => {
fetch(shutdownHost())
@@ -51,7 +54,7 @@ export default function CloseServer({ isOffline, isLoading }) {
autoFocus
>
{t('TurnOff')}
-
+
>
diff --git a/web/src/components/RemoveAll.jsx b/web/src/components/RemoveAll.jsx
index 8fccfc1..faa4874 100644
--- a/web/src/components/RemoveAll.jsx
+++ b/web/src/components/RemoveAll.jsx
@@ -6,29 +6,17 @@ import DeleteIcon from '@material-ui/icons/Delete'
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 +42,9 @@ export default function RemoveAll({ isOffline, isLoading }) {
{t('Cancel')}
- }
variant='contained'
onClick={() => {
fnRemoveAll()
@@ -64,7 +54,7 @@ export default function RemoveAll({ isOffline, isLoading }) {
autoFocus
>
{t('OK')}
-
+
>
diff --git a/web/src/components/UnsafeButton.jsx b/web/src/components/UnsafeButton.jsx
new file mode 100644
index 0000000..6edd730
--- /dev/null
+++ b/web/src/components/UnsafeButton.jsx
@@ -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 (
+
+ )
+}