Merge branch 'master' into use-auto-dark-palette-and-About

This commit is contained in:
nikk
2021-06-17 20:39:16 +03:00
committed by GitHub
12 changed files with 136 additions and 56 deletions

View File

@@ -21,7 +21,8 @@
<body> <body>
<noscript>You need to enable JavaScript to run this app.</noscript> <noscript>You need to enable JavaScript to run this app.</noscript>
<div id="root"></div> <div id="root"></div>
<script src='https://cdn.lordicon.com/libs/frhvbuzj/lord-icon-2.0.2.js' />
<script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-app.js"></script> <script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-analytics.js"></script> <script src="https://www.gstatic.com/firebasejs/8.1.2/firebase-analytics.js"></script>
<script> <script>

View File

@@ -46,10 +46,7 @@ export default function AddDialog({
const [skipDebounce, setSkipDebounce] = useState(false) const [skipDebounce, setSkipDebounce] = useState(false)
const [isCustomTitleEnabled, setIsCustomTitleEnabled] = useState(false) const [isCustomTitleEnabled, setIsCustomTitleEnabled] = useState(false)
const { data: torrents } = useQuery('torrents', getTorrents, { const { data: torrents } = useQuery('torrents', getTorrents, { retry: 1, refetchInterval: 1000 })
retry: 1,
refetchInterval: 1000,
})
useEffect(() => { useEffect(() => {
const allHashes = torrents.map(({ hash }) => hash) const allHashes = torrents.map(({ hash }) => hash)

View File

@@ -7,7 +7,7 @@ import { useTranslation } from 'react-i18next'
import AddDialog from './AddDialog' import AddDialog from './AddDialog'
export default function AddDialogButton() { export default function AddDialogButton({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()
const [isDialogOpen, setIsDialogOpen] = useState(false) const [isDialogOpen, setIsDialogOpen] = useState(false)
const handleClickOpen = () => setIsDialogOpen(true) const handleClickOpen = () => setIsDialogOpen(true)
@@ -15,7 +15,7 @@ export default function AddDialogButton() {
return ( return (
<div> <div>
<ListItem button key='Add' onClick={handleClickOpen}> <ListItem disabled={isOffline || isLoading} button key='Add' onClick={handleClickOpen}>
<ListItemIcon> <ListItemIcon>
<LibraryAddIcon /> <LibraryAddIcon />
</ListItemIcon> </ListItemIcon>

View File

@@ -10,24 +10,26 @@ import SettingsDialog from 'components/Settings'
import RemoveAll from 'components/RemoveAll' import RemoveAll from 'components/RemoveAll'
import AboutDialog from 'components/About' import AboutDialog from 'components/About'
import CloseServer from 'components/CloseServer' import CloseServer from 'components/CloseServer'
import { memo } from 'react'
import { AppSidebarStyle } from './style' import { AppSidebarStyle } from './style'
export default function Sidebar({ isDrawerOpen, setIsDonationDialogOpen }) { const Sidebar = ({ isDrawerOpen, setIsDonationDialogOpen, isOffline, isLoading }) => {
const { t } = useTranslation() const { t } = useTranslation()
return ( return (
<AppSidebarStyle isDrawerOpen={isDrawerOpen}> <AppSidebarStyle isDrawerOpen={isDrawerOpen}>
<List> <List>
<AddDialogButton /> <AddDialogButton isOffline={isOffline} isLoading={isLoading} />
<RemoveAll />
<RemoveAll isOffline={isOffline} isLoading={isLoading} />
</List> </List>
<Divider /> <Divider />
<List> <List>
<SettingsDialog /> <SettingsDialog />
<CloseServer /> <CloseServer isOffline={isOffline} isLoading={isLoading} />
</List> </List>
<Divider /> <Divider />
@@ -45,3 +47,5 @@ export default function Sidebar({ isDrawerOpen, setIsDonationDialogOpen }) {
</AppSidebarStyle> </AppSidebarStyle>
) )
} }
export default memo(Sidebar)

View File

@@ -13,6 +13,8 @@ import DonateSnackbar from 'components/Donate'
import DonateDialog from 'components/Donate/DonateDialog' import DonateDialog from 'components/Donate/DonateDialog'
import useChangeLanguage from 'utils/useChangeLanguage' import useChangeLanguage from 'utils/useChangeLanguage'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { useQuery } from 'react-query'
import { getTorrents } from 'utils/Utils'
import { AppWrapper, AppHeader, LanguageSwitch } from './style' import { AppWrapper, AppHeader, LanguageSwitch } from './style'
import Sidebar from './Sidebar' import Sidebar from './Sidebar'
@@ -56,6 +58,13 @@ export default function App() {
[prefersDarkMode], [prefersDarkMode],
) )
const [currentLang, changeLang] = useChangeLanguage() const [currentLang, changeLang] = useChangeLanguage()
const [isOffline, setIsOffline] = useState(false)
const { data: torrents, isLoading } = useQuery('torrents', getTorrents, {
retry: 1,
refetchInterval: 1000,
onError: () => setIsOffline(true),
onSuccess: () => setIsOffline(false),
})
useEffect(() => { useEffect(() => {
axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data)) axios.get(echoHost()).then(({ data }) => setTorrServerVersion(data))

View File

@@ -6,7 +6,7 @@ import { useTranslation } from 'react-i18next'
import { ThemeProvider } from '@material-ui/core/styles' import { ThemeProvider } from '@material-ui/core/styles'
import { lightTheme } from 'components/App' import { lightTheme } from 'components/App'
export default function CloseServer() { export default function CloseServer({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const closeDialog = () => setOpen(false) const closeDialog = () => setOpen(false)
@@ -14,7 +14,7 @@ export default function CloseServer() {
return ( return (
<> <>
<ListItem button key={t('CloseServer')} onClick={openDialog}> <ListItem disabled={isOffline || isLoading} button key={t('CloseServer')} onClick={openDialog}>
<ListItemIcon> <ListItemIcon>
<PowerSettingsNewIcon /> <PowerSettingsNewIcon />
</ListItemIcon> </ListItemIcon>

View File

@@ -33,14 +33,15 @@ const fnRemoveAll = () => {
}) })
} }
export default function RemoveAll() { export default function RemoveAll({ isOffline, isLoading }) {
const { t } = useTranslation() const { t } = useTranslation()
const [open, setOpen] = useState(false) const [open, setOpen] = useState(false)
const closeDialog = () => setOpen(false) const closeDialog = () => setOpen(false)
const openDialog = () => setOpen(true) const openDialog = () => setOpen(true)
return ( return (
<> <>
<ListItem button key={t('RemoveAll')} onClick={openDialog}> <ListItem disabled={isOffline || isLoading} button key={t('RemoveAll')} onClick={openDialog}>
<ListItemIcon> <ListItemIcon>
<DeleteIcon /> <DeleteIcon />
</ListItemIcon> </ListItemIcon>

View File

@@ -1,41 +0,0 @@
import { useState } from 'react'
import { Typography } from '@material-ui/core'
import TorrentCard from 'components/TorrentCard'
import CircularProgress from '@material-ui/core/CircularProgress'
import { TorrentListWrapper, CenteredGrid } from 'components/App/style'
import { useTranslation } from 'react-i18next'
import { useQuery } from 'react-query'
import { getTorrents } from 'utils/Utils'
export default function TorrentList() {
const { t } = useTranslation()
const [isOffline, setIsOffline] = useState(false)
const { data: torrents, isLoading } = useQuery('torrents', getTorrents, {
retry: 1,
refetchInterval: 1000,
onError: () => setIsOffline(true),
onSuccess: () => setIsOffline(false),
})
if (isLoading || isOffline || !torrents.length) {
return (
<CenteredGrid>
{isOffline ? (
<Typography>{t('Offline')}</Typography>
) : isLoading ? (
<CircularProgress />
) : (
!torrents.length && <Typography>{t('NoTorrentsAdded')}</Typography>
)}
</CenteredGrid>
)
}
return (
<TorrentListWrapper>
{torrents.map(torrent => (
<TorrentCard key={torrent.hash} torrent={torrent} />
))}
</TorrentListWrapper>
)
}

View File

@@ -0,0 +1,29 @@
import { useState } from 'react'
import { useTranslation } from 'react-i18next'
import AddDialog from '../Add/AddDialog'
import IconWrapper from './style'
export default function AddFirstTorrent() {
const { t } = useTranslation()
const [isDialogOpen, setIsDialogOpen] = useState(false)
const handleClickOpen = () => setIsDialogOpen(true)
const handleClose = () => setIsDialogOpen(false)
return (
<>
<IconWrapper onClick={() => handleClickOpen(true)} isButton>
<lord-icon
src='https://cdn.lordicon.com/bbnkwdur.json'
trigger='loop'
colors='primary:#121331,secondary:#00A572'
stroke='26'
scale='60'
/>
<div className='icon-label'>{t('NoTorrentsAdded')}</div>
</IconWrapper>
{isDialogOpen && <AddDialog handleClose={handleClose} />}
</>
)
}

View File

@@ -0,0 +1,20 @@
import { useTranslation } from 'react-i18next'
import IconWrapper from './style'
export default function NoServerConnection() {
const { t } = useTranslation()
return (
<IconWrapper>
<lord-icon
src='https://cdn.lordicon.com/wrprwmwt.json'
trigger='loop'
colors='primary:#121331,secondary:#00A572'
stroke='26'
scale='60'
/>
<div className='icon-label'>{t('Offline')}</div>
</IconWrapper>
)
}

View File

@@ -0,0 +1,30 @@
import TorrentCard from 'components/TorrentCard'
import CircularProgress from '@material-ui/core/CircularProgress'
import { TorrentListWrapper, CenteredGrid } from 'components/App/style'
import NoServerConnection from './NoServerConnection'
import AddFirstTorrent from './AddFirstTorrent'
export default function TorrentList({ isOffline, isLoading, torrents }) {
if (isLoading || isOffline || !torrents.length) {
return (
<CenteredGrid>
{isOffline ? (
<NoServerConnection />
) : isLoading ? (
<CircularProgress />
) : (
!torrents.length && <AddFirstTorrent />
)}
</CenteredGrid>
)
}
return (
<TorrentListWrapper>
{torrents.map(torrent => (
<TorrentCard key={torrent.hash} torrent={torrent} />
))}
</TorrentListWrapper>
)
}

View File

@@ -0,0 +1,30 @@
import styled, { css } from 'styled-components'
export default styled.div`
${({ isButton }) => css`
display: grid;
place-items: center;
padding: 20px 40px;
border-radius: 5px;
${isButton &&
css`
background: #93d7b4;
transition: 0.2s;
cursor: pointer;
:hover {
background: #71cc9d;
}
`}
lord-icon {
width: 200px;
height: 200px;
}
.icon-label {
font-size: 20px;
}
`}
`