mirror of
https://github.com/Ernous/TorrServerJellyfin.git
synced 2025-12-19 21:46:11 +05:00
refactor
This commit is contained in:
@@ -1,46 +1,23 @@
|
||||
import { useEffect, useMemo, useState } from 'react'
|
||||
import Button from '@material-ui/core/Button'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import Dialog from '@material-ui/core/Dialog'
|
||||
import { torrentsHost, torrentUploadHost } from 'utils/Hosts'
|
||||
import axios from 'axios'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { NoImageIcon, AddItemIcon, TorrentIcon } from 'icons'
|
||||
import debounce from 'lodash/debounce'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import useChangeLanguage from 'utils/useChangeLanguage'
|
||||
import { Cancel as CancelIcon } from '@material-ui/icons'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
import { useMediaQuery } from '@material-ui/core'
|
||||
import CircularProgress from '@material-ui/core/CircularProgress'
|
||||
import usePreviousState from 'utils/usePreviousState'
|
||||
|
||||
import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers'
|
||||
import {
|
||||
ButtonWrapper,
|
||||
CancelIconWrapper,
|
||||
ClearPosterButton,
|
||||
PosterLanguageSwitch,
|
||||
Content,
|
||||
Header,
|
||||
IconWrapper,
|
||||
RightSide,
|
||||
Poster,
|
||||
PosterSuggestions,
|
||||
PosterSuggestionsItem,
|
||||
PosterWrapper,
|
||||
LeftSide,
|
||||
LeftSideBottomSectionFileSelected,
|
||||
LeftSideBottomSectionNoFile,
|
||||
LeftSideTopSection,
|
||||
TorrentIconWrapper,
|
||||
RightSideContainer,
|
||||
} from './style'
|
||||
import { ButtonWrapper, Content, Header } from './style'
|
||||
import RightSideComponent from './RightSideComponent'
|
||||
import LeftSideComponent from './LeftSideComponent'
|
||||
|
||||
export default function AddDialog({ handleClose }) {
|
||||
const { t } = useTranslation()
|
||||
const [torrentSource, setTorrentSource] = useState('')
|
||||
const [isTorrentSourceActive, setIsTorrentSourceActive] = useState(false)
|
||||
const [title, setTitle] = useState('')
|
||||
const [posterUrl, setPosterUrl] = useState('')
|
||||
const [isPosterUrlCorrect, setIsPosterUrlCorrect] = useState(false)
|
||||
@@ -138,26 +115,6 @@ export default function AddDialog({ handleClose }) {
|
||||
}
|
||||
}, [selectedFile, torrentSource])
|
||||
|
||||
const handleCapture = files => {
|
||||
const [file] = files
|
||||
if (!file) return
|
||||
|
||||
setIsUserInteractedWithPoster(false)
|
||||
setSelectedFile(file)
|
||||
setTorrentSource(file.name)
|
||||
}
|
||||
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: handleCapture, accept: '.torrent' })
|
||||
|
||||
const handleTorrentSourceChange = ({ target: { value } }) => setTorrentSource(value)
|
||||
const handleTitleChange = ({ target: { value } }) => setTitle(value)
|
||||
const handlePosterUrlChange = ({ target: { value } }) => {
|
||||
setPosterUrl(value)
|
||||
checkImageURL(value).then(setIsPosterUrlCorrect)
|
||||
setIsUserInteractedWithPoster(!!value)
|
||||
setPosterList()
|
||||
}
|
||||
|
||||
const handleSave = () => {
|
||||
setIsLoadingButton(true)
|
||||
|
||||
@@ -177,17 +134,6 @@ export default function AddDialog({ handleClose }) {
|
||||
}
|
||||
}
|
||||
|
||||
const clearSelectedFile = () => {
|
||||
setSelectedFile()
|
||||
setTorrentSource('')
|
||||
}
|
||||
|
||||
const userChangesPosterUrl = url => {
|
||||
setPosterUrl(url)
|
||||
checkImageURL(url).then(setIsPosterUrlCorrect)
|
||||
setIsUserInteractedWithPoster(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<Dialog
|
||||
open
|
||||
@@ -200,120 +146,32 @@ export default function AddDialog({ handleClose }) {
|
||||
<Header>{t('AddNewTorrent')}</Header>
|
||||
|
||||
<Content>
|
||||
<LeftSide>
|
||||
<LeftSideTopSection active={isTorrentSourceActive}>
|
||||
<TextField
|
||||
onChange={handleTorrentSourceChange}
|
||||
value={torrentSource}
|
||||
margin='dense'
|
||||
label={t('TorrentSourceLink')}
|
||||
helperText={t('TorrentSourceOptions')}
|
||||
type='text'
|
||||
fullWidth
|
||||
onFocus={() => setIsTorrentSourceActive(true)}
|
||||
onBlur={() => setIsTorrentSourceActive(false)}
|
||||
inputProps={{ autoComplete: 'off' }}
|
||||
disabled={!!selectedFile}
|
||||
/>
|
||||
</LeftSideTopSection>
|
||||
|
||||
{selectedFile ? (
|
||||
<LeftSideBottomSectionFileSelected>
|
||||
<TorrentIconWrapper>
|
||||
<TorrentIcon />
|
||||
|
||||
<CancelIconWrapper onClick={clearSelectedFile}>
|
||||
<CancelIcon />
|
||||
</CancelIconWrapper>
|
||||
</TorrentIconWrapper>
|
||||
</LeftSideBottomSectionFileSelected>
|
||||
) : (
|
||||
<LeftSideBottomSectionNoFile isDragActive={isDragActive} {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<div>{t('AppendFile.Or')}</div>
|
||||
|
||||
<IconWrapper>
|
||||
<AddItemIcon color='primary' />
|
||||
<div>{t('AppendFile.ClickOrDrag')}</div>
|
||||
</IconWrapper>
|
||||
</LeftSideBottomSectionNoFile>
|
||||
)}
|
||||
</LeftSide>
|
||||
|
||||
<RightSide>
|
||||
<RightSideContainer isHidden={!isTorrentSourceCorrect}>
|
||||
<TextField
|
||||
onChange={handleTitleChange}
|
||||
value={title}
|
||||
margin='dense'
|
||||
label={t('Title')}
|
||||
type='text'
|
||||
fullWidth
|
||||
/>
|
||||
<TextField
|
||||
onChange={handlePosterUrlChange}
|
||||
value={posterUrl}
|
||||
margin='dense'
|
||||
label={t('AddPosterLinkInput')}
|
||||
type='url'
|
||||
fullWidth
|
||||
<LeftSideComponent
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setSelectedFile={setSelectedFile}
|
||||
torrentSource={torrentSource}
|
||||
setTorrentSource={setTorrentSource}
|
||||
selectedFile={selectedFile}
|
||||
/>
|
||||
|
||||
<PosterWrapper>
|
||||
<Poster poster={+isPosterUrlCorrect}>
|
||||
{isPosterUrlCorrect ? <img src={posterUrl} alt='poster' /> : <NoImageIcon />}
|
||||
</Poster>
|
||||
|
||||
<PosterSuggestions>
|
||||
{posterList
|
||||
?.filter(url => url !== posterUrl)
|
||||
.slice(0, 12)
|
||||
.map(url => (
|
||||
<PosterSuggestionsItem onClick={() => userChangesPosterUrl(url)} key={uuidv4()}>
|
||||
<img src={url} alt='poster' />
|
||||
</PosterSuggestionsItem>
|
||||
))}
|
||||
</PosterSuggestions>
|
||||
|
||||
{currentLang !== 'en' && (
|
||||
<PosterLanguageSwitch
|
||||
onClick={() => {
|
||||
const newLanguage = posterSearchLanguage === 'en' ? 'ru' : 'en'
|
||||
setPosterSearchLanguage(newLanguage)
|
||||
posterSearch(title, newLanguage, { shouldRefreshMainPoster: true })
|
||||
}}
|
||||
showbutton={+isPosterUrlCorrect}
|
||||
color='primary'
|
||||
variant='contained'
|
||||
size='small'
|
||||
>
|
||||
{posterSearchLanguage === 'en' ? 'EN' : 'RU'}
|
||||
</PosterLanguageSwitch>
|
||||
)}
|
||||
|
||||
<ClearPosterButton
|
||||
showbutton={+isPosterUrlCorrect}
|
||||
onClick={() => {
|
||||
removePoster()
|
||||
setIsUserInteractedWithPoster(true)
|
||||
}}
|
||||
color='primary'
|
||||
variant='contained'
|
||||
size='small'
|
||||
>
|
||||
{t('Clear')}
|
||||
</ClearPosterButton>
|
||||
</PosterWrapper>
|
||||
</RightSideContainer>
|
||||
|
||||
<RightSideContainer
|
||||
isError={torrentSource && !isTorrentSourceCorrect}
|
||||
notificationMessage={
|
||||
!torrentSource ? t('AddTorrentSourceNotification') : !isTorrentSourceCorrect && t('WrongTorrentSource')
|
||||
}
|
||||
isHidden={isTorrentSourceCorrect}
|
||||
<RightSideComponent
|
||||
setTitle={setTitle}
|
||||
setPosterUrl={setPosterUrl}
|
||||
setIsPosterUrlCorrect={setIsPosterUrlCorrect}
|
||||
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
|
||||
setPosterList={setPosterList}
|
||||
isTorrentSourceCorrect={isTorrentSourceCorrect}
|
||||
title={title}
|
||||
posterUrl={posterUrl}
|
||||
isPosterUrlCorrect={isPosterUrlCorrect}
|
||||
posterList={posterList}
|
||||
currentLang={currentLang}
|
||||
posterSearchLanguage={posterSearchLanguage}
|
||||
setPosterSearchLanguage={setPosterSearchLanguage}
|
||||
posterSearch={posterSearch}
|
||||
removePoster={removePoster}
|
||||
torrentSource={torrentSource}
|
||||
/>
|
||||
</RightSide>
|
||||
</Content>
|
||||
|
||||
<ButtonWrapper>
|
||||
|
||||
87
web/src/components/Add/LeftSideComponent.jsx
Normal file
87
web/src/components/Add/LeftSideComponent.jsx
Normal file
@@ -0,0 +1,87 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useDropzone } from 'react-dropzone'
|
||||
import { AddItemIcon, TorrentIcon } from 'icons'
|
||||
import TextField from '@material-ui/core/TextField'
|
||||
import { Cancel as CancelIcon } from '@material-ui/icons'
|
||||
import { useState } from 'react'
|
||||
|
||||
import {
|
||||
CancelIconWrapper,
|
||||
IconWrapper,
|
||||
LeftSide,
|
||||
LeftSideBottomSectionFileSelected,
|
||||
LeftSideBottomSectionNoFile,
|
||||
LeftSideTopSection,
|
||||
TorrentIconWrapper,
|
||||
} from './style'
|
||||
|
||||
export default function LeftSideComponent({
|
||||
setIsUserInteractedWithPoster,
|
||||
setSelectedFile,
|
||||
torrentSource,
|
||||
setTorrentSource,
|
||||
selectedFile,
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleCapture = files => {
|
||||
const [file] = files
|
||||
if (!file) return
|
||||
|
||||
setIsUserInteractedWithPoster(false)
|
||||
setSelectedFile(file)
|
||||
setTorrentSource(file.name)
|
||||
}
|
||||
|
||||
const clearSelectedFile = () => {
|
||||
setSelectedFile()
|
||||
setTorrentSource('')
|
||||
}
|
||||
|
||||
const [isTorrentSourceActive, setIsTorrentSourceActive] = useState(false)
|
||||
const { getRootProps, getInputProps, isDragActive } = useDropzone({ onDrop: handleCapture, accept: '.torrent' })
|
||||
|
||||
const handleTorrentSourceChange = ({ target: { value } }) => setTorrentSource(value)
|
||||
|
||||
return (
|
||||
<LeftSide>
|
||||
<LeftSideTopSection active={isTorrentSourceActive}>
|
||||
<TextField
|
||||
onChange={handleTorrentSourceChange}
|
||||
value={torrentSource}
|
||||
margin='dense'
|
||||
label={t('TorrentSourceLink')}
|
||||
helperText={t('TorrentSourceOptions')}
|
||||
type='text'
|
||||
fullWidth
|
||||
onFocus={() => setIsTorrentSourceActive(true)}
|
||||
onBlur={() => setIsTorrentSourceActive(false)}
|
||||
inputProps={{ autoComplete: 'off' }}
|
||||
disabled={!!selectedFile}
|
||||
/>
|
||||
</LeftSideTopSection>
|
||||
|
||||
{selectedFile ? (
|
||||
<LeftSideBottomSectionFileSelected>
|
||||
<TorrentIconWrapper>
|
||||
<TorrentIcon />
|
||||
|
||||
<CancelIconWrapper onClick={clearSelectedFile}>
|
||||
<CancelIcon />
|
||||
</CancelIconWrapper>
|
||||
</TorrentIconWrapper>
|
||||
</LeftSideBottomSectionFileSelected>
|
||||
) : (
|
||||
<LeftSideBottomSectionNoFile isDragActive={isDragActive} {...getRootProps()}>
|
||||
<input {...getInputProps()} />
|
||||
<div>{t('AppendFile.Or')}</div>
|
||||
|
||||
<IconWrapper>
|
||||
<AddItemIcon color='primary' />
|
||||
<div>{t('AppendFile.ClickOrDrag')}</div>
|
||||
</IconWrapper>
|
||||
</LeftSideBottomSectionNoFile>
|
||||
)}
|
||||
</LeftSide>
|
||||
)
|
||||
}
|
||||
120
web/src/components/Add/RightSideComponent.jsx
Normal file
120
web/src/components/Add/RightSideComponent.jsx
Normal file
@@ -0,0 +1,120 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
import { NoImageIcon } from 'icons'
|
||||
import { TextField } from '@material-ui/core'
|
||||
|
||||
import {
|
||||
ClearPosterButton,
|
||||
PosterLanguageSwitch,
|
||||
RightSide,
|
||||
Poster,
|
||||
PosterSuggestions,
|
||||
PosterSuggestionsItem,
|
||||
PosterWrapper,
|
||||
RightSideContainer,
|
||||
} from './style'
|
||||
import { checkImageURL } from './helpers'
|
||||
|
||||
export default function RightSideComponent({
|
||||
setTitle,
|
||||
setPosterUrl,
|
||||
setIsPosterUrlCorrect,
|
||||
setIsUserInteractedWithPoster,
|
||||
setPosterList,
|
||||
isTorrentSourceCorrect,
|
||||
title,
|
||||
posterUrl,
|
||||
isPosterUrlCorrect,
|
||||
posterList,
|
||||
currentLang,
|
||||
posterSearchLanguage,
|
||||
setPosterSearchLanguage,
|
||||
posterSearch,
|
||||
removePoster,
|
||||
torrentSource,
|
||||
}) {
|
||||
const { t } = useTranslation()
|
||||
|
||||
const handleTitleChange = ({ target: { value } }) => setTitle(value)
|
||||
const handlePosterUrlChange = ({ target: { value } }) => {
|
||||
setPosterUrl(value)
|
||||
checkImageURL(value).then(setIsPosterUrlCorrect)
|
||||
setIsUserInteractedWithPoster(!!value)
|
||||
setPosterList()
|
||||
}
|
||||
const userChangesPosterUrl = url => {
|
||||
setPosterUrl(url)
|
||||
checkImageURL(url).then(setIsPosterUrlCorrect)
|
||||
setIsUserInteractedWithPoster(true)
|
||||
}
|
||||
|
||||
return (
|
||||
<RightSide>
|
||||
<RightSideContainer isHidden={!isTorrentSourceCorrect}>
|
||||
<TextField onChange={handleTitleChange} value={title} margin='dense' label={t('Title')} type='text' fullWidth />
|
||||
<TextField
|
||||
onChange={handlePosterUrlChange}
|
||||
value={posterUrl}
|
||||
margin='dense'
|
||||
label={t('AddPosterLinkInput')}
|
||||
type='url'
|
||||
fullWidth
|
||||
/>
|
||||
|
||||
<PosterWrapper>
|
||||
<Poster poster={+isPosterUrlCorrect}>
|
||||
{isPosterUrlCorrect ? <img src={posterUrl} alt='poster' /> : <NoImageIcon />}
|
||||
</Poster>
|
||||
|
||||
<PosterSuggestions>
|
||||
{posterList
|
||||
?.filter(url => url !== posterUrl)
|
||||
.slice(0, 12)
|
||||
.map(url => (
|
||||
<PosterSuggestionsItem onClick={() => userChangesPosterUrl(url)} key={uuidv4()}>
|
||||
<img src={url} alt='poster' />
|
||||
</PosterSuggestionsItem>
|
||||
))}
|
||||
</PosterSuggestions>
|
||||
|
||||
{currentLang !== 'en' && (
|
||||
<PosterLanguageSwitch
|
||||
onClick={() => {
|
||||
const newLanguage = posterSearchLanguage === 'en' ? 'ru' : 'en'
|
||||
setPosterSearchLanguage(newLanguage)
|
||||
posterSearch(title, newLanguage, { shouldRefreshMainPoster: true })
|
||||
}}
|
||||
showbutton={+isPosterUrlCorrect}
|
||||
color='primary'
|
||||
variant='contained'
|
||||
size='small'
|
||||
>
|
||||
{posterSearchLanguage === 'en' ? 'EN' : 'RU'}
|
||||
</PosterLanguageSwitch>
|
||||
)}
|
||||
|
||||
<ClearPosterButton
|
||||
showbutton={+isPosterUrlCorrect}
|
||||
onClick={() => {
|
||||
removePoster()
|
||||
setIsUserInteractedWithPoster(true)
|
||||
}}
|
||||
color='primary'
|
||||
variant='contained'
|
||||
size='small'
|
||||
>
|
||||
{t('Clear')}
|
||||
</ClearPosterButton>
|
||||
</PosterWrapper>
|
||||
</RightSideContainer>
|
||||
|
||||
<RightSideContainer
|
||||
isError={torrentSource && !isTorrentSourceCorrect}
|
||||
notificationMessage={
|
||||
!torrentSource ? t('AddTorrentSourceNotification') : !isTorrentSourceCorrect && t('WrongTorrentSource')
|
||||
}
|
||||
isHidden={isTorrentSourceCorrect}
|
||||
/>
|
||||
</RightSide>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user