mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
added few sections
This commit is contained in:
@@ -0,0 +1,14 @@
|
|||||||
|
import { StatisticsFieldWrapper, StatisticsFieldIcon, StatisticsFieldValue, StatisticsFieldTitle } from './style'
|
||||||
|
|
||||||
|
export default function StatisticsField({ icon: Icon, title, value, iconBg, valueBg }) {
|
||||||
|
return (
|
||||||
|
<StatisticsFieldWrapper>
|
||||||
|
<StatisticsFieldTitle>{title}</StatisticsFieldTitle>
|
||||||
|
<StatisticsFieldIcon bgColor={iconBg}>
|
||||||
|
<Icon />
|
||||||
|
</StatisticsFieldIcon>
|
||||||
|
|
||||||
|
<StatisticsFieldValue bgColor={valueBg}>{value}</StatisticsFieldValue>
|
||||||
|
</StatisticsFieldWrapper>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
import { useEffect, useRef, useState } from 'react'
|
import { useEffect, useRef, useState } from 'react'
|
||||||
import { cacheHost } from 'utils/Hosts'
|
import { cacheHost, settingsHost } from 'utils/Hosts'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
|
|
||||||
export const useUpdateCache = hash => {
|
export const useUpdateCache = hash => {
|
||||||
@@ -71,3 +71,12 @@ export const useCreateCacheMap = cache => {
|
|||||||
|
|
||||||
return cacheMap
|
return cacheMap
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export const useGetSettings = cache => {
|
||||||
|
const [settings, setSettings] = useState()
|
||||||
|
useEffect(() => {
|
||||||
|
axios.post(settingsHost(), { action: 'get' }).then(({ data }) => setSettings(data))
|
||||||
|
}, [cache])
|
||||||
|
|
||||||
|
return settings
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,121 +1,34 @@
|
|||||||
import styled, { css } from 'styled-components'
|
import styled, { css } from 'styled-components'
|
||||||
import { NoImageIcon } from 'icons'
|
import { NoImageIcon } from 'icons'
|
||||||
import { getPeerString, humanizeSize } from 'utils/Utils'
|
import { getPeerString, humanizeSize } from 'utils/Utils'
|
||||||
import { viewedHost } from 'utils/Hosts'
|
// import { viewedHost } from 'utils/Hosts'
|
||||||
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
import { CopyToClipboard } from 'react-copy-to-clipboard'
|
||||||
import { useEffect, useState } from 'react'
|
import { useEffect, useState } from 'react'
|
||||||
import { Button } from '@material-ui/core'
|
import { Button } from '@material-ui/core'
|
||||||
|
import { ArrowDownward, ArrowUpward, SwapVerticalCircle, ViewAgenda } from '@material-ui/icons'
|
||||||
|
import axios from 'axios'
|
||||||
|
import { torrentsHost } from 'utils/Hosts'
|
||||||
|
|
||||||
import { useUpdateCache, useCreateCacheMap } from './customHooks'
|
import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks'
|
||||||
import DialogHeader from './DialogHeader'
|
import DialogHeader from './DialogHeader'
|
||||||
import TorrentCache from './TorrentCache'
|
import TorrentCache from './TorrentCache'
|
||||||
|
import {
|
||||||
const DialogContentGrid = styled.div`
|
DetailedTorrentCacheViewWrapper,
|
||||||
display: grid;
|
DialogContentGrid,
|
||||||
grid-template-rows: min-content min-content 80px min-content;
|
TorrentMainSection,
|
||||||
`
|
Poster,
|
||||||
const Poster = styled.div`
|
TorrentData,
|
||||||
${({ poster }) => css`
|
SectionTitle,
|
||||||
height: 400px;
|
SectionSubName,
|
||||||
border-radius: 5px;
|
StatisticsWrapper,
|
||||||
overflow: hidden;
|
ButtonSection,
|
||||||
|
LoadingProgress,
|
||||||
${poster
|
SectionHeader,
|
||||||
? css`
|
CacheSection,
|
||||||
img {
|
ButtonSectionButton,
|
||||||
border-radius: 5px;
|
TorrentFilesSection,
|
||||||
height: 100%;
|
} from './style'
|
||||||
}
|
import StatisticsField from './StatisticsField'
|
||||||
`
|
|
||||||
: css`
|
|
||||||
width: 300px;
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
background: #74c39c;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
transform: scale(2.5) translateY(-3px);
|
|
||||||
}
|
|
||||||
`}
|
|
||||||
`}
|
|
||||||
`
|
|
||||||
const TorrentMainSection = styled.section`
|
|
||||||
padding: 40px;
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: min-content 1fr;
|
|
||||||
gap: 30px;
|
|
||||||
background: lightgray;
|
|
||||||
`
|
|
||||||
|
|
||||||
const TorrentData = styled.div`
|
|
||||||
> :not(:last-child) {
|
|
||||||
margin-bottom: 20px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const CacheSection = styled.section`
|
|
||||||
padding: 40px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
`
|
|
||||||
|
|
||||||
const ButtonSection = styled.section`
|
|
||||||
box-shadow: 0px 4px 4px -1px rgb(0 0 0 / 30%);
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-evenly;
|
|
||||||
align-items: center;
|
|
||||||
text-transform: uppercase;
|
|
||||||
`
|
|
||||||
|
|
||||||
const ButtonSectionButton = styled.div`
|
|
||||||
background: lightblue;
|
|
||||||
height: 100%;
|
|
||||||
flex: 1;
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 15px;
|
|
||||||
|
|
||||||
:not(:last-child) {
|
|
||||||
border-right: 1px solid blue;
|
|
||||||
}
|
|
||||||
|
|
||||||
:hover {
|
|
||||||
background: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hash-group {
|
|
||||||
display: grid;
|
|
||||||
place-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hash-text {
|
|
||||||
font-size: 10px;
|
|
||||||
color: #7c7b7c;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
const TorrentFilesSection = styled.div``
|
|
||||||
|
|
||||||
const TorrentName = styled.div`
|
|
||||||
font-size: 50px;
|
|
||||||
font-weight: 200;
|
|
||||||
line-height: 1;
|
|
||||||
`
|
|
||||||
const TorrentSubName = styled.div`
|
|
||||||
color: #7c7b7c;
|
|
||||||
`
|
|
||||||
|
|
||||||
const SectionTitle = styled.div`
|
|
||||||
font-size: 35px;
|
|
||||||
font-weight: 200;
|
|
||||||
line-height: 1;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
`
|
|
||||||
|
|
||||||
const DetailedTorrentCacheViewWrapper = styled.div`
|
|
||||||
padding-top: 50px;
|
|
||||||
`
|
|
||||||
|
|
||||||
const shortenText = (text, count) => text.slice(0, count) + (text.length > count ? '...' : '')
|
const shortenText = (text, count) => text.slice(0, count) + (text.length > count ? '...' : '')
|
||||||
|
|
||||||
@@ -135,13 +48,22 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
|
|
||||||
const cache = useUpdateCache(hash)
|
const cache = useUpdateCache(hash)
|
||||||
const cacheMap = useCreateCacheMap(cache)
|
const cacheMap = useCreateCacheMap(cache)
|
||||||
|
const settings = useGetSettings(cache)
|
||||||
|
|
||||||
|
const dropTorrent = hash => {
|
||||||
|
axios.post(torrentsHost(), { action: 'drop', hash }).then(() => console.log('torrent dropped'))
|
||||||
|
}
|
||||||
|
|
||||||
|
const { Capacity, PiecesCount, PiecesLength, Filled } = cache
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const torrentLoaded = torrent.stat_string !== 'Torrent in db' && torrent.stat_string !== 'Torrent getting info'
|
const cacheIsLoading = !Object.entries(cache).length
|
||||||
torrentLoaded && isLoading && setIsLoading(false)
|
|
||||||
}, [torrent, isLoading])
|
|
||||||
|
|
||||||
const { Capacity, PiecesCount, PiecesLength } = cache
|
if (cacheIsLoading && !isLoading) setIsLoading(true)
|
||||||
|
if (!cacheIsLoading && isLoading) setIsLoading(false)
|
||||||
|
}, [cache, isLoading])
|
||||||
|
|
||||||
|
const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
@@ -156,6 +78,9 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
'loading'
|
'loading'
|
||||||
) : isDetailedCacheView ? (
|
) : isDetailedCacheView ? (
|
||||||
<DetailedTorrentCacheViewWrapper>
|
<DetailedTorrentCacheViewWrapper>
|
||||||
|
<div>PiecesCount: {PiecesCount}</div>
|
||||||
|
<div>PiecesLength: {humanizeSize(PiecesLength)}</div>
|
||||||
|
<div>status: {statString}</div>
|
||||||
<TorrentCache cache={cache} cacheMap={cacheMap} />
|
<TorrentCache cache={cache} cacheMap={cacheMap} />
|
||||||
</DetailedTorrentCacheViewWrapper>
|
</DetailedTorrentCacheViewWrapper>
|
||||||
) : (
|
) : (
|
||||||
@@ -167,34 +92,62 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
<div>
|
<div>
|
||||||
{name && name !== title ? (
|
{name && name !== title ? (
|
||||||
<>
|
<>
|
||||||
<TorrentName>{shortenText(name, 50)}</TorrentName>
|
<SectionTitle>{shortenText(name, 50)}</SectionTitle>
|
||||||
<TorrentSubName>{shortenText(title, 160)}</TorrentSubName>
|
<SectionSubName>{shortenText(title, 160)}</SectionSubName>
|
||||||
</>
|
</>
|
||||||
) : (
|
) : (
|
||||||
<TorrentName>{shortenText(title, 50)}</TorrentName>
|
<SectionTitle>{shortenText(title, 50)}</SectionTitle>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>peers: {getPeerString(torrent)}</div>
|
<StatisticsWrapper>
|
||||||
<div>loaded: {getPreload(torrent)}</div>
|
<StatisticsField
|
||||||
<div>download speed: {humanizeSize(downloadSpeed)}</div>
|
title='Download speed'
|
||||||
<div>upload speed: {humanizeSize(uploadSpeed)}</div>
|
value={humanizeSize(downloadSpeed) || '0 B'}
|
||||||
<div>status: {statString}</div>
|
iconBg='#118f00'
|
||||||
<div>torrent size: {humanizeSize(torrentSize)}</div>
|
valueBg='#13a300'
|
||||||
|
icon={ArrowDownward}
|
||||||
|
/>
|
||||||
|
|
||||||
<div>Capacity: {humanizeSize(Capacity)}</div>
|
<StatisticsField
|
||||||
<div>PiecesCount: {PiecesCount}</div>
|
title='Upload speed'
|
||||||
<div>PiecesLength: {humanizeSize(PiecesLength)}</div>
|
value={humanizeSize(uploadSpeed) || '0 B'}
|
||||||
|
iconBg='#0146ad'
|
||||||
|
valueBg='#0058db'
|
||||||
|
icon={ArrowUpward}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Peers'
|
||||||
|
value={getPeerString(torrent)}
|
||||||
|
iconBg='#0146ad'
|
||||||
|
valueBg='#0058db'
|
||||||
|
icon={SwapVerticalCircle}
|
||||||
|
/>
|
||||||
|
|
||||||
|
<StatisticsField
|
||||||
|
title='Torrent size'
|
||||||
|
value={humanizeSize(torrentSize)}
|
||||||
|
iconBg='#0146ad'
|
||||||
|
valueBg='#0058db'
|
||||||
|
icon={ViewAgenda}
|
||||||
|
/>
|
||||||
|
</StatisticsWrapper>
|
||||||
</TorrentData>
|
</TorrentData>
|
||||||
</TorrentMainSection>
|
</TorrentMainSection>
|
||||||
|
|
||||||
<CacheSection>
|
<CacheSection>
|
||||||
<SectionTitle>Cache</SectionTitle>
|
<SectionHeader>
|
||||||
|
<SectionTitle>Buffer</SectionTitle>
|
||||||
|
{!settings?.PreloadBuffer && (
|
||||||
|
<SectionSubName>Enable "Preload Buffer" in settings to change buffer size</SectionSubName>
|
||||||
|
)}
|
||||||
|
<LoadingProgress value={Filled} fullAmount={bufferSize} label={humanizeSize(bufferSize)} />
|
||||||
|
</SectionHeader>
|
||||||
|
|
||||||
<TorrentCache isMini cache={cache} cacheMap={cacheMap} />
|
<TorrentCache isMini cache={cache} cacheMap={cacheMap} />
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
style={{ alignSelf: 'flex-end', marginTop: '30px' }}
|
style={{ marginTop: '30px' }}
|
||||||
variant='contained'
|
variant='contained'
|
||||||
color='primary'
|
color='primary'
|
||||||
size='large'
|
size='large'
|
||||||
@@ -216,131 +169,133 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
|
|||||||
|
|
||||||
<ButtonSectionButton>remove views</ButtonSectionButton>
|
<ButtonSectionButton>remove views</ButtonSectionButton>
|
||||||
|
|
||||||
<ButtonSectionButton>drop torrent</ButtonSectionButton>
|
<ButtonSectionButton onClick={() => dropTorrent(hash)}>drop torrent</ButtonSectionButton>
|
||||||
|
|
||||||
<ButtonSectionButton>download playlist</ButtonSectionButton>
|
<ButtonSectionButton>download playlist</ButtonSectionButton>
|
||||||
|
|
||||||
<ButtonSectionButton>download playlist after last view</ButtonSectionButton>
|
<ButtonSectionButton>download playlist after last view</ButtonSectionButton>
|
||||||
</ButtonSection>
|
</ButtonSection>
|
||||||
|
|
||||||
<TorrentFilesSection />
|
<TorrentFilesSection>
|
||||||
|
<SectionTitle>Torrent Content</SectionTitle>
|
||||||
|
</TorrentFilesSection>
|
||||||
</DialogContentGrid>
|
</DialogContentGrid>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
function getPreload(torrent) {
|
// function getPreload(torrent) {
|
||||||
if (torrent.preloaded_bytes > 0 && torrent.preload_size > 0 && torrent.preloaded_bytes < torrent.preload_size) {
|
// if (torrent.preloaded_bytes > 0 && torrent.preload_size > 0 && torrent.preloaded_bytes < torrent.preload_size) {
|
||||||
const progress = ((torrent.preloaded_bytes * 100) / torrent.preload_size).toFixed(2)
|
// const progress = ((torrent.preloaded_bytes * 100) / torrent.preload_size).toFixed(2)
|
||||||
return `${humanizeSize(torrent.preloaded_bytes)} / ${humanizeSize(torrent.preload_size)} ${progress}%`
|
// return `${humanizeSize(torrent.preloaded_bytes)} / ${humanizeSize(torrent.preload_size)} ${progress}%`
|
||||||
}
|
// }
|
||||||
|
|
||||||
if (!torrent.preloaded_bytes) return humanizeSize(0)
|
// if (!torrent.preloaded_bytes) return humanizeSize(0)
|
||||||
|
|
||||||
return humanizeSize(torrent.preloaded_bytes)
|
// return humanizeSize(torrent.preloaded_bytes)
|
||||||
}
|
// }
|
||||||
|
|
||||||
function remViews(hash) {
|
// function remViews(hash) {
|
||||||
try {
|
// try {
|
||||||
if (hash)
|
// if (hash)
|
||||||
fetch(viewedHost(), {
|
// fetch(viewedHost(), {
|
||||||
method: 'post',
|
// method: 'post',
|
||||||
body: JSON.stringify({ action: 'rem', hash, file_index: -1 }),
|
// body: JSON.stringify({ action: 'rem', hash, file_index: -1 }),
|
||||||
headers: {
|
// headers: {
|
||||||
Accept: 'application/json, text/plain, */*',
|
// Accept: 'application/json, text/plain, */*',
|
||||||
'Content-Type': 'application/json',
|
// 'Content-Type': 'application/json',
|
||||||
},
|
// },
|
||||||
})
|
// })
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
console.error(e)
|
// console.error(e)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
function getViewed(hash, callback) {
|
// function getViewed(hash, callback) {
|
||||||
try {
|
// try {
|
||||||
fetch(viewedHost(), {
|
// fetch(viewedHost(), {
|
||||||
method: 'post',
|
// method: 'post',
|
||||||
body: JSON.stringify({ action: 'list', hash }),
|
// body: JSON.stringify({ action: 'list', hash }),
|
||||||
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(res => res.json())
|
||||||
.then(callback)
|
// .then(callback)
|
||||||
} catch (e) {
|
// } catch (e) {
|
||||||
console.error(e)
|
// console.error(e)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
|
||||||
function getPlayableFile(torrent) {
|
// function getPlayableFile(torrent) {
|
||||||
if (!torrent || !torrent.file_stats) return null
|
// if (!torrent || !torrent.file_stats) return null
|
||||||
return torrent.file_stats.filter(file => extPlayable.includes(getExt(file.path)))
|
// return torrent.file_stats.filter(file => extPlayable.includes(getExt(file.path)))
|
||||||
}
|
// }
|
||||||
|
|
||||||
function getExt(filename) {
|
// function getExt(filename) {
|
||||||
const ext = filename.split('.').pop()
|
// const ext = filename.split('.').pop()
|
||||||
if (ext === filename) return ''
|
// if (ext === filename) return ''
|
||||||
return ext.toLowerCase()
|
// return ext.toLowerCase()
|
||||||
}
|
// }
|
||||||
const extPlayable = [
|
// const extPlayable = [
|
||||||
// video
|
// // video
|
||||||
'3g2',
|
// '3g2',
|
||||||
'3gp',
|
// '3gp',
|
||||||
'aaf',
|
// 'aaf',
|
||||||
'asf',
|
// 'asf',
|
||||||
'avchd',
|
// 'avchd',
|
||||||
'avi',
|
// 'avi',
|
||||||
'drc',
|
// 'drc',
|
||||||
'flv',
|
// 'flv',
|
||||||
'iso',
|
// 'iso',
|
||||||
'm2v',
|
// 'm2v',
|
||||||
'm2ts',
|
// 'm2ts',
|
||||||
'm4p',
|
// 'm4p',
|
||||||
'm4v',
|
// 'm4v',
|
||||||
'mkv',
|
// 'mkv',
|
||||||
'mng',
|
// 'mng',
|
||||||
'mov',
|
// 'mov',
|
||||||
'mp2',
|
// 'mp2',
|
||||||
'mp4',
|
// 'mp4',
|
||||||
'mpe',
|
// 'mpe',
|
||||||
'mpeg',
|
// 'mpeg',
|
||||||
'mpg',
|
// 'mpg',
|
||||||
'mpv',
|
// 'mpv',
|
||||||
'mxf',
|
// 'mxf',
|
||||||
'nsv',
|
// 'nsv',
|
||||||
'ogg',
|
// 'ogg',
|
||||||
'ogv',
|
// 'ogv',
|
||||||
'ts',
|
// 'ts',
|
||||||
'qt',
|
// 'qt',
|
||||||
'rm',
|
// 'rm',
|
||||||
'rmvb',
|
// 'rmvb',
|
||||||
'roq',
|
// 'roq',
|
||||||
'svi',
|
// 'svi',
|
||||||
'vob',
|
// 'vob',
|
||||||
'webm',
|
// 'webm',
|
||||||
'wmv',
|
// 'wmv',
|
||||||
'yuv',
|
// 'yuv',
|
||||||
// audio
|
// // audio
|
||||||
'aac',
|
// 'aac',
|
||||||
'aiff',
|
// 'aiff',
|
||||||
'ape',
|
// 'ape',
|
||||||
'au',
|
// 'au',
|
||||||
'flac',
|
// 'flac',
|
||||||
'gsm',
|
// 'gsm',
|
||||||
'it',
|
// 'it',
|
||||||
'm3u',
|
// 'm3u',
|
||||||
'm4a',
|
// 'm4a',
|
||||||
'mid',
|
// 'mid',
|
||||||
'mod',
|
// 'mod',
|
||||||
'mp3',
|
// 'mp3',
|
||||||
'mpa',
|
// 'mpa',
|
||||||
'pls',
|
// 'pls',
|
||||||
'ra',
|
// 'ra',
|
||||||
's3m',
|
// 's3m',
|
||||||
'sid',
|
// 'sid',
|
||||||
'wav',
|
// 'wav',
|
||||||
'wma',
|
// 'wma',
|
||||||
'xm',
|
// 'xm',
|
||||||
]
|
// ]
|
||||||
|
|||||||
185
web/src/components/DialogTorrentDetailsContent/style.js
Normal file
185
web/src/components/DialogTorrentDetailsContent/style.js
Normal file
@@ -0,0 +1,185 @@
|
|||||||
|
import styled, { css } from 'styled-components'
|
||||||
|
|
||||||
|
export const DialogContentGrid = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 70% 1fr;
|
||||||
|
grid-template-rows: min-content 80px min-content;
|
||||||
|
grid-template-areas:
|
||||||
|
'main cache'
|
||||||
|
'buttons buttons'
|
||||||
|
'file-list file-list';
|
||||||
|
`
|
||||||
|
export const Poster = styled.div`
|
||||||
|
${({ poster }) => css`
|
||||||
|
height: 400px;
|
||||||
|
border-radius: 5px;
|
||||||
|
overflow: hidden;
|
||||||
|
|
||||||
|
${poster
|
||||||
|
? css`
|
||||||
|
img {
|
||||||
|
border-radius: 5px;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
: css`
|
||||||
|
width: 300px;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
background: #74c39c;
|
||||||
|
|
||||||
|
svg {
|
||||||
|
transform: scale(2.5) translateY(-3px);
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
`}
|
||||||
|
`
|
||||||
|
export const TorrentMainSection = styled.section`
|
||||||
|
grid-area: main;
|
||||||
|
padding: 40px;
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: min-content 1fr;
|
||||||
|
gap: 30px;
|
||||||
|
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||||
|
`
|
||||||
|
|
||||||
|
export const TorrentData = styled.div`
|
||||||
|
> :not(:last-child) {
|
||||||
|
margin-bottom: 20px;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const CacheSection = styled.section`
|
||||||
|
grid-area: cache;
|
||||||
|
padding: 40px;
|
||||||
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
|
grid-template-rows: min-content 1fr min-content;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const ButtonSection = styled.section`
|
||||||
|
grid-area: buttons;
|
||||||
|
box-shadow: 0px 4px 4px -1px rgb(0 0 0 / 30%);
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-evenly;
|
||||||
|
align-items: center;
|
||||||
|
text-transform: uppercase;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const ButtonSectionButton = styled.div`
|
||||||
|
background: lightblue;
|
||||||
|
height: 100%;
|
||||||
|
flex: 1;
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
cursor: pointer;
|
||||||
|
font-size: 15px;
|
||||||
|
|
||||||
|
:not(:last-child) {
|
||||||
|
border-right: 1px solid blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
:hover {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hash-group {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.hash-text {
|
||||||
|
font-size: 10px;
|
||||||
|
color: #7c7b7c;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const TorrentFilesSection = styled.div`
|
||||||
|
grid-area: file-list;
|
||||||
|
padding: 40px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const SectionSubName = styled.div`
|
||||||
|
color: #7c7b7c;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const SectionTitle = styled.div`
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 200;
|
||||||
|
line-height: 1;
|
||||||
|
word-break: break-word;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const SectionHeader = styled.div`
|
||||||
|
margin-bottom: 20px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const DetailedTorrentCacheViewWrapper = styled.div`
|
||||||
|
padding-top: 50px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const StatisticsWrapper = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(190px, min-content));
|
||||||
|
gap: 20px;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const StatisticsFieldWrapper = styled.div`
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: 40px max-content;
|
||||||
|
grid-template-rows: min-content 50px;
|
||||||
|
grid-template-areas:
|
||||||
|
'title title'
|
||||||
|
'icon value';
|
||||||
|
|
||||||
|
> * {
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
}
|
||||||
|
`
|
||||||
|
export const StatisticsFieldTitle = styled.div`
|
||||||
|
grid-area: title;
|
||||||
|
justify-self: start;
|
||||||
|
text-transform: uppercase;
|
||||||
|
font-size: 11px;
|
||||||
|
margin-bottom: 2px;
|
||||||
|
font-weight: 500;
|
||||||
|
`
|
||||||
|
|
||||||
|
export const StatisticsFieldIcon = styled.div`
|
||||||
|
${({ bgColor }) => css`
|
||||||
|
grid-area: icon;
|
||||||
|
color: rgba(255, 255, 255, 0.8);
|
||||||
|
background: ${bgColor};
|
||||||
|
border-radius: 5px 0 0 5px;
|
||||||
|
`}
|
||||||
|
`
|
||||||
|
export const StatisticsFieldValue = styled.div`
|
||||||
|
${({ bgColor }) => css`
|
||||||
|
grid-area: value;
|
||||||
|
min-width: 150px;
|
||||||
|
padding: 0 20px;
|
||||||
|
color: #fff;
|
||||||
|
font-size: 25px;
|
||||||
|
background: ${bgColor};
|
||||||
|
border-radius: 0 5px 5px 0;
|
||||||
|
`}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => ({
|
||||||
|
percentage: Math.min(100, (value * 100) / fullAmount),
|
||||||
|
}))`
|
||||||
|
${({ percentage, label }) => css`
|
||||||
|
border: 1px solid;
|
||||||
|
padding: 10px 20px;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: linear-gradient(to right, #b5dec9 0%, #b5dec9 ${percentage}%, #fff ${percentage}%, #fff 100%);
|
||||||
|
|
||||||
|
:before {
|
||||||
|
content: '${label}';
|
||||||
|
display: grid;
|
||||||
|
place-items: center;
|
||||||
|
font-size: 20px;
|
||||||
|
}
|
||||||
|
`}
|
||||||
|
`
|
||||||
@@ -26,7 +26,6 @@ export default function SettingsDialog() {
|
|||||||
setOpen(false)
|
setOpen(false)
|
||||||
const sets = JSON.parse(JSON.stringify(settings))
|
const sets = JSON.parse(JSON.stringify(settings))
|
||||||
sets.CacheSize *= 1024 * 1024
|
sets.CacheSize *= 1024 * 1024
|
||||||
sets.PreloadBufferSize *= 1024 * 1024
|
|
||||||
fetch(settingsHost(), {
|
fetch(settingsHost(), {
|
||||||
method: 'post',
|
method: 'post',
|
||||||
body: JSON.stringify({ action: 'set', sets }),
|
body: JSON.stringify({ action: 'set', sets }),
|
||||||
@@ -51,8 +50,6 @@ export default function SettingsDialog() {
|
|||||||
json => {
|
json => {
|
||||||
// eslint-disable-next-line no-param-reassign
|
// eslint-disable-next-line no-param-reassign
|
||||||
json.CacheSize /= 1024 * 1024
|
json.CacheSize /= 1024 * 1024
|
||||||
// eslint-disable-next-line no-param-reassign
|
|
||||||
json.PreloadBufferSize /= 1024 * 1024
|
|
||||||
setSets(json)
|
setSets(json)
|
||||||
setShow(true)
|
setShow(true)
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user