mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
edit torrents function added
This commit is contained in:
@@ -15,11 +15,11 @@ import { ButtonWrapper, Content, Header } from './style'
|
|||||||
import RightSideComponent from './RightSideComponent'
|
import RightSideComponent from './RightSideComponent'
|
||||||
import LeftSideComponent from './LeftSideComponent'
|
import LeftSideComponent from './LeftSideComponent'
|
||||||
|
|
||||||
export default function AddDialog({ handleClose }) {
|
export default function AddDialog({ handleClose, hash: originalHash, title: originalTitle, poster: originalPoster }) {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const [torrentSource, setTorrentSource] = useState('')
|
const [torrentSource, setTorrentSource] = useState(originalHash || '')
|
||||||
const [title, setTitle] = useState('')
|
const [title, setTitle] = useState(originalTitle || '')
|
||||||
const [posterUrl, setPosterUrl] = useState('')
|
const [posterUrl, setPosterUrl] = useState(originalPoster || '')
|
||||||
const [isPosterUrlCorrect, setIsPosterUrlCorrect] = useState(false)
|
const [isPosterUrlCorrect, setIsPosterUrlCorrect] = useState(false)
|
||||||
const [isTorrentSourceCorrect, setIsTorrentSourceCorrect] = useState(false)
|
const [isTorrentSourceCorrect, setIsTorrentSourceCorrect] = useState(false)
|
||||||
const [posterList, setPosterList] = useState()
|
const [posterList, setPosterList] = useState()
|
||||||
@@ -29,9 +29,22 @@ export default function AddDialog({ handleClose }) {
|
|||||||
const [posterSearchLanguage, setPosterSearchLanguage] = useState(currentLang === 'ru' ? 'ru' : 'en')
|
const [posterSearchLanguage, setPosterSearchLanguage] = useState(currentLang === 'ru' ? 'ru' : 'en')
|
||||||
const [isLoadingButton, setIsLoadingButton] = useState(false)
|
const [isLoadingButton, setIsLoadingButton] = useState(false)
|
||||||
const [skipDebounce, setSkipDebounce] = useState(false)
|
const [skipDebounce, setSkipDebounce] = useState(false)
|
||||||
|
const [isEditMode, setIsEditMode] = useState(false)
|
||||||
|
|
||||||
const fullScreen = useMediaQuery('@media (max-width:930px)')
|
const fullScreen = useMediaQuery('@media (max-width:930px)')
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (originalHash) {
|
||||||
|
setIsEditMode(true)
|
||||||
|
|
||||||
|
checkImageURL(posterUrl).then(correctImage => {
|
||||||
|
correctImage ? setIsPosterUrlCorrect(true) : removePoster()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// This is needed only on mount
|
||||||
|
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||||
|
}, [])
|
||||||
|
|
||||||
const posterSearch = useMemo(
|
const posterSearch = useMemo(
|
||||||
() =>
|
() =>
|
||||||
(movieName, language, { shouldRefreshMainPoster = false } = {}) => {
|
(movieName, language, { shouldRefreshMainPoster = false } = {}) => {
|
||||||
@@ -118,7 +131,9 @@ export default function AddDialog({ handleClose }) {
|
|||||||
const handleSave = () => {
|
const handleSave = () => {
|
||||||
setIsLoadingButton(true)
|
setIsLoadingButton(true)
|
||||||
|
|
||||||
if (selectedFile) {
|
if (isEditMode) {
|
||||||
|
axios.post(torrentsHost(), { action: 'set', hash: originalHash, title, poster: posterUrl }).finally(handleClose)
|
||||||
|
} else if (selectedFile) {
|
||||||
// file save
|
// file save
|
||||||
const data = new FormData()
|
const data = new FormData()
|
||||||
data.append('save', 'true')
|
data.append('save', 'true')
|
||||||
@@ -143,16 +158,18 @@ export default function AddDialog({ handleClose }) {
|
|||||||
fullWidth
|
fullWidth
|
||||||
maxWidth='md'
|
maxWidth='md'
|
||||||
>
|
>
|
||||||
<Header>{t('AddNewTorrent')}</Header>
|
<Header>{t(isEditMode ? 'EditTorrent' : 'AddNewTorrent')}</Header>
|
||||||
|
|
||||||
<Content>
|
<Content isEditMode={isEditMode}>
|
||||||
<LeftSideComponent
|
{!isEditMode && (
|
||||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
<LeftSideComponent
|
||||||
setSelectedFile={setSelectedFile}
|
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||||
torrentSource={torrentSource}
|
setSelectedFile={setSelectedFile}
|
||||||
setTorrentSource={setTorrentSource}
|
torrentSource={torrentSource}
|
||||||
selectedFile={selectedFile}
|
setTorrentSource={setTorrentSource}
|
||||||
/>
|
selectedFile={selectedFile}
|
||||||
|
/>
|
||||||
|
)}
|
||||||
|
|
||||||
<RightSideComponent
|
<RightSideComponent
|
||||||
setTitle={setTitle}
|
setTitle={setTitle}
|
||||||
@@ -186,7 +203,7 @@ export default function AddDialog({ handleClose }) {
|
|||||||
onClick={handleSave}
|
onClick={handleSave}
|
||||||
color='primary'
|
color='primary'
|
||||||
>
|
>
|
||||||
{isLoadingButton ? <CircularProgress style={{ color: 'white' }} size={20} /> : t('Add')}
|
{isLoadingButton ? <CircularProgress style={{ color: 'white' }} size={20} /> : t(isEditMode ? 'Save' : 'Add')}
|
||||||
</Button>
|
</Button>
|
||||||
</ButtonWrapper>
|
</ButtonWrapper>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import { v4 as uuidv4 } from 'uuid'
|
|
||||||
import { NoImageIcon } from 'icons'
|
import { NoImageIcon } from 'icons'
|
||||||
import { TextField } from '@material-ui/core'
|
import { TextField } from '@material-ui/core'
|
||||||
|
|
||||||
@@ -71,7 +70,7 @@ export default function RightSideComponent({
|
|||||||
?.filter(url => url !== posterUrl)
|
?.filter(url => url !== posterUrl)
|
||||||
.slice(0, 12)
|
.slice(0, 12)
|
||||||
.map(url => (
|
.map(url => (
|
||||||
<PosterSuggestionsItem onClick={() => userChangesPosterUrl(url)} key={uuidv4()}>
|
<PosterSuggestionsItem onClick={() => userChangesPosterUrl(url)} key={url}>
|
||||||
<img src={url} alt='poster' />
|
<img src={url} alt='poster' />
|
||||||
</PosterSuggestionsItem>
|
</PosterSuggestionsItem>
|
||||||
))}
|
))}
|
||||||
|
|||||||
@@ -13,16 +13,23 @@ export const Header = styled.div`
|
|||||||
`
|
`
|
||||||
|
|
||||||
export const Content = styled.div`
|
export const Content = styled.div`
|
||||||
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
${({ isEditMode }) => css`
|
||||||
flex: 1;
|
background: linear-gradient(145deg, #e4f6ed, #b5dec9);
|
||||||
display: grid;
|
flex: 1;
|
||||||
grid-template-columns: repeat(2, 1fr);
|
display: grid;
|
||||||
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
grid-template-columns: repeat(${isEditMode ? '1' : '2'}, 1fr);
|
||||||
overflow: auto;
|
border-bottom: 1px solid rgba(0, 0, 0, 0.12);
|
||||||
|
overflow: auto;
|
||||||
|
|
||||||
@media (max-width: 930px) {
|
@media (max-width: 540px) {
|
||||||
grid-template-columns: 1fr;
|
${'' /* Just for bug fixing on small screens */}
|
||||||
}
|
overflow: scroll;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 930px) {
|
||||||
|
grid-template-columns: 1fr;
|
||||||
|
}
|
||||||
|
`}
|
||||||
`
|
`
|
||||||
|
|
||||||
export const RightSide = styled.div`
|
export const RightSide = styled.div`
|
||||||
|
|||||||
@@ -1,6 +1,11 @@
|
|||||||
import 'fontsource-roboto'
|
import 'fontsource-roboto'
|
||||||
import { forwardRef, memo, useState } from 'react'
|
import { forwardRef, memo, useState } from 'react'
|
||||||
import { UnfoldMore as UnfoldMoreIcon, Close as CloseIcon, Delete as DeleteIcon } from '@material-ui/icons'
|
import {
|
||||||
|
UnfoldMore as UnfoldMoreIcon,
|
||||||
|
Edit as EditIcon,
|
||||||
|
Close as CloseIcon,
|
||||||
|
Delete as DeleteIcon,
|
||||||
|
} from '@material-ui/icons'
|
||||||
import { getPeerString, humanizeSize, shortenText } from 'utils/Utils'
|
import { getPeerString, humanizeSize, shortenText } from 'utils/Utils'
|
||||||
import { torrentsHost } from 'utils/Hosts'
|
import { torrentsHost } from 'utils/Hosts'
|
||||||
import { NoImageIcon } from 'icons'
|
import { NoImageIcon } from 'icons'
|
||||||
@@ -11,6 +16,7 @@ import { Button, DialogActions, DialogTitle, useMediaQuery, useTheme } from '@ma
|
|||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import ptt from 'parse-torrent-title'
|
import ptt from 'parse-torrent-title'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import AddDialog from 'components/Add/AddDialog'
|
||||||
|
|
||||||
import { StyledButton, TorrentCard, TorrentCardButtons, TorrentCardDescription, TorrentCardPoster } from './style'
|
import { StyledButton, TorrentCard, TorrentCardButtons, TorrentCardDescription, TorrentCardPoster } from './style'
|
||||||
|
|
||||||
@@ -36,6 +42,10 @@ const Torrent = ({ torrent }) => {
|
|||||||
|
|
||||||
const parsedTitle = (title || name) && ptt.parse(title || name).title
|
const parsedTitle = (title || name) && ptt.parse(title || name).title
|
||||||
|
|
||||||
|
const [isEditDialogOpen, setIsEditDialogOpen] = useState(false)
|
||||||
|
const handleClickOpenEditDialog = () => setIsEditDialogOpen(true)
|
||||||
|
const handleCloseEditDialog = () => setIsEditDialogOpen(false)
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
<>
|
||||||
<TorrentCard>
|
<TorrentCard>
|
||||||
@@ -49,6 +59,11 @@ const Torrent = ({ torrent }) => {
|
|||||||
<span>{t('Details')}</span>
|
<span>{t('Details')}</span>
|
||||||
</StyledButton>
|
</StyledButton>
|
||||||
|
|
||||||
|
<StyledButton onClick={handleClickOpenEditDialog}>
|
||||||
|
<EditIcon />
|
||||||
|
<span>{t('Edit')}</span>
|
||||||
|
</StyledButton>
|
||||||
|
|
||||||
<StyledButton onClick={() => dropTorrent(torrent)}>
|
<StyledButton onClick={() => dropTorrent(torrent)}>
|
||||||
<CloseIcon />
|
<CloseIcon />
|
||||||
<span>{t('Drop')}</span>
|
<span>{t('Drop')}</span>
|
||||||
@@ -118,6 +133,8 @@ const Torrent = ({ torrent }) => {
|
|||||||
</Button>
|
</Button>
|
||||||
</DialogActions>
|
</DialogActions>
|
||||||
</Dialog>
|
</Dialog>
|
||||||
|
|
||||||
|
{isEditDialogOpen && <AddDialog hash={hash} title={title} poster={poster} handleClose={handleCloseEditDialog} />}
|
||||||
</>
|
</>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -66,7 +66,11 @@ export const TorrentCardButtons = styled.div`
|
|||||||
gap: 10px;
|
gap: 10px;
|
||||||
|
|
||||||
@media (max-width: 1260px), (max-height: 500px) {
|
@media (max-width: 1260px), (max-height: 500px) {
|
||||||
grid-template-columns: repeat(3, 1fr);
|
grid-template-columns: repeat(4, 1fr);
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 340px) {
|
||||||
|
gap: 5px;
|
||||||
}
|
}
|
||||||
`
|
`
|
||||||
export const TorrentCardDescription = styled.div`
|
export const TorrentCardDescription = styled.div`
|
||||||
@@ -165,10 +169,13 @@ export const StyledButton = styled.button`
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
background: #268757;
|
background: #268757;
|
||||||
color: #fff;
|
color: #fff;
|
||||||
font-size: 1rem;
|
font-size: 0.9rem;
|
||||||
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
|
font-family: 'Roboto', 'Helvetica', 'Arial', sans-serif;
|
||||||
letter-spacing: 0.009em;
|
letter-spacing: 0.009em;
|
||||||
padding: 10px 20px;
|
padding: 0 12px;
|
||||||
|
svg {
|
||||||
|
width: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
:hover {
|
:hover {
|
||||||
background: #2a7e54;
|
background: #2a7e54;
|
||||||
@@ -179,28 +186,21 @@ export const StyledButton = styled.button`
|
|||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 1260px), (max-height: 500px) {
|
@media (max-width: 1260px), (max-height: 500px) {
|
||||||
padding: 5px 10px;
|
|
||||||
font-size: 0.8rem;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 20px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 770px) {
|
|
||||||
font-size: 0.7rem;
|
|
||||||
|
|
||||||
svg {
|
|
||||||
width: 15px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media (max-width: 420px) {
|
|
||||||
padding: 7px 10px;
|
padding: 7px 10px;
|
||||||
justify-content: center;
|
justify-content: center;
|
||||||
|
font-size: 0.8rem;
|
||||||
|
|
||||||
svg {
|
svg {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@media (max-width: 770px) {
|
||||||
|
font-size: 0.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 420px) {
|
||||||
|
font-size: 0.6rem;
|
||||||
|
padding: 7px 5px;
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
"Add": "Add",
|
"Add": "Add",
|
||||||
"AddFromLink": "Add from Link",
|
"AddFromLink": "Add from Link",
|
||||||
"AddNewTorrent": "Add new torrent",
|
"AddNewTorrent": "Add new torrent",
|
||||||
|
"EditTorrent": "Edit torrent",
|
||||||
"AddRetrackers": "Add retrackers",
|
"AddRetrackers": "Add retrackers",
|
||||||
"Buffer": "Preload Buffer / Cache",
|
"Buffer": "Preload Buffer / Cache",
|
||||||
"BufferNote": "Enable “Preload Buffer” in settings to see cache loading progress",
|
"BufferNote": "Enable “Preload Buffer” in settings to see cache loading progress",
|
||||||
@@ -110,5 +111,6 @@
|
|||||||
"WrongTorrentSource": "Wrong torrent source",
|
"WrongTorrentSource": "Wrong torrent source",
|
||||||
"ScrollDown": "scroll down",
|
"ScrollDown": "scroll down",
|
||||||
"Cache": "Cache",
|
"Cache": "Cache",
|
||||||
"Data": "Data"
|
"Data": "Data",
|
||||||
|
"Edit": "Edit"
|
||||||
}
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
"Add": "Добавить",
|
"Add": "Добавить",
|
||||||
"AddFromLink": "Добавить",
|
"AddFromLink": "Добавить",
|
||||||
"AddNewTorrent": "Добавить новый торрент",
|
"AddNewTorrent": "Добавить новый торрент",
|
||||||
|
"EditTorrent": "Изменить торрент",
|
||||||
"AddRetrackers": "Добавлять",
|
"AddRetrackers": "Добавлять",
|
||||||
"Buffer": "Предзагрузка / Кеш",
|
"Buffer": "Предзагрузка / Кеш",
|
||||||
"BufferNote": "Включите «Наполнять кеш перед началом воспроизведения» в настройках для показа заполнения кеша",
|
"BufferNote": "Включите «Наполнять кеш перед началом воспроизведения» в настройках для показа заполнения кеша",
|
||||||
@@ -110,5 +111,6 @@
|
|||||||
"WrongTorrentSource": "Неправильный torrent источник",
|
"WrongTorrentSource": "Неправильный torrent источник",
|
||||||
"ScrollDown": "прокрутить вниз",
|
"ScrollDown": "прокрутить вниз",
|
||||||
"Cache": "Кеш",
|
"Cache": "Кеш",
|
||||||
"Data": "Данные"
|
"Data": "Данные",
|
||||||
|
"Edit": "Изменить"
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user