diff --git a/web/src/components/DialogTorrentDetailsContent/index.jsx b/web/src/components/DialogTorrentDetailsContent/index.jsx
index 675365e..808cac7 100644
--- a/web/src/components/DialogTorrentDetailsContent/index.jsx
+++ b/web/src/components/DialogTorrentDetailsContent/index.jsx
@@ -1,13 +1,18 @@
-import styled, { css } from 'styled-components'
import { NoImageIcon } from 'icons'
import { getPeerString, humanizeSize } from 'utils/Utils'
-// import { viewedHost } from 'utils/Hosts'
import { CopyToClipboard } from 'react-copy-to-clipboard'
import { useEffect, useState } from 'react'
-import { Button } from '@material-ui/core'
-import { ArrowDownward, ArrowUpward, SwapVerticalCircle, ViewAgenda } from '@material-ui/icons'
+import { Button, ButtonGroup, Typography } from '@material-ui/core'
+import {
+ ArrowDownward as ArrowDownwardIcon,
+ ArrowUpward as ArrowUpwardIcon,
+ SwapVerticalCircle as SwapVerticalCircleIcon,
+ ViewAgenda as ViewAgendaIcon,
+ Cached as CachedIcon,
+} from '@material-ui/icons'
import axios from 'axios'
-import { torrentsHost } from 'utils/Hosts'
+import { streamHost, torrentsHost, viewedHost } from 'utils/Hosts'
+import { GETTING_INFO, IN_DB } from 'torrentStates'
import { useUpdateCache, useCreateCacheMap, useGetSettings } from './customHooks'
import DialogHeader from './DialogHeader'
@@ -35,32 +40,56 @@ const shortenText = (text, count) => text.slice(0, count) + (text.length > count
export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
const [isLoading, setIsLoading] = useState(true)
const [isDetailedCacheView, setIsDetailedCacheView] = useState(false)
+ const [viewedFileList, setViewedFileList] = useState()
+ const [playableFileList, setPlayableFileList] = useState()
+
const {
poster,
hash,
title,
name,
+ stat,
download_speed: downloadSpeed,
upload_speed: uploadSpeed,
stat_string: statString,
torrent_size: torrentSize,
+ file_stats: torrentFileList,
} = torrent
const cache = useUpdateCache(hash)
const cacheMap = useCreateCacheMap(cache)
const settings = useGetSettings(cache)
- const dropTorrent = hash => axios.post(torrentsHost(), { action: 'drop', hash })
+ const dropTorrent = () => axios.post(torrentsHost(), { action: 'drop', hash })
+ const removeTorrentViews = () =>
+ axios.post(viewedHost(), { action: 'rem', hash, file_index: -1 }).then(() => setViewedFileList())
+ const preloadBuffer = fileId => fetch(`${streamHost()}?link=${hash}&index=${fileId}&preload`)
+ const getFileLink = (path, id) =>
+ `${streamHost()}/${encodeURIComponent(path.split('\\').pop().split('/').pop())}?link=${hash}&index=${id}&play`
const { Capacity, PiecesCount, PiecesLength, Filled } = cache
+ useEffect(() => {
+ setPlayableFileList(torrentFileList?.filter(file => playableExtList.includes(getExt(file.path))))
+ }, [torrentFileList])
+
useEffect(() => {
const cacheLoaded = !!Object.entries(cache).length
- const torrentLoaded = torrent.stat_string !== 'Torrent in db' && torrent.stat_string !== 'Torrent getting info'
+ const torrentLoaded = stat !== GETTING_INFO && stat !== IN_DB
if (!cacheLoaded && !isLoading) setIsLoading(true)
if (cacheLoaded && isLoading && torrentLoaded) setIsLoading(false)
- }, [torrent, cache, isLoading])
+ }, [stat, cache, isLoading])
+
+ useEffect(() => {
+ // getting viewed file list
+ axios.post(viewedHost(), { action: 'list', hash }).then(({ data }) => {
+ if (data) {
+ const lst = data.map(itm => itm.file_index)
+ setViewedFileList(lst)
+ } else setViewedFileList()
+ })
+ }, [hash])
const bufferSize = settings?.PreloadBuffer ? Capacity : 33554432 // Default is 32mb if PreloadBuffer is false
@@ -105,7 +134,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
value={humanizeSize(downloadSpeed) || '0 B'}
iconBg='#118f00'
valueBg='#13a300'
- icon={ArrowDownward}
+ icon={ArrowDownwardIcon}
/>
@@ -141,7 +170,11 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
{!settings?.PreloadBuffer && (
Enable "Preload Buffer" in settings to change buffer size
)}
-
+
@@ -166,9 +199,9 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
- remove views
+ removeTorrentViews()}>remove views
- dropTorrent(hash)}>drop torrent
+ dropTorrent()}>drop torrent
download playlist
@@ -177,6 +210,26 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
Torrent Content
+
+ {!playableFileList?.length
+ ? 'No playable files in this torrent'
+ : playableFileList.map(({ id, path, length }) => (
+
+
+
+
+
+ ))}
)}
@@ -184,117 +237,68 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
)
}
-// function getPreload(torrent) {
-// 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)
-// return `${humanizeSize(torrent.preloaded_bytes)} / ${humanizeSize(torrent.preload_size)} ${progress}%`
-// }
-
-// if (!torrent.preloaded_bytes) return humanizeSize(0)
-
-// return humanizeSize(torrent.preloaded_bytes)
-// }
-
-// function remViews(hash) {
-// try {
-// if (hash)
-// fetch(viewedHost(), {
-// method: 'post',
-// body: JSON.stringify({ action: 'rem', hash, file_index: -1 }),
-// headers: {
-// Accept: 'application/json, text/plain, */*',
-// 'Content-Type': 'application/json',
-// },
-// })
-// } catch (e) {
-// console.error(e)
-// }
-// }
-
-// function getViewed(hash, callback) {
-// try {
-// fetch(viewedHost(), {
-// method: 'post',
-// body: JSON.stringify({ action: 'list', hash }),
-// headers: {
-// Accept: 'application/json, text/plain, */*',
-// 'Content-Type': 'application/json',
-// },
-// })
-// .then(res => res.json())
-// .then(callback)
-// } catch (e) {
-// console.error(e)
-// }
-// }
-
-// function getPlayableFile(torrent) {
-// if (!torrent || !torrent.file_stats) return null
-// return torrent.file_stats.filter(file => extPlayable.includes(getExt(file.path)))
-// }
-
-// function getExt(filename) {
-// const ext = filename.split('.').pop()
-// if (ext === filename) return ''
-// return ext.toLowerCase()
-// }
-// const extPlayable = [
-// // video
-// '3g2',
-// '3gp',
-// 'aaf',
-// 'asf',
-// 'avchd',
-// 'avi',
-// 'drc',
-// 'flv',
-// 'iso',
-// 'm2v',
-// 'm2ts',
-// 'm4p',
-// 'm4v',
-// 'mkv',
-// 'mng',
-// 'mov',
-// 'mp2',
-// 'mp4',
-// 'mpe',
-// 'mpeg',
-// 'mpg',
-// 'mpv',
-// 'mxf',
-// 'nsv',
-// 'ogg',
-// 'ogv',
-// 'ts',
-// 'qt',
-// 'rm',
-// 'rmvb',
-// 'roq',
-// 'svi',
-// 'vob',
-// 'webm',
-// 'wmv',
-// 'yuv',
-// // audio
-// 'aac',
-// 'aiff',
-// 'ape',
-// 'au',
-// 'flac',
-// 'gsm',
-// 'it',
-// 'm3u',
-// 'm4a',
-// 'mid',
-// 'mod',
-// 'mp3',
-// 'mpa',
-// 'pls',
-// 'ra',
-// 's3m',
-// 'sid',
-// 'wav',
-// 'wma',
-// 'xm',
-// ]
+function getExt(filename) {
+ const ext = filename.split('.').pop()
+ if (ext === filename) return ''
+ return ext.toLowerCase()
+}
+const playableExtList = [
+ // video
+ '3g2',
+ '3gp',
+ 'aaf',
+ 'asf',
+ 'avchd',
+ 'avi',
+ 'drc',
+ 'flv',
+ 'iso',
+ 'm2v',
+ 'm2ts',
+ 'm4p',
+ 'm4v',
+ 'mkv',
+ 'mng',
+ 'mov',
+ 'mp2',
+ 'mp4',
+ 'mpe',
+ 'mpeg',
+ 'mpg',
+ 'mpv',
+ 'mxf',
+ 'nsv',
+ 'ogg',
+ 'ogv',
+ 'ts',
+ 'qt',
+ 'rm',
+ 'rmvb',
+ 'roq',
+ 'svi',
+ 'vob',
+ 'webm',
+ 'wmv',
+ 'yuv',
+ // audio
+ 'aac',
+ 'aiff',
+ 'ape',
+ 'au',
+ 'flac',
+ 'gsm',
+ 'it',
+ 'm3u',
+ 'm4a',
+ 'mid',
+ 'mod',
+ 'mp3',
+ 'mpa',
+ 'pls',
+ 'ra',
+ 's3m',
+ 'sid',
+ 'wav',
+ 'wma',
+ 'xm',
+]
diff --git a/web/src/components/DialogTorrentDetailsContent/style.js b/web/src/components/DialogTorrentDetailsContent/style.js
index 4716897..bdb94b0 100644
--- a/web/src/components/DialogTorrentDetailsContent/style.js
+++ b/web/src/components/DialogTorrentDetailsContent/style.js
@@ -166,14 +166,22 @@ export const StatisticsFieldValue = styled.div`
`}
`
-export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => ({
- percentage: Math.min(100, (value * 100) / fullAmount),
-}))`
- ${({ percentage, label }) => css`
+export const LoadingProgress = styled.div.attrs(({ value, fullAmount }) => {
+ const percentage = (value * 100) / fullAmount
+ const percentageMinmax = Math.min(100, percentage)
+ // console.log(percentage)
+ const stylePercentage = percentageMinmax === 100 ? 100 : percentageMinmax % 100
+
+ return {
+ style: {
+ background: `linear-gradient(to right, #b5dec9 0%, #b5dec9 ${stylePercentage}%, #fff ${stylePercentage}%, #fff 100%)`,
+ },
+ }
+})`
+ ${({ 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}';
diff --git a/web/src/torrentStates.js b/web/src/torrentStates.js
new file mode 100644
index 0000000..a2cef45
--- /dev/null
+++ b/web/src/torrentStates.js
@@ -0,0 +1 @@
+export const [GETTING_INFO, PRELOAD, WORKING, CLOSED, IN_DB] = [1, 2, 3, 4, 5]