merge maser

This commit is contained in:
nikk gitanes
2021-08-20 08:10:17 +03:00
41 changed files with 353 additions and 135 deletions

View File

@@ -46,7 +46,7 @@ export const Section = styled.section`
padding: 20px;
> span {
font-size: 20px;
font-size: 22px;
display: block;
margin-bottom: 15px;
}
@@ -87,7 +87,7 @@ export const LinkWrapper = styled.a`
align-items: center;
justify-content: start;
border: 1px solid;
padding: 10px;
padding: 7px 10px;
border-radius: 5px;
text-transform: uppercase;
text-decoration: none;
@@ -105,7 +105,7 @@ export const LinkWrapper = styled.a`
filter: brightness(1.1);
> * {
transform: translateY(-1px);
transform: translateY(0px);
}
}
`

View File

@@ -14,7 +14,7 @@ import { getTorrents } from 'utils/Utils'
import parseTorrent from 'parse-torrent'
import { ButtonWrapper, Header } from 'style/DialogStyles'
import { checkImageURL, getMoviePosters, chechTorrentSource, parseTorrentTitle } from './helpers'
import { checkImageURL, getMoviePosters, checkTorrentSource, parseTorrentTitle } from './helpers'
import { Content } from './style'
import RightSideComponent from './RightSideComponent'
import LeftSideComponent from './LeftSideComponent'
@@ -147,7 +147,7 @@ export default function AddDialog({
const prevTorrentSourceState = usePreviousState(torrentSource)
useEffect(() => {
const isCorrectSource = chechTorrentSource(torrentSource)
const isCorrectSource = checkTorrentSource(torrentSource)
if (!isCorrectSource) return setIsTorrentSourceCorrect(false)
setIsTorrentSourceCorrect(true)
@@ -227,10 +227,10 @@ export default function AddDialog({
{!isEditMode && (
<LeftSideComponent
setIsUserInteractedWithPoster={setIsUserInteractedWithPoster}
selectedFile={selectedFile}
setSelectedFile={setSelectedFile}
torrentSource={torrentSource}
setTorrentSource={setTorrentSource}
selectedFile={selectedFile}
/>
)}
@@ -271,7 +271,7 @@ export default function AddDialog({
style={{ minWidth: '110px' }}
disabled={!torrentSource || (isHashAlreadyExists && !isEditMode) || !isTorrentSourceCorrect}
onClick={handleSave}
color='primary'
color='secondary'
>
{isSaving ? <CircularProgress style={{ color: 'white' }} size={20} /> : t(isEditMode ? 'Save' : 'Add')}
</Button>

View File

@@ -1,7 +1,8 @@
import { useTranslation } from 'react-i18next'
import { rgba } from 'polished'
import { NoImageIcon } from 'icons'
import { IconButton, InputAdornment, TextField, useTheme } from '@material-ui/core'
import { CheckBox as CheckBoxIcon } from '@material-ui/icons'
import { HighlightOff as HighlightOffIcon } from '@material-ui/icons'
import {
ClearPosterButton,
@@ -84,7 +85,7 @@ export default function RightSideComponent({
endAdornment: (
<InputAdornment position='end'>
<IconButton
style={{ padding: '0 0 0 7px' }}
style={{ padding: '1px' }}
onClick={() => {
setTitle('')
setIsCustomTitleEnabled(!isCustomTitleEnabled)
@@ -92,7 +93,7 @@ export default function RightSideComponent({
setIsUserInteractedWithPoster(false)
}}
>
<CheckBoxIcon style={{ color: isCustomTitleEnabled ? primary : 'gray' }} />
<HighlightOffIcon style={{ color: isCustomTitleEnabled ? primary : rgba('#ccc', 0.5) }} />
</IconButton>
</InputAdornment>
),

View File

@@ -22,20 +22,19 @@ export const getMoviePosters = (movieName, language = 'en') => {
export const checkImageURL = async url => {
if (!url || !url.match(/.(jpg|jpeg|png|gif)$/i)) return false
try {
await fetch(url, { mode: 'no-cors' })
return true
} catch (e) {
return false
}
return true
}
const magnetRegex = /^magnet:\?xt=urn:[a-z0-9].*/i
export const hashRegex = /^\b[0-9a-f]{32}\b$|^\b[0-9a-f]{40}\b$|^\b[0-9a-f]{64}\b$/i
const torrentRegex = /^.*\.(torrent)$/i
export const chechTorrentSource = source =>
source.match(hashRegex) !== null || source.match(magnetRegex) !== null || source.match(torrentRegex) !== null
const linkRegex = /^(http(s?)):\/\/.*/i
export const checkTorrentSource = source =>
source.match(hashRegex) !== null ||
source.match(magnetRegex) !== null ||
source.match(torrentRegex) !== null ||
source.match(linkRegex) !== null
export const parseTorrentTitle = (parsingSource, callback) => {
parseTorrent.remote(parsingSource, (err, { name, files } = {}) => {

View File

@@ -1,34 +1,31 @@
import Button from '@material-ui/core/Button'
import { AppBar, IconButton, makeStyles, Toolbar, Typography } from '@material-ui/core'
import CloseIcon from '@material-ui/icons/Close'
import { ArrowBack } from '@material-ui/icons'
import { useTranslation } from 'react-i18next'
const useStyles = makeStyles(theme => ({
const useStyles = makeStyles({
appBar: { position: 'relative' },
title: { marginLeft: '6px', flex: 1 },
}))
title: { marginLeft: '5px', flex: 1 },
})
export default function DialogHeader({ title, onClose, onBack }) {
const { t } = useTranslation()
const classes = useStyles()
return (
<AppBar className={classes.appBar}>
<Toolbar>
<IconButton edge='start' color='inherit' onClick={onBack || onClose} aria-label='close'>
{onBack ? <ArrowBack /> : <CloseIcon />}
</IconButton>
{onBack && (
<IconButton edge='start' color='inherit' onClick={onBack} aria-label='back'>
<ArrowBack />
</IconButton>
)}
<Typography variant='h6' className={classes.title}>
{title}
</Typography>
{onBack && (
<Button autoFocus color='inherit' onClick={onClose}>
{t('Close')}
</Button>
)}
<IconButton autoFocus color='inherit' onClick={onClose} aria-label='close' style={{ marginRight: '-10px' }}>
<CloseIcon />
</IconButton>
</Toolbar>
</AppBar>
)

View File

@@ -62,9 +62,10 @@ const TorrentCache = ({ cache, isMini }) => {
ctx.clearRect(0, 0, canvasWidth, height)
source.forEach(({ percentage, isReader, isReaderRange }, i) => {
source.forEach(({ percentage, priority, isReader, isReaderRange }, i) => {
const inProgress = percentage > 0 && percentage < 100
const isCompleted = percentage === 100
const peacePriority = priority
const currentRow = i % piecesInOneRow
const currentColumn = Math.floor(i / piecesInOneRow)
const fixBlurStroke = borderWidth % 2 === 0 ? 0 : 0.5
@@ -90,6 +91,20 @@ const TorrentCache = ({ cache, isMini }) => {
ctx.fillRect(0, 0, pieceSize, pieceSize)
ctx.strokeRect(0, 0, pieceSize, pieceSize)
ctx.setTransform(1, 0, 0, 1, 0, 0)
if (peacePriority > 0) {
let info = ''
if (peacePriority === 1) info = '*'
else if (peacePriority === 2) info = 'H'
else if (peacePriority === 3) info = 'R'
else if (peacePriority === 4) info = 'N'
else if (peacePriority === 5) info = 'A'
ctx.font = isMini ? '12px monospace' : '10px monospace'
const xpad = isMini ? pieceSize * 0.34 : pieceSize * 0.28
const ypad = isMini ? pieceSize * 0.69 : pieceSize * 0.78
ctx.fillStyle = 'black'
ctx.fillText(info, x + xpad, y + ypad)
}
})
}, [
cacheMap,
@@ -107,6 +122,7 @@ const TorrentCache = ({ cache, isMini }) => {
completeColor,
readerColor,
rangeColor,
isMini,
theme,
])

View File

@@ -4,14 +4,14 @@ import { mainColors } from 'style/colors'
export const snakeSettings = {
dark: {
default: {
borderWidth: 2,
borderWidth: 1,
pieceSize: 14,
gapBetweenPieces: 3,
borderColor: mainColors.dark.secondary,
completeColor: rgba(mainColors.dark.primary, 0.65),
borderColor: rgba('#949ca0', 0.25),
completeColor: rgba(mainColors.dark.primary, 0.5),
backgroundColor: '#f1eff3',
progressColor: mainColors.dark.secondary,
readerColor: '#000',
readerColor: '#8f0405',
rangeColor: '#cda184',
},
mini: {
@@ -19,11 +19,11 @@ export const snakeSettings = {
borderWidth: 2,
pieceSize: 23,
gapBetweenPieces: 6,
borderColor: '#545a5e',
completeColor: '#545a5e',
backgroundColor: '#dee3e5',
progressColor: '#dee3e5',
readerColor: '#000',
borderColor: '#5c6469',
completeColor: '#5c6469',
backgroundColor: '#949ca0',
progressColor: '#949ca0',
readerColor: '#ccc',
rangeColor: '#cda184',
},
},
@@ -48,7 +48,7 @@ export const snakeSettings = {
completeColor: '#4db380',
backgroundColor: '#dbf2e8',
progressColor: '#dbf2e8',
readerColor: '#2d714f',
readerColor: '#0a0a0a',
rangeColor: '#afa6e3',
},
},

View File

@@ -43,9 +43,9 @@ export const useCreateCacheMap = cache => {
const map = []
for (let i = 0; i < PiecesCount; i++) {
const { Size, Length } = Pieces[i] || {}
const { Size, Length, Priority } = Pieces[i] || {}
const newPiece = { id: i, percentage: (Size / Length) * 100 || 0 }
const newPiece = { id: i, percentage: (Size / Length) * 100 || 0, priority: Priority || 0 }
Readers.forEach(r => {
if (i === r.Reader) newPiece.isReader = true

View File

@@ -204,6 +204,7 @@ export default function DialogTorrentDetailsContent({ closeDialog, torrent }) {
{bufferSize <= 33554432 && <SectionSubName>{t('BufferNote')}</SectionSubName>}
<LoadingProgress
value={Filled}
style={{ marginTop: '5px' }}
fullAmount={bufferSize}
label={`${humanizeSize(bufferSize)} / ${humanizeSize(Filled) || `0 ${t('B')}`}`}
/>

View File

@@ -129,12 +129,15 @@ export const SectionSubName = styled.div`
},
}) => css`
${({ mb }) => css`
${mb && `margin-top: ${mb / 3}px`};
${mb && `margin-bottom: ${mb}px`};
line-height: 1.2;
color: ${subNameFontColor};
@media (max-width: 800px) {
${mb && `margin-top: ${mb / 4}px`};
${mb && `margin-bottom: ${mb / 2}px`};
font-size: 11px;
font-size: 14px;
}
`}
`}
@@ -149,14 +152,15 @@ export const SectionTitle = styled.div`
}) => css`
${({ mb }) => css`
${mb && `margin-bottom: ${mb}px`};
font-size: 35px;
font-size: 34px;
font-weight: 300;
line-height: 1;
word-break: break-word;
color: ${color || titleFontColor};
@media (max-width: 800px) {
font-size: 25px;
font-size: 24px;
line-height: 1.1;
${mb && `margin-bottom: ${mb / 2}px`};
}
`}
@@ -258,15 +262,16 @@ export const WidgetFieldValue = styled.div`
},
}) => css`
grid-area: value;
padding: 0 20px;
font-size: 24px;
padding: 0 20px 0 0;
color: ${widgetFontColor};
font-size: 25px;
background: ${bgColor};
border-radius: 0 5px 5px 0;
white-space: nowrap;
@media (max-width: 800px) {
font-size: 18px;
padding: 0 4px;
padding: 0 16px 0 0;
}
`}
`
@@ -276,7 +281,7 @@ export const LoadingProgress = styled.div.attrs(
value,
fullAmount,
theme: {
dialogTorrentDetailsContent: { gradientEndColor },
dialogTorrentDetailsContent: { gradientStartColor, gradientEndColor },
},
}) => {
const percentage = Math.min(100, (value * 100) / fullAmount)
@@ -284,7 +289,7 @@ export const LoadingProgress = styled.div.attrs(
return {
// this block is here according to styled-components recomendation about fast changable components
style: {
background: `linear-gradient(to right, ${gradientEndColor} 0%, ${gradientEndColor} ${percentage}%, #fff ${percentage}%, #fff 100%)`,
background: `linear-gradient(to right, ${gradientStartColor} 0%, ${gradientEndColor} ${percentage}%, #fff ${percentage}%, #fff 100%)`,
},
}
},

View File

@@ -50,13 +50,13 @@ export default function PrimarySettingsComponent({
<PreloadCachePercentage
value={100 - cachePercentage}
label={`${t('Cache')} ${cacheSize} MB`}
label={`${t('Cache')} ${cacheSize} ${t('MB')}`}
preloadCachePercentage={preloadCachePercentage}
/>
<PreloadCacheValue color={cacheBeforeReaderColor}>
<div>
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} MB)
{100 - cachePercentage}% ({Math.round((cacheSize / 100) * (100 - cachePercentage))} {t('MB')})
</div>
<div>{t('SettingsDialog.CacheBeforeReaderDesc')}</div>
@@ -64,7 +64,7 @@ export default function PrimarySettingsComponent({
<PreloadCacheValue color={cacheAfterReaderColor}>
<div>
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} MB)
{cachePercentage}% ({Math.round((cacheSize / 100) * cachePercentage)} {t('MB')})
</div>
<div>{t('SettingsDialog.CacheAfterReaderDesc')}</div>
@@ -80,9 +80,9 @@ export default function PrimarySettingsComponent({
sliderMin={32}
sliderMax={1024}
inputMin={32}
inputMax={20000}
step={8}
onBlurCallback={value => setCacheSize(Math.round(value / 8) * 8)}
inputMax={999999}
step={4}
onBlurCallback={value => setCacheSize(Math.round(value / 4) * 4)}
/>
<SliderInput
@@ -98,7 +98,7 @@ export default function PrimarySettingsComponent({
<SliderInput
isProMode={isProMode}
title={`${t('SettingsDialog.PreloadCache')} - ${preloadCachePercentage}% (${preloadCacheSize} MB)`}
title={`${t('SettingsDialog.PreloadCache')} - ${preloadCachePercentage}% (${preloadCacheSize} ${t('MB')})`}
value={preloadCachePercentage}
setValue={setPreloadCachePercentage}
sliderMin={0}

View File

@@ -85,16 +85,6 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
label={t('SettingsDialog.DHT')}
labelPlacement='start'
/>
<TextField
onChange={inputForm}
margin='normal'
id='DhtConnectionLimit'
label={t('SettingsDialog.DhtConnectionLimit')}
value={DhtConnectionLimit}
type='number'
variant='outlined'
fullWidth
/>
<br />
<TextField
onChange={inputForm}
@@ -134,6 +124,7 @@ export default function SecondarySettingsComponent({ settings, inputForm }) {
margin='normal'
id='PeersListenPort'
label={t('SettingsDialog.PeersListenPort')}
helperText={t('SettingsDialog.PeersListenPortHint')}
value={PeersListenPort}
type='number'
variant='outlined'

View File

@@ -129,7 +129,7 @@ const Torrent = ({ torrent }) => {
<Dialog open={isDeleteTorrentOpened} onClose={closeDeleteTorrentAlert}>
<DialogTitle>{t('DeleteTorrent?')}</DialogTitle>
<DialogActions>
<Button variant='outlined' onClick={closeDeleteTorrentAlert} color='primary'>
<Button variant='outlined' onClick={closeDeleteTorrentAlert} color='secondary'>
{t('Cancel')}
</Button>
@@ -139,7 +139,7 @@ const Torrent = ({ torrent }) => {
deleteTorrent(torrent)
closeDeleteTorrentAlert()
}}
color='primary'
color='secondary'
autoFocus
>
{t('OK')}

View File

@@ -14,11 +14,11 @@
"HashExists": "This torrent is already in database",
"OriginalTorrentTitle": "Original torrent title",
"TitleBlank": "Title (blank for orig. torrent title)",
"TorrentSourceLink": "Torrent source link",
"TorrentSourceLink": "Torrent source",
"TorrentSourceOptions": "magnet / hash / .torrent file link",
"WrongTorrentSource": "Wrong torrent source"
},
"AddFromLink": "Add from Link",
"AddFromLink": "Add Torrent",
"AddNewTorrent": "Add new torrent",
"B": "B",
"bps": "bps",
@@ -100,6 +100,7 @@
"DownloadRateLimit": "Download Rate Limit",
"ForceEncrypt": "Force Encrypt Headers",
"PeersListenPort": "Peers Listen Port",
"PeersListenPortHint": "1024 - 65535, 0 - auto",
"PreloadCache": "Preload Cache Before Play",
"ProMode": "PRO mode",
"RAM": "RAM",

View File

@@ -9,11 +9,11 @@
"Or": "ИЛИ",
"ClickOrDrag": "НАЖМИТЕ / ПЕРЕТАЩИТЕ ФАЙЛ (.torrent)"
},
"CustomTorrentTitle": "Cвое имя (не обязательно)",
"CustomTorrentTitle": "Cвое название (не обязательно)",
"CustomTorrentTitleHelperText": "Напишите свое название, чтобы найти постер",
"HashExists": "Этот торрент уже есть в базе данных",
"OriginalTorrentTitle": "Оригинальное имя торрента",
"TitleBlank": "Имя (пустое - ориг. имя торрента)",
"OriginalTorrentTitle": "Оригинальное название торрента",
"TitleBlank": "Название (пустое - ориг. название торрента)",
"TorrentSourceLink": "Ссылка на источник торрента",
"TorrentSourceOptions": "magnet-ссылка / хеш / ссылка на .torrent файл",
"WrongTorrentSource": "Неправильный torrent-источник"
@@ -100,6 +100,7 @@
"DownloadRateLimit": "Ограничение скорости загрузки",
"ForceEncrypt": "Принудительное шифрование заголовков",
"PeersListenPort": "Порт для входящих подключений",
"PeersListenPortHint": "1024 - 65535, 0 - авто",
"PreloadCache": "Буфер предзагрузки",
"ProMode": "ПРО-режим",
"RAM": "Оперативная память",