From 1f7554489c68299645a6f09a729b81619ec39ad1 Mon Sep 17 00:00:00 2001 From: Daniel Shleifman Date: Mon, 31 May 2021 12:44:13 +0300 Subject: [PATCH] teble added for file list --- web/package.json | 1 + .../DialogTorrentDetailsContent/index.jsx | 217 +++++++++++++----- .../DialogTorrentDetailsContent/style.js | 116 ++++++---- web/yarn.lock | 5 + 4 files changed, 238 insertions(+), 101 deletions(-) diff --git a/web/package.json b/web/package.json index 7a7908b..282af49 100644 --- a/web/package.json +++ b/web/package.json @@ -10,6 +10,7 @@ "fontsource-roboto": "^4.0.0", "konva": "^8.0.1", "material-ui-image": "^3.3.2", + "parse-torrent-title": "^1.3.0", "react": "^17.0.2", "react-copy-to-clipboard": "^5.0.3", "react-dom": "^17.0.2", diff --git a/web/src/components/DialogTorrentDetailsContent/index.jsx b/web/src/components/DialogTorrentDetailsContent/index.jsx index f53c521..16648d3 100644 --- a/web/src/components/DialogTorrentDetailsContent/index.jsx +++ b/web/src/components/DialogTorrentDetailsContent/index.jsx @@ -3,6 +3,7 @@ import { getPeerString, humanizeSize } from 'utils/Utils' import { CopyToClipboard } from 'react-copy-to-clipboard' import { useEffect, useState } from 'react' import { Button, ButtonGroup, Typography } from '@material-ui/core' +import ptt from 'parse-torrent-title' import { ArrowDownward as ArrowDownwardIcon, ArrowUpward as ArrowUpwardIcon, @@ -26,17 +27,18 @@ import { SectionTitle, SectionSubName, StatisticsWrapper, - ButtonSection, LoadingProgress, SectionHeader, CacheSection, - ButtonSectionButton, TorrentFilesSection, Divider, SmallLabel, + Table, } from './style' import StatisticsField from './StatisticsField' +ptt.addHandler('part', /Part[. ]([0-9])/i, { type: 'integer' }) + const shortenText = (text, count) => text.slice(0, count) + (text.length > count ? '...' : '') export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { @@ -45,6 +47,11 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { const [viewedFileList, setViewedFileList] = useState() const [playableFileList, setPlayableFileList] = useState() + const isOnlyOnePlayableFile = playableFileList?.length === 1 + const latestViewedFileId = viewedFileList?.[viewedFileList?.length - 1] + const latestViewedFile = playableFileList?.find(({ id }) => id === latestViewedFileId)?.path + const latestViewedFileData = latestViewedFile && ptt.parse(latestViewedFile) + const { poster, hash, @@ -87,7 +94,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { // getting viewed file list axios.post(viewedHost(), { action: 'list', hash }).then(({ data }) => { if (data) { - const lst = data.map(itm => itm.file_index) + const lst = data.map(itm => itm.file_index).sort((a, b) => a - b) setViewedFileList(lst) } else setViewedFileList() }) @@ -148,43 +155,70 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { - Download Playlist + {!isOnlyOnePlayableFile && !!viewedFileList?.length && ( + <> + Download Playlist + + Latest file played: {latestViewedFileData.title}. + {latestViewedFileData.season && ( + <> + {' '} + Season: {latestViewedFileData.season}. Episode: {latestViewedFileData.episode}. + + )} + + + + + + + + )} + + Torrent State + - - - More + Info + - - - + {(isOnlyOnePlayableFile || !viewedFileList?.length) && ( + + )} + + + {/* @@ -232,47 +266,116 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) { - - - -
-
copy hash
-
{hash}
-
-
-
- - removeTorrentViews()}>remove views - - dropTorrent()}>drop torrent - - download full playlist - - download playlist after last view -
- Torrent Content + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
viewednameseasonepisoderesolutionsizeactions
+ Jupiters Legacy311080p945,41 MB + + + +
+ Jupiters Legacy321080p712,47 MB + + + +
+ Jupiters Legacy331080p687,44 MB + + + +
+ {!playableFileList?.length ? 'No playable files in this torrent' - : playableFileList.map(({ id, path, length }) => ( - - + : playableFileList.map(({ id, path, length }) => { + { + /* console.log(ptt.parse(path)) */ + } + { + /* console.log({ title: ptt.parse(path).title }) + console.log({ resolution: ptt.parse(path).resolution }) + console.log({ episode: ptt.parse(path).episode }) + console.log({ season: ptt.parse(path).season }) */ + } - - - ))} + return ( + + + + + + ) + })}
)} diff --git a/web/src/components/DialogTorrentDetailsContent/style.js b/web/src/components/DialogTorrentDetailsContent/style.js index d5c17f4..0cd7a50 100644 --- a/web/src/components/DialogTorrentDetailsContent/style.js +++ b/web/src/components/DialogTorrentDetailsContent/style.js @@ -3,10 +3,9 @@ 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-rows: repeat(2, min-content); grid-template-areas: 'main cache' - 'buttons buttons' 'file-list file-list'; ` export const Poster = styled.div` @@ -60,48 +59,13 @@ export const CacheSection = styled.section` display: grid; align-content: start; grid-template-rows: min-content 1fr min-content; + background: #88cdaa; ` -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` +export const TorrentFilesSection = styled.section` grid-area: file-list; padding: 40px; + box-shadow: inset 3px 25px 8px -25px rgba(0, 0, 0, 0.5); ` export const SectionSubName = styled.div` @@ -208,8 +172,72 @@ export const Divider = styled.div` ` export const SmallLabel = styled.div` - font-size: 20px; - margin-bottom: 10px; - font-weight: 300; - line-height: 1; + ${({ mb }) => css` + ${mb && `margin-bottom: ${mb}px`}; + font-size: 20px; + font-weight: 300; + line-height: 1; + `} +` + +export const Table = styled.table` + border-collapse: collapse; + margin: 25px 0; + font-size: 0.9em; + width: 100%; + border-radius: 5px 5px 0 0; + overflow: hidden; + box-shadow: 0 0 20px rgba(0, 0, 0, 0.15); + + thead tr { + background: #009879; + color: #fff; + text-align: left; + text-transform: uppercase; + } + + th, + td { + padding: 12px 15px; + } + + tbody tr { + border-bottom: 1px solid #ddd; + + /* :nth-of-type(even) { + background: #f3f3f3; + } */ + + :last-of-type { + border-bottom: 2px solid #009879; + } + + &.viewed-file-row { + color: lightgray; + background: #f3f3f3; + } + } + + td { + &.viewed-file-indicator { + position: relative; + :before { + content: ''; + width: 10px; + height: 10px; + background: #15d5af; + border-radius: 50%; + position: absolute; + top: 50%; + left: 50%; + transform: translate(-50%, -50%); + } + } + + &.button-cell { + display: grid; + grid-template-columns: repeat(3, 1fr); + gap: 10px; + } + } ` diff --git a/web/yarn.lock b/web/yarn.lock index f21794e..a0bf6c7 100644 --- a/web/yarn.lock +++ b/web/yarn.lock @@ -9057,6 +9057,11 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= +parse-torrent-title@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/parse-torrent-title/-/parse-torrent-title-1.3.0.tgz#3dedea10277b17998b124a4fd67d9e190b0306b8" + integrity sha512-R5wya73/Ef0qUhb9177Ko8nRQyN1ziWD5DPnlrDrrgcchUnmIrG//cPENunvFYRZCLDZosXTKTo7TpQ2Pgbryg== + parse5@6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/parse5/-/parse5-6.0.1.tgz#e1a1c085c569b3dc08321184f19a39cc27f7c30b"