fix eslint
This commit is contained in:
@ -4,17 +4,17 @@ import Page from './page';
|
||||
import RecentTorrents from './recent-torrents'
|
||||
|
||||
export default class ActivityPage extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Content Search Engine');
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='column center'>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<RecentTorrents />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Content Search Engine');
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='column center'>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<RecentTorrents />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -20,52 +20,52 @@ if(typeof WEB !== 'undefined')
|
||||
}
|
||||
else
|
||||
{
|
||||
const { ipcRenderer, remote } = require('electron');
|
||||
window.currentWindow = remote.getCurrentWindow()
|
||||
const { ipcRenderer, remote } = require('electron');
|
||||
window.currentWindow = remote.getCurrentWindow()
|
||||
|
||||
window.torrentSocket = {}
|
||||
window.torrentSocket.callbacks = {}
|
||||
window.torrentSocket.listeners = {}
|
||||
window.torrentSocket.on = (name, func) => {
|
||||
const newListener = (event, ...data) => {
|
||||
func(...data)
|
||||
}
|
||||
window.torrentSocket.listeners[func] = newListener
|
||||
ipcRenderer.on(name, newListener);
|
||||
}
|
||||
window.torrentSocket.off = (name, func) => {
|
||||
if(!func)
|
||||
ipcRenderer.removeAllListeners(name);
|
||||
else
|
||||
{
|
||||
const realListener = window.torrentSocket.listeners[func]
|
||||
if(realListener)
|
||||
{
|
||||
ipcRenderer.removeListener(name, realListener);
|
||||
delete window.torrentSocket.listeners[func]
|
||||
window.torrentSocket = {}
|
||||
window.torrentSocket.callbacks = {}
|
||||
window.torrentSocket.listeners = {}
|
||||
window.torrentSocket.on = (name, func) => {
|
||||
const newListener = (event, ...data) => {
|
||||
func(...data)
|
||||
}
|
||||
}
|
||||
}
|
||||
window.torrentSocket.emit = (name, ...data) => {
|
||||
if(typeof data[data.length - 1] === 'function')
|
||||
{
|
||||
const id = Math.random().toString(36).substring(5)
|
||||
window.torrentSocket.callbacks[id] = data[data.length - 1];
|
||||
data[data.length - 1] = {callback: id}
|
||||
}
|
||||
ipcRenderer.send(name, data)
|
||||
}
|
||||
ipcRenderer.on('callback', (event, id, data) => {
|
||||
const callback = window.torrentSocket.callbacks[id]
|
||||
if(callback)
|
||||
callback(data)
|
||||
delete window.torrentSocket.callbacks[id]
|
||||
});
|
||||
window.torrentSocket.listeners[func] = newListener
|
||||
ipcRenderer.on(name, newListener);
|
||||
}
|
||||
window.torrentSocket.off = (name, func) => {
|
||||
if(!func)
|
||||
ipcRenderer.removeAllListeners(name);
|
||||
else
|
||||
{
|
||||
const realListener = window.torrentSocket.listeners[func]
|
||||
if(realListener)
|
||||
{
|
||||
ipcRenderer.removeListener(name, realListener);
|
||||
delete window.torrentSocket.listeners[func]
|
||||
}
|
||||
}
|
||||
}
|
||||
window.torrentSocket.emit = (name, ...data) => {
|
||||
if(typeof data[data.length - 1] === 'function')
|
||||
{
|
||||
const id = Math.random().toString(36).substring(5)
|
||||
window.torrentSocket.callbacks[id] = data[data.length - 1];
|
||||
data[data.length - 1] = {callback: id}
|
||||
}
|
||||
ipcRenderer.send(name, data)
|
||||
}
|
||||
ipcRenderer.on('callback', (event, id, data) => {
|
||||
const callback = window.torrentSocket.callbacks[id]
|
||||
if(callback)
|
||||
callback(data)
|
||||
delete window.torrentSocket.callbacks[id]
|
||||
});
|
||||
|
||||
ipcRenderer.on('url', (event, url) => {
|
||||
console.log('url', url)
|
||||
router(url)
|
||||
});
|
||||
ipcRenderer.on('url', (event, url) => {
|
||||
console.log('url', url)
|
||||
router(url)
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
@ -164,8 +164,8 @@ class App extends Component {
|
||||
<div>
|
||||
{
|
||||
checkNotModal
|
||||
&&
|
||||
<Header />
|
||||
&&
|
||||
<Header />
|
||||
}
|
||||
<PagesPie />
|
||||
<Footer />
|
||||
|
@ -1,259 +1,259 @@
|
||||
const XXX_BLOCK_WORDS = ['incestcash', 'asacp', 'xondemand', 'yankscash', 'klixxx', 'cybersitter', 'safesurf',
|
||||
'surfwatch', 'netcash', 'watersport', 'fuck', 'threesome', 'tits',
|
||||
'masturbating', 'incest', 'bestiality', 'analintercourse', 'analsex', 'animesex',
|
||||
'anitablonde', 'autosex', 'blackass', 'blackasses', 'boner', 'boobcruise',
|
||||
'boobies', 'bordello', 'braless', 'brothel', 'callgirl', 'callgirls',
|
||||
'clit', 'clitoris', 'clits', 'cums', 'cybererotic', 'cybererotica',
|
||||
'cybersex', 'cybersexx', 'ejaculation', 'erotica', 'eroticfilm', 'eroticfilms',
|
||||
'eroticism', 'eroticphoto', 'eroticphotography', 'eroticphotos', 'erotics', 'eroticsex',
|
||||
'eroticsexstories', 'eroticstories', 'eroticstory', 'erotik', 'erotika', 'antasysex',
|
||||
'gaysex', 'gruppensex', 'horny', 'jackoff', 'lesbo', 'lesbos',
|
||||
'makinglove', 'motherfucker', 'horsesex', 'dogsex', 'snakesex', 'sextracker',
|
||||
'tranny', 'bdsm', 'porn', 'beastality', 'bizarre', 'blowjob',
|
||||
'bondage', 'bondages', 'celebs', 'cum', 'cunt', 'transsexual',
|
||||
'transsexuals', 'cumbath', 'cumshot', 'dildo', 'dildos', 'transvestites',
|
||||
'transvestite', 'dominatrix', 'spank', 'dungeon', 'sexbilder', 'dungeons',
|
||||
'pussie', 'ebony', 'fisting', 'gayshop', 'facesitting', 'sexshop',
|
||||
'pussy', 'bukkake', 'escort', 'blowjobs', 'facial', 'facialized',
|
||||
'facials', 'fetish', 'footfetish', 'fuckingpussy', 'fucking', 'hardcore',
|
||||
'hentai', 'hustlerlatex', 'latex', 'lolita', 'lolitas', 'mlm',
|
||||
'oralsex', 'peepshow', 'peepshows', 'phonesex', 'pornstars', 'preteen',
|
||||
'preteens', 'pussies', 'shemale', 'shemales', 'sluts', 'whores',
|
||||
'whore', 'spanking', 'strapon', 'twinks', 'upskirts', 'voyeur',
|
||||
'whip', 'whipping', 'xxx', 'sexkey', 'femdom', 'gangbang',
|
||||
'gloryhole', 'adultbuffet', 'adultcartoons', 'adultchat', 'adultchatnetwork', 'adultdvd',
|
||||
'adultentertainment', 'adultentertainmenthouse', 'adulterotica', 'adultfilms', 'adultfree', 'adultfreepics',
|
||||
'adultfreepix', 'adultfun', 'adulthardcore', 'adultimages', 'adultjpeg', 'adultlink',
|
||||
'adultlinks', 'adultmovie', 'adultmovies', 'adultmpeg', 'adultmpegs', 'adultpass',
|
||||
'adultpersonals', 'adultphotos', 'adultpic', 'adultpics', 'adultpicture', 'adultpictures',
|
||||
'adultpix', 'adultporn', 'adultpornography', 'adultsearch', 'adultsex', 'adultsights',
|
||||
'adultsites', 'adultsonly', 'adultstars', 'adultstories', 'adultvideo', 'adultvideos',
|
||||
'adultweb', 'adultxxx', 'alt.sex', 'altsex', 'alt.sex.exhibitionism', 'alt.sex.pictures',
|
||||
'altsexst', 'alt.sex.stories', 'alt.sex.voyeurism', 'amateurerotica', 'amateurfotos', 'amateurhardcore',
|
||||
'amateurindex', 'amateurnaked', 'amateurnudes', 'amateurporn', 'amateurpussy', 'amateursex',
|
||||
'amateursxxx', 'amatuerhardcore', 'amatuersex', 'ampland', 'analaction', 'analcum',
|
||||
'analfuck', 'analfucking', 'analgallery', 'analingus', 'analpics', 'analpicture',
|
||||
'analsex', 'analsexpics', 'analsexpictures', 'analxxx', 'animalbeastiality', 'animehentai',
|
||||
'animeporno', 'animexxx', 'asiacarrera', 'assfuck', 'assfucking', 'asshole',
|
||||
'assholes', 'asslick', 'asspics', 'assworship', 'autofellatio', 'babepix',
|
||||
'badgirls', 'bakedchicks', 'baldcunt', 'baldpussies', 'baldpussy', 'barecelebs',
|
||||
'barenaked', 'barepussy', 'beastiality', 'beaverboy', 'beavershots', 'bigballs',
|
||||
'bigblackboobs', 'bigblackcocks', 'bigblackdicks', 'bigblacktits', 'bigboob', 'bigboobs',
|
||||
'bigbreast', 'bigbreastlovers', 'bigbreasts', 'bigbutt', 'bigbutts', 'bigclit',
|
||||
'bigclitoris', 'bigclits', 'bigcock', 'bigcocks', 'bigcunt', 'bigcunts',
|
||||
'bigdick', 'bigdicks', 'biggestboobs', 'biggestdick', 'biggesttit', 'biggesttits',
|
||||
'bighairyballs', 'bighardons', 'bighooters', 'bignipples', 'bigpussies', 'bigpussy',
|
||||
'bigtit', 'bigtits', 'bigtitties', 'bigtitts', 'bizarresex', 'bizarrexxx',
|
||||
'bizzaresex', 'blackbondage', 'blackboobs', 'blackbooty', 'blackbutt', 'blackcock',
|
||||
'blackcocks', 'blackcum', 'blackcunt', 'blackcunts', 'blackdick', 'blackdicks',
|
||||
'blackerotica', 'blackhardcore', 'blacknudes', 'blackonblondes', 'blackporn', 'blackporno',
|
||||
'blackpornography', 'blackpussy', 'blacksex', 'blacksluts', 'blacksonblondes', 'blacktit',
|
||||
'blacktits', 'blacktwat', 'blackxxx', 'blondepussy', 'blondsgay', 'bondagefree',
|
||||
'bondagegallery', 'bondagelinks', 'bondagepics', 'bondagepictures', 'bondagesex', 'bondagestories',
|
||||
'bondagestory', 'bukake', 'bustybabes', 'bustyblondes', 'bustyceleb', 'butt-fuck',
|
||||
'buttfuck', 'buttfucker', 'buttfuckers', 'buttfucking', 'buttholes', 'buttman',
|
||||
'buttpics', 'buttplug', 'buttthumbnails', 'cartoonporn', 'cartoonsex', 'cartoonsxxx',
|
||||
'cartoonxxx', 'celebritiesnaked', 'celebritiesnude', 'celebritiesxxx', 'celebritybush', 'celebritybutts',
|
||||
'celebritynude', 'celebritynudes', 'celebrityporn', 'celebritypussy', 'celebritysex', 'celebrityxxx',
|
||||
'celebsxxx', 'celebxxx', 'centerfolds', 'chaseylain', 'chatsex', 'cheerleadersxxx',
|
||||
'cheerleaderxxx', 'chickswithdicks', 'christycanyon', 'cicciolina', 'clitpics', 'clitpictures',
|
||||
'closeuppussy', 'comixxx', 'crotchless', 'cruisingforsex', 'cumbaths', 'cumcoveredcunts',
|
||||
'cumcunt', 'cumdrinker', 'cumdrinkers', 'cumdrinking', 'cumdrops', 'cumeater',
|
||||
'cumeaters', 'cumeating', 'cumface', 'cumfaces', 'cumfacial', 'cumfacials',
|
||||
'cumgallery', 'cumgargle', 'cumguzzlers', 'cumincunt', 'cumjunkies', 'cumlovers',
|
||||
'cummpeg', 'cumpic', 'cumpics', 'cumpicture', 'cumpictures', 'cumpussy',
|
||||
'cumsluts', 'cumsucker', 'cumsuckers', 'cumsucking', 'cumswallow', 'cumswallowers',
|
||||
'cumswallowing', 'cumtasting', 'cumthumbnails', 'cunilingus', 'cunnilingus', 'cuntcum',
|
||||
'cuntfuck', 'cuntfucking', 'cuntjuice', 'cuntlapper', 'cuntlick', 'cuntlickers',
|
||||
'cuntlicking', 'cuntpics', 'cuntpictures', 'cunts', 'cuntstories', 'cuntsuckers',
|
||||
'cuntz', 'cyberlust', 'cybernude', 'cyberporn', 'cyberpornlinks', 'cyberpornsexlinks',
|
||||
'cyberslut', 'd’amateur', 'danniashe', 'dicksex', 'dicksuckers', 'dicksucking',
|
||||
'digixxx', 'directporn', 'dirtypictures', 'dirtysex', 'doggiestyle', 'doggystyle',
|
||||
'domatrix', 'dominatrixes', 'downblouse', 'drinkingcum', 'drippingcunt', 'drippingcunts',
|
||||
'drippingpussy', 'easypic.com', 'eatcum', 'eatingcum', 'eatingpussy', 'eatpussy',
|
||||
'ebony+ayres', 'ebonyporn', 'ebonypussy', 'ebonysex', 'ebonyxxx', 'enormoustits',
|
||||
'erosvillage', 'eroticanime', 'eroticart', 'eroticas', 'eroticastories', 'eroticfiction',
|
||||
'eroticlesbianstories', 'eroticmovie', 'eroticmovies', 'erotico', 'eroticos', 'eroticpics',
|
||||
'eroticpicture', 'eroticpictures', 'eroticsites', 'eroticsounds', 'erotictales', 'erotictext',
|
||||
'eroticvideo', 'eroticvideos', 'eroticwomen', 'eroticwriting', 'erotikchat', 'erotique',
|
||||
'erotismo', 'escortservice', 'escortservices', 'eurosex', 'explicitsex', 'facecum',
|
||||
'facesit', 'facesitters', 'fastporn', 'fatass', 'fatsex', 'feetfetish',
|
||||
'feetsex', 'felatio', 'fellatio', 'fellations', 'fetishwear', 'fettegirls',
|
||||
'fingerbang', 'fingerfuck', 'flesh4free', 'footjobs', 'footlicking', 'footworship',
|
||||
'fornication', 'freeanal', 'freeanalsex', 'freeass', 'freebigboobs', 'freebigtit',
|
||||
'freebigtits', 'freeblackcunt', 'freeblackpussy', 'freeblowjob', 'freeblowjobs', 'freebondage',
|
||||
'freeboobs', 'freecum', 'freecumshot', 'freecumshots', 'freecunt', 'freecunts',
|
||||
'freedick', 'freeerotic', 'freeerotica', 'freeeroticstories', 'freefuck', 'freefucking',
|
||||
'freefuckpics', 'freegay', 'freegaypics', 'freehardcore', 'freehardcorepics', 'freehardcorepictures',
|
||||
'freehardcoreporn', 'freehardcoresex', 'freehardcoresexpics', 'freehentai', 'freehooters', 'freelargehooters',
|
||||
'freelesbian', 'freelesbianporn', 'freelesbiansex', 'freenakedpic', 'freenakedpics', 'freenakedpictures',
|
||||
'freenakedwomen', 'freenude', 'freenudecelebs', 'freenudephotos', 'freenudepics', 'freenudes',
|
||||
'freeporn', 'freepornmovies', 'freeporno', 'freepornography', 'freepornopics', 'freepornopictures',
|
||||
'freepornos', 'freepornpic', 'freepornpics', 'freepornpictures', 'freeporns', 'freepornsite',
|
||||
'freepornsites', 'freepussy', 'freepussypic', 'freepussypics', 'freepussypictures', 'freesex',
|
||||
'freesexchat', 'freesexmovies', 'freesexnet', 'freesexphotos', 'freesexpic', 'freesexpics',
|
||||
'freesexpicture', 'freesexpictures', 'freesexsites', 'freesexstories', 'freesexvideos', 'freesexycam',
|
||||
'freeshemale', 'freesmut', 'freetit', 'freetits', 'freevoyeur', 'freexxx',
|
||||
'freexxxmovie', 'freexxxmovies', 'freexxxmpeg', 'freexxxphotos', 'freexxxpic', 'freexxxpics',
|
||||
'freexxxpicture', 'freexxxpictures', 'freexxxstories', 'freexxxvideo', 'freexxxx', 'fuking',
|
||||
'gangbangs', 'gratishardcoregalerie', 'hardcorecelebs', 'hardcorefisting', 'hardcorefree', 'hardcorefucking',
|
||||
'hardcorehooters', 'hardcorejunkie', 'hardcorejunky', 'hardcoremovie', 'hardcoremovies', 'hardcorepic',
|
||||
'hardcorepics', 'hardcorepictures', 'hardcorepix', 'hardcoreporn', 'hardcoreporno', 'hardcorepornography',
|
||||
'hardcorepornos', 'hardcorepussy', 'hardcoresamples', 'hardcoresex', 'hardcoresexpictures', 'hardcorestories',
|
||||
'hardcorethumbnails', 'hardcorevideo', 'hardcorevideos', 'hardcorexxx', 'harddicks', 'hardnipples',
|
||||
'hardons', 'hardporn', 'indiasex', 'interacialhardcore', 'interacialsex', 'interacialxxx',
|
||||
'intercoursepositions', 'internetsex', 'interracialfucking', 'interracialhardcore', 'interracialporn', 'interracialpornography',
|
||||
'interracialsex', 'interracialsexstories', 'interracialxxx', 'intimatesex', 'ittybittytitty', 'japaneseporn',
|
||||
'japanesesex', 'japansex', 'japanxxx', 'jennacam.com', 'jennajameson', 'jennicam',
|
||||
'jerkoff', 'jism', 'jiz', 'jizz', 'juicycunts', 'juicypussy',
|
||||
'justhardcore', 'karasamateurs', 'karasxxx', 'kascha', 'kaylakleevage', 'kobetai',
|
||||
'koreasex', 'lapdance', 'largeclits', 'largecunts', 'largedicks', 'largehooters',
|
||||
'largepussy', 'largetit', 'largetits', 'latinapussy', 'latinasex', 'latinosex',
|
||||
'latinoxxx', 'latinxxx', 'legsex', 'lesbianerotica', 'lesbianhardcore', 'lesbianorgies',
|
||||
'lesbianorgy', 'lesbianpics', 'lesbianpink', 'lesbianporn', 'lesbian-porno', 'lesbianporno',
|
||||
'lesbianpornography', 'lesbianpornos', 'lesbianpussy', 'lesbiansex', 'lesbiansexpics', 'lesbiansexstories',
|
||||
'lesbianxxx', 'lickadick', 'lickingpussy', 'lindalovelace', 'lingeriexxx', 'literotica',
|
||||
'littleboobs', 'littlepussy', 'littletits', 'livefucking', 'liveporn', 'livesex',
|
||||
'livesexcam', 'livesexcams', 'longdicks', 'lovedoll', 'lovedolls', 'magazinessex',
|
||||
'makinglove', 'malaysex', 'malenudes', 'malesex', 'mangaporno', 'mangax',
|
||||
'mangaxxx', 'manpics', 'mansex', 'marilynchambers', 'massivecocks', 'masterbating',
|
||||
'masturbation', 'masturbationvideos', 'maturefucking', 'maturesex', 'maturexxx', 'megaboobs',
|
||||
'megaporno', 'megapussy', 'megatits', 'mensdicks', 'mensex', 'm.i.l.f.',
|
||||
'milf', 'milfhunterpic', 'milfmpegsample', 'modelsex', 'mondoporn', 'monstercocks',
|
||||
'monsterdicks', 'motherfucker', 'moviepost.com', 'mpegsex', 'mpegxxx', 'muffdiving',
|
||||
'myslutwife', 'nacktfotos', 'nakedbabes', 'nakedblackwomen', 'nakedcelebrity', 'nakedcelebs',
|
||||
'nakedcheerleader', 'nakedchicks', 'nakedgirls', 'nakedguys', 'nakedladies', 'nakedlady',
|
||||
'nakedman', 'nakedmen', 'nakedness', 'nakedphotographs', 'nakedphotography', 'nakedphotos',
|
||||
'nakedpic', 'nakedpics', 'nakedpicture', 'nakedpictures', 'nakedpussy', 'nakedstars',
|
||||
'nakedwife', 'nakedwoman', 'nakedwomen', 'nastychat', 'nastypussy', 'nastysex',
|
||||
'nastythumbs', 'naturaltits', 'naughty.com', 'naughtylinks', 'naughtylinx', 'naughtylynx',
|
||||
'naughtynurses', 'netsex', 'niceass', 'nicetits', 'nikkinova', 'nikkityler',
|
||||
'nipples', 'nookie', 'nookies', 'nudeactress', 'nudeactresses', 'nudeamateur',
|
||||
'nudeamateurs', 'nudeasianwomen', 'nudebabes', 'nudebigboobs', 'nudeblack', 'nudeblackwomen',
|
||||
'nudeblondes', 'nudeceleb', 'nudeceleberties', 'nudecelebraties', 'nudecelebrites', 'nudecelebrities',
|
||||
'nudecelebrity', 'nudecelebs', 'nudecollegegirls', 'nudefemale', 'nudefemales', 'nudefree',
|
||||
'nudegay', 'nudeimages', 'nudeladies', 'nudelesbians', 'nudemale', 'nudemales',
|
||||
'nudeman', 'nudemen', 'nudepic', 'nudepics', 'nudepicture', 'nudepictures',
|
||||
'nudepornography', 'nudepussy', 'nuderaider', 'nuderedheads', 'nudes', 'nudesex',
|
||||
'nudestar', 'nudestars', 'nudevideoconferencing', 'nudewoman', 'nudewomen', 'nudism',
|
||||
'nudist', 'nudists', 'nudity', 'nylonfetish', 'nylonsex', 'nympho',
|
||||
'nymphos', 'olderbabes', 'oldersex', 'oldersluts', 'oldpussy', 'oldsex',
|
||||
'oldsluts', 'openlegs', 'openpussy', 'oral4free', 'oral-sex', 'oralsexpictures',
|
||||
'orgie', 'orgies', 'orgypics', 'orgys', 'pantyhosefetish', 'pantyhosesex',
|
||||
'peepcam', 'persiankitty', 'persiankitty.com', 'perverted', 'picsxxx', 'picturesex',
|
||||
'picturesofsex', 'picturessex', 'pimpserver', 'pimpserver.com', 'pinkpussy', 'pissing',
|
||||
'pixxx', 'poontang', 'pornagraphy', 'porncast', 'porncity', 'porndirectory',
|
||||
'porne', 'pornfree', 'pornmovies', 'pornno', 'pornnude', 'porno',
|
||||
'pornoadult', 'pornocartoons', 'pornochat', 'pornodeluxe', 'pornoe', 'pornofilms',
|
||||
'pornofree', 'pornogame', 'pornografi', 'pornografia', 'pornografie', 'pornografy',
|
||||
'pornograph', 'pornographi', 'pornographia', 'pornographic', 'pornographicpictures', 'pornographics',
|
||||
'pornographicvideo', 'pornographicvideos', 'pornographie', 'pornography', 'pornographyfree', 'pornographyphotos',
|
||||
'pornographypictures', 'pornography-sex', 'pornographysex', 'pornoland', 'pornolinks', 'pornolynx',
|
||||
'pornomagazines', 'pornomovies', 'pornompeg', 'pornophotos', 'pornopic', 'pornopics',
|
||||
'pornopicture', 'pornopictures', 'pornos', 'pornosex', 'pornosite', 'pornosites',
|
||||
'pornostar', 'pornostories', 'pornovideo', 'pornovideos', 'pornoxxx', 'pornphotos',
|
||||
'pornpics', 'pornpictures', 'pornpix', 'pornpost', 'pornqueens', 'pornrated',
|
||||
'porns', 'pornsex', 'pornstar', 'pornstories', 'porntrack', 'pornvideo',
|
||||
'pornvideos', 'pornypics', 'porstars', 'privatesex', 'privatex', 'privatexx',
|
||||
'privatexxx', 'prono', 'pronography', 'publicnudity', 'puffynipples', 'purple+passion',
|
||||
'pussyboard', 'pussycam', 'pussycams', 'pussycloseup', 'pussycloseups', 'pussycum',
|
||||
'pussycunt', 'pussyeater', 'pussyeaters', 'pussyeating', 'pussyfuck', 'pussyfucking',
|
||||
'pussyhair', 'pussyheaven', 'pussyjuice', 'pussylickers', 'pussylicking', 'pussylink',
|
||||
'pussylips', 'pussyphotos', 'pussyporno', 'pussys', 'pussysex', 'pussyshots',
|
||||
'pussythumbnails', 'pussytits', 'pusy', 'racqueldarrian', 'rape', 'rawlinks',
|
||||
'rawpussy', 'rawsex', 'realhardcore', 'realsex', 'redneckporn', 'redpussy',
|
||||
'rubberfetish', 'russianxxx', 'scat', 'schiffernude', 'seka', 'seniorsex',
|
||||
'sex4free', 'sex66', 'sexacts', 'sexadult', 'sexaids', 'sexamateur',
|
||||
'sexanal', 'sexandpictures', 'sexaphone', 'sexaudio', 'sexavi', 'sexbondage',
|
||||
'sexboner', 'sexbuttfucker', 'sexcam', 'sexcams', 'sexchat', 'sexchatrooms',
|
||||
'sexcites', 'sexclub', 'sexclubs', 'sex.com', 'sexdating', 'sexe',
|
||||
'sexfantasies', 'sexfantasy', 'sexfilm', 'sexgallery', 'sexgame', 'sexgames',
|
||||
'sexgirl', 'sexgirls', 'sexgroup', 'sexguide', 'sexhardcore', 'sexhphoto',
|
||||
'sexhungry', 'sexhungryjoe', 'sexhungryjoes', 'sexi', 'seximages', 'sexis',
|
||||
'sexjapan', 'sex.jpg', 'sexlinda', 'sexlinks', 'sexlinx', 'sexlive',
|
||||
'sexmagazine', 'sexmagazines', 'sexmature', 'sexmelayu', 'sexmodels', 'sexmovie',
|
||||
'sexmovies', 'sexmpeg', 'sexnude', 'sexnudity', 'sexo', 'sexoanal',
|
||||
'sexole', 'sexontheinternet', 'sexoral', 'sexpasswords', 'sexphoto', 'sexphotos',
|
||||
'sexpic', 'sexpicnet', 'sexpics', 'sexpicture', 'sexpictures', 'sexpicturesfree',
|
||||
'sexpix', 'sexplaza', 'sexporn', 'sexporno', 'sexpositions', 'sexpussy',
|
||||
'sexroulette', 'sexs', 'sexsamples', 'sexsearch', 'sexsex', 'sexsexsex',
|
||||
'sexshare', 'sexshops', 'sexshow', 'sexshows', 'sexsite', 'sexsites',
|
||||
'sexslave', 'sexsound', 'sexsounds', 'sexsource', 'sexspaces', 'sexspaces.com',
|
||||
'sexstories', 'sexstory', 'sexstorys', 'sextalk', 'sexteen', 'sexthumbnails',
|
||||
'sex-toons', 'sextoons', 'sextour', 'sextoy', 'sextoys', 'sextpus',
|
||||
'sextracker.com', 'sextropolis', 'sexualbondage', 'sexualfantasies', 'sexualfantasy', 'sexualintercourse',
|
||||
'sexualpictures', 'sexualpleasure', 'sexualpositions', 'sexuncensored', 'sexvideo', 'sexvision',
|
||||
'sexvote', 'sexwomen', 'sexworld', 'sexx', 'sexxx', 'sexxxx',
|
||||
'sexxxxx', 'sexyamateurs', 'sexybabes', 'sexyblack', 'sexyboobs', 'sexybookmark',
|
||||
'sexybookmarka', 'sexybookmarks', 'sexybutts', 'sexycunts', 'sexygirl', 'sexygirls',
|
||||
'sexyladies', 'sexylady', 'sexylegs', 'sexylingerie', 'sexymen', 'sexyphotos',
|
||||
'sexypics', 'sexypictures', 'sexypost', 'sexypussies', 'sexypussy', 'sexysites',
|
||||
'sexystories', 'sexywoman', 'sexywomen', 'shavedcunt', 'shavedcunts', 'shavedpussies',
|
||||
'shavedpussy', 'shavedpussypics', 'shavedsluts', 'shavedwomen', 'shavenpussies', 'shavenpussy',
|
||||
'shavepussy', 'sheboy', 'she-male', 'shemale+video', 'shemaleyum', 'showcam',
|
||||
'showcams', 'showercam', 'showercams', 'slavesex', 'smallboobs', 'smallbreasts',
|
||||
'smalldicks', 'smallpussy', 'smalltits', 'smut', 'smut69', 'smutland',
|
||||
'smutserver', 'smutshack', 'softcore', 'softporn', 'softpornography', 'spankingpage',
|
||||
'spreadpussy', 'spycamadult', 'stockingsex', 'storieserotic', 'storiessex', 'straightsex',
|
||||
'stretchedcunt', 'stripclub', 'stripclubs', 'stripshow', 'striptease', 'strokeit',
|
||||
'strokeme', 'suckdick', 'sucksex', 'superchicken', 'supersex', 'supertits',
|
||||
'swallowcum', 'swinger', 'swingerclub', 'swingers', 'swollenclits', 'syberporn',
|
||||
'sylviasaint', 'teenanal', 'teenanalsex', 'teenhardcore', 'teenie', 'teenies',
|
||||
'teennude', 'teenpics', 'teenporn', 'teenporno', 'teenpussy', 'teensex',
|
||||
'teenslut', 'teensluts', 'teensuck', 'teenxxx', 'tgp', 'thaipussy',
|
||||
'thaisex', 'thehun', 'threesomes', 'thumblords', 'thumbnailssex', 'thumbzilla',
|
||||
'tiffanytowers', 'tightcunt', 'tightpussies', 'tightpussy', 'tinypussy', 'tinytits',
|
||||
'tinytitties', 'tisandass', 'tit', 'titbondage', 'titfuck', 'titfucking',
|
||||
'tities', 'titman', 'titsandass', 'titsass', 'titties', 'titts',
|
||||
'titty', 'tittyfuck', 'tittyfucking', 'tittys', 'tokyotopless', 'tommysbookmark',
|
||||
'toplesswomen', 'trannies', 'transexual', 'transsexuels', 'twat', 'twats',
|
||||
'twink', 'ultradonkey', 'ultrahardcore', 'uncutcocks', 'vaginalintercourse', 'vaginapictures',
|
||||
'videoporno', 'videosex', 'videoxxx', 'vintageporn', 'virtualsex', 'vividtv',
|
||||
'wank', 'wankers', 'wanking', 'wendywhoppers', 'wetcunt', 'wetcunts',
|
||||
'wetdick', 'wetpanties', 'wetpussies', 'wetpussy', 'wetsex', 'wetvagina',
|
||||
'whitepussy', 'whitesex', 'whitetits', 'whitexxx', 'wifesharing', 'wifeswapping',
|
||||
'wildpussy', 'wildsex', 'womensex', 'worldsex', 'worldsexguide', 'x-rated',
|
||||
'xrated', 'x-ratedmovie', 'x-ratedmovies', 'x-ratedvideo', 'x-ratedvideos', 'xxx4free',
|
||||
'xxxadult', 'xxxadultmovies', 'xxxadultvideo', 'xxxadultvideos', 'xxxbabes', 'xxxcam',
|
||||
'xxxcelebrities', 'xxxfree', 'xxxfreepics', 'xxxgalleries', 'xxxhardcore', 'xxxjapan',
|
||||
'xxxlinks', 'xxxmodels', 'xxxmovie', 'xxxmovies', 'xxxmpeg', 'xxxpassword',
|
||||
'xxxphoto', 'xxxphotos', 'xxxpic', 'xxx-pics', 'xxxpics', 'xxxpicture',
|
||||
'xxxpictures', 'xxxpicturesfree', 'xxxpicx', 'xxxpirtures', 'xxxporn', 'xxxporno',
|
||||
'xxxpussy', 'xxx-rated', 'xxxrated', 'xxxsex', 'xxxsites', 'xxxsluts',
|
||||
'xxxstories', 'xxxteen', 'xxxthumbnails', 'xxxthumbs', 'xxxtoons', 'xxxtoys',
|
||||
'xxxvideo', 'xxxvideos', 'xxxwomen', 'xxxx', 'xxxxx', 'xxxxxx',
|
||||
'filthyfarm', 'adultcheck', 'erotic', 'mistresses', 'naughty',
|
||||
'adult', 'amateur', 'amateurs', 'anal', 'analau', 'poker',
|
||||
'anally', 'asian', 'swinging', 'ass', 'orgy', 'sexvideos',
|
||||
'babe', 'babes', 'bare', 'glamour', 'casino', 'bed',
|
||||
'vibrator', 'bikini', 'bisexual', 'blonde', 'breasted', 'breasts',
|
||||
'busty', 'butts', 'candy', 'caning', 'caps', 'catholic',
|
||||
'chained', 'chested', 'chubby', 'close-ups', 'coupling',
|
||||
'cucumber', 'doll', 'dolls', 'dolly', 'dominating', 'drinking',
|
||||
'drunk', 'fat', 'feet', 'fingering', 'fishnet', 'flasher',
|
||||
'footjob', 'foreplay', 'foreplaying', 'girlfriend', 'girlfriends', 'gymnast',
|
||||
'hairy', 'holly', 'horse', 'housewife', 'houswife', 'insertion',
|
||||
'insertions', 'interracial', 'jerka', 'juicy', 'kissing', 'kitty',
|
||||
'lactating', 'ladyboy', 'lance', 'latina', 'latins', 'leather',
|
||||
'legs', 'lesbian', 'lesbians', 'licking', 'lingerie', 'lubricants',
|
||||
'mature', 'midget', 'minor', 'mistress', 'nude',
|
||||
'older', 'olez', 'oral', 'panties', 'pantyhose', 'pedro',
|
||||
'peeing', 'penetration', 'pigtailed', 'pleasure', 'plump',
|
||||
'plumper', 'poser', 'posers', 'poses', 'posing', 'prosecuted',
|
||||
'punishment', 'reproducing', 'sex', 'shaved', 'shock', 'slave',
|
||||
'sleeping', 'speculums', 'spread', 'spreading', 'squirting', 'stripper',
|
||||
'stripping', 'swapping', 'thong', 'topless', 'toying',
|
||||
'trix', 'undressing', 'uniform', 'whipcream', 'brazzers', 'порно',
|
||||
'порн', 'лесб', 'гей', 'геи', 'прон'
|
||||
'surfwatch', 'netcash', 'watersport', 'fuck', 'threesome', 'tits',
|
||||
'masturbating', 'incest', 'bestiality', 'analintercourse', 'analsex', 'animesex',
|
||||
'anitablonde', 'autosex', 'blackass', 'blackasses', 'boner', 'boobcruise',
|
||||
'boobies', 'bordello', 'braless', 'brothel', 'callgirl', 'callgirls',
|
||||
'clit', 'clitoris', 'clits', 'cums', 'cybererotic', 'cybererotica',
|
||||
'cybersex', 'cybersexx', 'ejaculation', 'erotica', 'eroticfilm', 'eroticfilms',
|
||||
'eroticism', 'eroticphoto', 'eroticphotography', 'eroticphotos', 'erotics', 'eroticsex',
|
||||
'eroticsexstories', 'eroticstories', 'eroticstory', 'erotik', 'erotika', 'antasysex',
|
||||
'gaysex', 'gruppensex', 'horny', 'jackoff', 'lesbo', 'lesbos',
|
||||
'makinglove', 'motherfucker', 'horsesex', 'dogsex', 'snakesex', 'sextracker',
|
||||
'tranny', 'bdsm', 'porn', 'beastality', 'bizarre', 'blowjob',
|
||||
'bondage', 'bondages', 'celebs', 'cum', 'cunt', 'transsexual',
|
||||
'transsexuals', 'cumbath', 'cumshot', 'dildo', 'dildos', 'transvestites',
|
||||
'transvestite', 'dominatrix', 'spank', 'dungeon', 'sexbilder', 'dungeons',
|
||||
'pussie', 'ebony', 'fisting', 'gayshop', 'facesitting', 'sexshop',
|
||||
'pussy', 'bukkake', 'escort', 'blowjobs', 'facial', 'facialized',
|
||||
'facials', 'fetish', 'footfetish', 'fuckingpussy', 'fucking', 'hardcore',
|
||||
'hentai', 'hustlerlatex', 'latex', 'lolita', 'lolitas', 'mlm',
|
||||
'oralsex', 'peepshow', 'peepshows', 'phonesex', 'pornstars', 'preteen',
|
||||
'preteens', 'pussies', 'shemale', 'shemales', 'sluts', 'whores',
|
||||
'whore', 'spanking', 'strapon', 'twinks', 'upskirts', 'voyeur',
|
||||
'whip', 'whipping', 'xxx', 'sexkey', 'femdom', 'gangbang',
|
||||
'gloryhole', 'adultbuffet', 'adultcartoons', 'adultchat', 'adultchatnetwork', 'adultdvd',
|
||||
'adultentertainment', 'adultentertainmenthouse', 'adulterotica', 'adultfilms', 'adultfree', 'adultfreepics',
|
||||
'adultfreepix', 'adultfun', 'adulthardcore', 'adultimages', 'adultjpeg', 'adultlink',
|
||||
'adultlinks', 'adultmovie', 'adultmovies', 'adultmpeg', 'adultmpegs', 'adultpass',
|
||||
'adultpersonals', 'adultphotos', 'adultpic', 'adultpics', 'adultpicture', 'adultpictures',
|
||||
'adultpix', 'adultporn', 'adultpornography', 'adultsearch', 'adultsex', 'adultsights',
|
||||
'adultsites', 'adultsonly', 'adultstars', 'adultstories', 'adultvideo', 'adultvideos',
|
||||
'adultweb', 'adultxxx', 'alt.sex', 'altsex', 'alt.sex.exhibitionism', 'alt.sex.pictures',
|
||||
'altsexst', 'alt.sex.stories', 'alt.sex.voyeurism', 'amateurerotica', 'amateurfotos', 'amateurhardcore',
|
||||
'amateurindex', 'amateurnaked', 'amateurnudes', 'amateurporn', 'amateurpussy', 'amateursex',
|
||||
'amateursxxx', 'amatuerhardcore', 'amatuersex', 'ampland', 'analaction', 'analcum',
|
||||
'analfuck', 'analfucking', 'analgallery', 'analingus', 'analpics', 'analpicture',
|
||||
'analsex', 'analsexpics', 'analsexpictures', 'analxxx', 'animalbeastiality', 'animehentai',
|
||||
'animeporno', 'animexxx', 'asiacarrera', 'assfuck', 'assfucking', 'asshole',
|
||||
'assholes', 'asslick', 'asspics', 'assworship', 'autofellatio', 'babepix',
|
||||
'badgirls', 'bakedchicks', 'baldcunt', 'baldpussies', 'baldpussy', 'barecelebs',
|
||||
'barenaked', 'barepussy', 'beastiality', 'beaverboy', 'beavershots', 'bigballs',
|
||||
'bigblackboobs', 'bigblackcocks', 'bigblackdicks', 'bigblacktits', 'bigboob', 'bigboobs',
|
||||
'bigbreast', 'bigbreastlovers', 'bigbreasts', 'bigbutt', 'bigbutts', 'bigclit',
|
||||
'bigclitoris', 'bigclits', 'bigcock', 'bigcocks', 'bigcunt', 'bigcunts',
|
||||
'bigdick', 'bigdicks', 'biggestboobs', 'biggestdick', 'biggesttit', 'biggesttits',
|
||||
'bighairyballs', 'bighardons', 'bighooters', 'bignipples', 'bigpussies', 'bigpussy',
|
||||
'bigtit', 'bigtits', 'bigtitties', 'bigtitts', 'bizarresex', 'bizarrexxx',
|
||||
'bizzaresex', 'blackbondage', 'blackboobs', 'blackbooty', 'blackbutt', 'blackcock',
|
||||
'blackcocks', 'blackcum', 'blackcunt', 'blackcunts', 'blackdick', 'blackdicks',
|
||||
'blackerotica', 'blackhardcore', 'blacknudes', 'blackonblondes', 'blackporn', 'blackporno',
|
||||
'blackpornography', 'blackpussy', 'blacksex', 'blacksluts', 'blacksonblondes', 'blacktit',
|
||||
'blacktits', 'blacktwat', 'blackxxx', 'blondepussy', 'blondsgay', 'bondagefree',
|
||||
'bondagegallery', 'bondagelinks', 'bondagepics', 'bondagepictures', 'bondagesex', 'bondagestories',
|
||||
'bondagestory', 'bukake', 'bustybabes', 'bustyblondes', 'bustyceleb', 'butt-fuck',
|
||||
'buttfuck', 'buttfucker', 'buttfuckers', 'buttfucking', 'buttholes', 'buttman',
|
||||
'buttpics', 'buttplug', 'buttthumbnails', 'cartoonporn', 'cartoonsex', 'cartoonsxxx',
|
||||
'cartoonxxx', 'celebritiesnaked', 'celebritiesnude', 'celebritiesxxx', 'celebritybush', 'celebritybutts',
|
||||
'celebritynude', 'celebritynudes', 'celebrityporn', 'celebritypussy', 'celebritysex', 'celebrityxxx',
|
||||
'celebsxxx', 'celebxxx', 'centerfolds', 'chaseylain', 'chatsex', 'cheerleadersxxx',
|
||||
'cheerleaderxxx', 'chickswithdicks', 'christycanyon', 'cicciolina', 'clitpics', 'clitpictures',
|
||||
'closeuppussy', 'comixxx', 'crotchless', 'cruisingforsex', 'cumbaths', 'cumcoveredcunts',
|
||||
'cumcunt', 'cumdrinker', 'cumdrinkers', 'cumdrinking', 'cumdrops', 'cumeater',
|
||||
'cumeaters', 'cumeating', 'cumface', 'cumfaces', 'cumfacial', 'cumfacials',
|
||||
'cumgallery', 'cumgargle', 'cumguzzlers', 'cumincunt', 'cumjunkies', 'cumlovers',
|
||||
'cummpeg', 'cumpic', 'cumpics', 'cumpicture', 'cumpictures', 'cumpussy',
|
||||
'cumsluts', 'cumsucker', 'cumsuckers', 'cumsucking', 'cumswallow', 'cumswallowers',
|
||||
'cumswallowing', 'cumtasting', 'cumthumbnails', 'cunilingus', 'cunnilingus', 'cuntcum',
|
||||
'cuntfuck', 'cuntfucking', 'cuntjuice', 'cuntlapper', 'cuntlick', 'cuntlickers',
|
||||
'cuntlicking', 'cuntpics', 'cuntpictures', 'cunts', 'cuntstories', 'cuntsuckers',
|
||||
'cuntz', 'cyberlust', 'cybernude', 'cyberporn', 'cyberpornlinks', 'cyberpornsexlinks',
|
||||
'cyberslut', 'd’amateur', 'danniashe', 'dicksex', 'dicksuckers', 'dicksucking',
|
||||
'digixxx', 'directporn', 'dirtypictures', 'dirtysex', 'doggiestyle', 'doggystyle',
|
||||
'domatrix', 'dominatrixes', 'downblouse', 'drinkingcum', 'drippingcunt', 'drippingcunts',
|
||||
'drippingpussy', 'easypic.com', 'eatcum', 'eatingcum', 'eatingpussy', 'eatpussy',
|
||||
'ebony+ayres', 'ebonyporn', 'ebonypussy', 'ebonysex', 'ebonyxxx', 'enormoustits',
|
||||
'erosvillage', 'eroticanime', 'eroticart', 'eroticas', 'eroticastories', 'eroticfiction',
|
||||
'eroticlesbianstories', 'eroticmovie', 'eroticmovies', 'erotico', 'eroticos', 'eroticpics',
|
||||
'eroticpicture', 'eroticpictures', 'eroticsites', 'eroticsounds', 'erotictales', 'erotictext',
|
||||
'eroticvideo', 'eroticvideos', 'eroticwomen', 'eroticwriting', 'erotikchat', 'erotique',
|
||||
'erotismo', 'escortservice', 'escortservices', 'eurosex', 'explicitsex', 'facecum',
|
||||
'facesit', 'facesitters', 'fastporn', 'fatass', 'fatsex', 'feetfetish',
|
||||
'feetsex', 'felatio', 'fellatio', 'fellations', 'fetishwear', 'fettegirls',
|
||||
'fingerbang', 'fingerfuck', 'flesh4free', 'footjobs', 'footlicking', 'footworship',
|
||||
'fornication', 'freeanal', 'freeanalsex', 'freeass', 'freebigboobs', 'freebigtit',
|
||||
'freebigtits', 'freeblackcunt', 'freeblackpussy', 'freeblowjob', 'freeblowjobs', 'freebondage',
|
||||
'freeboobs', 'freecum', 'freecumshot', 'freecumshots', 'freecunt', 'freecunts',
|
||||
'freedick', 'freeerotic', 'freeerotica', 'freeeroticstories', 'freefuck', 'freefucking',
|
||||
'freefuckpics', 'freegay', 'freegaypics', 'freehardcore', 'freehardcorepics', 'freehardcorepictures',
|
||||
'freehardcoreporn', 'freehardcoresex', 'freehardcoresexpics', 'freehentai', 'freehooters', 'freelargehooters',
|
||||
'freelesbian', 'freelesbianporn', 'freelesbiansex', 'freenakedpic', 'freenakedpics', 'freenakedpictures',
|
||||
'freenakedwomen', 'freenude', 'freenudecelebs', 'freenudephotos', 'freenudepics', 'freenudes',
|
||||
'freeporn', 'freepornmovies', 'freeporno', 'freepornography', 'freepornopics', 'freepornopictures',
|
||||
'freepornos', 'freepornpic', 'freepornpics', 'freepornpictures', 'freeporns', 'freepornsite',
|
||||
'freepornsites', 'freepussy', 'freepussypic', 'freepussypics', 'freepussypictures', 'freesex',
|
||||
'freesexchat', 'freesexmovies', 'freesexnet', 'freesexphotos', 'freesexpic', 'freesexpics',
|
||||
'freesexpicture', 'freesexpictures', 'freesexsites', 'freesexstories', 'freesexvideos', 'freesexycam',
|
||||
'freeshemale', 'freesmut', 'freetit', 'freetits', 'freevoyeur', 'freexxx',
|
||||
'freexxxmovie', 'freexxxmovies', 'freexxxmpeg', 'freexxxphotos', 'freexxxpic', 'freexxxpics',
|
||||
'freexxxpicture', 'freexxxpictures', 'freexxxstories', 'freexxxvideo', 'freexxxx', 'fuking',
|
||||
'gangbangs', 'gratishardcoregalerie', 'hardcorecelebs', 'hardcorefisting', 'hardcorefree', 'hardcorefucking',
|
||||
'hardcorehooters', 'hardcorejunkie', 'hardcorejunky', 'hardcoremovie', 'hardcoremovies', 'hardcorepic',
|
||||
'hardcorepics', 'hardcorepictures', 'hardcorepix', 'hardcoreporn', 'hardcoreporno', 'hardcorepornography',
|
||||
'hardcorepornos', 'hardcorepussy', 'hardcoresamples', 'hardcoresex', 'hardcoresexpictures', 'hardcorestories',
|
||||
'hardcorethumbnails', 'hardcorevideo', 'hardcorevideos', 'hardcorexxx', 'harddicks', 'hardnipples',
|
||||
'hardons', 'hardporn', 'indiasex', 'interacialhardcore', 'interacialsex', 'interacialxxx',
|
||||
'intercoursepositions', 'internetsex', 'interracialfucking', 'interracialhardcore', 'interracialporn', 'interracialpornography',
|
||||
'interracialsex', 'interracialsexstories', 'interracialxxx', 'intimatesex', 'ittybittytitty', 'japaneseporn',
|
||||
'japanesesex', 'japansex', 'japanxxx', 'jennacam.com', 'jennajameson', 'jennicam',
|
||||
'jerkoff', 'jism', 'jiz', 'jizz', 'juicycunts', 'juicypussy',
|
||||
'justhardcore', 'karasamateurs', 'karasxxx', 'kascha', 'kaylakleevage', 'kobetai',
|
||||
'koreasex', 'lapdance', 'largeclits', 'largecunts', 'largedicks', 'largehooters',
|
||||
'largepussy', 'largetit', 'largetits', 'latinapussy', 'latinasex', 'latinosex',
|
||||
'latinoxxx', 'latinxxx', 'legsex', 'lesbianerotica', 'lesbianhardcore', 'lesbianorgies',
|
||||
'lesbianorgy', 'lesbianpics', 'lesbianpink', 'lesbianporn', 'lesbian-porno', 'lesbianporno',
|
||||
'lesbianpornography', 'lesbianpornos', 'lesbianpussy', 'lesbiansex', 'lesbiansexpics', 'lesbiansexstories',
|
||||
'lesbianxxx', 'lickadick', 'lickingpussy', 'lindalovelace', 'lingeriexxx', 'literotica',
|
||||
'littleboobs', 'littlepussy', 'littletits', 'livefucking', 'liveporn', 'livesex',
|
||||
'livesexcam', 'livesexcams', 'longdicks', 'lovedoll', 'lovedolls', 'magazinessex',
|
||||
'makinglove', 'malaysex', 'malenudes', 'malesex', 'mangaporno', 'mangax',
|
||||
'mangaxxx', 'manpics', 'mansex', 'marilynchambers', 'massivecocks', 'masterbating',
|
||||
'masturbation', 'masturbationvideos', 'maturefucking', 'maturesex', 'maturexxx', 'megaboobs',
|
||||
'megaporno', 'megapussy', 'megatits', 'mensdicks', 'mensex', 'm.i.l.f.',
|
||||
'milf', 'milfhunterpic', 'milfmpegsample', 'modelsex', 'mondoporn', 'monstercocks',
|
||||
'monsterdicks', 'motherfucker', 'moviepost.com', 'mpegsex', 'mpegxxx', 'muffdiving',
|
||||
'myslutwife', 'nacktfotos', 'nakedbabes', 'nakedblackwomen', 'nakedcelebrity', 'nakedcelebs',
|
||||
'nakedcheerleader', 'nakedchicks', 'nakedgirls', 'nakedguys', 'nakedladies', 'nakedlady',
|
||||
'nakedman', 'nakedmen', 'nakedness', 'nakedphotographs', 'nakedphotography', 'nakedphotos',
|
||||
'nakedpic', 'nakedpics', 'nakedpicture', 'nakedpictures', 'nakedpussy', 'nakedstars',
|
||||
'nakedwife', 'nakedwoman', 'nakedwomen', 'nastychat', 'nastypussy', 'nastysex',
|
||||
'nastythumbs', 'naturaltits', 'naughty.com', 'naughtylinks', 'naughtylinx', 'naughtylynx',
|
||||
'naughtynurses', 'netsex', 'niceass', 'nicetits', 'nikkinova', 'nikkityler',
|
||||
'nipples', 'nookie', 'nookies', 'nudeactress', 'nudeactresses', 'nudeamateur',
|
||||
'nudeamateurs', 'nudeasianwomen', 'nudebabes', 'nudebigboobs', 'nudeblack', 'nudeblackwomen',
|
||||
'nudeblondes', 'nudeceleb', 'nudeceleberties', 'nudecelebraties', 'nudecelebrites', 'nudecelebrities',
|
||||
'nudecelebrity', 'nudecelebs', 'nudecollegegirls', 'nudefemale', 'nudefemales', 'nudefree',
|
||||
'nudegay', 'nudeimages', 'nudeladies', 'nudelesbians', 'nudemale', 'nudemales',
|
||||
'nudeman', 'nudemen', 'nudepic', 'nudepics', 'nudepicture', 'nudepictures',
|
||||
'nudepornography', 'nudepussy', 'nuderaider', 'nuderedheads', 'nudes', 'nudesex',
|
||||
'nudestar', 'nudestars', 'nudevideoconferencing', 'nudewoman', 'nudewomen', 'nudism',
|
||||
'nudist', 'nudists', 'nudity', 'nylonfetish', 'nylonsex', 'nympho',
|
||||
'nymphos', 'olderbabes', 'oldersex', 'oldersluts', 'oldpussy', 'oldsex',
|
||||
'oldsluts', 'openlegs', 'openpussy', 'oral4free', 'oral-sex', 'oralsexpictures',
|
||||
'orgie', 'orgies', 'orgypics', 'orgys', 'pantyhosefetish', 'pantyhosesex',
|
||||
'peepcam', 'persiankitty', 'persiankitty.com', 'perverted', 'picsxxx', 'picturesex',
|
||||
'picturesofsex', 'picturessex', 'pimpserver', 'pimpserver.com', 'pinkpussy', 'pissing',
|
||||
'pixxx', 'poontang', 'pornagraphy', 'porncast', 'porncity', 'porndirectory',
|
||||
'porne', 'pornfree', 'pornmovies', 'pornno', 'pornnude', 'porno',
|
||||
'pornoadult', 'pornocartoons', 'pornochat', 'pornodeluxe', 'pornoe', 'pornofilms',
|
||||
'pornofree', 'pornogame', 'pornografi', 'pornografia', 'pornografie', 'pornografy',
|
||||
'pornograph', 'pornographi', 'pornographia', 'pornographic', 'pornographicpictures', 'pornographics',
|
||||
'pornographicvideo', 'pornographicvideos', 'pornographie', 'pornography', 'pornographyfree', 'pornographyphotos',
|
||||
'pornographypictures', 'pornography-sex', 'pornographysex', 'pornoland', 'pornolinks', 'pornolynx',
|
||||
'pornomagazines', 'pornomovies', 'pornompeg', 'pornophotos', 'pornopic', 'pornopics',
|
||||
'pornopicture', 'pornopictures', 'pornos', 'pornosex', 'pornosite', 'pornosites',
|
||||
'pornostar', 'pornostories', 'pornovideo', 'pornovideos', 'pornoxxx', 'pornphotos',
|
||||
'pornpics', 'pornpictures', 'pornpix', 'pornpost', 'pornqueens', 'pornrated',
|
||||
'porns', 'pornsex', 'pornstar', 'pornstories', 'porntrack', 'pornvideo',
|
||||
'pornvideos', 'pornypics', 'porstars', 'privatesex', 'privatex', 'privatexx',
|
||||
'privatexxx', 'prono', 'pronography', 'publicnudity', 'puffynipples', 'purple+passion',
|
||||
'pussyboard', 'pussycam', 'pussycams', 'pussycloseup', 'pussycloseups', 'pussycum',
|
||||
'pussycunt', 'pussyeater', 'pussyeaters', 'pussyeating', 'pussyfuck', 'pussyfucking',
|
||||
'pussyhair', 'pussyheaven', 'pussyjuice', 'pussylickers', 'pussylicking', 'pussylink',
|
||||
'pussylips', 'pussyphotos', 'pussyporno', 'pussys', 'pussysex', 'pussyshots',
|
||||
'pussythumbnails', 'pussytits', 'pusy', 'racqueldarrian', 'rape', 'rawlinks',
|
||||
'rawpussy', 'rawsex', 'realhardcore', 'realsex', 'redneckporn', 'redpussy',
|
||||
'rubberfetish', 'russianxxx', 'scat', 'schiffernude', 'seka', 'seniorsex',
|
||||
'sex4free', 'sex66', 'sexacts', 'sexadult', 'sexaids', 'sexamateur',
|
||||
'sexanal', 'sexandpictures', 'sexaphone', 'sexaudio', 'sexavi', 'sexbondage',
|
||||
'sexboner', 'sexbuttfucker', 'sexcam', 'sexcams', 'sexchat', 'sexchatrooms',
|
||||
'sexcites', 'sexclub', 'sexclubs', 'sex.com', 'sexdating', 'sexe',
|
||||
'sexfantasies', 'sexfantasy', 'sexfilm', 'sexgallery', 'sexgame', 'sexgames',
|
||||
'sexgirl', 'sexgirls', 'sexgroup', 'sexguide', 'sexhardcore', 'sexhphoto',
|
||||
'sexhungry', 'sexhungryjoe', 'sexhungryjoes', 'sexi', 'seximages', 'sexis',
|
||||
'sexjapan', 'sex.jpg', 'sexlinda', 'sexlinks', 'sexlinx', 'sexlive',
|
||||
'sexmagazine', 'sexmagazines', 'sexmature', 'sexmelayu', 'sexmodels', 'sexmovie',
|
||||
'sexmovies', 'sexmpeg', 'sexnude', 'sexnudity', 'sexo', 'sexoanal',
|
||||
'sexole', 'sexontheinternet', 'sexoral', 'sexpasswords', 'sexphoto', 'sexphotos',
|
||||
'sexpic', 'sexpicnet', 'sexpics', 'sexpicture', 'sexpictures', 'sexpicturesfree',
|
||||
'sexpix', 'sexplaza', 'sexporn', 'sexporno', 'sexpositions', 'sexpussy',
|
||||
'sexroulette', 'sexs', 'sexsamples', 'sexsearch', 'sexsex', 'sexsexsex',
|
||||
'sexshare', 'sexshops', 'sexshow', 'sexshows', 'sexsite', 'sexsites',
|
||||
'sexslave', 'sexsound', 'sexsounds', 'sexsource', 'sexspaces', 'sexspaces.com',
|
||||
'sexstories', 'sexstory', 'sexstorys', 'sextalk', 'sexteen', 'sexthumbnails',
|
||||
'sex-toons', 'sextoons', 'sextour', 'sextoy', 'sextoys', 'sextpus',
|
||||
'sextracker.com', 'sextropolis', 'sexualbondage', 'sexualfantasies', 'sexualfantasy', 'sexualintercourse',
|
||||
'sexualpictures', 'sexualpleasure', 'sexualpositions', 'sexuncensored', 'sexvideo', 'sexvision',
|
||||
'sexvote', 'sexwomen', 'sexworld', 'sexx', 'sexxx', 'sexxxx',
|
||||
'sexxxxx', 'sexyamateurs', 'sexybabes', 'sexyblack', 'sexyboobs', 'sexybookmark',
|
||||
'sexybookmarka', 'sexybookmarks', 'sexybutts', 'sexycunts', 'sexygirl', 'sexygirls',
|
||||
'sexyladies', 'sexylady', 'sexylegs', 'sexylingerie', 'sexymen', 'sexyphotos',
|
||||
'sexypics', 'sexypictures', 'sexypost', 'sexypussies', 'sexypussy', 'sexysites',
|
||||
'sexystories', 'sexywoman', 'sexywomen', 'shavedcunt', 'shavedcunts', 'shavedpussies',
|
||||
'shavedpussy', 'shavedpussypics', 'shavedsluts', 'shavedwomen', 'shavenpussies', 'shavenpussy',
|
||||
'shavepussy', 'sheboy', 'she-male', 'shemale+video', 'shemaleyum', 'showcam',
|
||||
'showcams', 'showercam', 'showercams', 'slavesex', 'smallboobs', 'smallbreasts',
|
||||
'smalldicks', 'smallpussy', 'smalltits', 'smut', 'smut69', 'smutland',
|
||||
'smutserver', 'smutshack', 'softcore', 'softporn', 'softpornography', 'spankingpage',
|
||||
'spreadpussy', 'spycamadult', 'stockingsex', 'storieserotic', 'storiessex', 'straightsex',
|
||||
'stretchedcunt', 'stripclub', 'stripclubs', 'stripshow', 'striptease', 'strokeit',
|
||||
'strokeme', 'suckdick', 'sucksex', 'superchicken', 'supersex', 'supertits',
|
||||
'swallowcum', 'swinger', 'swingerclub', 'swingers', 'swollenclits', 'syberporn',
|
||||
'sylviasaint', 'teenanal', 'teenanalsex', 'teenhardcore', 'teenie', 'teenies',
|
||||
'teennude', 'teenpics', 'teenporn', 'teenporno', 'teenpussy', 'teensex',
|
||||
'teenslut', 'teensluts', 'teensuck', 'teenxxx', 'tgp', 'thaipussy',
|
||||
'thaisex', 'thehun', 'threesomes', 'thumblords', 'thumbnailssex', 'thumbzilla',
|
||||
'tiffanytowers', 'tightcunt', 'tightpussies', 'tightpussy', 'tinypussy', 'tinytits',
|
||||
'tinytitties', 'tisandass', 'tit', 'titbondage', 'titfuck', 'titfucking',
|
||||
'tities', 'titman', 'titsandass', 'titsass', 'titties', 'titts',
|
||||
'titty', 'tittyfuck', 'tittyfucking', 'tittys', 'tokyotopless', 'tommysbookmark',
|
||||
'toplesswomen', 'trannies', 'transexual', 'transsexuels', 'twat', 'twats',
|
||||
'twink', 'ultradonkey', 'ultrahardcore', 'uncutcocks', 'vaginalintercourse', 'vaginapictures',
|
||||
'videoporno', 'videosex', 'videoxxx', 'vintageporn', 'virtualsex', 'vividtv',
|
||||
'wank', 'wankers', 'wanking', 'wendywhoppers', 'wetcunt', 'wetcunts',
|
||||
'wetdick', 'wetpanties', 'wetpussies', 'wetpussy', 'wetsex', 'wetvagina',
|
||||
'whitepussy', 'whitesex', 'whitetits', 'whitexxx', 'wifesharing', 'wifeswapping',
|
||||
'wildpussy', 'wildsex', 'womensex', 'worldsex', 'worldsexguide', 'x-rated',
|
||||
'xrated', 'x-ratedmovie', 'x-ratedmovies', 'x-ratedvideo', 'x-ratedvideos', 'xxx4free',
|
||||
'xxxadult', 'xxxadultmovies', 'xxxadultvideo', 'xxxadultvideos', 'xxxbabes', 'xxxcam',
|
||||
'xxxcelebrities', 'xxxfree', 'xxxfreepics', 'xxxgalleries', 'xxxhardcore', 'xxxjapan',
|
||||
'xxxlinks', 'xxxmodels', 'xxxmovie', 'xxxmovies', 'xxxmpeg', 'xxxpassword',
|
||||
'xxxphoto', 'xxxphotos', 'xxxpic', 'xxx-pics', 'xxxpics', 'xxxpicture',
|
||||
'xxxpictures', 'xxxpicturesfree', 'xxxpicx', 'xxxpirtures', 'xxxporn', 'xxxporno',
|
||||
'xxxpussy', 'xxx-rated', 'xxxrated', 'xxxsex', 'xxxsites', 'xxxsluts',
|
||||
'xxxstories', 'xxxteen', 'xxxthumbnails', 'xxxthumbs', 'xxxtoons', 'xxxtoys',
|
||||
'xxxvideo', 'xxxvideos', 'xxxwomen', 'xxxx', 'xxxxx', 'xxxxxx',
|
||||
'filthyfarm', 'adultcheck', 'erotic', 'mistresses', 'naughty',
|
||||
'adult', 'amateur', 'amateurs', 'anal', 'analau', 'poker',
|
||||
'anally', 'asian', 'swinging', 'ass', 'orgy', 'sexvideos',
|
||||
'babe', 'babes', 'bare', 'glamour', 'casino', 'bed',
|
||||
'vibrator', 'bikini', 'bisexual', 'blonde', 'breasted', 'breasts',
|
||||
'busty', 'butts', 'candy', 'caning', 'caps', 'catholic',
|
||||
'chained', 'chested', 'chubby', 'close-ups', 'coupling',
|
||||
'cucumber', 'doll', 'dolls', 'dolly', 'dominating', 'drinking',
|
||||
'drunk', 'fat', 'feet', 'fingering', 'fishnet', 'flasher',
|
||||
'footjob', 'foreplay', 'foreplaying', 'girlfriend', 'girlfriends', 'gymnast',
|
||||
'hairy', 'holly', 'horse', 'housewife', 'houswife', 'insertion',
|
||||
'insertions', 'interracial', 'jerka', 'juicy', 'kissing', 'kitty',
|
||||
'lactating', 'ladyboy', 'lance', 'latina', 'latins', 'leather',
|
||||
'legs', 'lesbian', 'lesbians', 'licking', 'lingerie', 'lubricants',
|
||||
'mature', 'midget', 'minor', 'mistress', 'nude',
|
||||
'older', 'olez', 'oral', 'panties', 'pantyhose', 'pedro',
|
||||
'peeing', 'penetration', 'pigtailed', 'pleasure', 'plump',
|
||||
'plumper', 'poser', 'posers', 'poses', 'posing', 'prosecuted',
|
||||
'punishment', 'reproducing', 'sex', 'shaved', 'shock', 'slave',
|
||||
'sleeping', 'speculums', 'spread', 'spreading', 'squirting', 'stripper',
|
||||
'stripping', 'swapping', 'thong', 'topless', 'toying',
|
||||
'trix', 'undressing', 'uniform', 'whipcream', 'brazzers', 'порно',
|
||||
'порн', 'лесб', 'гей', 'геи', 'прон'
|
||||
];
|
||||
|
||||
const XXX_VERY_BAD_WORDS = [
|
||||
'catgoddess', 'gracel', 'fatman', 'falko', 'pthc',
|
||||
'ptsc', 'yukikax', 'ls-models', '3yo', '4yo', '5yo', '6yo', '7yo', '8yo', '9yo',
|
||||
'10yo', '11yo', '12yo', '13yo', '14yo', '15yo', '16yo'
|
||||
'catgoddess', 'gracel', 'fatman', 'falko', 'pthc',
|
||||
'ptsc', 'yukikax', 'ls-models', '3yo', '4yo', '5yo', '6yo', '7yo', '8yo', '9yo',
|
||||
'10yo', '11yo', '12yo', '13yo', '14yo', '15yo', '16yo'
|
||||
]
|
||||
|
||||
module.exports = {
|
||||
XXX_BLOCK_WORDS,
|
||||
XXX_VERY_BAD_WORDS
|
||||
XXX_BLOCK_WORDS,
|
||||
XXX_VERY_BAD_WORDS
|
||||
};
|
||||
|
@ -4,23 +4,23 @@ import ReactMarkdown from 'react-markdown'
|
||||
import fs from 'fs'
|
||||
|
||||
export default class ChangeLog extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Changelog');
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Changelog');
|
||||
|
||||
let changelogPath = 'CHANGELOG.md'
|
||||
if(!fs.existsSync(changelogPath))
|
||||
changelogPath = 'resources/CHANGELOG.md'
|
||||
let changelogPath = 'CHANGELOG.md'
|
||||
if(!fs.existsSync(changelogPath))
|
||||
changelogPath = 'resources/CHANGELOG.md'
|
||||
|
||||
this.changelog = fs.readFileSync(changelogPath)
|
||||
if(!this.changelog)
|
||||
throw new Error('no changelog file')
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='pad0-75'>
|
||||
<ReactMarkdown skipHtml={true} source={this.changelog} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
this.changelog = fs.readFileSync(changelogPath)
|
||||
if(!this.changelog)
|
||||
throw new Error('no changelog file')
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='pad0-75'>
|
||||
<ReactMarkdown skipHtml={true} source={this.changelog} />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -6,13 +6,13 @@ export default class BTComponent extends Component {
|
||||
// Свайп действия
|
||||
if(
|
||||
this.props.onSwipeLeft ||
|
||||
this.props.onSwipeRight ||
|
||||
this.props.onSwipeTop ||
|
||||
this.props.onSwipeBottom ||
|
||||
this.onSwipeLeft ||
|
||||
this.onSwipeRight ||
|
||||
this.onSwipeTop ||
|
||||
this.onSwipeBottom
|
||||
this.props.onSwipeRight ||
|
||||
this.props.onSwipeTop ||
|
||||
this.props.onSwipeBottom ||
|
||||
this.onSwipeLeft ||
|
||||
this.onSwipeRight ||
|
||||
this.onSwipeTop ||
|
||||
this.onSwipeBottom
|
||||
)
|
||||
{
|
||||
this.swipeFunctions = listenSwipe(this, {
|
||||
|
@ -9,302 +9,302 @@ import Slider from 'material-ui/Slider'
|
||||
import fs from 'fs'
|
||||
let dialog
|
||||
if(typeof WEB === 'undefined')
|
||||
dialog = require('electron').remote.dialog
|
||||
dialog = require('electron').remote.dialog
|
||||
|
||||
export default class ConfigPage extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats settings');
|
||||
this.options = {}
|
||||
}
|
||||
componentDidMount() {
|
||||
this.loadSettings()
|
||||
}
|
||||
loadSettings() {
|
||||
window.torrentSocket.emit('config', window.customLoader((options) => {
|
||||
this.options = options;
|
||||
console.log(this.options)
|
||||
this.forceUpdate();
|
||||
}));
|
||||
}
|
||||
saveSettings() {
|
||||
window.torrentSocket.emit('setConfig', this.options)
|
||||
this.settingsSavedMessage = true
|
||||
this.forceUpdate()
|
||||
setTimeout(() => {
|
||||
this.settingsSavedMessage = false
|
||||
this.forceUpdate()
|
||||
}, 1000)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Back to main page')} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
</div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled network scanning')}
|
||||
toggled={this.options.indexer}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.indexer = checked
|
||||
if(!this.options.indexer)
|
||||
this.options.p2p = false
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Scanning port')}</div>
|
||||
<TextField
|
||||
style={{width: 65}}
|
||||
hintText={__('Port')}
|
||||
errorText={this.options.spiderPort > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.spiderPort}
|
||||
onChange={(e, value) => {
|
||||
if(!value)
|
||||
value = 0
|
||||
if(value > 65535)
|
||||
value = 65535
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats settings');
|
||||
this.options = {}
|
||||
}
|
||||
componentDidMount() {
|
||||
this.loadSettings()
|
||||
}
|
||||
loadSettings() {
|
||||
window.torrentSocket.emit('config', window.customLoader((options) => {
|
||||
this.options = options;
|
||||
console.log(this.options)
|
||||
this.forceUpdate();
|
||||
}));
|
||||
}
|
||||
saveSettings() {
|
||||
window.torrentSocket.emit('setConfig', this.options)
|
||||
this.settingsSavedMessage = true
|
||||
this.forceUpdate()
|
||||
setTimeout(() => {
|
||||
this.settingsSavedMessage = false
|
||||
this.forceUpdate()
|
||||
}, 1000)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Back to main page')} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
</div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled network scanning')}
|
||||
toggled={this.options.indexer}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.indexer = checked
|
||||
if(!this.options.indexer)
|
||||
this.options.p2p = false
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Scanning port')}</div>
|
||||
<TextField
|
||||
style={{width: 65}}
|
||||
hintText={__('Port')}
|
||||
errorText={this.options.spiderPort > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.spiderPort}
|
||||
onChange={(e, value) => {
|
||||
if(!value)
|
||||
value = 0
|
||||
if(value > 65535)
|
||||
value = 65535
|
||||
|
||||
this.options.spiderPort = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('For current work TCP and UDP ports must be fully open and forward in case of router usage')}</div>
|
||||
</div>
|
||||
this.options.spiderPort = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('For current work TCP and UDP ports must be fully open and forward in case of router usage')}</div>
|
||||
</div>
|
||||
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Trackers responce port')}</div>
|
||||
<TextField
|
||||
style={{width: 65}}
|
||||
hintText="Port"
|
||||
errorText={this.options.udpTrackersPort > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.udpTrackersPort}
|
||||
onChange={(e, value) => {
|
||||
if(!value)
|
||||
value = 0
|
||||
if(value > 65535)
|
||||
value = 65535
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Trackers responce port')}</div>
|
||||
<TextField
|
||||
style={{width: 65}}
|
||||
hintText="Port"
|
||||
errorText={this.options.udpTrackersPort > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.udpTrackersPort}
|
||||
onChange={(e, value) => {
|
||||
if(!value)
|
||||
value = 0
|
||||
if(value > 65535)
|
||||
value = 65535
|
||||
|
||||
this.options.udpTrackersPort = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('For current work UDP port must be fully open and forward in case of router usage')}</div>
|
||||
</div>
|
||||
this.options.udpTrackersPort = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('For current work UDP port must be fully open and forward in case of router usage')}</div>
|
||||
</div>
|
||||
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled UPnP')}
|
||||
toggled={this.options.upnp}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.upnp = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled UPnP')}
|
||||
toggled={this.options.upnp}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.upnp = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Collection directory')}</div>
|
||||
<TextField
|
||||
hintText={__('Db path')}
|
||||
errorText={this.options.dbPath && this.options.dbPath.length > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.dbPath}
|
||||
onChange={(e, value) => {
|
||||
if(!fs.existsSync(value))
|
||||
return
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Collection directory')}</div>
|
||||
<TextField
|
||||
hintText={__('Db path')}
|
||||
errorText={this.options.dbPath && this.options.dbPath.length > 0 ? undefined : __('This field is required')}
|
||||
value={this.options.dbPath}
|
||||
onChange={(e, value) => {
|
||||
if(!fs.existsSync(value))
|
||||
return
|
||||
|
||||
this.options.dbPath = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<RaisedButton style={{marginLeft: 20}} label={__('Browse')} primary={true} onClick={() => {
|
||||
if(!dialog)
|
||||
return
|
||||
const dir = dialog.showOpenDialog({properties: ['openDirectory']})[0]
|
||||
if(dir)
|
||||
{
|
||||
this.options.dbPath = dir
|
||||
this.forceUpdate()
|
||||
}
|
||||
}} />
|
||||
</div>
|
||||
this.options.dbPath = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<RaisedButton style={{marginLeft: 20}} label={__('Browse')} primary={true} onClick={() => {
|
||||
if(!dialog)
|
||||
return
|
||||
const dir = dialog.showOpenDialog({properties: ['openDirectory']})[0]
|
||||
if(dir)
|
||||
{
|
||||
this.options.dbPath = dir
|
||||
this.forceUpdate()
|
||||
}
|
||||
}} />
|
||||
</div>
|
||||
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Download torrents directory')}</div>
|
||||
<TextField
|
||||
hintText={__('Download path')}
|
||||
value={this.options.client && this.options.client.downloadPath}
|
||||
onChange={(e, value) => {
|
||||
if(!fs.existsSync(value))
|
||||
return
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Download torrents directory')}</div>
|
||||
<TextField
|
||||
hintText={__('Download path')}
|
||||
value={this.options.client && this.options.client.downloadPath}
|
||||
onChange={(e, value) => {
|
||||
if(!fs.existsSync(value))
|
||||
return
|
||||
|
||||
this.options.client.downloadPath = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<RaisedButton style={{marginLeft: 20}} label={__('Browse')} primary={true} onClick={() => {
|
||||
if(!dialog)
|
||||
return
|
||||
const dir = dialog.showOpenDialog({properties: ['openDirectory']})[0]
|
||||
if(dir)
|
||||
{
|
||||
this.options.client.downloadPath = dir
|
||||
this.forceUpdate()
|
||||
}
|
||||
}} />
|
||||
</div>
|
||||
this.options.client.downloadPath = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<RaisedButton style={{marginLeft: 20}} label={__('Browse')} primary={true} onClick={() => {
|
||||
if(!dialog)
|
||||
return
|
||||
const dir = dialog.showOpenDialog({properties: ['openDirectory']})[0]
|
||||
if(dir)
|
||||
{
|
||||
this.options.client.downloadPath = dir
|
||||
this.forceUpdate()
|
||||
}
|
||||
}} />
|
||||
</div>
|
||||
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Hide to tray on application minimize')}
|
||||
toggled={this.options.trayOnMinimize}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.trayOnMinimize = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Hide to tray on application minimize')}
|
||||
toggled={this.options.trayOnMinimize}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.trayOnMinimize = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Hide to tray on application close')}
|
||||
toggled={this.options.trayOnClose}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.trayOnClose = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Hide to tray on application close')}
|
||||
toggled={this.options.trayOnClose}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.trayOnClose = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{marginTop: 10}}>{__('P2P Rats network settings')}:</div>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled p2p search')}
|
||||
toggled={this.options.p2p}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2p = this.options.indexer && checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='column w100p'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled bootstrap peers')}
|
||||
toggled={this.options.p2pBootstrap}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2pBootstrap = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Use extrnral bootstrap nodes to get p2p peers when network setted wrong or need external source')}</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Max peers limit')} ({__('current')}: {this.options.p2pConnections})</div>
|
||||
<Slider
|
||||
min={10}
|
||||
max={25}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.p2pConnections}
|
||||
onChange={(event, value) => {
|
||||
this.options.p2pConnections = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('P2P torrents replication')}
|
||||
toggled={this.options.p2pReplication}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2pReplication = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Enable torrents replication from another rats clients. Dont recomended if torrent scanner works correct')}.</div>
|
||||
</div>
|
||||
<div style={{marginTop: 10}}>{__('P2P Rats network settings')}:</div>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled p2p search')}
|
||||
toggled={this.options.p2p}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2p = this.options.indexer && checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='column w100p'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Enabled bootstrap peers')}
|
||||
toggled={this.options.p2pBootstrap}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2pBootstrap = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Use extrnral bootstrap nodes to get p2p peers when network setted wrong or need external source')}</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Max peers limit')} ({__('current')}: {this.options.p2pConnections})</div>
|
||||
<Slider
|
||||
min={10}
|
||||
max={25}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.p2pConnections}
|
||||
onChange={(event, value) => {
|
||||
this.options.p2pConnections = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('P2P torrents replication')}
|
||||
toggled={this.options.p2pReplication}
|
||||
onToggle={(e, checked) => {
|
||||
this.options.p2pReplication = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Enable torrents replication from another rats clients. Dont recomended if torrent scanner works correct')}.</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div style={{marginTop: 10}}>{__('Torrent network scanner settings')}:</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Scanner walk speed')} ({__('current')}: {this.options.spider && this.options.spider.walkInterval}) [{__('affected after program reload')}]</div>
|
||||
<Slider
|
||||
min={1}
|
||||
max={150}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.walkInterval}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.walkInterval = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low value')} - {__('fast initial scanning and high cpu usage')}. {__('High Value')} - {__('low cpu usage but very slow scanning')}.
|
||||
{__('Good value between')} 3-60. {__('Defaul value')}: 5</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Nodes usage')} ({__('current')}: {this.options.spider && this.options.spider.nodesUsage})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={1000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.nodesUsage}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.nodesUsage = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low Value')} - {__('very low usage of nodes, low network traffic, slow torrent scanning')}. {__('High value')} - {__('high traffic, fast scanning, high routers usage')}.
|
||||
{__('Recomended value between')} 10-1000. {__('Defaul value')}: 100. 0 - {__('Ignore this option')} ({__('no limit')}).
|
||||
</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Reduce network packages')} ({__('current')}: {this.options.spider && this.options.spider.packagesLimit})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={2000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.packagesLimit}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.packagesLimit = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low Value')} - {__('ignore more usless network packages, lower traffic and routers usage')}. {__('High Value')} - {__('high traffic and router usage in prospect')}.
|
||||
{__('Recomended value between')} 300-2000. {__('Defaul value')}: 500. 0 - {__('Ignore this option')} ({__('no limit')}).
|
||||
</div>
|
||||
</div>
|
||||
<div style={{marginTop: 10}}>{__('Torrent network scanner settings')}:</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Scanner walk speed')} ({__('current')}: {this.options.spider && this.options.spider.walkInterval}) [{__('affected after program reload')}]</div>
|
||||
<Slider
|
||||
min={1}
|
||||
max={150}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.walkInterval}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.walkInterval = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low value')} - {__('fast initial scanning and high cpu usage')}. {__('High Value')} - {__('low cpu usage but very slow scanning')}.
|
||||
{__('Good value between')} 3-60. {__('Defaul value')}: 5</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Nodes usage')} ({__('current')}: {this.options.spider && this.options.spider.nodesUsage})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={1000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.nodesUsage}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.nodesUsage = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low Value')} - {__('very low usage of nodes, low network traffic, slow torrent scanning')}. {__('High value')} - {__('high traffic, fast scanning, high routers usage')}.
|
||||
{__('Recomended value between')} 10-1000. {__('Defaul value')}: 100. 0 - {__('Ignore this option')} ({__('no limit')}).
|
||||
</div>
|
||||
</div>
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Reduce network packages')} ({__('current')}: {this.options.spider && this.options.spider.packagesLimit})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={2000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.spider.packagesLimit}
|
||||
onChange={(event, value) => {
|
||||
this.options.spider.packagesLimit = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* {__('Low Value')} - {__('ignore more usless network packages, lower traffic and routers usage')}. {__('High Value')} - {__('high traffic and router usage in prospect')}.
|
||||
{__('Recomended value between')} 300-2000. {__('Defaul value')}: 500. 0 - {__('Ignore this option')} ({__('no limit')}).
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{
|
||||
this.settingsSavedMessage
|
||||
{
|
||||
this.settingsSavedMessage
|
||||
&&
|
||||
<div style={{color: 'green'}}>{__('Settings saved')}</div>
|
||||
}
|
||||
}
|
||||
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Save Settings')} primary={true} onClick={() => {
|
||||
this.saveSettings()
|
||||
}} />
|
||||
</div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Save Settings')} primary={true} onClick={() => {
|
||||
this.saveSettings()
|
||||
}} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -236,7 +236,7 @@ const ContentCategoryProp = 'contentCategory';
|
||||
|
||||
const {
|
||||
XXX_BLOCK_WORDS,
|
||||
XXX_VERY_BAD_WORDS
|
||||
XXX_VERY_BAD_WORDS
|
||||
} = require('./bad-words');
|
||||
|
||||
// блокируем порнографию
|
||||
@ -270,7 +270,7 @@ const detectSubCategory = (torrent, files, typesPriority, contentType) => {
|
||||
fileCheck = fileCheck.join('.');
|
||||
|
||||
blockBadName(torrent, fileCheck);
|
||||
|
||||
|
||||
return torrent[ContentTypeProp] == 'bad';
|
||||
})
|
||||
}
|
||||
@ -304,7 +304,7 @@ const torrentTypeDetect = (torrent, files) => {
|
||||
}
|
||||
}
|
||||
let priority = Object.keys(typesPriority).sort(function(a, b){
|
||||
return typesPriority[b] - typesPriority[a]
|
||||
return typesPriority[b] - typesPriority[a]
|
||||
});
|
||||
if(priority.length > 0)
|
||||
torrent[ContentTypeProp] = priority[0];
|
||||
|
@ -7,27 +7,27 @@ import NavigationClose from 'material-ui/svg-icons/navigation/close';
|
||||
|
||||
export default class DMCAPage extends Page {
|
||||
|
||||
render() {
|
||||
return (
|
||||
<div className='w100p column'>
|
||||
<AppBar
|
||||
title="DMCA / Copyright"
|
||||
iconElementLeft={<IconButton onClick={()=>{ window.router('/') }}><NavigationClose /></IconButton>}
|
||||
/>
|
||||
render() {
|
||||
return (
|
||||
<div className='w100p column'>
|
||||
<AppBar
|
||||
title="DMCA / Copyright"
|
||||
iconElementLeft={<IconButton onClick={()=>{ window.router('/') }}><NavigationClose /></IconButton>}
|
||||
/>
|
||||
|
||||
<div className='column w100p pad1 center'>
|
||||
<div>RatsOnTheBoat.org is in compliance with 17 U.S.C. § 512, the Digital Millennium Copyright Act ("DMCA") and the Directive 2001/29/EC of the European Parliament.</div>
|
||||
|
||||
<div className='fs1-5 pad0-75'>Content status</div>
|
||||
<div className='column w100p pad1 center'>
|
||||
<div>RatsOnTheBoat.org is in compliance with 17 U.S.C. § 512, the Digital Millennium Copyright Act ("DMCA") and the Directive 2001/29/EC of the European Parliament.</div>
|
||||
|
||||
<div className='fs1-5 pad0-75'>Content status</div>
|
||||
|
||||
Our main goal is collect and make analysis of information from the torrent network. We don't save/distribute any real content/data and also don't save any torrents files - we are respect DMCA law.
|
||||
Information collected automaticly and the real source are torrent clients based on torrent protocol.
|
||||
Our main goal is collect and make analysis of information from the torrent network. We don't save/distribute any real content/data and also don't save any torrents files - we are respect DMCA law.
|
||||
Information collected automaticly and the real source are torrent clients based on torrent protocol.
|
||||
|
||||
<div className='fs1-5 pad0-75'>Block mechanisms (for rightholders)</div>
|
||||
<div className='fs1-5 pad0-75'>Block mechanisms (for rightholders)</div>
|
||||
|
||||
Right holders can block/remove content that they responsible for. Contact administration or left application about content removal.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Right holders can block/remove content that they responsible for. Contact administration or left application about content removal.
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -10,48 +10,48 @@ export default class TopPage extends Page {
|
||||
downloads = []
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Current Downloads');
|
||||
super(props)
|
||||
this.setTitle('Current Downloads');
|
||||
}
|
||||
getDownloads()
|
||||
{
|
||||
window.torrentSocket.emit('downloads', window.customLoader((downloads) => {
|
||||
this.downloads = downloads
|
||||
this.forceUpdate()
|
||||
}))
|
||||
window.torrentSocket.emit('downloads', window.customLoader((downloads) => {
|
||||
this.downloads = downloads
|
||||
this.forceUpdate()
|
||||
}))
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
super.componentDidMount();
|
||||
this.getDownloads()
|
||||
this.downloading = () => this.getDownloads()
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
this.downloadDone = () => this.getDownloads()
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
super.componentDidMount();
|
||||
this.getDownloads()
|
||||
this.downloading = () => this.getDownloads()
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
this.downloadDone = () => this.getDownloads()
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<RaisedButton label={__('Back to main page')} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
<List style={{paddingBottom: '70px'}} className='animated recent-torrents'>
|
||||
{
|
||||
this.downloads.map((download, index) => {
|
||||
return <TorrentLine key={index} torrent={download.torrentObject} download={download} />
|
||||
})
|
||||
}
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
return (
|
||||
<div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<RaisedButton label={__('Back to main page')} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
<List style={{paddingBottom: '70px'}} className='animated recent-torrents'>
|
||||
{
|
||||
this.downloads.map((download, index) => {
|
||||
return <TorrentLine key={index} torrent={download.torrentObject} download={download} />
|
||||
})
|
||||
}
|
||||
</List>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,89 +8,89 @@ import MenuItem from 'material-ui/MenuItem';
|
||||
import Feed from './feed';
|
||||
|
||||
export default class FeedPage extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Content Search Engine');
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
Search.instance().onSearchUpdate = () => this.forceUpdate()
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
Search.instance().onSearchUpdate = () => {}
|
||||
}
|
||||
render() {
|
||||
const orderText = (text, field) => {
|
||||
if(field !== Search.instance().state.orderBy)
|
||||
return text;
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Content Search Engine');
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
Search.instance().onSearchUpdate = () => this.forceUpdate()
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
Search.instance().onSearchUpdate = () => {}
|
||||
}
|
||||
render() {
|
||||
const orderText = (text, field) => {
|
||||
if(field !== Search.instance().state.orderBy)
|
||||
return text;
|
||||
|
||||
if(Search.instance().state.orderDesc)
|
||||
return text + ' ⇩'
|
||||
else
|
||||
return text + ' ⇧'
|
||||
}
|
||||
if(Search.instance().state.orderDesc)
|
||||
return text + ' ⇩'
|
||||
else
|
||||
return text + ' ⇧'
|
||||
}
|
||||
|
||||
return (
|
||||
<div id='index-window' className='column center'>
|
||||
<div className='torrents-container'>
|
||||
<SearchResults
|
||||
torrentsSearchResults={Search.instance().searchTorrents}
|
||||
filesSearchResults={Search.instance().searchFiles}
|
||||
currentSearching={Search.instance().state.searchingIndicator}
|
||||
searchText={Search.instance().currentSearch}
|
||||
resultSelector={
|
||||
<SelectField
|
||||
floatingLabelText={__("Sort by")}
|
||||
floatingLabelFixed={true}
|
||||
value={Search.instance().state.orderBy}
|
||||
onChange={(event, index, value) => {
|
||||
event.preventDefault(); // fix overclick on torrent
|
||||
if(value === 'none') {
|
||||
Search.instance().setState({orderBy: null}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
return;
|
||||
}
|
||||
return (
|
||||
<div id='index-window' className='column center'>
|
||||
<div className='torrents-container'>
|
||||
<SearchResults
|
||||
torrentsSearchResults={Search.instance().searchTorrents}
|
||||
filesSearchResults={Search.instance().searchFiles}
|
||||
currentSearching={Search.instance().state.searchingIndicator}
|
||||
searchText={Search.instance().currentSearch}
|
||||
resultSelector={
|
||||
<SelectField
|
||||
floatingLabelText={__("Sort by")}
|
||||
floatingLabelFixed={true}
|
||||
value={Search.instance().state.orderBy}
|
||||
onChange={(event, index, value) => {
|
||||
event.preventDefault(); // fix overclick on torrent
|
||||
if(value === 'none') {
|
||||
Search.instance().setState({orderBy: null}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
if(value === Search.instance().state.orderBy)
|
||||
{
|
||||
Search.instance().setState({orderDesc: !Search.instance().state.orderDesc}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
return;
|
||||
}
|
||||
if(value === Search.instance().state.orderBy)
|
||||
{
|
||||
Search.instance().setState({orderDesc: !Search.instance().state.orderDesc}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
return;
|
||||
}
|
||||
|
||||
Search.instance().setState({
|
||||
orderBy: value,
|
||||
orderDesc: (value === 'seeders' || value === 'completed' || value === 'added') ? true : Search.instance().state.orderDesc
|
||||
}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<MenuItem value='none' primaryText={__('None')} />
|
||||
<MenuItem value='seeders' primaryText={orderText(__('Seeders'), 'seeders')} />
|
||||
<MenuItem value='name' primaryText={orderText(__('Name'), 'name')} />
|
||||
<MenuItem value='files' primaryText={orderText(__('Files'), 'files')} />
|
||||
<MenuItem value='size' primaryText={orderText(__('Size'), 'size')} />
|
||||
<MenuItem value='added' primaryText={orderText(__('Added date'), 'added')} />
|
||||
<MenuItem value='completed' primaryText={orderText(__('Completed'), 'completed')} />
|
||||
</SelectField>
|
||||
}
|
||||
Search.instance().setState({
|
||||
orderBy: value,
|
||||
orderDesc: (value === 'seeders' || value === 'completed' || value === 'added') ? true : Search.instance().state.orderDesc
|
||||
}, () => {
|
||||
Search.instance().search(true)
|
||||
})
|
||||
}}
|
||||
>
|
||||
<MenuItem value='none' primaryText={__('None')} />
|
||||
<MenuItem value='seeders' primaryText={orderText(__('Seeders'), 'seeders')} />
|
||||
<MenuItem value='name' primaryText={orderText(__('Name'), 'name')} />
|
||||
<MenuItem value='files' primaryText={orderText(__('Files'), 'files')} />
|
||||
<MenuItem value='size' primaryText={orderText(__('Size'), 'size')} />
|
||||
<MenuItem value='added' primaryText={orderText(__('Added date'), 'added')} />
|
||||
<MenuItem value='completed' primaryText={orderText(__('Completed'), 'completed')} />
|
||||
</SelectField>
|
||||
}
|
||||
|
||||
moreTorrentsEnabled={Search.instance().moreSearchTorrents && !Search.instance().state.searchingIndicator}
|
||||
moreFilesEnabled={Search.instance().moreSearchFiles && !Search.instance().state.searchingIndicator}
|
||||
onMoreTorrents={() => Search.instance().moreTorrents()}
|
||||
onMoreFiles={() => Search.instance().moreFiles()}
|
||||
moreTorrentsIndicator={Search.instance().state.moreTorrentsIndicator}
|
||||
moreFilesIndicator={Search.instance().state.moreFilesIndicator}
|
||||
/>
|
||||
</div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<Feed />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
moreTorrentsEnabled={Search.instance().moreSearchTorrents && !Search.instance().state.searchingIndicator}
|
||||
moreFilesEnabled={Search.instance().moreSearchFiles && !Search.instance().state.searchingIndicator}
|
||||
onMoreTorrents={() => Search.instance().moreTorrents()}
|
||||
onMoreFiles={() => Search.instance().moreFiles()}
|
||||
moreTorrentsIndicator={Search.instance().state.moreTorrentsIndicator}
|
||||
moreFilesIndicator={Search.instance().state.moreFilesIndicator}
|
||||
/>
|
||||
</div>
|
||||
<div className='column center w100p pad0-75'>
|
||||
<Feed />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -5,32 +5,32 @@ import Divider from 'material-ui/Divider';
|
||||
import Subheader from 'material-ui/Subheader';
|
||||
|
||||
export default class RecentTorrents extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.torrents = [];
|
||||
}
|
||||
componentDidMount() {
|
||||
window.torrentSocket.emit('feed', window.customLoader((data) => {
|
||||
if(data) {
|
||||
this.torrents = data;
|
||||
console.log(data)
|
||||
this.forceUpdate();
|
||||
}
|
||||
}))
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<List className='animated torrents-container'>
|
||||
<Subheader className='recent-title' inset={true}>
|
||||
{__('Feed')}
|
||||
</Subheader>
|
||||
<Divider />
|
||||
{
|
||||
this.torrents.map((torrent, index) =>{
|
||||
return <TorrentLine key={index} torrent={torrent} />;
|
||||
})
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
constructor() {
|
||||
super()
|
||||
this.torrents = [];
|
||||
}
|
||||
componentDidMount() {
|
||||
window.torrentSocket.emit('feed', window.customLoader((data) => {
|
||||
if(data) {
|
||||
this.torrents = data;
|
||||
console.log(data)
|
||||
this.forceUpdate();
|
||||
}
|
||||
}))
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<List className='animated torrents-container'>
|
||||
<Subheader className='recent-title' inset={true}>
|
||||
{__('Feed')}
|
||||
</Subheader>
|
||||
<Divider />
|
||||
{
|
||||
this.torrents.map((torrent, index) =>{
|
||||
return <TorrentLine key={index} torrent={torrent} />;
|
||||
})
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -11,182 +11,182 @@ import MenuItem from 'material-ui/MenuItem';
|
||||
import fs from 'fs'
|
||||
|
||||
export default class ConfigPage extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats filters');
|
||||
this.options = {}
|
||||
}
|
||||
componentDidMount() {
|
||||
this.loadSettings()
|
||||
}
|
||||
loadSettings() {
|
||||
window.torrentSocket.emit('config', window.customLoader((options) => {
|
||||
this.options = options;
|
||||
console.log(this.options)
|
||||
this.forceUpdate();
|
||||
}));
|
||||
}
|
||||
saveSettings() {
|
||||
window.torrentSocket.emit('setConfig', this.options)
|
||||
this.settingsSavedMessage = true
|
||||
this.forceUpdate()
|
||||
setTimeout(() => {
|
||||
this.settingsSavedMessage = false
|
||||
this.forceUpdate()
|
||||
}, 1000)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__("Back to main page")} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
</div>
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats filters');
|
||||
this.options = {}
|
||||
}
|
||||
componentDidMount() {
|
||||
this.loadSettings()
|
||||
}
|
||||
loadSettings() {
|
||||
window.torrentSocket.emit('config', window.customLoader((options) => {
|
||||
this.options = options;
|
||||
console.log(this.options)
|
||||
this.forceUpdate();
|
||||
}));
|
||||
}
|
||||
saveSettings() {
|
||||
window.torrentSocket.emit('setConfig', this.options)
|
||||
this.settingsSavedMessage = true
|
||||
this.forceUpdate()
|
||||
setTimeout(() => {
|
||||
this.settingsSavedMessage = false
|
||||
this.forceUpdate()
|
||||
}, 1000)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__("Back to main page")} primary={true} onClick={() => {
|
||||
window.router('/')
|
||||
}} />
|
||||
</div>
|
||||
|
||||
<div className='column center w100p pad0-75'>
|
||||
<div className='column center w100p pad0-75'>
|
||||
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Max files per torrent')} ({__('current')}: {this.options.filters && this.options.filters.maxFiles})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={50000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.filters.maxFiles}
|
||||
onChange={(event, value) => {
|
||||
this.options.filters.maxFiles = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
hintText={__('Max files')}
|
||||
className='pad0-75'
|
||||
style={{width: 200}}
|
||||
value={this.options.filters && this.options.filters.maxFiles}
|
||||
onChange={(e, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Max files per torrent')} ({__('current')}: {this.options.filters && this.options.filters.maxFiles})</div>
|
||||
<Slider
|
||||
min={0}
|
||||
max={50000}
|
||||
step={1}
|
||||
style={{width: 300}}
|
||||
value={this.options.spider && this.options.filters.maxFiles}
|
||||
onChange={(event, value) => {
|
||||
this.options.filters.maxFiles = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<TextField
|
||||
hintText={__('Max files')}
|
||||
className='pad0-75'
|
||||
style={{width: 200}}
|
||||
value={this.options.filters && this.options.filters.maxFiles}
|
||||
onChange={(e, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
|
||||
this.options.filters.maxFiles = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* 0 - {__('Disabled')}.
|
||||
</div>
|
||||
</div>
|
||||
this.options.filters.maxFiles = parseInt(value)
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
</div>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>* 0 - {__('Disabled')}.
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Torrent name regular extension filtering')}</div>
|
||||
<TextField
|
||||
hintText="regex"
|
||||
className='pad0-75'
|
||||
style={{width: 400}}
|
||||
value={this.options.filters && this.options.filters.namingRegExp}
|
||||
onChange={(e, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
<div className='column w100p'>
|
||||
<div className='row inline w100p'>
|
||||
<div style={{flex: 1}}>{__('Torrent name regular extension filtering')}</div>
|
||||
<TextField
|
||||
hintText="regex"
|
||||
className='pad0-75'
|
||||
style={{width: 400}}
|
||||
value={this.options.filters && this.options.filters.namingRegExp}
|
||||
onChange={(e, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
|
||||
this.options.filters.namingRegExp = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<SelectField
|
||||
style={{marginLeft: 15}}
|
||||
floatingLabelText={__('Examples')}
|
||||
value={this.options.filters && this.options.filters.namingRegExp}
|
||||
onChange={(event, index, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
this.options.filters.namingRegExp = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<SelectField
|
||||
style={{marginLeft: 15}}
|
||||
floatingLabelText={__('Examples')}
|
||||
value={this.options.filters && this.options.filters.namingRegExp}
|
||||
onChange={(event, index, value) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
|
||||
this.options.filters.namingRegExp = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
>
|
||||
<MenuItem value={String.raw`^[А-Яа-я0-9A-Za-z.!@?#"$%&:;() *\+,\/;\-=[\\\]\^_{|}<>\u0400-\u04FF]+$`} primaryText={__('Russian + English only (With symbols)')} />
|
||||
<MenuItem value={'^[0-9A-Za-z.!@?#"$%&:;() *\+,\/;\-=[\\\]\^_{|}<>]+$'} primaryText={__('English only (With symbols)')} />
|
||||
<MenuItem value={'^((?!badword).)*$'} primaryText={__('Ignore badword')} />
|
||||
</SelectField>
|
||||
</div>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Negative regular extension filtering')}
|
||||
toggled={this.options.filters && this.options.filters.namingRegExpNegative}
|
||||
onToggle={(e, checked) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
this.options.filters.namingRegExp = value
|
||||
this.forceUpdate()
|
||||
}}
|
||||
>
|
||||
<MenuItem value={String.raw`^[А-Яа-я0-9A-Za-z.!@?#"$%&:;() *\+,\/;\-=[\\\]\^_{|}<>\u0400-\u04FF]+$`} primaryText={__('Russian + English only (With symbols)')} />
|
||||
<MenuItem value={'^[0-9A-Za-z.!@?#"$%&:;() *\+,\/;\-=[\\\]\^_{|}<>]+$'} primaryText={__('English only (With symbols)')} />
|
||||
<MenuItem value={'^((?!badword).)*$'} primaryText={__('Ignore badword')} />
|
||||
</SelectField>
|
||||
</div>
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Negative regular extension filtering')}
|
||||
toggled={this.options.filters && this.options.filters.namingRegExpNegative}
|
||||
onToggle={(e, checked) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
|
||||
this.options.filters.namingRegExpNegative = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>
|
||||
this.options.filters.namingRegExpNegative = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'grey'}}>
|
||||
* - {__('clean string means disabled')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Adult filter')}
|
||||
toggled={this.options.filters && this.options.filters.adultFilter}
|
||||
onToggle={(e, checked) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
<Toggle
|
||||
style={{marginTop: '10px'}}
|
||||
label={__('Adult filter')}
|
||||
toggled={this.options.filters && this.options.filters.adultFilter}
|
||||
onToggle={(e, checked) => {
|
||||
if(!this.options.filters)
|
||||
return
|
||||
|
||||
this.options.filters.adultFilter = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
this.options.filters.adultFilter = checked
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
{
|
||||
this.toRemoveProbably && this.toRemoveProbably > 0
|
||||
?
|
||||
<div style={{color: 'orange'}}>{__('Torrents to clean')}: {this.toRemoveProbably}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.toRemove && this.toRemove > 0
|
||||
?
|
||||
<div style={{color: 'red'}}>{__('Torrents cleaned')}: {this.toRemove}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.toRemoveProbably && this.toRemoveProbably > 0
|
||||
?
|
||||
<div style={{color: 'orange'}}>{__('Torrents to clean')}: {this.toRemoveProbably}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.toRemove && this.toRemove > 0
|
||||
?
|
||||
<div style={{color: 'red'}}>{__('Torrents cleaned')}: {this.toRemove}</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
|
||||
{
|
||||
this.settingsSavedMessage
|
||||
{
|
||||
this.settingsSavedMessage
|
||||
&&
|
||||
<div style={{color: 'green'}}>{__('Settings saved')}</div>
|
||||
}
|
||||
}
|
||||
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Check torrents')} primary={true} onClick={() => {
|
||||
window.torrentSocket.emit('removeTorrents', true, window.customLoader((toRemove) => {
|
||||
this.toRemoveProbably = toRemove
|
||||
this.forceUpdate()
|
||||
}));
|
||||
}} />
|
||||
<RaisedButton label={__('Clean torrents')} secondary={true} onClick={() => {
|
||||
window.torrentSocket.emit('removeTorrents', false, window.customLoader((toRemove) => {
|
||||
this.toRemove = toRemove
|
||||
this.forceUpdate()
|
||||
}));
|
||||
}} />
|
||||
</div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Check torrents')} primary={true} onClick={() => {
|
||||
window.torrentSocket.emit('removeTorrents', true, window.customLoader((toRemove) => {
|
||||
this.toRemoveProbably = toRemove
|
||||
this.forceUpdate()
|
||||
}));
|
||||
}} />
|
||||
<RaisedButton label={__('Clean torrents')} secondary={true} onClick={() => {
|
||||
window.torrentSocket.emit('removeTorrents', false, window.customLoader((toRemove) => {
|
||||
this.toRemove = toRemove
|
||||
this.forceUpdate()
|
||||
}));
|
||||
}} />
|
||||
</div>
|
||||
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Save Settings')} primary={true} onClick={() => {
|
||||
this.saveSettings()
|
||||
}} />
|
||||
</div>
|
||||
<div className='row center pad0-75'>
|
||||
<RaisedButton label={__('Save Settings')} primary={true} onClick={() => {
|
||||
this.saveSettings()
|
||||
}} />
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
);
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -3,18 +3,18 @@ import React from 'react';
|
||||
export default (props) => {
|
||||
return (
|
||||
<div className='column center' style={{color: 'grey', marginTop: '12px'}}>
|
||||
<svg style={{height: '100px', fill: 'grey'}} viewBox="0 0 264.725 264.725">
|
||||
<svg style={{height: '100px', fill: 'grey'}} viewBox="0 0 264.725 264.725">
|
||||
<path d="M220.195,71.427c-0.589-7.654-9.135-15.619-17.979-16.209c-8.844-0.584-17.398,0.301-12.087,6.483
|
||||
c5.308,6.188,7.074,12.091,4.423,11.212c-2.66-0.896-13.267-7.08-45.104-2.066c-4.126,1.17-21.221-12.682-44.513-12.977
|
||||
c-23.283-0.295-40.381,6.346-64.85,72.296c-2.356,5.828-18.866,19.386-27.71,25.865C3.536,162.529,0.007,169.787,0,182.763
|
||||
c-0.018,18.158,25.934,27.187,81.648,26.889c55.715-0.292,85.195-9.388,85.195-9.388c-62.789,6.773-158.907,10.52-158.907-18.687
|
||||
c0-20.641,28.321-28.47,36.281-28.184c7.958,0.3,13.562,12.673,33.307,5.603c3.247-0.295,1.48,4.423-1.18,7.369
|
||||
c-2.651,2.942-0.586,6.487,9.73,6.487c10.315,0,41.183,0.295,47.707,0c6.531-0.299,11.839-11.792-9.384-12.68
|
||||
c-18.548,0.311,12.023-5.773,15.915-21.813c0.709-3.927,8.84-4.139,15.918-4.119c20.777,0.029,34.485,38.193,38.912,38.338
|
||||
c4.416,0.15,17.979,1.621,17.683-4.273c-0.292-5.897-11.491-3.241-13.854-6.487c-2.359-3.234-10.023-15.504-7.366-21.104
|
||||
c2.65-5.59,12.674-21.229,24.463-22.988c11.789-1.777,42.451,7.361,47.459,0c5.012-7.372-6.783-11.512-15.918-28.611
|
||||
C243.779,80.572,238.768,71.728,220.195,71.427z"/>
|
||||
c5.308,6.188,7.074,12.091,4.423,11.212c-2.66-0.896-13.267-7.08-45.104-2.066c-4.126,1.17-21.221-12.682-44.513-12.977
|
||||
c-23.283-0.295-40.381,6.346-64.85,72.296c-2.356,5.828-18.866,19.386-27.71,25.865C3.536,162.529,0.007,169.787,0,182.763
|
||||
c-0.018,18.158,25.934,27.187,81.648,26.889c55.715-0.292,85.195-9.388,85.195-9.388c-62.789,6.773-158.907,10.52-158.907-18.687
|
||||
c0-20.641,28.321-28.47,36.281-28.184c7.958,0.3,13.562,12.673,33.307,5.603c3.247-0.295,1.48,4.423-1.18,7.369
|
||||
c-2.651,2.942-0.586,6.487,9.73,6.487c10.315,0,41.183,0.295,47.707,0c6.531-0.299,11.839-11.792-9.384-12.68
|
||||
c-18.548,0.311,12.023-5.773,15.915-21.813c0.709-3.927,8.84-4.139,15.918-4.119c20.777,0.029,34.485,38.193,38.912,38.338
|
||||
c4.416,0.15,17.979,1.621,17.683-4.273c-0.292-5.897-11.491-3.241-13.854-6.487c-2.359-3.234-10.023-15.504-7.366-21.104
|
||||
c2.65-5.59,12.674-21.229,24.463-22.988c11.789-1.777,42.451,7.361,47.459,0c5.012-7.372-6.783-11.512-15.918-28.611
|
||||
C243.779,80.572,238.768,71.728,220.195,71.427z"/>
|
||||
</svg>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
export default function formatBytes(bytes,decimals) {
|
||||
if(bytes == 0) return '0 Byte';
|
||||
var k = 1000; // or 1024 for binary
|
||||
var dm = decimals + 1 || 3;
|
||||
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
if(bytes == 0) return '0 Byte';
|
||||
var k = 1000; // or 1024 for binary
|
||||
var dm = decimals + 1 || 3;
|
||||
var sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
|
||||
var i = Math.floor(Math.log(bytes) / Math.log(k));
|
||||
return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];
|
||||
}
|
@ -5,64 +5,64 @@ import RaisedButton from 'material-ui/RaisedButton';
|
||||
import Search from './search'
|
||||
|
||||
class Header extends React.Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.header = React.createRef();
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.header = React.createRef();
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
window.onscroll = () => {
|
||||
if (window.pageYOffset >= 15)
|
||||
{
|
||||
const scrollHeight = Math.max(
|
||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||
document.body.clientHeight, document.documentElement.clientHeight
|
||||
);
|
||||
const scrollHeight = Math.max(
|
||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||
document.body.clientHeight, document.documentElement.clientHeight
|
||||
);
|
||||
|
||||
if(scrollHeight - 240 < document.documentElement.clientHeight)
|
||||
{
|
||||
return
|
||||
}
|
||||
if(scrollHeight - 240 < document.documentElement.clientHeight)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
if(!this.stickyHeader)
|
||||
{
|
||||
this.stickyHeader = true
|
||||
this.header.current.classList.add("sticky");
|
||||
this.stickyHeader = true
|
||||
this.header.current.classList.add("sticky");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(this.stickyHeader)
|
||||
{
|
||||
this.stickyHeader = false
|
||||
this.header.current.classList.remove("sticky");
|
||||
this.stickyHeader = false
|
||||
this.header.current.classList.remove("sticky");
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
window.onscroll = null
|
||||
}
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
window.onscroll = null
|
||||
}
|
||||
|
||||
render()
|
||||
{
|
||||
return (
|
||||
<div ref={this.header} className='header'>
|
||||
<Card className='w100p header-main' style={{position: 'fixed', zIndex: 2}}>
|
||||
<CardMedia
|
||||
overlay={<CardTitle className='header-title' title={__('Yarrr, Landlubbers!')} style={{paddingTop: 2}} subtitle={
|
||||
<div>
|
||||
<div className='row' style={{position: 'absolute', top: -65}}>
|
||||
<svg className='clickable'
|
||||
onClick={() => {
|
||||
window.router('/config')
|
||||
}}
|
||||
fill='white' style={{height: 45, margin: 4}} viewBox="0 0 932.179 932.179">
|
||||
<g>
|
||||
<path d="M61.2,341.538c4.9,16.8,11.7,33,20.3,48.2l-24.5,30.9c-8,10.1-7.1,24.5,1.9,33.6l42.2,42.2c9.1,9.1,23.5,9.899,33.6,1.899
|
||||
render()
|
||||
{
|
||||
return (
|
||||
<div ref={this.header} className='header'>
|
||||
<Card className='w100p header-main' style={{position: 'fixed', zIndex: 2}}>
|
||||
<CardMedia
|
||||
overlay={<CardTitle className='header-title' title={__('Yarrr, Landlubbers!')} style={{paddingTop: 2}} subtitle={
|
||||
<div>
|
||||
<div className='row' style={{position: 'absolute', top: -65}}>
|
||||
<svg className='clickable'
|
||||
onClick={() => {
|
||||
window.router('/config')
|
||||
}}
|
||||
fill='white' style={{height: 45, margin: 4}} viewBox="0 0 932.179 932.179">
|
||||
<g>
|
||||
<path d="M61.2,341.538c4.9,16.8,11.7,33,20.3,48.2l-24.5,30.9c-8,10.1-7.1,24.5,1.9,33.6l42.2,42.2c9.1,9.1,23.5,9.899,33.6,1.899
|
||||
l30.7-24.3c15.8,9.101,32.6,16.2,50.1,21.2l4.6,39.5c1.5,12.8,12.3,22.4,25.1,22.4h59.7c12.8,0,23.6-9.601,25.1-22.4l4.4-38.1
|
||||
c18.8-4.9,36.8-12.2,53.7-21.7l29.7,23.5c10.1,8,24.5,7.1,33.6-1.9l42.2-42.2c9.1-9.1,9.9-23.5,1.9-33.6l-23.1-29.3
|
||||
c9.6-16.601,17.1-34.3,22.1-52.8l35.6-4.1c12.801-1.5,22.4-12.3,22.4-25.1v-59.7c0-12.8-9.6-23.6-22.4-25.1l-35.1-4.1
|
||||
@ -71,7 +71,7 @@ class Header extends React.Component {
|
||||
c-19.8,5.3-38.7,13.3-56.3,23.8l-27.5-21.8c-10.1-8-24.5-7.1-33.6,1.9l-42.2,42.2c-9.1,9.1-9.9,23.5-1.9,33.6l23,29.1
|
||||
c-9.2,16.6-16.2,34.3-20.8,52.7l-36.8,4.2c-12.8,1.5-22.4,12.3-22.4,25.1v59.7c0,12.8,9.6,23.6,22.4,25.1L61.2,341.538z
|
||||
M277.5,180.038c54.4,0,98.7,44.3,98.7,98.7s-44.3,98.7-98.7,98.7c-54.399,0-98.7-44.3-98.7-98.7S223.1,180.038,277.5,180.038z"/>
|
||||
<path d="M867.699,356.238l-31.5-26.6c-9.699-8.2-24-7.8-33.199,0.9l-17.4,16.3c-14.699-7.1-30.299-12.1-46.4-15l-4.898-24
|
||||
<path d="M867.699,356.238l-31.5-26.6c-9.699-8.2-24-7.8-33.199,0.9l-17.4,16.3c-14.699-7.1-30.299-12.1-46.4-15l-4.898-24
|
||||
c-2.5-12.4-14-21-26.602-20l-41.1,3.5c-12.6,1.1-22.5,11.4-22.9,24.1l-0.799,24.4c-15.801,5.7-30.701,13.5-44.301,23.3
|
||||
l-20.799-13.8c-10.602-7-24.701-5-32.9,4.7l-26.6,31.7c-8.201,9.7-7.801,24,0.898,33.2l18.201,19.399
|
||||
c-6.301,14.2-10.801,29.101-13.4,44.4l-26,5.3c-12.4,2.5-21,14-20,26.601l3.5,41.1c1.1,12.6,11.4,22.5,24.1,22.9l28.1,0.899
|
||||
@ -82,7 +82,7 @@ class Header extends React.Component {
|
||||
c-5.201-14.6-12.201-28.399-20.9-41.2l13.699-20.6C879.4,378.638,877.4,364.438,867.699,356.238z M712.801,593.837
|
||||
c-44.4,3.801-83.602-29.3-87.301-73.699c-3.801-44.4,29.301-83.601,73.699-87.301c44.4-3.8,83.602,29.301,87.301,73.7
|
||||
C790.301,550.938,757.199,590.138,712.801,593.837z"/>
|
||||
<path d="M205,704.438c-12.6,1.3-22.3,11.899-22.4,24.6l-0.3,25.3c-0.2,12.7,9.2,23.5,21.8,25.101l18.6,2.399
|
||||
<path d="M205,704.438c-12.6,1.3-22.3,11.899-22.4,24.6l-0.3,25.3c-0.2,12.7,9.2,23.5,21.8,25.101l18.6,2.399
|
||||
c3.1,11.301,7.5,22.101,13.2,32.301l-12,14.8c-8,9.899-7.4,24.1,1.5,33.2l17.7,18.1c8.9,9.1,23.1,10.1,33.2,2.3l14.899-11.5
|
||||
c10.5,6.2,21.601,11.101,33.2,14.5l2,19.2c1.3,12.6,11.9,22.3,24.6,22.4l25.301,0.3c12.699,0.2,23.5-9.2,25.1-21.8l2.3-18.2
|
||||
c12.601-3.101,24.601-7.8,36-14l14,11.3c9.9,8,24.101,7.4,33.201-1.5l18.1-17.7c9.1-8.899,10.1-23.1,2.301-33.2L496.6,818.438
|
||||
@ -93,47 +93,47 @@ class Header extends React.Component {
|
||||
l-18.2,17.801c-9.1,8.899-10.1,23.1-2.3,33.199l10.7,13.801c-6.2,11-11.1,22.699-14.3,35L205,704.438z M368.3,675.837
|
||||
c36.3,0.4,65.399,30.301,65,66.601c-0.4,36.3-30.301,65.399-66.601,65c-36.3-0.4-65.399-30.3-65-66.601
|
||||
C302.1,704.538,332,675.438,368.3,675.837z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<svg className='clickable'
|
||||
onClick={() => {
|
||||
window.router('/filters')
|
||||
}}
|
||||
fill='white' style={{height: 45, margin: 4}} viewBox="0 0 512 512">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M256,103.536c-58.559,0-106.2,47.641-106.2,106.2c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
|
||||
</g>
|
||||
</svg>
|
||||
<svg className='clickable'
|
||||
onClick={() => {
|
||||
window.router('/filters')
|
||||
}}
|
||||
fill='white' style={{height: 45, margin: 4}} viewBox="0 0 512 512">
|
||||
<g>
|
||||
<g>
|
||||
<path d="M256,103.536c-58.559,0-106.2,47.641-106.2,106.2c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
|
||||
c0-49.55,40.313-89.862,89.862-89.862c49.549,0,89.862,40.311,89.862,89.862c0,4.512,3.658,8.169,8.169,8.169
|
||||
c4.513,0,8.169-3.658,8.169-8.169C362.2,151.177,314.559,103.536,256,103.536z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M256,136.213c-40.541,0-73.523,32.982-73.523,73.523c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M256,136.213c-40.541,0-73.523,32.982-73.523,73.523c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169
|
||||
c0-31.532,25.654-57.185,57.185-57.185s57.185,25.653,57.185,57.185c0,4.512,3.657,8.169,8.169,8.169
|
||||
c4.513,0,8.169-3.658,8.169-8.169C329.523,169.195,296.541,136.213,256,136.213z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M503.801,234.245H8.199c-4.513,0-8.169,3.658-8.169,8.169v43.569c0,2.721,1.354,5.263,3.612,6.781L167.331,402.76
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M503.801,234.245H8.199c-4.513,0-8.169,3.658-8.169,8.169v43.569c0,2.721,1.354,5.263,3.612,6.781L167.331,402.76
|
||||
c5.092,3.857,9.699,13.038,9.699,19.379v81.693c0,4.512,3.656,8.169,8.169,8.169h141.6c4.513,0,8.169-3.658,8.169-8.169v-81.693
|
||||
c0-6.34,4.606-15.522,9.699-19.379l163.691-109.995c2.258-1.517,3.612-4.06,3.612-6.781v-43.569
|
||||
C511.97,237.903,508.313,234.245,503.801,234.245z M495.632,277.815H157.969c-4.513,0-8.169,3.658-8.169,8.169
|
||||
s3.657,8.169,8.169,8.169h319.028l-141.61,95.159c-0.1,0.068-0.199,0.137-0.296,0.209c-9.383,6.93-16.458,20.951-16.458,32.616
|
||||
v73.523H193.37v-73.523c0-11.665-7.076-25.686-16.458-32.616c-0.098-0.072-0.197-0.142-0.296-0.209L35.003,294.153h90.289
|
||||
c4.513,0,8.169-3.658,8.169-8.169s-3.657-8.169-8.169-8.169H16.368v-27.231h479.263V277.815z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M296.504,397.63h-81.006c-4.513,0-8.169,3.658-8.169,8.169c0,4.512,3.657,8.169,8.169,8.169h81.006
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M296.504,397.63h-81.006c-4.513,0-8.169,3.658-8.169,8.169c0,4.512,3.657,8.169,8.169,8.169h81.006
|
||||
c4.513,0,8.169-3.658,8.169-8.169C304.674,401.288,301.016,397.63,296.504,397.63z"/>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M458.171,168.573l-36.481-3.382c-3.895-14.477-9.68-28.351-17.251-41.376l23.416-28.2
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M458.171,168.573l-36.481-3.382c-3.895-14.477-9.68-28.351-17.251-41.376l23.416-28.2
|
||||
c2.696-3.246,2.475-8.011-0.509-10.995l-46.545-46.545c-2.983-2.983-7.749-3.206-10.996-0.509L341.51,61.063
|
||||
c-13.017-7.52-26.88-13.258-41.343-17.113l-3.386-36.534C296.391,3.213,292.866,0,288.647,0h-65.826
|
||||
c-4.22,0-7.745,3.213-8.134,7.416l-3.401,36.68c-14.413,3.894-28.222,9.657-41.187,17.193L141.73,37.731
|
||||
@ -146,56 +146,56 @@ class Header extends React.Component {
|
||||
c2.986,1.866,6.834,1.607,9.545-0.645l27.023-22.438l36.013,36.013l-22.371,26.941c-2.255,2.717-2.511,6.575-0.632,9.565
|
||||
c9.189,14.625,15.814,30.514,19.69,47.225c0.795,3.429,3.699,5.964,7.203,6.287l34.829,3.229v25.582
|
||||
c0,4.512,3.657,8.169,8.169,8.169s8.169-3.658,8.169-8.169v-33.029C465.586,172.488,462.373,168.963,458.171,168.573z"/>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
</div>
|
||||
|
||||
{__('Welcome to')} ROTB! {__('This is file search engine based on the torrents from the internet')}.
|
||||
{__('Here you can easily find torrent or file that you intrested for')}. {__('We are not responsible for any content')}:
|
||||
{__('this is only information about content that collected automatically')}!
|
||||
</div>} />}
|
||||
>
|
||||
<div className='row header-row' style={{
|
||||
padding: '15px',
|
||||
background: `url('${Background}') no-repeat`,
|
||||
backgroundSize: 'cover',
|
||||
transition: '1s'
|
||||
}}>
|
||||
<RaisedButton
|
||||
label={__('Feed')}
|
||||
onClick={() => {
|
||||
window.router('/')
|
||||
}}
|
||||
backgroundColor='#69238c'
|
||||
labelColor='white'
|
||||
style={{height: 60, borderRadius: 6, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 28}} viewBox="0 0 64.051 64.051">
|
||||
<g>
|
||||
<path d="M8,0v2c16,0,31.173,7.065,41.472,19.386C57.567,31.065,62.051,43.358,62.051,56h2c0-13.11-4.649-25.858-13.044-35.897
|
||||
C40.326,7.327,25,0,8,0z"/>
|
||||
<path d="M50.769,56h2C52.769,31.343,33,11.282,8,11.282v2C32,13.282,50.769,32.445,50.769,56z"/>
|
||||
<path d="M8,22.564v2c17,0,31.486,14.102,31.486,31.436h2C41.486,37.563,26,22.564,8,22.564z"/>
|
||||
<path d="M30.205,56C30.205,43.784,20,33.846,8,33.846v2c11,0,20.205,9.041,20.205,20.154H30.205z"/>
|
||||
<path d="M16.103,56c0-4.439-3.612-8.051-8.052-8.051S0,51.561,0,56s3.611,8.051,8.051,8.051S16.103,60.439,16.103,56z M2,56
|
||||
c0-3.336,2.715-6.051,6.051-6.051c3.337,0,6.052,2.715,6.052,6.051s-2.715,6.051-6.052,6.051C4.715,62.051,2,59.336,2,56z"/>
|
||||
</g>
|
||||
</svg>
|
||||
{__('Welcome to')} ROTB! {__('This is file search engine based on the torrents from the internet')}.
|
||||
{__('Here you can easily find torrent or file that you intrested for')}. {__('We are not responsible for any content')}:
|
||||
{__('this is only information about content that collected automatically')}!
|
||||
</div>} />}
|
||||
>
|
||||
<div className='row header-row' style={{
|
||||
padding: '15px',
|
||||
background: `url('${Background}') no-repeat`,
|
||||
backgroundSize: 'cover',
|
||||
transition: '1s'
|
||||
}}>
|
||||
<RaisedButton
|
||||
label={__('Feed')}
|
||||
onClick={() => {
|
||||
window.router('/')
|
||||
}}
|
||||
backgroundColor='#69238c'
|
||||
labelColor='white'
|
||||
style={{height: 60, borderRadius: 6, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 28}} viewBox="0 0 64.051 64.051">
|
||||
<g>
|
||||
<path d="M8,0v2c16,0,31.173,7.065,41.472,19.386C57.567,31.065,62.051,43.358,62.051,56h2c0-13.11-4.649-25.858-13.044-35.897
|
||||
C40.326,7.327,25,0,8,0z"/>
|
||||
<path d="M50.769,56h2C52.769,31.343,33,11.282,8,11.282v2C32,13.282,50.769,32.445,50.769,56z"/>
|
||||
<path d="M8,22.564v2c17,0,31.486,14.102,31.486,31.436h2C41.486,37.563,26,22.564,8,22.564z"/>
|
||||
<path d="M30.205,56C30.205,43.784,20,33.846,8,33.846v2c11,0,20.205,9.041,20.205,20.154H30.205z"/>
|
||||
<path d="M16.103,56c0-4.439-3.612-8.051-8.052-8.051S0,51.561,0,56s3.611,8.051,8.051,8.051S16.103,60.439,16.103,56z M2,56
|
||||
c0-3.336,2.715-6.051,6.051-6.051c3.337,0,6.052,2.715,6.052,6.051s-2.715,6.051-6.052,6.051C4.715,62.051,2,59.336,2,56z"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Downloads')}
|
||||
onClick={() => {
|
||||
window.router('/downloads')
|
||||
}}
|
||||
backgroundColor='#2080E4'
|
||||
labelColor='white'
|
||||
style={{height: 60, borderRadius: 6, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 548.176 548.176">
|
||||
<path d="M524.326,297.352c-15.896-19.89-36.21-32.782-60.959-38.684c7.81-11.8,11.704-24.934,11.704-39.399
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Downloads')}
|
||||
onClick={() => {
|
||||
window.router('/downloads')
|
||||
}}
|
||||
backgroundColor='#2080E4'
|
||||
labelColor='white'
|
||||
style={{height: 60, borderRadius: 6, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 548.176 548.176">
|
||||
<path d="M524.326,297.352c-15.896-19.89-36.21-32.782-60.959-38.684c7.81-11.8,11.704-24.934,11.704-39.399
|
||||
c0-20.177-7.139-37.401-21.409-51.678c-14.273-14.272-31.498-21.411-51.675-21.411c-18.083,0-33.879,5.901-47.39,17.703
|
||||
c-11.225-27.41-29.171-49.393-53.817-65.95c-24.646-16.562-51.818-24.842-81.514-24.842c-40.349,0-74.802,14.279-103.353,42.83
|
||||
c-28.553,28.544-42.825,62.999-42.825,103.351c0,2.474,0.191,6.567,0.571,12.275c-22.459,10.469-40.349,26.171-53.676,47.106
|
||||
@ -206,82 +206,82 @@ class Header extends React.Component {
|
||||
c0-2.474,0.905-4.616,2.712-6.427c1.809-1.805,3.949-2.708,6.423-2.708h54.823c2.478,0,4.609,0.9,6.427,2.708
|
||||
c1.804,1.811,2.707,3.953,2.707,6.427v100.497h63.954c2.665,0,4.855,0.855,6.563,2.566c1.714,1.711,2.562,3.901,2.562,6.567
|
||||
C365.438,303.789,364.494,306.064,362.595,308.344z"/>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Top')}
|
||||
onClick={() => {
|
||||
window.router('/top')
|
||||
}}
|
||||
backgroundColor='#B1CE57'
|
||||
labelColor='white'
|
||||
style={{height: 60, width: 120, borderRadius: 5, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 284.929 284.929">
|
||||
<g>
|
||||
<path d="M17.128,167.872c1.903,1.902,4.093,2.854,6.567,2.854c2.474,0,4.664-0.952,6.567-2.854L142.466,55.666l112.208,112.206
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Top')}
|
||||
onClick={() => {
|
||||
window.router('/top')
|
||||
}}
|
||||
backgroundColor='#B1CE57'
|
||||
labelColor='white'
|
||||
style={{height: 60, width: 120, borderRadius: 5, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 284.929 284.929">
|
||||
<g>
|
||||
<path d="M17.128,167.872c1.903,1.902,4.093,2.854,6.567,2.854c2.474,0,4.664-0.952,6.567-2.854L142.466,55.666l112.208,112.206
|
||||
c1.902,1.902,4.093,2.854,6.563,2.854c2.478,0,4.668-0.952,6.57-2.854l14.274-14.277c1.902-1.902,2.847-4.093,2.847-6.563
|
||||
c0-2.475-0.951-4.665-2.847-6.567L149.028,7.419c-1.901-1.906-4.088-2.853-6.562-2.853s-4.665,0.95-6.567,2.853L2.856,140.464
|
||||
C0.95,142.367,0,144.554,0,147.034c0,2.468,0.953,4.658,2.856,6.561L17.128,167.872z"/>
|
||||
<path d="M149.028,117.055c-1.901-1.906-4.088-2.856-6.562-2.856s-4.665,0.953-6.567,2.856L2.856,250.1
|
||||
<path d="M149.028,117.055c-1.901-1.906-4.088-2.856-6.562-2.856s-4.665,0.953-6.567,2.856L2.856,250.1
|
||||
C0.95,252.003,0,254.192,0,256.67c0,2.472,0.953,4.661,2.856,6.564l14.272,14.276c1.903,1.903,4.093,2.848,6.567,2.848
|
||||
c2.474,0,4.664-0.951,6.567-2.848l112.204-112.209l112.208,112.209c1.902,1.903,4.093,2.852,6.563,2.852
|
||||
c2.478,0,4.668-0.948,6.57-2.852l14.274-14.276c1.902-1.903,2.847-4.093,2.847-6.564c0-2.478-0.951-4.667-2.847-6.57
|
||||
L149.028,117.055z"/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Activity')}
|
||||
onClick={() => {
|
||||
window.router('/activity')
|
||||
}}
|
||||
backgroundColor='#2a5cba'
|
||||
labelColor='white'
|
||||
style={{height: 60, width: 150, borderRadius: 5, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 352.352 352.352">
|
||||
<g>
|
||||
<path d="M255.432,37.172c-7.956-15.3-20.808-28.152-36.107-36.108c-4.284-2.448-10.404-0.612-11.628,4.896
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<RaisedButton
|
||||
label={__('Activity')}
|
||||
onClick={() => {
|
||||
window.router('/activity')
|
||||
}}
|
||||
backgroundColor='#2a5cba'
|
||||
labelColor='white'
|
||||
style={{height: 60, width: 150, borderRadius: 5, margin: 5, zIndex: 1}}
|
||||
buttonStyle={{borderRadius: 5}}
|
||||
icon={<svg fill='white' style={{height: 30}} viewBox="0 0 352.352 352.352">
|
||||
<g>
|
||||
<path d="M255.432,37.172c-7.956-15.3-20.808-28.152-36.107-36.108c-4.284-2.448-10.404-0.612-11.628,4.896
|
||||
c-1.225,4.284-3.061,8.568-4.896,12.24C153.84-4.444,95.699,20.036,58.979,54.308c-41.616,39.168-62.424,102.816-45.9,157.896
|
||||
c1.837,7.344,12.24,4.283,11.017-3.061c-7.956-51.408,6.12-99.756,40.392-138.924c37.332-42.228,82.008-45.9,133.416-40.392
|
||||
c-1.224,3.672-1.836,7.344-1.836,11.016c0,3.06,1.225,4.896,3.673,5.508c0,1.224,0,3.06,0.611,4.284
|
||||
c3.672,7.956,12.853,6.732,20.196,5.508c11.016-1.224,22.644-3.672,32.436-8.568C256.656,45.74,257.268,40.231,255.432,37.172z
|
||||
M210.144,40.844c-0.611,0-1.224,0-2.447,0c1.224-7.344,5.508-14.688,9.791-22.032c7.345,4.896,13.465,11.016,18.973,18.36
|
||||
c-5.508,1.836-11.017,2.448-16.524,3.06C216.876,40.844,213.204,40.844,210.144,40.844z"/>
|
||||
<path d="M297.048,318.08c58.752-74.664,80.172-204.408-9.18-265.608c-5.509-3.672-11.628,4.896-6.732,9.18
|
||||
<path d="M297.048,318.08c58.752-74.664,80.172-204.408-9.18-265.608c-5.509-3.672-11.628,4.896-6.732,9.18
|
||||
c71.604,67.32,63.036,173.196,4.896,246.636c-1.836-1.837-4.284-3.061-6.12-4.284c0-6.12-7.956-11.017-12.853-5.508
|
||||
c-11.016,12.239-14.688,27.539-18.972,43.451c-1.224,4.896,2.448,10.404,7.956,10.404c17.136,0,34.884-3.672,50.796-11.016
|
||||
c4.284-2.448,4.896-9.181,1.836-12.24C303.78,324.812,300.72,321.752,297.048,318.08z M273.18,314.407
|
||||
c5.508,4.896,10.404,10.404,15.3,15.912c-7.344,2.448-15.3,3.672-23.256,4.896C267.06,327.872,269.508,320.527,273.18,314.407z"/>
|
||||
<path d="M219.936,321.14c-36.72,14.076-63.648,15.912-100.979-0.612c-27.54-12.239-51.408-31.212-71.604-52.02
|
||||
<path d="M219.936,321.14c-36.72,14.076-63.648,15.912-100.979-0.612c-27.54-12.239-51.408-31.212-71.604-52.02
|
||||
c4.896-3.672,9.792-7.344,15.3-11.016c4.896-3.673,4.896-9.793,0-13.465c-13.464-9.18-29.376-16.523-45.288-20.808
|
||||
c-4.284-1.224-8.567,1.224-9.792,5.508c-3.06,11.017-4.284,21.42-2.447,33.048c1.224,7.956,5.508,20.809,13.464,24.48
|
||||
c3.672,1.836,9.792,0,9.18-5.508l0,0c3.06-1.836,6.12-3.061,9.18-4.896c19.584,28.764,51.408,50.796,83.232,63.036
|
||||
c30.6,12.24,80.784,22.644,105.264-7.344C229.728,327.26,226.668,318.691,219.936,321.14z M21.035,260.552
|
||||
c-1.836-6.732-1.224-13.464,0-19.584c9.181,3.06,17.748,7.344,26.316,12.24c-6.732,6.731-14.688,11.628-22.644,17.136
|
||||
C23.483,266.06,21.647,263.611,21.035,260.552z"/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<div className='fs0-85 pad0-75 column search-panel' style={{
|
||||
marginLeft: 'auto',
|
||||
marginTop: '-10px',
|
||||
zIndex: 2
|
||||
}}>
|
||||
<Search />
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
<div className='fs0-85 pad0-75 column search-panel' style={{
|
||||
marginLeft: 'auto',
|
||||
marginTop: '-10px',
|
||||
zIndex: 2
|
||||
}}>
|
||||
<Search />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</CardMedia>
|
||||
</Card>
|
||||
<div className='clear-header-space' style={{transition: '1.0s'}} />
|
||||
</div>
|
||||
)
|
||||
</CardMedia>
|
||||
</Card>
|
||||
<div className='clear-header-space' style={{transition: '1.0s'}} />
|
||||
</div>
|
||||
)
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export {Header}
|
||||
|
@ -12,6 +12,6 @@ import './css/izi/animations.css';
|
||||
import './index.css';
|
||||
|
||||
ReactDOM.render(
|
||||
<App />,
|
||||
document.getElementById('mount-point')
|
||||
<App />,
|
||||
document.getElementById('mount-point')
|
||||
);
|
||||
|
@ -8,65 +8,65 @@ import MenuItem from 'material-ui/MenuItem';
|
||||
import Checkbox from 'material-ui/Checkbox';
|
||||
|
||||
export default class InputFilesFilter extends Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
files: this.props.value || { min: 0, max: 50 },
|
||||
enabled: false || this.props.enabled,
|
||||
filesMax: this.props.filesMax || 100 // 1mb
|
||||
}
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
if(val.filesMax && this.state.files.max > val.filesMax)
|
||||
val.files = {min: this.state.files.min, max: val.filesMax};
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
files: this.props.value || { min: 0, max: 50 },
|
||||
enabled: false || this.props.enabled,
|
||||
filesMax: this.props.filesMax || 100 // 1mb
|
||||
}
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
if(val.filesMax && this.state.files.max > val.filesMax)
|
||||
val.files = {min: this.state.files.min, max: val.filesMax};
|
||||
|
||||
if(val.filesMax && this.state.files.min > val.filesMax)
|
||||
val.files = {min: 0, max: val.files ? val.files.max || this.state.files.max : this.state.files.max };
|
||||
if(val.filesMax && this.state.files.min > val.filesMax)
|
||||
val.files = {min: 0, max: val.files ? val.files.max || this.state.files.max : this.state.files.max };
|
||||
|
||||
super.setState(val, () => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange({
|
||||
enabled: this.state.enabled,
|
||||
filesMax: this.state.filesMax,
|
||||
files: !this.state.enabled ? {min: 0, max: 0} : this.state.files
|
||||
})
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='filter-row row inline w100p'>
|
||||
<Checkbox
|
||||
label={__("Files filter")}
|
||||
checked={this.state.enabled}
|
||||
style={{width: 150, display: 'flex', minWidth: 130}}
|
||||
onCheck={() => this.setState({enabled: !this.state.enabled})}
|
||||
/>
|
||||
<div className='filter-control-row row inline w100p' style={{opacity: this.state.enabled ? 1 : 0.4, transition: '0.5s', paddingLeft: 9}}>
|
||||
<InputRange
|
||||
maxValue={this.state.filesMax}
|
||||
minValue={0}
|
||||
value={this.state.files}
|
||||
style={this.props.style}
|
||||
className={this.props.className}
|
||||
onChange={files => this.setState({ files })}
|
||||
/>
|
||||
<SelectField
|
||||
floatingLabelText={__('Size type')}
|
||||
value={this.state.filesMax}
|
||||
onChange={(event, index, value) => this.setState({filesMax: value})}
|
||||
className='filter-control-border'
|
||||
>
|
||||
<MenuItem value={10} primaryText={"10 " + __("Files or less")} />
|
||||
<MenuItem value={100} primaryText={"100 " + __("Files or less")} />
|
||||
<MenuItem value={1000} primaryText={"1000 " + __("Files or less")} />
|
||||
<MenuItem value={10000} primaryText={"10000 " + __("Files or less")} />
|
||||
<MenuItem value={100000} primaryText={"100000 " + __("Files or less")} />
|
||||
<MenuItem value={1000000} primaryText={"1000000 " + __("Files or less")} />
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
super.setState(val, () => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange({
|
||||
enabled: this.state.enabled,
|
||||
filesMax: this.state.filesMax,
|
||||
files: !this.state.enabled ? {min: 0, max: 0} : this.state.files
|
||||
})
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='filter-row row inline w100p'>
|
||||
<Checkbox
|
||||
label={__("Files filter")}
|
||||
checked={this.state.enabled}
|
||||
style={{width: 150, display: 'flex', minWidth: 130}}
|
||||
onCheck={() => this.setState({enabled: !this.state.enabled})}
|
||||
/>
|
||||
<div className='filter-control-row row inline w100p' style={{opacity: this.state.enabled ? 1 : 0.4, transition: '0.5s', paddingLeft: 9}}>
|
||||
<InputRange
|
||||
maxValue={this.state.filesMax}
|
||||
minValue={0}
|
||||
value={this.state.files}
|
||||
style={this.props.style}
|
||||
className={this.props.className}
|
||||
onChange={files => this.setState({ files })}
|
||||
/>
|
||||
<SelectField
|
||||
floatingLabelText={__('Size type')}
|
||||
value={this.state.filesMax}
|
||||
onChange={(event, index, value) => this.setState({filesMax: value})}
|
||||
className='filter-control-border'
|
||||
>
|
||||
<MenuItem value={10} primaryText={"10 " + __("Files or less")} />
|
||||
<MenuItem value={100} primaryText={"100 " + __("Files or less")} />
|
||||
<MenuItem value={1000} primaryText={"1000 " + __("Files or less")} />
|
||||
<MenuItem value={10000} primaryText={"10000 " + __("Files or less")} />
|
||||
<MenuItem value={100000} primaryText={"100000 " + __("Files or less")} />
|
||||
<MenuItem value={1000000} primaryText={"1000000 " + __("Files or less")} />
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -8,67 +8,67 @@ import MenuItem from 'material-ui/MenuItem';
|
||||
import Checkbox from 'material-ui/Checkbox';
|
||||
|
||||
export default class InputSize extends Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
size: this.props.value || { min: 0, max: 500 * 1024 },
|
||||
enabled: false || this.props.enabled,
|
||||
maxSize: this.props.maxSize || 1024 * 1024 // 1mb
|
||||
}
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
if(val.maxSize && this.state.size.max > val.maxSize)
|
||||
val.size = {min: this.state.size.min, max: val.maxSize};
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
size: this.props.value || { min: 0, max: 500 * 1024 },
|
||||
enabled: false || this.props.enabled,
|
||||
maxSize: this.props.maxSize || 1024 * 1024 // 1mb
|
||||
}
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
if(val.maxSize && this.state.size.max > val.maxSize)
|
||||
val.size = {min: this.state.size.min, max: val.maxSize};
|
||||
|
||||
if(val.maxSize && this.state.size.min > val.maxSize)
|
||||
val.size = {min: 0, max: val.size ? val.size.max || this.state.size.max : this.state.size.max };
|
||||
if(val.maxSize && this.state.size.min > val.maxSize)
|
||||
val.size = {min: 0, max: val.size ? val.size.max || this.state.size.max : this.state.size.max };
|
||||
|
||||
super.setState(val, () => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange({
|
||||
enabled: this.state.enabled,
|
||||
maxSize: this.state.maxSize,
|
||||
size: !this.state.enabled ? {min: 0, max: 0} : this.state.size
|
||||
})
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='filter-row row inline w100p'>
|
||||
<Checkbox
|
||||
label={__('Size filter')}
|
||||
checked={this.state.enabled}
|
||||
style={{width: 150, display: 'flex', minWidth: 130}}
|
||||
onCheck={() => this.setState({enabled: !this.state.enabled})}
|
||||
/>
|
||||
<div className='filter-control-row row inline w100p' style={{opacity: this.state.enabled ? 1 : 0.4, transition: '0.5s', paddingLeft: 9}}>
|
||||
<InputRange
|
||||
maxValue={this.state.maxSize}
|
||||
minValue={0}
|
||||
value={this.state.size}
|
||||
formatLabel={size => formatBytes(size)}
|
||||
style={this.props.style}
|
||||
className={this.props.className}
|
||||
onChange={size => this.setState({ size })}
|
||||
/>
|
||||
<SelectField
|
||||
floatingLabelText={__('Size type max')}
|
||||
value={this.state.maxSize}
|
||||
onChange={(event, index, value) => this.setState({maxSize: value})}
|
||||
className='filter-control-border'
|
||||
>
|
||||
<MenuItem value={1024} primaryText="KB" />
|
||||
<MenuItem value={1024 * 1024} primaryText="MB" />
|
||||
<MenuItem value={1024 * 1024 * 100} primaryText="100 MB" />
|
||||
<MenuItem value={1024 * 1024 * 1024} primaryText="GB" />
|
||||
<MenuItem value={10 * 1024 * 1024 * 1024} primaryText="10 GB" />
|
||||
<MenuItem value={100 * 1024 * 1024 * 1024} primaryText="100 GB" />
|
||||
<MenuItem value={1024 * 1024 * 1024 * 1024} primaryText="TB" />
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
super.setState(val, () => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange({
|
||||
enabled: this.state.enabled,
|
||||
maxSize: this.state.maxSize,
|
||||
size: !this.state.enabled ? {min: 0, max: 0} : this.state.size
|
||||
})
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='filter-row row inline w100p'>
|
||||
<Checkbox
|
||||
label={__('Size filter')}
|
||||
checked={this.state.enabled}
|
||||
style={{width: 150, display: 'flex', minWidth: 130}}
|
||||
onCheck={() => this.setState({enabled: !this.state.enabled})}
|
||||
/>
|
||||
<div className='filter-control-row row inline w100p' style={{opacity: this.state.enabled ? 1 : 0.4, transition: '0.5s', paddingLeft: 9}}>
|
||||
<InputRange
|
||||
maxValue={this.state.maxSize}
|
||||
minValue={0}
|
||||
value={this.state.size}
|
||||
formatLabel={size => formatBytes(size)}
|
||||
style={this.props.style}
|
||||
className={this.props.className}
|
||||
onChange={size => this.setState({ size })}
|
||||
/>
|
||||
<SelectField
|
||||
floatingLabelText={__('Size type max')}
|
||||
value={this.state.maxSize}
|
||||
onChange={(event, index, value) => this.setState({maxSize: value})}
|
||||
className='filter-control-border'
|
||||
>
|
||||
<MenuItem value={1024} primaryText="KB" />
|
||||
<MenuItem value={1024 * 1024} primaryText="MB" />
|
||||
<MenuItem value={1024 * 1024 * 100} primaryText="100 MB" />
|
||||
<MenuItem value={1024 * 1024 * 1024} primaryText="GB" />
|
||||
<MenuItem value={10 * 1024 * 1024 * 1024} primaryText="10 GB" />
|
||||
<MenuItem value={100 * 1024 * 1024 * 1024} primaryText="100 GB" />
|
||||
<MenuItem value={1024 * 1024 * 1024 * 1024} primaryText="TB" />
|
||||
</SelectField>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,84 +2,84 @@ import React, { Component } from 'react';
|
||||
import singleton from './singleton'
|
||||
|
||||
class PagesPie extends Component {
|
||||
pie = [];
|
||||
pie = [];
|
||||
|
||||
open(pages, params) {
|
||||
if (params && params.replace) {
|
||||
if (params.replace === 'all') {
|
||||
this.pie = [];
|
||||
} else
|
||||
if (params.replace === 'last') {
|
||||
this.pie.pop();
|
||||
}
|
||||
this.forceUpdate();
|
||||
delete params.replace;
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (Array.isArray(pages)) {
|
||||
for (let i in pages) {
|
||||
this.pie.push({
|
||||
Page: pages[i],
|
||||
params: params
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.pie.push({
|
||||
Page: pages,
|
||||
params: params
|
||||
});
|
||||
}
|
||||
this.forceUpdate();
|
||||
}, 0);
|
||||
}
|
||||
close(count) {
|
||||
if (count && typeof count === 'number') {
|
||||
for (let i = 0; i < count; i++) {
|
||||
this.pie.pop();
|
||||
}
|
||||
} else {
|
||||
this.pie.pop();
|
||||
}
|
||||
this.forceUpdate();
|
||||
}
|
||||
findOpened(windowType) {
|
||||
for (let i in this.refs) {
|
||||
if(this.refs[i] instanceof windowType)
|
||||
return this.refs[i];
|
||||
}
|
||||
}
|
||||
// ОТРИСОВКА
|
||||
render() {
|
||||
if (this.pie.length > 0) {
|
||||
return (
|
||||
<div
|
||||
className={'pie full-size ' + (this.props.className || '')}
|
||||
>
|
||||
{
|
||||
this.pie.map(({Page, params}, index) => {
|
||||
let focus = false;
|
||||
if (index === this.pie.length-1) {
|
||||
focus = true;
|
||||
}
|
||||
return (
|
||||
<Page
|
||||
focused={focus}
|
||||
closeHandler={() => { index> 0 ? this.close() : null}}
|
||||
index={index}
|
||||
key={index}
|
||||
ref={index}
|
||||
{...params}
|
||||
>
|
||||
</Page>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
open(pages, params) {
|
||||
if (params && params.replace) {
|
||||
if (params.replace === 'all') {
|
||||
this.pie = [];
|
||||
} else
|
||||
if (params.replace === 'last') {
|
||||
this.pie.pop();
|
||||
}
|
||||
this.forceUpdate();
|
||||
delete params.replace;
|
||||
}
|
||||
setTimeout(() => {
|
||||
if (Array.isArray(pages)) {
|
||||
for (let i in pages) {
|
||||
this.pie.push({
|
||||
Page: pages[i],
|
||||
params: params
|
||||
});
|
||||
}
|
||||
} else {
|
||||
this.pie.push({
|
||||
Page: pages,
|
||||
params: params
|
||||
});
|
||||
}
|
||||
this.forceUpdate();
|
||||
}, 0);
|
||||
}
|
||||
close(count) {
|
||||
if (count && typeof count === 'number') {
|
||||
for (let i = 0; i < count; i++) {
|
||||
this.pie.pop();
|
||||
}
|
||||
} else {
|
||||
this.pie.pop();
|
||||
}
|
||||
this.forceUpdate();
|
||||
}
|
||||
findOpened(windowType) {
|
||||
for (let i in this.refs) {
|
||||
if(this.refs[i] instanceof windowType)
|
||||
return this.refs[i];
|
||||
}
|
||||
}
|
||||
// ОТРИСОВКА
|
||||
render() {
|
||||
if (this.pie.length > 0) {
|
||||
return (
|
||||
<div
|
||||
className={'pie full-size ' + (this.props.className || '')}
|
||||
>
|
||||
{
|
||||
this.pie.map(({Page, params}, index) => {
|
||||
let focus = false;
|
||||
if (index === this.pie.length-1) {
|
||||
focus = true;
|
||||
}
|
||||
return (
|
||||
<Page
|
||||
focused={focus}
|
||||
closeHandler={() => { index> 0 ? this.close() : null}}
|
||||
index={index}
|
||||
key={index}
|
||||
ref={index}
|
||||
{...params}
|
||||
>
|
||||
</Page>
|
||||
)
|
||||
})
|
||||
}
|
||||
</div>
|
||||
)
|
||||
} else {
|
||||
return null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export default singleton(PagesPie)
|
@ -8,152 +8,152 @@ import FlatButton from 'material-ui/FlatButton';
|
||||
import RefreshIndicator from 'material-ui/RefreshIndicator';
|
||||
|
||||
export default class RecentTorrents extends Component {
|
||||
constructor() {
|
||||
super()
|
||||
this.torrents = [];
|
||||
this.torrentsAssoc = {};
|
||||
this.displayQueue = [];
|
||||
this.displayQueueAssoc = {};
|
||||
this.maxQueueSize = 1000;
|
||||
this.maxDisplaySize = 10;
|
||||
this.state = {
|
||||
pause: false,
|
||||
searchingIndicator: false
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
window.torrentSocket.emit('recentTorrents', window.customLoader((data) => {
|
||||
if(data) {
|
||||
this.torrents = data;
|
||||
//this.forceUpdate(); // вызывается через searchingIndicator
|
||||
}
|
||||
constructor() {
|
||||
super()
|
||||
this.torrents = [];
|
||||
this.torrentsAssoc = {};
|
||||
this.displayQueue = [];
|
||||
this.displayQueueAssoc = {};
|
||||
this.maxQueueSize = 1000;
|
||||
this.maxDisplaySize = 10;
|
||||
this.state = {
|
||||
pause: false,
|
||||
searchingIndicator: false
|
||||
}
|
||||
}
|
||||
componentDidMount() {
|
||||
window.torrentSocket.emit('recentTorrents', window.customLoader((data) => {
|
||||
if(data) {
|
||||
this.torrents = data;
|
||||
//this.forceUpdate(); // вызывается через searchingIndicator
|
||||
}
|
||||
|
||||
this.displayNewTorrent = () => {
|
||||
if(!this.displayNewTorrent) {
|
||||
return;
|
||||
}
|
||||
this.displayNewTorrent = () => {
|
||||
if(!this.displayNewTorrent) {
|
||||
return;
|
||||
}
|
||||
|
||||
if(this.displayQueue.length == 0) {
|
||||
setTimeout(this.displayNewTorrent, 1000);
|
||||
return;
|
||||
}
|
||||
if(this.displayQueue.length == 0) {
|
||||
setTimeout(this.displayNewTorrent, 1000);
|
||||
return;
|
||||
}
|
||||
|
||||
const speed = 850;
|
||||
const speed = 850;
|
||||
|
||||
if(this.state.pause) {
|
||||
setTimeout(this.displayNewTorrent, speed);
|
||||
return;
|
||||
}
|
||||
if(this.state.pause) {
|
||||
setTimeout(this.displayNewTorrent, speed);
|
||||
return;
|
||||
}
|
||||
|
||||
let torrent = this.displayQueue.shift();
|
||||
this.torrents.unshift(torrent);
|
||||
this.torrentsAssoc[torrent.hash] = torrent;
|
||||
if(this.torrents.length > this.maxDisplaySize) {
|
||||
let toDelete = this.torrents.pop()
|
||||
delete this.torrentsAssoc[toDelete.hash];
|
||||
delete this.displayQueueAssoc[toDelete.hash];
|
||||
}
|
||||
this.displayTorrentCounterValue = this.displayQueue.length;
|
||||
let torrent = this.displayQueue.shift();
|
||||
this.torrents.unshift(torrent);
|
||||
this.torrentsAssoc[torrent.hash] = torrent;
|
||||
if(this.torrents.length > this.maxDisplaySize) {
|
||||
let toDelete = this.torrents.pop()
|
||||
delete this.torrentsAssoc[toDelete.hash];
|
||||
delete this.displayQueueAssoc[toDelete.hash];
|
||||
}
|
||||
this.displayTorrentCounterValue = this.displayQueue.length;
|
||||
|
||||
this.forceUpdate();
|
||||
setTimeout(this.displayNewTorrent, speed);
|
||||
}
|
||||
this.displayNewTorrent();
|
||||
this.forceUpdate();
|
||||
setTimeout(this.displayNewTorrent, speed);
|
||||
}
|
||||
this.displayNewTorrent();
|
||||
|
||||
this.displayTorrentCounterValue = 0;
|
||||
this.displayTorrentCounter = setInterval(() => {
|
||||
if(this.displayTorrentCounterValue != this.displayQueue.length) {
|
||||
this.displayTorrentCounterValue = this.displayQueue.length;
|
||||
this.forceUpdate();
|
||||
}
|
||||
}, 40);
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}));
|
||||
this.newTorrentFunc = (torrent) => {
|
||||
if(this.displayQueue.length < this.maxQueueSize) {
|
||||
this.displayQueue.push(torrent);
|
||||
this.displayQueueAssoc[torrent.hash] = torrent;
|
||||
}
|
||||
};
|
||||
window.torrentSocket.on('newTorrent', this.newTorrentFunc);
|
||||
this.displayTorrentCounterValue = 0;
|
||||
this.displayTorrentCounter = setInterval(() => {
|
||||
if(this.displayTorrentCounterValue != this.displayQueue.length) {
|
||||
this.displayTorrentCounterValue = this.displayQueue.length;
|
||||
this.forceUpdate();
|
||||
}
|
||||
}, 40);
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}));
|
||||
this.newTorrentFunc = (torrent) => {
|
||||
if(this.displayQueue.length < this.maxQueueSize) {
|
||||
this.displayQueue.push(torrent);
|
||||
this.displayQueueAssoc[torrent.hash] = torrent;
|
||||
}
|
||||
};
|
||||
window.torrentSocket.on('newTorrent', this.newTorrentFunc);
|
||||
|
||||
this.tracketUpdate = (statistic) => {
|
||||
if(statistic.hash in this.displayQueueAssoc)
|
||||
{
|
||||
Object.assign(this.displayQueueAssoc[statistic.hash], statistic);
|
||||
if(statistic.hash in this.torrentsAssoc) {
|
||||
this.forceUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
window.torrentSocket.on('trackerTorrentUpdate', this.tracketUpdate);
|
||||
}
|
||||
pauseAndContinue() {
|
||||
this.setState({
|
||||
pause: !this.state.pause
|
||||
});
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if(this.newTorrentFunc)
|
||||
window.torrentSocket.off('newTorrent', this.newTorrentFunc);
|
||||
if(this.tracketUpdate)
|
||||
window.torrentSocket.off('trackerTorrentUpdate', this.tracketUpdate);
|
||||
if(this.displayNewTorrent)
|
||||
delete this.displayNewTorrent;
|
||||
if(this.displayTorrentCounter)
|
||||
clearInterval(this.displayTorrentCounter);
|
||||
}
|
||||
render() {
|
||||
const style = {
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
this.tracketUpdate = (statistic) => {
|
||||
if(statistic.hash in this.displayQueueAssoc)
|
||||
{
|
||||
Object.assign(this.displayQueueAssoc[statistic.hash], statistic);
|
||||
if(statistic.hash in this.torrentsAssoc) {
|
||||
this.forceUpdate();
|
||||
}
|
||||
}
|
||||
}
|
||||
window.torrentSocket.on('trackerTorrentUpdate', this.tracketUpdate);
|
||||
}
|
||||
pauseAndContinue() {
|
||||
this.setState({
|
||||
pause: !this.state.pause
|
||||
});
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if(this.newTorrentFunc)
|
||||
window.torrentSocket.off('newTorrent', this.newTorrentFunc);
|
||||
if(this.tracketUpdate)
|
||||
window.torrentSocket.off('trackerTorrentUpdate', this.tracketUpdate);
|
||||
if(this.displayNewTorrent)
|
||||
delete this.displayNewTorrent;
|
||||
if(this.displayTorrentCounter)
|
||||
clearInterval(this.displayTorrentCounter);
|
||||
}
|
||||
render() {
|
||||
const style = {
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
|
||||
if(this.state.searchingIndicator) {
|
||||
return (
|
||||
<div className='pad1'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if(this.state.searchingIndicator) {
|
||||
return (
|
||||
<div className='pad1'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
if(!this.torrents || this.torrents.length == 0)
|
||||
return null;
|
||||
if(!this.torrents || this.torrents.length == 0)
|
||||
return null;
|
||||
|
||||
return (
|
||||
<List className='animated recent-torrents torrents-container'>
|
||||
<Subheader className='recent-title' inset={true}>
|
||||
<FlatButton style={{marginRight: '8px'}} primary={true} label={__('top')} labelStyle={{color: "#a4c639"}} onClick={() =>{
|
||||
window.router('/top');
|
||||
}} />
|
||||
<FlatButton style={{marginRight: '8px'}} label={!this.state.pause ? __('running') : __('stoped')} secondary={this.state.pause} primary={!this.state.pause} onClick={() =>{
|
||||
this.pauseAndContinue()
|
||||
}} />
|
||||
{__('Most recent torrents')}{this.displayQueue.length > 0 ? ` (${__('and')} ${this.displayQueue.length} ${__('more')})` : null}
|
||||
</Subheader>
|
||||
<Divider />
|
||||
{
|
||||
this.torrents.map((torrent, index) =>{
|
||||
return <TorrentLine key={index} torrent={torrent} />;
|
||||
})
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
return (
|
||||
<List className='animated recent-torrents torrents-container'>
|
||||
<Subheader className='recent-title' inset={true}>
|
||||
<FlatButton style={{marginRight: '8px'}} primary={true} label={__('top')} labelStyle={{color: "#a4c639"}} onClick={() =>{
|
||||
window.router('/top');
|
||||
}} />
|
||||
<FlatButton style={{marginRight: '8px'}} label={!this.state.pause ? __('running') : __('stoped')} secondary={this.state.pause} primary={!this.state.pause} onClick={() =>{
|
||||
this.pauseAndContinue()
|
||||
}} />
|
||||
{__('Most recent torrents')}{this.displayQueue.length > 0 ? ` (${__('and')} ${this.displayQueue.length} ${__('more')})` : null}
|
||||
</Subheader>
|
||||
<Divider />
|
||||
{
|
||||
this.torrents.map((torrent, index) =>{
|
||||
return <TorrentLine key={index} torrent={torrent} />;
|
||||
})
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -9,105 +9,105 @@
|
||||
// This link also includes instructions on opting out of this behavior.
|
||||
|
||||
const isLocalhost = Boolean(
|
||||
window.location.hostname === 'localhost' ||
|
||||
window.location.hostname === 'localhost' ||
|
||||
// [::1] is the IPv6 localhost address.
|
||||
window.location.hostname === '[::1]' ||
|
||||
// 127.0.0.1/8 is considered localhost for IPv4.
|
||||
window.location.hostname.match(
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/
|
||||
)
|
||||
);
|
||||
|
||||
export default function register() {
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {
|
||||
// The URL constructor is available in all browsers that support SW.
|
||||
const publicUrl = new URL(process.env.PUBLIC_URL, window.location);
|
||||
if (publicUrl.origin !== window.location.origin) {
|
||||
// Our service worker won't work if PUBLIC_URL is on a different origin
|
||||
// from what our page is served on. This might happen if a CDN is used to
|
||||
// serve assets; see https://github.com/facebookincubator/create-react-app/issues/2374
|
||||
return;
|
||||
}
|
||||
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
window.addEventListener('load', () => {
|
||||
const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;
|
||||
|
||||
if (!isLocalhost) {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
} else {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
if (!isLocalhost) {
|
||||
// Is not local host. Just register service worker
|
||||
registerValidSW(swUrl);
|
||||
} else {
|
||||
// This is running on localhost. Lets check if a service worker still exists or not.
|
||||
checkValidServiceWorker(swUrl);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
function registerValidSW(swUrl) {
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
navigator.serviceWorker
|
||||
.register(swUrl)
|
||||
.then(registration => {
|
||||
registration.onupdatefound = () => {
|
||||
const installingWorker = registration.installing;
|
||||
installingWorker.onstatechange = () => {
|
||||
if (installingWorker.state === 'installed') {
|
||||
if (navigator.serviceWorker.controller) {
|
||||
// At this point, the old content will have been purged and
|
||||
// the fresh content will have been added to the cache.
|
||||
// It's the perfect time to display a "New content is
|
||||
// available; please refresh." message in your web app.
|
||||
console.log('New content is available; please refresh.');
|
||||
} else {
|
||||
// At this point, everything has been precached.
|
||||
// It's the perfect time to display a
|
||||
// "Content is cached for offline use." message.
|
||||
console.log('Content is cached for offline use.');
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
})
|
||||
.catch(error => {
|
||||
console.error('Error during service worker registration:', error);
|
||||
});
|
||||
}
|
||||
|
||||
function checkValidServiceWorker(swUrl) {
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
// Check if the service worker can be found. If it can't reload the page.
|
||||
fetch(swUrl)
|
||||
.then(response => {
|
||||
// Ensure service worker exists, and that we really are getting a JS file.
|
||||
if (
|
||||
response.status === 404 ||
|
||||
response.headers.get('content-type').indexOf('javascript') === -1
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
) {
|
||||
// No service worker found. Probably a different app. Reload the page.
|
||||
navigator.serviceWorker.ready.then(registration => {
|
||||
registration.unregister().then(() => {
|
||||
window.location.reload();
|
||||
});
|
||||
});
|
||||
} else {
|
||||
// Service worker found. Proceed as normal.
|
||||
registerValidSW(swUrl);
|
||||
}
|
||||
})
|
||||
.catch(() => {
|
||||
console.log(
|
||||
'No internet connection found. App is running in offline mode.'
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
export function unregister() {
|
||||
if ('serviceWorker' in navigator) {
|
||||
return navigator.serviceWorker.ready.then(registration => {
|
||||
console.log("Unregister service worker");
|
||||
return registration.unregister();
|
||||
});
|
||||
} else {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve();
|
||||
})
|
||||
}
|
||||
if ('serviceWorker' in navigator) {
|
||||
return navigator.serviceWorker.ready.then(registration => {
|
||||
console.log("Unregister service worker");
|
||||
return registration.unregister();
|
||||
});
|
||||
} else {
|
||||
return new Promise(function(resolve, reject) {
|
||||
resolve();
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -31,7 +31,7 @@ const router = (page, callback) => {
|
||||
params[pg.args[i]] = p[i]
|
||||
}
|
||||
console.log(params)
|
||||
|
||||
|
||||
pg.callback({
|
||||
params
|
||||
})
|
||||
|
@ -5,52 +5,52 @@ import InputSize from './input-size';
|
||||
import FilesFilterInput from './input-files-filter';
|
||||
|
||||
export default class AdvancedSearchControl extends Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
type: undefined,
|
||||
size: {min: 0, max: 0},
|
||||
maxSize: 1024 * 1024 * 1024,
|
||||
sizeEnabled: false,
|
||||
filesEnabled: false,
|
||||
files: {min: 0, max: 0},
|
||||
filesMax: 100,
|
||||
}
|
||||
if(this.props.state)
|
||||
this.state = Object.assign(this.state, this.props.state)
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
super.setState(val, (v) => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange(this.state)
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='column w100p' style={{maxWidth: 750, overflow: 'hidden', padding: '0px 18px 15px', background: 'white', borderRadius: 3}}>
|
||||
<SelectField
|
||||
floatingLabelText={__('Filter content type')}
|
||||
value={this.state.type}
|
||||
onChange={(event, index, value) => this.setState({type: value})}
|
||||
>
|
||||
<MenuItem value={undefined} primaryText="" />
|
||||
<MenuItem value='video' primaryText={__('Video')} />
|
||||
<MenuItem value='audio' primaryText={__('Audio')} />
|
||||
<MenuItem value='pictures' primaryText={__('Pictures')} />
|
||||
<MenuItem value='books' primaryText={__('Books')} />
|
||||
<MenuItem value='application' primaryText={__('Applications')} />
|
||||
<MenuItem value='archive' primaryText={__('Archives')} />
|
||||
<MenuItem value='disc' primaryText={__('Disk Images')} />
|
||||
</SelectField>
|
||||
<div className='w100p'>
|
||||
<InputSize value={this.state.size} enabled={this.state.sizeEnabled} maxSize={this.state.maxSize} onChange={({size, maxSize, enabled}) => this.setState({size, maxSize, sizeEnabled: enabled})} />
|
||||
</div>
|
||||
<div className='w100p'>
|
||||
<FilesFilterInput value={this.state.files} filesMax={this.state.filesMax} enabled={this.state.filesEnabled} onChange={({files, filesMax, enabled}) => this.setState({files, filesMax, filesEnabled: enabled})} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.state = {
|
||||
type: undefined,
|
||||
size: {min: 0, max: 0},
|
||||
maxSize: 1024 * 1024 * 1024,
|
||||
sizeEnabled: false,
|
||||
filesEnabled: false,
|
||||
files: {min: 0, max: 0},
|
||||
filesMax: 100,
|
||||
}
|
||||
if(this.props.state)
|
||||
this.state = Object.assign(this.state, this.props.state)
|
||||
}
|
||||
setState(val)
|
||||
{
|
||||
super.setState(val, (v) => {
|
||||
if(this.props.onChange)
|
||||
this.props.onChange(this.state)
|
||||
})
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div className='column w100p' style={{maxWidth: 750, overflow: 'hidden', padding: '0px 18px 15px', background: 'white', borderRadius: 3}}>
|
||||
<SelectField
|
||||
floatingLabelText={__('Filter content type')}
|
||||
value={this.state.type}
|
||||
onChange={(event, index, value) => this.setState({type: value})}
|
||||
>
|
||||
<MenuItem value={undefined} primaryText="" />
|
||||
<MenuItem value='video' primaryText={__('Video')} />
|
||||
<MenuItem value='audio' primaryText={__('Audio')} />
|
||||
<MenuItem value='pictures' primaryText={__('Pictures')} />
|
||||
<MenuItem value='books' primaryText={__('Books')} />
|
||||
<MenuItem value='application' primaryText={__('Applications')} />
|
||||
<MenuItem value='archive' primaryText={__('Archives')} />
|
||||
<MenuItem value='disc' primaryText={__('Disk Images')} />
|
||||
</SelectField>
|
||||
<div className='w100p'>
|
||||
<InputSize value={this.state.size} enabled={this.state.sizeEnabled} maxSize={this.state.maxSize} onChange={({size, maxSize, enabled}) => this.setState({size, maxSize, sizeEnabled: enabled})} />
|
||||
</div>
|
||||
<div className='w100p'>
|
||||
<FilesFilterInput value={this.state.files} filesMax={this.state.filesMax} enabled={this.state.filesEnabled} onChange={({files, filesMax, enabled}) => this.setState({files, filesMax, filesEnabled: enabled})} />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -7,130 +7,130 @@ import Divider from 'material-ui/Divider';
|
||||
import LinearProgress from 'material-ui/LinearProgress';
|
||||
|
||||
export default class SearchResults extends Component {
|
||||
render() {
|
||||
return (
|
||||
<List style={{minWidth: '20em'}}>
|
||||
{
|
||||
(this.props.torrentsSearchResults && this.props.torrentsSearchResults.length > 0)
|
||||
|| (this.props.filesSearchResults && this.props.filesSearchResults.length > 0)
|
||||
?
|
||||
<div>
|
||||
<Subheader className='row center w100p' style={{paddingLeft: 0}} inset={true}><span>{__('Search results for')}</span> <span style={{marginLeft: '0.4em'}}><b>{this.props.searchText}</b></span></Subheader>
|
||||
<div className='w100p row center' style={{marginTop: '-16px'}}>{this.props.resultSelector}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.torrentsSearchResults && this.props.torrentsSearchResults.length > 0
|
||||
?
|
||||
this.props.torrentsSearchResults.map((torrent, index) =>{
|
||||
return(
|
||||
<TorrentLine torrent={torrent} key={index} />
|
||||
);
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreTorrentsEnabled && !this.props.moreTorrentsIndicator
|
||||
?
|
||||
<div>
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={<span>{__('More Torrents')}</span>} onClick={() => {
|
||||
if(this.props.onMoreTorrents)
|
||||
this.props.onMoreTorrents();
|
||||
}} />
|
||||
<Divider />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreTorrentsIndicator
|
||||
?
|
||||
<div style={{padding: '0.8em'}}>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.filesSearchResults && this.props.filesSearchResults.length > 0
|
||||
?
|
||||
this.props.filesSearchResults.map((torrent, index) =>{
|
||||
return(
|
||||
<TorrentLine torrent={torrent} key={index} />
|
||||
);
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreFilesEnabled && !this.props.moreFilesIndicator
|
||||
?
|
||||
<div>
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={__('More Files')} onClick={() => {
|
||||
if(this.props.onMoreFiles)
|
||||
this.props.onMoreFiles();
|
||||
}} />
|
||||
<Divider />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreFilesIndicator
|
||||
?
|
||||
<div style={{padding: '0.8em'}}>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.torrentsSearchResults && this.props.torrentsSearchResults.length == 0
|
||||
&& this.props.filesSearchResults && this.props.filesSearchResults.length == 0
|
||||
&& !this.props.currentSearching
|
||||
?
|
||||
<div className='row inline center w100p pad0-75'>
|
||||
<svg style={{fill: 'grey', height: '30px'}} viewBox="0 0 264.695 264.695">
|
||||
<g>
|
||||
<path d="M219.171,216.785c-4.762,0-10.322,2.3-16.672,6.881l-35.211-12.968l35.734-12.978
|
||||
c6.003,3.888,11.558,5.833,16.682,5.833c5.639,0,9.347-2.917,11.117-8.733c0.351-1.235,0.527-2.57,0.527-3.981
|
||||
c0-7.397-4.766-11.378-14.295-11.9c3.876-3.882,5.828-7.687,5.828-11.392c0-3.871-2.039-7.149-6.092-9.797
|
||||
c-2.118-1.049-4.325-1.584-6.615-1.584c-7.769,0-13.064,6.258-15.887,18.797l-61.941,23.039l-61.94-22.504
|
||||
c-2.823-12.885-8.125-19.332-15.885-19.332c-2.293,0-4.501,0.535-6.62,1.584c-3.876,2.647-5.82,5.926-5.82,9.797
|
||||
c0,3.705,1.944,7.51,5.82,11.392c-9.701,0.522-14.555,4.503-14.555,11.901c0,1.41,0.179,2.746,0.526,3.98
|
||||
c1.946,5.816,5.651,8.733,11.122,8.733c5.113,0,10.671-1.945,16.677-5.832l35.998,12.977l-35.476,12.698
|
||||
c-6.175-4.406-11.637-6.611-16.402-6.611c-5.654,0-9.623,2.918-11.919,8.733c-0.348,1.235-0.526,2.553-0.526,3.975
|
||||
c0,7.405,4.853,11.385,14.555,11.907c-3.876,3.883-5.82,7.688-5.82,11.393c0,3.869,1.944,7.134,5.82,9.797
|
||||
c2.477,1.412,4.854,2.105,7.153,2.105c7.227,0,12.443-6.176,15.619-18.525l61.673-22.504l61.678,22.504
|
||||
c3.178,12.35,8.475,18.525,15.882,18.525c2.121,0,4.407-0.693,6.884-2.105c4.052-2.663,6.092-5.928,6.092-9.797
|
||||
c0-3.705-1.953-7.51-5.828-11.393c9.528-0.522,14.295-4.502,14.295-11.907c0-1.422-0.177-2.739-0.527-3.975
|
||||
C228.702,219.702,224.82,216.785,219.171,216.785z"/>
|
||||
<path d="M48.436,128.904c9.703,11.114,23.379,19.242,41.035,24.346v3.986c0,4.936,1.672,9.086,5.025,12.433
|
||||
c3.35,3.358,7.498,5.211,12.441,5.563c5.116,0.357,8.905-0.528,11.378-2.646c3.879,2.817,8.204,4.229,12.974,4.229
|
||||
c4.41,0,8.474-1.316,12.175-3.963c2.471,1.934,6.087,2.738,10.856,2.381c4.937-0.528,9.089-2.426,12.44-5.689
|
||||
c3.35-3.281,5.025-7.371,5.025-12.307v-2.91c19.057-4.945,33.795-13.237,44.21-24.898c10.059-11.109,15.087-24.253,15.087-39.435
|
||||
c0-3.359-0.355-6.886-1.063-10.597c-3.525-22.571-13.938-41.201-31.229-55.844C180.612,7.856,158.464,0,132.347,0
|
||||
c-26.123,0-48.27,7.767-66.44,23.282C48.61,38.118,38.289,56.825,34.937,79.396c-0.709,3.711-1.064,7.238-1.064,10.597
|
||||
C33.873,104.817,38.724,117.778,48.436,128.904L48.436,128.904z M152.865,60.749c5.206-6.085,11.514-9.13,18.922-9.13
|
||||
c7.592,0,13.986,3.045,19.194,9.13c5.2,6.076,7.81,13.446,7.81,22.087c0,8.649-2.609,16.021-7.81,22.108
|
||||
c-5.208,6.097-11.603,9.13-19.194,9.13c-7.408,0-13.716-3.033-18.922-9.13c-5.211-6.087-7.814-13.459-7.814-22.108
|
||||
C145.05,74.195,147.654,66.825,152.865,60.749z M124.805,121.428c2.556-3.307,5.065-4.968,7.542-4.968
|
||||
c2.47,0,4.802,1.831,7.012,5.509c2.205,3.662,3.317,7.145,3.317,10.469c0,5.062-3.361,7.581-10.067,7.581
|
||||
c-4.414,0-7.677-1.136-9.792-3.396c-1.237-1.411-1.849-3.147-1.849-5.249C120.969,128.065,122.245,124.752,124.805,121.428z
|
||||
M71.465,60.749c5.295-6.085,11.65-9.13,19.059-9.13c7.406,0,13.762,3.045,19.06,9.13c5.296,6.076,7.948,13.446,7.948,22.087
|
||||
c0,8.649-2.651,16.021-7.948,22.108c-5.297,6.097-11.654,9.13-19.06,9.13c-7.409,0-13.764-3.033-19.059-9.13
|
||||
c-5.292-6.087-7.944-13.459-7.944-22.108C63.521,74.195,66.173,66.825,71.465,60.749z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div className='fs0-85 pad0-75' style={{color: 'grey'}}>{__('no torrents for')} <b>{this.props.searchText}</b> {__('were found')}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<List style={{minWidth: '20em'}}>
|
||||
{
|
||||
(this.props.torrentsSearchResults && this.props.torrentsSearchResults.length > 0)
|
||||
|| (this.props.filesSearchResults && this.props.filesSearchResults.length > 0)
|
||||
?
|
||||
<div>
|
||||
<Subheader className='row center w100p' style={{paddingLeft: 0}} inset={true}><span>{__('Search results for')}</span> <span style={{marginLeft: '0.4em'}}><b>{this.props.searchText}</b></span></Subheader>
|
||||
<div className='w100p row center' style={{marginTop: '-16px'}}>{this.props.resultSelector}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.torrentsSearchResults && this.props.torrentsSearchResults.length > 0
|
||||
?
|
||||
this.props.torrentsSearchResults.map((torrent, index) =>{
|
||||
return(
|
||||
<TorrentLine torrent={torrent} key={index} />
|
||||
);
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreTorrentsEnabled && !this.props.moreTorrentsIndicator
|
||||
?
|
||||
<div>
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={<span>{__('More Torrents')}</span>} onClick={() => {
|
||||
if(this.props.onMoreTorrents)
|
||||
this.props.onMoreTorrents();
|
||||
}} />
|
||||
<Divider />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreTorrentsIndicator
|
||||
?
|
||||
<div style={{padding: '0.8em'}}>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.filesSearchResults && this.props.filesSearchResults.length > 0
|
||||
?
|
||||
this.props.filesSearchResults.map((torrent, index) =>{
|
||||
return(
|
||||
<TorrentLine torrent={torrent} key={index} />
|
||||
);
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreFilesEnabled && !this.props.moreFilesIndicator
|
||||
?
|
||||
<div>
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={__('More Files')} onClick={() => {
|
||||
if(this.props.onMoreFiles)
|
||||
this.props.onMoreFiles();
|
||||
}} />
|
||||
<Divider />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.moreFilesIndicator
|
||||
?
|
||||
<div style={{padding: '0.8em'}}>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
this.props.torrentsSearchResults && this.props.torrentsSearchResults.length == 0
|
||||
&& this.props.filesSearchResults && this.props.filesSearchResults.length == 0
|
||||
&& !this.props.currentSearching
|
||||
?
|
||||
<div className='row inline center w100p pad0-75'>
|
||||
<svg style={{fill: 'grey', height: '30px'}} viewBox="0 0 264.695 264.695">
|
||||
<g>
|
||||
<path d="M219.171,216.785c-4.762,0-10.322,2.3-16.672,6.881l-35.211-12.968l35.734-12.978
|
||||
c6.003,3.888,11.558,5.833,16.682,5.833c5.639,0,9.347-2.917,11.117-8.733c0.351-1.235,0.527-2.57,0.527-3.981
|
||||
c0-7.397-4.766-11.378-14.295-11.9c3.876-3.882,5.828-7.687,5.828-11.392c0-3.871-2.039-7.149-6.092-9.797
|
||||
c-2.118-1.049-4.325-1.584-6.615-1.584c-7.769,0-13.064,6.258-15.887,18.797l-61.941,23.039l-61.94-22.504
|
||||
c-2.823-12.885-8.125-19.332-15.885-19.332c-2.293,0-4.501,0.535-6.62,1.584c-3.876,2.647-5.82,5.926-5.82,9.797
|
||||
c0,3.705,1.944,7.51,5.82,11.392c-9.701,0.522-14.555,4.503-14.555,11.901c0,1.41,0.179,2.746,0.526,3.98
|
||||
c1.946,5.816,5.651,8.733,11.122,8.733c5.113,0,10.671-1.945,16.677-5.832l35.998,12.977l-35.476,12.698
|
||||
c-6.175-4.406-11.637-6.611-16.402-6.611c-5.654,0-9.623,2.918-11.919,8.733c-0.348,1.235-0.526,2.553-0.526,3.975
|
||||
c0,7.405,4.853,11.385,14.555,11.907c-3.876,3.883-5.82,7.688-5.82,11.393c0,3.869,1.944,7.134,5.82,9.797
|
||||
c2.477,1.412,4.854,2.105,7.153,2.105c7.227,0,12.443-6.176,15.619-18.525l61.673-22.504l61.678,22.504
|
||||
c3.178,12.35,8.475,18.525,15.882,18.525c2.121,0,4.407-0.693,6.884-2.105c4.052-2.663,6.092-5.928,6.092-9.797
|
||||
c0-3.705-1.953-7.51-5.828-11.393c9.528-0.522,14.295-4.502,14.295-11.907c0-1.422-0.177-2.739-0.527-3.975
|
||||
C228.702,219.702,224.82,216.785,219.171,216.785z"/>
|
||||
<path d="M48.436,128.904c9.703,11.114,23.379,19.242,41.035,24.346v3.986c0,4.936,1.672,9.086,5.025,12.433
|
||||
c3.35,3.358,7.498,5.211,12.441,5.563c5.116,0.357,8.905-0.528,11.378-2.646c3.879,2.817,8.204,4.229,12.974,4.229
|
||||
c4.41,0,8.474-1.316,12.175-3.963c2.471,1.934,6.087,2.738,10.856,2.381c4.937-0.528,9.089-2.426,12.44-5.689
|
||||
c3.35-3.281,5.025-7.371,5.025-12.307v-2.91c19.057-4.945,33.795-13.237,44.21-24.898c10.059-11.109,15.087-24.253,15.087-39.435
|
||||
c0-3.359-0.355-6.886-1.063-10.597c-3.525-22.571-13.938-41.201-31.229-55.844C180.612,7.856,158.464,0,132.347,0
|
||||
c-26.123,0-48.27,7.767-66.44,23.282C48.61,38.118,38.289,56.825,34.937,79.396c-0.709,3.711-1.064,7.238-1.064,10.597
|
||||
C33.873,104.817,38.724,117.778,48.436,128.904L48.436,128.904z M152.865,60.749c5.206-6.085,11.514-9.13,18.922-9.13
|
||||
c7.592,0,13.986,3.045,19.194,9.13c5.2,6.076,7.81,13.446,7.81,22.087c0,8.649-2.609,16.021-7.81,22.108
|
||||
c-5.208,6.097-11.603,9.13-19.194,9.13c-7.408,0-13.716-3.033-18.922-9.13c-5.211-6.087-7.814-13.459-7.814-22.108
|
||||
C145.05,74.195,147.654,66.825,152.865,60.749z M124.805,121.428c2.556-3.307,5.065-4.968,7.542-4.968
|
||||
c2.47,0,4.802,1.831,7.012,5.509c2.205,3.662,3.317,7.145,3.317,10.469c0,5.062-3.361,7.581-10.067,7.581
|
||||
c-4.414,0-7.677-1.136-9.792-3.396c-1.237-1.411-1.849-3.147-1.849-5.249C120.969,128.065,122.245,124.752,124.805,121.428z
|
||||
M71.465,60.749c5.295-6.085,11.65-9.13,19.059-9.13c7.406,0,13.762,3.045,19.06,9.13c5.296,6.076,7.948,13.446,7.948,22.087
|
||||
c0,8.649-2.651,16.021-7.948,22.108c-5.297,6.097-11.654,9.13-19.06,9.13c-7.409,0-13.764-3.033-19.059-9.13
|
||||
c-5.292-6.087-7.944-13.459-7.944-22.108C63.521,74.195,66.173,66.825,71.465,60.749z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div className='fs0-85 pad0-75' style={{color: 'grey'}}>{__('no torrents for')} <b>{this.props.searchText}</b> {__('were found')}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</List>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -17,332 +17,332 @@ import _ from 'lodash'
|
||||
import singleton from './singleton';
|
||||
|
||||
class Search extends Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.onSearchUpdate = () => {}
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
this.onSearchUpdate = () => {}
|
||||
|
||||
this.state = {
|
||||
searchingIndicator: false,
|
||||
safeSearchText: __('safe search enabled'),
|
||||
safeSearchColor: 'rgb(0, 188, 212)',
|
||||
moreTorrentsIndicator: false,
|
||||
moreFilesIndicator: false,
|
||||
orderBy: null,
|
||||
orderDesc: false,
|
||||
advancedSearch: false,
|
||||
}
|
||||
this.searchLimit = 10
|
||||
this.advanced = {}
|
||||
this.searchError = undefined;
|
||||
}
|
||||
this.state = {
|
||||
searchingIndicator: false,
|
||||
safeSearchText: __('safe search enabled'),
|
||||
safeSearchColor: 'rgb(0, 188, 212)',
|
||||
moreTorrentsIndicator: false,
|
||||
moreFilesIndicator: false,
|
||||
orderBy: null,
|
||||
orderDesc: false,
|
||||
advancedSearch: false,
|
||||
}
|
||||
this.searchLimit = 10
|
||||
this.advanced = {}
|
||||
this.searchError = undefined;
|
||||
}
|
||||
|
||||
search(oldSearch) {
|
||||
window.router('/')
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
this.onSearchUpdate('indicator')
|
||||
search(oldSearch) {
|
||||
window.router('/')
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
this.onSearchUpdate('indicator')
|
||||
|
||||
this.searchTorrents = [];
|
||||
this.moreSearchTorrents = true;
|
||||
this.searchFiles = [];
|
||||
this.moreSearchFiles = true;
|
||||
this.currentSearch = this.searchValue;
|
||||
let queries = 2;
|
||||
let searchTorrentsParams = {
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
};
|
||||
if(this.state.advancedSearch && this.advanced)
|
||||
searchTorrentsParams = Object.assign(searchTorrentsParams, this.advanced);
|
||||
this.searchTorrents = [];
|
||||
this.moreSearchTorrents = true;
|
||||
this.searchFiles = [];
|
||||
this.moreSearchFiles = true;
|
||||
this.currentSearch = this.searchValue;
|
||||
let queries = 2;
|
||||
let searchTorrentsParams = {
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
};
|
||||
if(this.state.advancedSearch && this.advanced)
|
||||
searchTorrentsParams = Object.assign(searchTorrentsParams, this.advanced);
|
||||
|
||||
window.torrentSocket.emit('searchTorrent', oldSearch ? this.currentSearch : this.searchValue, searchTorrentsParams, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchTorrents = torrents;
|
||||
if(torrents.length != this.searchLimit)
|
||||
this.moreSearchTorrents = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.moreSearchTorrents = false;
|
||||
}
|
||||
if(--queries == 0) {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}
|
||||
this.onSearchUpdate('torrents')
|
||||
}));
|
||||
let searchFilesParams = {
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
};
|
||||
if(this.state.advancedSearch && this.advanced)
|
||||
searchFilesParams = Object.assign(searchFilesParams, this.advanced);
|
||||
window.torrentSocket.emit('searchTorrent', oldSearch ? this.currentSearch : this.searchValue, searchTorrentsParams, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchTorrents = torrents;
|
||||
if(torrents.length != this.searchLimit)
|
||||
this.moreSearchTorrents = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.moreSearchTorrents = false;
|
||||
}
|
||||
if(--queries == 0) {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}
|
||||
this.onSearchUpdate('torrents')
|
||||
}));
|
||||
let searchFilesParams = {
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
};
|
||||
if(this.state.advancedSearch && this.advanced)
|
||||
searchFilesParams = Object.assign(searchFilesParams, this.advanced);
|
||||
|
||||
window.torrentSocket.emit('searchFiles', oldSearch ? this.currentSearch : this.searchValue, searchFilesParams, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchFiles = torrents;
|
||||
let files = 0;
|
||||
torrents.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
files += torrent.path.length
|
||||
});
|
||||
if(files != this.searchLimit)
|
||||
this.moreSearchFiles = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.moreSearchFiles = false;
|
||||
}
|
||||
if(--queries == 0) {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}
|
||||
this.onSearchUpdate('files')
|
||||
}));
|
||||
}
|
||||
moreTorrents() {
|
||||
this.setState({moreTorrentsIndicator: true});
|
||||
this.onSearchUpdate('indicator')
|
||||
window.torrentSocket.emit('searchFiles', oldSearch ? this.currentSearch : this.searchValue, searchFilesParams, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchFiles = torrents;
|
||||
let files = 0;
|
||||
torrents.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
files += torrent.path.length
|
||||
});
|
||||
if(files != this.searchLimit)
|
||||
this.moreSearchFiles = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
this.moreSearchFiles = false;
|
||||
}
|
||||
if(--queries == 0) {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}
|
||||
this.onSearchUpdate('files')
|
||||
}));
|
||||
}
|
||||
moreTorrents() {
|
||||
this.setState({moreTorrentsIndicator: true});
|
||||
this.onSearchUpdate('indicator')
|
||||
|
||||
window.torrentSocket.emit('searchTorrent', this.currentSearch, {
|
||||
index: this.searchTorrents.length,
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
}, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchTorrents = this.searchTorrents.concat(torrents);
|
||||
if(torrents.length != this.searchLimit)
|
||||
this.moreSearchTorrents = false;
|
||||
window.torrentSocket.emit('searchTorrent', this.currentSearch, {
|
||||
index: this.searchTorrents.length,
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
}, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchTorrents = this.searchTorrents.concat(torrents);
|
||||
if(torrents.length != this.searchLimit)
|
||||
this.moreSearchTorrents = false;
|
||||
|
||||
this.setState({moreTorrentsIndicator: false});
|
||||
this.onSearchUpdate('more torrents')
|
||||
}
|
||||
}));
|
||||
}
|
||||
calcTorrentsFiles(torrents)
|
||||
{
|
||||
let files = 0;
|
||||
torrents.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
files += torrent.path.length
|
||||
});
|
||||
return files
|
||||
}
|
||||
moreFiles() {
|
||||
let index = 0;
|
||||
this.searchFiles.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
index += torrent.path.length;
|
||||
});
|
||||
this.setState({moreTorrentsIndicator: false});
|
||||
this.onSearchUpdate('more torrents')
|
||||
}
|
||||
}));
|
||||
}
|
||||
calcTorrentsFiles(torrents)
|
||||
{
|
||||
let files = 0;
|
||||
torrents.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
files += torrent.path.length
|
||||
});
|
||||
return files
|
||||
}
|
||||
moreFiles() {
|
||||
let index = 0;
|
||||
this.searchFiles.forEach((torrent) => {
|
||||
if(torrent.path && torrent.path.length > 0)
|
||||
index += torrent.path.length;
|
||||
});
|
||||
|
||||
this.setState({moreFilesIndicator: true});
|
||||
this.onSearchUpdate('indicator')
|
||||
this.setState({moreFilesIndicator: true});
|
||||
this.onSearchUpdate('indicator')
|
||||
|
||||
window.torrentSocket.emit('searchFiles', this.currentSearch, {
|
||||
index: index,
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
}, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchFiles = this.searchFiles.concat(torrents);
|
||||
window.torrentSocket.emit('searchFiles', this.currentSearch, {
|
||||
index: index,
|
||||
limit: this.searchLimit,
|
||||
safeSearch: !this.notSafeSearch,
|
||||
orderBy: this.state.orderBy,
|
||||
orderDesc: this.state.orderDesc,
|
||||
}, window.customLoader((torrents) => {
|
||||
if(torrents) {
|
||||
this.searchFiles = this.searchFiles.concat(torrents);
|
||||
|
||||
if(this.calcTorrentsFiles(torrents) != this.searchLimit)
|
||||
this.moreSearchFiles = false;
|
||||
if(this.calcTorrentsFiles(torrents) != this.searchLimit)
|
||||
this.moreSearchFiles = false;
|
||||
|
||||
this.mergeFiles()
|
||||
this.mergeFiles()
|
||||
|
||||
this.setState({moreFilesIndicator: false});
|
||||
this.onSearchUpdate('more files')
|
||||
}
|
||||
}));
|
||||
}
|
||||
mergeFiles()
|
||||
{
|
||||
for(let i = 0; i < this.searchFiles.length; i++)
|
||||
{
|
||||
for(let j = i + 1; j < this.searchFiles.length; j++)
|
||||
{
|
||||
if(this.searchFiles[i].hash != this.searchFiles[j].hash)
|
||||
continue
|
||||
this.setState({moreFilesIndicator: false});
|
||||
this.onSearchUpdate('more files')
|
||||
}
|
||||
}));
|
||||
}
|
||||
mergeFiles()
|
||||
{
|
||||
for(let i = 0; i < this.searchFiles.length; i++)
|
||||
{
|
||||
for(let j = i + 1; j < this.searchFiles.length; j++)
|
||||
{
|
||||
if(this.searchFiles[i].hash != this.searchFiles[j].hash)
|
||||
continue
|
||||
|
||||
if(!this.searchFiles[i].remove)
|
||||
{
|
||||
this.searchFiles[i].path = this.searchFiles[i].path.concat(this.searchFiles[j].path)
|
||||
}
|
||||
if(!this.searchFiles[i].remove)
|
||||
{
|
||||
this.searchFiles[i].path = this.searchFiles[i].path.concat(this.searchFiles[j].path)
|
||||
}
|
||||
|
||||
this.searchFiles[j].remove = true
|
||||
}
|
||||
}
|
||||
this.searchFiles[j].remove = true
|
||||
}
|
||||
}
|
||||
|
||||
this.searchFiles = this.searchFiles.filter(torrent => !torrent.remove)
|
||||
}
|
||||
this.searchFiles = this.searchFiles.filter(torrent => !torrent.remove)
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.newStatisticFunc = (statistic) => {
|
||||
if(statistic) {
|
||||
this.stats = statistic;
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
window.torrentSocket.emit('statistic', window.customLoader(this.newStatisticFunc));
|
||||
window.torrentSocket.on('newStatistic', this.newStatisticFunc);
|
||||
componentDidMount() {
|
||||
this.newStatisticFunc = (statistic) => {
|
||||
if(statistic) {
|
||||
this.stats = statistic;
|
||||
this.forceUpdate();
|
||||
}
|
||||
};
|
||||
window.torrentSocket.emit('statistic', window.customLoader(this.newStatisticFunc));
|
||||
window.torrentSocket.on('newStatistic', this.newStatisticFunc);
|
||||
|
||||
this.remoteSearchTorrent = (torrents) => {
|
||||
if(!torrents)
|
||||
return
|
||||
this.remoteSearchTorrent = (torrents) => {
|
||||
if(!torrents)
|
||||
return
|
||||
|
||||
if(torrents.length === this.searchLimit)
|
||||
this.moreSearchTorrents = true;
|
||||
if(torrents.length === this.searchLimit)
|
||||
this.moreSearchTorrents = true;
|
||||
|
||||
this.searchTorrents = _.unionBy(this.searchTorrents, torrents, 'hash')
|
||||
this.onSearchUpdate('remote torrents')
|
||||
}
|
||||
window.torrentSocket.on('remoteSearchTorrent', this.remoteSearchTorrent);
|
||||
this.searchTorrents = _.unionBy(this.searchTorrents, torrents, 'hash')
|
||||
this.onSearchUpdate('remote torrents')
|
||||
}
|
||||
window.torrentSocket.on('remoteSearchTorrent', this.remoteSearchTorrent);
|
||||
|
||||
this.remoteSearchFiles = (torrents) => {
|
||||
if(!torrents)
|
||||
return
|
||||
this.remoteSearchFiles = (torrents) => {
|
||||
if(!torrents)
|
||||
return
|
||||
|
||||
if(torrents.length > 0 && this.calcTorrentsFiles(torrents) === this.searchLimit)
|
||||
this.moreSearchFiles = true;
|
||||
if(torrents.length > 0 && this.calcTorrentsFiles(torrents) === this.searchLimit)
|
||||
this.moreSearchFiles = true;
|
||||
|
||||
this.searchFiles = _.unionBy(this.searchFiles, torrents, 'hash')
|
||||
this.mergeFiles()
|
||||
this.onSearchUpdate('remote files')
|
||||
}
|
||||
window.torrentSocket.on('remoteSearchFiles', this.remoteSearchFiles);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.newStatisticFunc)
|
||||
window.torrentSocket.off('newStatistic', this.newStatisticFunc);
|
||||
this.searchFiles = _.unionBy(this.searchFiles, torrents, 'hash')
|
||||
this.mergeFiles()
|
||||
this.onSearchUpdate('remote files')
|
||||
}
|
||||
window.torrentSocket.on('remoteSearchFiles', this.remoteSearchFiles);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.newStatisticFunc)
|
||||
window.torrentSocket.off('newStatistic', this.newStatisticFunc);
|
||||
|
||||
if(this.remoteSearchTorrent)
|
||||
window.torrentSocket.off('remoteSearchTorrent', this.remoteSearchTorrent);
|
||||
if(this.remoteSearchTorrent)
|
||||
window.torrentSocket.off('remoteSearchTorrent', this.remoteSearchTorrent);
|
||||
|
||||
if(this.remoteSearchFiles)
|
||||
window.torrentSocket.off('remoteSearchFiles', this.remoteSearchFiles);
|
||||
}
|
||||
setSafeSearch(ch) {
|
||||
this.notSafeSearch = ch;
|
||||
if(ch)
|
||||
{
|
||||
return {safeSearchText: __('safe search disabled'), safeSearchColor: '#EC407A'}
|
||||
}
|
||||
else
|
||||
{
|
||||
return {safeSearchText: __('safe search enabled'), safeSearchColor: 'rgb(0, 188, 212)'}
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const style = {
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
if(this.remoteSearchFiles)
|
||||
window.torrentSocket.off('remoteSearchFiles', this.remoteSearchFiles);
|
||||
}
|
||||
setSafeSearch(ch) {
|
||||
this.notSafeSearch = ch;
|
||||
if(ch)
|
||||
{
|
||||
return {safeSearchText: __('safe search disabled'), safeSearchColor: '#EC407A'}
|
||||
}
|
||||
else
|
||||
{
|
||||
return {safeSearchText: __('safe search enabled'), safeSearchColor: 'rgb(0, 188, 212)'}
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const style = {
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="column w100p center">
|
||||
<div className='row inline w100p pad0-75 search-row' style={{minWidth: '35em', backgroundColor: 'white', paddingTop: 0, paddingBottom: this.searchError ? 17 : 0, margin: 5, borderRadius: 3}}>
|
||||
<TextField
|
||||
style={{marginTop: -12}}
|
||||
hintText={__('Search torrent or file')}
|
||||
floatingLabelText={__('What to search?')}
|
||||
fullWidth={true}
|
||||
ref='searchInput'
|
||||
defaultValue={this.searchValue}
|
||||
errorText={this.searchError}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.search();
|
||||
}
|
||||
}}
|
||||
onChange={e => {
|
||||
this.searchValue = e.target.value
|
||||
if(this.searchValue.length < 3 && this.searchValue.length > 0)
|
||||
this.searchError = __('too short string for search');
|
||||
else
|
||||
this.searchError = undefined;
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
return (
|
||||
<div className="column w100p center">
|
||||
<div className='row inline w100p pad0-75 search-row' style={{minWidth: '35em', backgroundColor: 'white', paddingTop: 0, paddingBottom: this.searchError ? 17 : 0, margin: 5, borderRadius: 3}}>
|
||||
<TextField
|
||||
style={{marginTop: -12}}
|
||||
hintText={__('Search torrent or file')}
|
||||
floatingLabelText={__('What to search?')}
|
||||
fullWidth={true}
|
||||
ref='searchInput'
|
||||
defaultValue={this.searchValue}
|
||||
errorText={this.searchError}
|
||||
onKeyPress={(e) => {
|
||||
if (e.key === 'Enter') {
|
||||
this.search();
|
||||
}
|
||||
}}
|
||||
onChange={e => {
|
||||
this.searchValue = e.target.value
|
||||
if(this.searchValue.length < 3 && this.searchValue.length > 0)
|
||||
this.searchError = __('too short string for search');
|
||||
else
|
||||
this.searchError = undefined;
|
||||
this.forceUpdate()
|
||||
}}
|
||||
/>
|
||||
|
||||
<div style={{width: 25, height: 25, margin: 2}}>
|
||||
<Checkbox
|
||||
ref='safeSearch'
|
||||
checked={this.notSafeSearch ? true : false}
|
||||
checkedIcon={<Visibility />}
|
||||
uncheckedIcon={<VisibilityOff />}
|
||||
iconStyle={{fill: this.state.safeSearchColor}}
|
||||
onCheck={(ev, ch) => {
|
||||
this.setState(this.setSafeSearch(ch));
|
||||
}}
|
||||
style={{paddingBottom: '0.8em'}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{width: 25, height: 25, margin: 2}}>
|
||||
<Checkbox
|
||||
ref='advancedSearch'
|
||||
checked={this.state.advancedSearch}
|
||||
checkedIcon={<RemoveIcon />}
|
||||
uncheckedIcon={<AddIcon />}
|
||||
iconStyle={{fill: 'black'}}
|
||||
onCheck={(ev, ch) => {
|
||||
this.setState({advancedSearch: ch});
|
||||
}}
|
||||
style={{paddingBottom: '0.8em'}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{width: 25, height: 25, margin: 2}}>
|
||||
<Checkbox
|
||||
ref='safeSearch'
|
||||
checked={this.notSafeSearch ? true : false}
|
||||
checkedIcon={<Visibility />}
|
||||
uncheckedIcon={<VisibilityOff />}
|
||||
iconStyle={{fill: this.state.safeSearchColor}}
|
||||
onCheck={(ev, ch) => {
|
||||
this.setState(this.setSafeSearch(ch));
|
||||
}}
|
||||
style={{paddingBottom: '0.8em'}}
|
||||
/>
|
||||
</div>
|
||||
<div style={{width: 25, height: 25, margin: 2}}>
|
||||
<Checkbox
|
||||
ref='advancedSearch'
|
||||
checked={this.state.advancedSearch}
|
||||
checkedIcon={<RemoveIcon />}
|
||||
uncheckedIcon={<AddIcon />}
|
||||
iconStyle={{fill: 'black'}}
|
||||
onCheck={(ev, ch) => {
|
||||
this.setState({advancedSearch: ch});
|
||||
}}
|
||||
style={{paddingBottom: '0.8em'}}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<RaisedButton style={{marginLeft: '10px'}} label={__('Search')} primary={true} onClick={() =>{
|
||||
this.search()
|
||||
}} />
|
||||
</div>
|
||||
{
|
||||
this.state.advancedSearch
|
||||
<RaisedButton style={{marginLeft: '10px'}} label={__('Search')} primary={true} onClick={() =>{
|
||||
this.search()
|
||||
}} />
|
||||
</div>
|
||||
{
|
||||
this.state.advancedSearch
|
||||
&&
|
||||
<AdvancedSearch onChange={(state) => {
|
||||
this.advanced = state;
|
||||
this.advanced = state;
|
||||
}} state={this.advanced} />
|
||||
|
||||
}
|
||||
{
|
||||
this.stats
|
||||
}
|
||||
{
|
||||
this.stats
|
||||
&&
|
||||
<TorrentsStatistic stats={this.stats} />
|
||||
}
|
||||
{
|
||||
this.state.searchingIndicator
|
||||
?
|
||||
<div className='pad1'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
{
|
||||
this.state.searchingIndicator
|
||||
?
|
||||
<div className='pad1'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default singleton(Search)
|
@ -1,6 +1,6 @@
|
||||
export default (Superclass) => {
|
||||
let instance;
|
||||
|
||||
|
||||
return class Singleton extends Superclass {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
@ -14,12 +14,12 @@ export default (Superclass) => {
|
||||
if (instance) {
|
||||
return instance;
|
||||
} else {
|
||||
return new Singleton();
|
||||
return new Singleton();
|
||||
}
|
||||
}
|
||||
static do(key, ...params) {
|
||||
if ( typeof this.instance()[key] === 'function') {
|
||||
return this.instance()[key](...params);
|
||||
return this.instance()[key](...params);
|
||||
} else {
|
||||
return this.instance()[key];
|
||||
}
|
||||
|
@ -12,171 +12,171 @@ import {Tabs, Tab} from 'material-ui/Tabs';
|
||||
import _ from 'lodash'
|
||||
|
||||
export default class TopPage extends Page {
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Torrents top');
|
||||
this.topTorrents = {};
|
||||
this.types = ['main', 'video', 'audio', 'books', 'pictures', 'application', 'archive']
|
||||
this.descriptions = {
|
||||
main: __('All'),
|
||||
video: __('Video'),
|
||||
audio: __('Audio/Music'),
|
||||
books: __('Books'),
|
||||
pictures: __('Pictures/Images'),
|
||||
application: __('Apps/Games'),
|
||||
archive: __('Archives')
|
||||
}
|
||||
this.times = {
|
||||
overall: __('Overall'),
|
||||
hours: __('Last hour'),
|
||||
week: __('Last week'),
|
||||
month: __('Last month')
|
||||
}
|
||||
this.state = {type: 'main', time: 'overall'}
|
||||
}
|
||||
loadMoreTorrents(type, time)
|
||||
{
|
||||
time = time ? time : this.state.time
|
||||
window.torrentSocket.emit('topTorrents',
|
||||
type == 'main' ? null : type,
|
||||
{index: (this.topTorrents[type] && this.topTorrents[type][time] && this.topTorrents[type][time].length) || 0, time},
|
||||
window.customLoader((data) => {
|
||||
if(!this.topTorrents[type])
|
||||
this.topTorrents[type] = {}
|
||||
if(!this.topTorrents[type][time])
|
||||
this.topTorrents[type][time] = []
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.setTitle('Rats On The Boat - Torrents top');
|
||||
this.topTorrents = {};
|
||||
this.types = ['main', 'video', 'audio', 'books', 'pictures', 'application', 'archive']
|
||||
this.descriptions = {
|
||||
main: __('All'),
|
||||
video: __('Video'),
|
||||
audio: __('Audio/Music'),
|
||||
books: __('Books'),
|
||||
pictures: __('Pictures/Images'),
|
||||
application: __('Apps/Games'),
|
||||
archive: __('Archives')
|
||||
}
|
||||
this.times = {
|
||||
overall: __('Overall'),
|
||||
hours: __('Last hour'),
|
||||
week: __('Last week'),
|
||||
month: __('Last month')
|
||||
}
|
||||
this.state = {type: 'main', time: 'overall'}
|
||||
}
|
||||
loadMoreTorrents(type, time)
|
||||
{
|
||||
time = time ? time : this.state.time
|
||||
window.torrentSocket.emit('topTorrents',
|
||||
type == 'main' ? null : type,
|
||||
{index: (this.topTorrents[type] && this.topTorrents[type][time] && this.topTorrents[type][time].length) || 0, time},
|
||||
window.customLoader((data) => {
|
||||
if(!this.topTorrents[type])
|
||||
this.topTorrents[type] = {}
|
||||
if(!this.topTorrents[type][time])
|
||||
this.topTorrents[type][time] = []
|
||||
|
||||
if(data && data.length > 0)
|
||||
{
|
||||
this.topTorrents[type][time] = this.topTorrents[type][time].concat(data);
|
||||
this._update()
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
_update()
|
||||
{
|
||||
if(this.timeForce)
|
||||
return
|
||||
this.timeForce = setTimeout(() => {
|
||||
delete this.timeForce
|
||||
this.forceUpdate()
|
||||
}, 550)
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
super.componentDidMount();
|
||||
for(const type of this.types)
|
||||
{
|
||||
this.loadMoreTorrents(type)
|
||||
}
|
||||
this.remoteTopTorrents = ({torrents, type, time}) => {
|
||||
if(!torrents)
|
||||
return
|
||||
if(data && data.length > 0)
|
||||
{
|
||||
this.topTorrents[type][time] = this.topTorrents[type][time].concat(data);
|
||||
this._update()
|
||||
}
|
||||
})
|
||||
)
|
||||
}
|
||||
_update()
|
||||
{
|
||||
if(this.timeForce)
|
||||
return
|
||||
this.timeForce = setTimeout(() => {
|
||||
delete this.timeForce
|
||||
this.forceUpdate()
|
||||
}, 550)
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
super.componentDidMount();
|
||||
for(const type of this.types)
|
||||
{
|
||||
this.loadMoreTorrents(type)
|
||||
}
|
||||
this.remoteTopTorrents = ({torrents, type, time}) => {
|
||||
if(!torrents)
|
||||
return
|
||||
|
||||
time = time ? time : 'overall'
|
||||
type = type ? type : 'main'
|
||||
this.topTorrents[type][time] = _.orderBy(_.unionBy(this.topTorrents[type][time], torrents, 'hash'), ['seeders'], ['desc'])
|
||||
this._update();
|
||||
}
|
||||
window.torrentSocket.on('remoteTopTorrents', this.remoteTopTorrents);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.remoteTopTorrents)
|
||||
window.torrentSocket.off('remoteTopTorrents', this.remoteTopTorrents);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='column center w100p'>
|
||||
{
|
||||
Object.keys(this.topTorrents).length == 0
|
||||
time = time ? time : 'overall'
|
||||
type = type ? type : 'main'
|
||||
this.topTorrents[type][time] = _.orderBy(_.unionBy(this.topTorrents[type][time], torrents, 'hash'), ['seeders'], ['desc'])
|
||||
this._update();
|
||||
}
|
||||
window.torrentSocket.on('remoteTopTorrents', this.remoteTopTorrents);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.remoteTopTorrents)
|
||||
window.torrentSocket.off('remoteTopTorrents', this.remoteTopTorrents);
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<div>
|
||||
<div className='column center w100p'>
|
||||
{
|
||||
Object.keys(this.topTorrents).length == 0
|
||||
&&
|
||||
<div className='pad0-75 w100p '>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
}
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.type}
|
||||
onChange={(type) => {
|
||||
this.setState({type});
|
||||
// lost other content
|
||||
if(!this.topTorrents[type][this.state.time])
|
||||
{
|
||||
this.loadMoreTorrents(type, this.state.time)
|
||||
}
|
||||
}}
|
||||
tabItemContainerStyle={{flexWrap: 'wrap', alignItems: 'stretch'}}
|
||||
inkBarStyle={{display: 'none'}}
|
||||
>
|
||||
{
|
||||
this.types.map((type, index) => {
|
||||
if(!this.topTorrents[type])
|
||||
return null;
|
||||
}
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.type}
|
||||
onChange={(type) => {
|
||||
this.setState({type});
|
||||
// lost other content
|
||||
if(!this.topTorrents[type][this.state.time])
|
||||
{
|
||||
this.loadMoreTorrents(type, this.state.time)
|
||||
}
|
||||
}}
|
||||
tabItemContainerStyle={{flexWrap: 'wrap', alignItems: 'stretch'}}
|
||||
inkBarStyle={{display: 'none'}}
|
||||
>
|
||||
{
|
||||
this.types.map((type, index) => {
|
||||
if(!this.topTorrents[type])
|
||||
return null;
|
||||
|
||||
return (
|
||||
<Tab buttonStyle={type === this.state.type ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.descriptions[type]} value={type}>
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.time}
|
||||
onChange={(time) => {
|
||||
this.setState({time})
|
||||
// lost other content
|
||||
if(!this.topTorrents[type][time])
|
||||
{
|
||||
this.loadMoreTorrents(type, time)
|
||||
}
|
||||
}}
|
||||
tabItemContainerStyle={{flexWrap: 'wrap', alignItems: 'stretch'}}
|
||||
inkBarStyle={{display: 'none'}}
|
||||
>
|
||||
{
|
||||
Object.keys(this.times).map((time, index) => {
|
||||
const torrents = this.topTorrents[type][time];
|
||||
return (
|
||||
<Tab buttonStyle={type === this.state.type ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.descriptions[type]} value={type}>
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.time}
|
||||
onChange={(time) => {
|
||||
this.setState({time})
|
||||
// lost other content
|
||||
if(!this.topTorrents[type][time])
|
||||
{
|
||||
this.loadMoreTorrents(type, time)
|
||||
}
|
||||
}}
|
||||
tabItemContainerStyle={{flexWrap: 'wrap', alignItems: 'stretch'}}
|
||||
inkBarStyle={{display: 'none'}}
|
||||
>
|
||||
{
|
||||
Object.keys(this.times).map((time, index) => {
|
||||
const torrents = this.topTorrents[type][time];
|
||||
|
||||
if(!torrents)
|
||||
return (
|
||||
<Tab buttonStyle={time === this.state.time ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.times[time]} value={time}>
|
||||
<div className='pad0-75 w100p '>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
</Tab>
|
||||
)
|
||||
if(!torrents)
|
||||
return (
|
||||
<Tab buttonStyle={time === this.state.time ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.times[time]} value={time}>
|
||||
<div className='pad0-75 w100p '>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
</Tab>
|
||||
)
|
||||
|
||||
return (
|
||||
<Tab buttonStyle={time === this.state.time ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.times[time]} value={time}>
|
||||
<List style={{minWidth: '20em'}}>
|
||||
{
|
||||
torrents.map((torrent, index) => {
|
||||
return <TorrentLine key={index} torrent={torrent} />
|
||||
})
|
||||
}
|
||||
{
|
||||
torrents.length > 0
|
||||
return (
|
||||
<Tab buttonStyle={time === this.state.time ? {fontWeight: 'bold'} : undefined} style={{minWidth: 150}} key={index} label={this.times[time]} value={time}>
|
||||
<List style={{minWidth: '20em'}}>
|
||||
{
|
||||
torrents.map((torrent, index) => {
|
||||
return <TorrentLine key={index} torrent={torrent} />
|
||||
})
|
||||
}
|
||||
{
|
||||
torrents.length > 0
|
||||
&&
|
||||
<div>
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={<span>{__('More Torrents')}</span>} onClick={() => {
|
||||
this.loadMoreTorrents(type)
|
||||
}} />
|
||||
<Divider />
|
||||
<ListItem innerDivStyle={{textAlign: 'center', padding: '1em'}} primaryText={<span>{__('More Torrents')}</span>} onClick={() => {
|
||||
this.loadMoreTorrents(type)
|
||||
}} />
|
||||
<Divider />
|
||||
</div>
|
||||
}
|
||||
</List>
|
||||
</Tab>)
|
||||
})
|
||||
}
|
||||
}
|
||||
</List>
|
||||
</Tab>)
|
||||
})
|
||||
}
|
||||
|
||||
</Tabs>
|
||||
</Tab>
|
||||
)
|
||||
</Tabs>
|
||||
</Tab>
|
||||
)
|
||||
|
||||
})
|
||||
}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
})
|
||||
}
|
||||
</Tabs>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -53,34 +53,34 @@ const treeToTorrentFiles = (tree) => {
|
||||
arr.push(<ListItem
|
||||
key={file}
|
||||
primaryText={file}
|
||||
secondaryText={formatBytes(tree[file].__sizeBT)}
|
||||
nestedItems={treeToTorrentFiles(tree[file])}
|
||||
primaryTogglesNestedList={true}
|
||||
innerDivStyle={{wordBreak: 'break-word'}}
|
||||
leftIcon={tree[file] && Object.keys(tree[file]).length > 1 ? <FileFolder /> : contentIcon(fileTypeDetect({path: file}))}
|
||||
/>);
|
||||
secondaryText={formatBytes(tree[file].__sizeBT)}
|
||||
nestedItems={treeToTorrentFiles(tree[file])}
|
||||
primaryTogglesNestedList={true}
|
||||
innerDivStyle={{wordBreak: 'break-word'}}
|
||||
leftIcon={tree[file] && Object.keys(tree[file]).length > 1 ? <FileFolder /> : contentIcon(fileTypeDetect({path: file}))}
|
||||
/>);
|
||||
}
|
||||
return arr;
|
||||
}
|
||||
|
||||
const TorrentFiles = (props) => {
|
||||
let filesList = props.torrent.filesList;
|
||||
let filesList = props.torrent.filesList;
|
||||
let tree = buildFilesTree(filesList);
|
||||
return (
|
||||
<List className='w100p'>
|
||||
{
|
||||
filesList.length > 0
|
||||
?
|
||||
<div className='w100p'>
|
||||
<Subheader inset={true}>{__('Content of the torrent')}:</Subheader>
|
||||
{treeToTorrentFiles(tree)}
|
||||
</div>
|
||||
:
|
||||
<div className='column center'>
|
||||
<span className='pad0-75'>{__('Processing files')}...</span>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
}
|
||||
{
|
||||
filesList.length > 0
|
||||
?
|
||||
<div className='w100p'>
|
||||
<Subheader inset={true}>{__('Content of the torrent')}:</Subheader>
|
||||
{treeToTorrentFiles(tree)}
|
||||
</div>
|
||||
:
|
||||
<div className='column center'>
|
||||
<span className='pad0-75'>{__('Processing files')}...</span>
|
||||
<LinearProgress mode="indeterminate" />
|
||||
</div>
|
||||
}
|
||||
</List>
|
||||
);
|
||||
};
|
||||
@ -89,84 +89,84 @@ const TorrentInformation = (props) => {
|
||||
let torrent = props.torrent;
|
||||
return (
|
||||
<List className='w100p'>
|
||||
<Subheader inset={true}>{__('Information about torrent')}</Subheader>
|
||||
<ListItem
|
||||
//leftAvatar={<Avatar icon={<ActionAssignment />} backgroundColor={blue500} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent Name')}
|
||||
secondaryText={<span className='break-word' style={{whiteSpace: 'normal'}}>{torrent.name}</span>}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent Size')}
|
||||
secondaryText={formatBytes(torrent.size)}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent contains files')}
|
||||
secondaryText={torrent.files}
|
||||
onClick={() => {
|
||||
if(!props.parent)
|
||||
return
|
||||
<Subheader inset={true}>{__('Information about torrent')}</Subheader>
|
||||
<ListItem
|
||||
//leftAvatar={<Avatar icon={<ActionAssignment />} backgroundColor={blue500} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent Name')}
|
||||
secondaryText={<span className='break-word' style={{whiteSpace: 'normal'}}>{torrent.name}</span>}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent Size')}
|
||||
secondaryText={formatBytes(torrent.size)}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Torrent contains files')}
|
||||
secondaryText={torrent.files}
|
||||
onClick={() => {
|
||||
if(!props.parent)
|
||||
return
|
||||
|
||||
props.parent.setState({
|
||||
value: 'files'
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Indexed/Added torrent date')}
|
||||
secondaryText={moment(torrent.added * 1000).format('MMMM Do YYYY, hh:mm')}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Content type')}
|
||||
secondaryText={torrent.contentType || 'unknown'}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Category')}
|
||||
secondaryText={torrent.contentCategory || 'unknown'}
|
||||
/>
|
||||
</List>
|
||||
props.parent.setState({
|
||||
value: 'files'
|
||||
})
|
||||
}}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Indexed/Added torrent date')}
|
||||
secondaryText={moment(torrent.added * 1000).format('MMMM Do YYYY, hh:mm')}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Content type')}
|
||||
secondaryText={torrent.contentType || 'unknown'}
|
||||
/>
|
||||
<ListItem
|
||||
// leftAvatar={<Avatar icon={<EditorInsertChart />} backgroundColor={yellow600} />}
|
||||
rightIcon={<ActionInfo />}
|
||||
primaryText={__('Category')}
|
||||
secondaryText={torrent.contentCategory || 'unknown'}
|
||||
/>
|
||||
</List>
|
||||
);
|
||||
}
|
||||
|
||||
export default class TorrentPage extends Page {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: 'info',
|
||||
searchingIndicator: false,
|
||||
voting: false,
|
||||
voted: false,
|
||||
askDownloading: false,
|
||||
downloading: false,
|
||||
downloadProgress: {}
|
||||
};
|
||||
this.setTitle('Information about torrent');
|
||||
}
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
value: 'info',
|
||||
searchingIndicator: false,
|
||||
voting: false,
|
||||
voted: false,
|
||||
askDownloading: false,
|
||||
downloading: false,
|
||||
downloadProgress: {}
|
||||
};
|
||||
this.setTitle('Information about torrent');
|
||||
}
|
||||
|
||||
changeTab(tab) {
|
||||
if(this.state.value != tab) {
|
||||
this.setState({
|
||||
value: tab
|
||||
});
|
||||
console.log('change');
|
||||
}
|
||||
}
|
||||
onSwipeRight() {
|
||||
this.changeTab('files');
|
||||
}
|
||||
onSwipeLeft() {
|
||||
this.changeTab('info');
|
||||
}
|
||||
changeTab(tab) {
|
||||
if(this.state.value != tab) {
|
||||
this.setState({
|
||||
value: tab
|
||||
});
|
||||
console.log('change');
|
||||
}
|
||||
}
|
||||
onSwipeRight() {
|
||||
this.changeTab('files');
|
||||
}
|
||||
onSwipeLeft() {
|
||||
this.changeTab('info');
|
||||
}
|
||||
|
||||
handleChange = (value) => {
|
||||
if(value == 'main') {
|
||||
@ -174,18 +174,18 @@ export default class TorrentPage extends Page {
|
||||
return;
|
||||
}
|
||||
|
||||
this.setState({
|
||||
value: value,
|
||||
});
|
||||
this.setState({
|
||||
value: value,
|
||||
});
|
||||
};
|
||||
getTorrentInfo() {
|
||||
window.torrentSocket.emit('torrent', this.props.hash, {files: true, peer: this.props.peer}, window.customLoader((data) => {
|
||||
if(data) {
|
||||
this.torrent = data
|
||||
this.setTitle(this.torrent.name + ' - Rats On The Boat');
|
||||
if(this.torrent.contentCategory == 'xxx') {
|
||||
this.setMetaTag('robots', 'noindex');
|
||||
}
|
||||
if(this.torrent.contentCategory == 'xxx') {
|
||||
this.setMetaTag('robots', 'noindex');
|
||||
}
|
||||
//this.forceUpdate(); // вызывается через searchingIndicator
|
||||
|
||||
// Получаем более новую статистику пира
|
||||
@ -194,195 +194,195 @@ export default class TorrentPage extends Page {
|
||||
}
|
||||
}
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}));
|
||||
this.setState({
|
||||
searchingIndicator: true
|
||||
});
|
||||
}, () => {
|
||||
this.setState({
|
||||
searchingIndicator: false
|
||||
});
|
||||
}));
|
||||
}
|
||||
componentDidMount() {
|
||||
super.componentDidMount();
|
||||
|
||||
this.filesUpdated = (hash) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
return;
|
||||
|
||||
this.getTorrentInfo();
|
||||
}
|
||||
window.torrentSocket.on('filesReady', this.filesUpdated);
|
||||
|
||||
this.trackerUpdate = (info) => {
|
||||
if(this.props.hash != info.hash)
|
||||
return;
|
||||
if(this.props.hash != info.hash)
|
||||
return;
|
||||
|
||||
if(!this.torrent)
|
||||
return;
|
||||
if(!this.torrent)
|
||||
return;
|
||||
|
||||
Object.assign(this.torrent, info);
|
||||
this.forceUpdate();
|
||||
}
|
||||
window.torrentSocket.on('trackerTorrentUpdate', this.trackerUpdate);
|
||||
Object.assign(this.torrent, info);
|
||||
this.forceUpdate();
|
||||
}
|
||||
window.torrentSocket.on('trackerTorrentUpdate', this.trackerUpdate);
|
||||
|
||||
this.onVotes = async ({hash, good, bad, selfVote}) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
this.onVotes = async ({hash, good, bad, selfVote}) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
|
||||
if(!this.torrent)
|
||||
return
|
||||
if(!this.torrent)
|
||||
return
|
||||
|
||||
this.torrent.good = good;
|
||||
this.torrent.bad = bad;
|
||||
this.state.voted = selfVote;
|
||||
this.forceUpdate();
|
||||
}
|
||||
window.torrentSocket.on('votes', this.onVotes);
|
||||
this.torrent.good = good;
|
||||
this.torrent.bad = bad;
|
||||
this.state.voted = selfVote;
|
||||
this.forceUpdate();
|
||||
}
|
||||
window.torrentSocket.on('votes', this.onVotes);
|
||||
|
||||
this.downloading = (hash) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
this.downloading = (hash) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({downloading: true})
|
||||
}
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
this.setState({downloading: true})
|
||||
}
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
|
||||
this.downloadDone = (hash, canceled) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
this.downloadDone = (hash, canceled) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({
|
||||
downloading: false,
|
||||
askDownloading: !canceled
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
this.setState({
|
||||
downloading: false,
|
||||
askDownloading: !canceled
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
|
||||
this.downloadProgress = (hash, progress) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
this.downloadProgress = (hash, progress) => {
|
||||
if(this.props.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({downloadProgress: progress})
|
||||
}
|
||||
window.torrentSocket.on('downloadProgress', this.downloadProgress);
|
||||
this.setState({downloadProgress: progress})
|
||||
}
|
||||
window.torrentSocket.on('downloadProgress', this.downloadProgress);
|
||||
|
||||
this.getTorrentInfo();
|
||||
this.getTorrentInfo();
|
||||
}
|
||||
componentWillUnmount() {
|
||||
if(this.filesUpdated)
|
||||
window.torrentSocket.off('filesReady', this.filesUpdated);
|
||||
window.torrentSocket.off('filesReady', this.filesUpdated);
|
||||
if(this.trackerUpdate)
|
||||
window.torrentSocket.off('trackerTorrentUpdate', this.trackerUpdate);
|
||||
if(this.onVotes)
|
||||
window.torrentSocket.off('votes', this.onVotes);
|
||||
if(this.torrent && this.torrent.contentCategory == 'xxx') {
|
||||
this.removeMetaTag('robots');
|
||||
}
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
if(this.downloadProgress)
|
||||
window.torrentSocket.off('downloadProgress', this.downloadProgress);
|
||||
window.torrentSocket.off('trackerTorrentUpdate', this.trackerUpdate);
|
||||
if(this.onVotes)
|
||||
window.torrentSocket.off('votes', this.onVotes);
|
||||
if(this.torrent && this.torrent.contentCategory == 'xxx') {
|
||||
this.removeMetaTag('robots');
|
||||
}
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
if(this.downloadProgress)
|
||||
window.torrentSocket.off('downloadProgress', this.downloadProgress);
|
||||
}
|
||||
vote(good) {
|
||||
if(!this.torrent)
|
||||
return;
|
||||
if(!this.torrent)
|
||||
return;
|
||||
|
||||
this.setState({
|
||||
voting: true
|
||||
});
|
||||
window.torrentSocket.emit('vote', this.torrent.hash, !!good, window.customLoader((success) => {
|
||||
this.setState({
|
||||
voted: true,
|
||||
voting: false
|
||||
});
|
||||
}));
|
||||
this.setState({
|
||||
voting: true
|
||||
});
|
||||
window.torrentSocket.emit('vote', this.torrent.hash, !!good, window.customLoader((success) => {
|
||||
this.setState({
|
||||
voted: true,
|
||||
voting: false
|
||||
});
|
||||
}));
|
||||
}
|
||||
render() {
|
||||
const style = {
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
refresh: {
|
||||
display: 'inline-block',
|
||||
position: 'relative',
|
||||
},
|
||||
};
|
||||
|
||||
if(this.state.searchingIndicator) {
|
||||
return (
|
||||
<div className='pad1 w100p column center'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
if(this.state.searchingIndicator) {
|
||||
return (
|
||||
<div className='pad1 w100p column center'>
|
||||
<RefreshIndicator
|
||||
size={50}
|
||||
left={0}
|
||||
top={0}
|
||||
loadingColor="#FF9800"
|
||||
status="loading"
|
||||
style={style.refresh}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
let torrentRating;
|
||||
if(this.torrent) {
|
||||
torrentRating = Math.round(rating(this.torrent.good, this.torrent.bad) * 100);
|
||||
}
|
||||
let torrentRating;
|
||||
if(this.torrent) {
|
||||
torrentRating = Math.round(rating(this.torrent.good, this.torrent.bad) * 100);
|
||||
}
|
||||
|
||||
return (
|
||||
<div className="w100p column center">
|
||||
{
|
||||
this.torrent
|
||||
?
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.value}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
<Tab label={__('Back to main')} value="main" />
|
||||
<Tab label={__('Information')} value="info" >
|
||||
<div className='column w100p'>
|
||||
<div className='row w100p torrent-information-row'>
|
||||
<div className='info-table'>
|
||||
<TorrentInformation torrent={this.torrent} parent={this} />
|
||||
</div>
|
||||
<div style={{flexBasis: '40%'}} className='column center w100p'>
|
||||
<img src={NoImage} className='pad0-75' style={{height: '200px'}} />
|
||||
<RaisedButton
|
||||
href={`magnet:?xt=urn:btih:${this.torrent.hash}`}
|
||||
target="_self"
|
||||
label="Magnet"
|
||||
secondary={true}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
window.open(`magnet:?xt=urn:btih:${this.torrent.hash}`, '_self')
|
||||
}}
|
||||
icon={<svg fill='white' viewBox="0 0 24 24"><path d="M17.374 20.235c2.444-2.981 6.626-8.157 6.626-8.157l-3.846-3.092s-2.857 3.523-6.571 8.097c-4.312 5.312-11.881-2.41-6.671-6.671 4.561-3.729 8.097-6.57 8.097-6.57l-3.092-3.842s-5.173 4.181-8.157 6.621c-2.662 2.175-3.76 4.749-3.76 7.24 0 5.254 4.867 10.139 10.121 10.139 2.487 0 5.064-1.095 7.253-3.765zm4.724-7.953l-1.699 2.111-1.74-1.397 1.701-2.114 1.738 1.4zm-10.386-10.385l1.4 1.738-2.113 1.701-1.397-1.74 2.11-1.699z"/></svg>}
|
||||
/>
|
||||
{
|
||||
!this.state.askDownloading && !this.state.downloading
|
||||
return (
|
||||
<div className="w100p column center">
|
||||
{
|
||||
this.torrent
|
||||
?
|
||||
<Tabs
|
||||
className='w100p'
|
||||
value={this.state.value}
|
||||
onChange={this.handleChange}
|
||||
>
|
||||
<Tab label={__('Back to main')} value="main" />
|
||||
<Tab label={__('Information')} value="info" >
|
||||
<div className='column w100p'>
|
||||
<div className='row w100p torrent-information-row'>
|
||||
<div className='info-table'>
|
||||
<TorrentInformation torrent={this.torrent} parent={this} />
|
||||
</div>
|
||||
<div style={{flexBasis: '40%'}} className='column center w100p'>
|
||||
<img src={NoImage} className='pad0-75' style={{height: '200px'}} />
|
||||
<RaisedButton
|
||||
href={`magnet:?xt=urn:btih:${this.torrent.hash}`}
|
||||
target="_self"
|
||||
label="Magnet"
|
||||
secondary={true}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
window.open(`magnet:?xt=urn:btih:${this.torrent.hash}`, '_self')
|
||||
}}
|
||||
icon={<svg fill='white' viewBox="0 0 24 24"><path d="M17.374 20.235c2.444-2.981 6.626-8.157 6.626-8.157l-3.846-3.092s-2.857 3.523-6.571 8.097c-4.312 5.312-11.881-2.41-6.671-6.671 4.561-3.729 8.097-6.57 8.097-6.57l-3.092-3.842s-5.173 4.181-8.157 6.621c-2.662 2.175-3.76 4.749-3.76 7.24 0 5.254 4.867 10.139 10.121 10.139 2.487 0 5.064-1.095 7.253-3.765zm4.724-7.953l-1.699 2.111-1.74-1.397 1.701-2.114 1.738 1.4zm-10.386-10.385l1.4 1.738-2.113 1.701-1.397-1.74 2.11-1.699z"/></svg>}
|
||||
/>
|
||||
{
|
||||
!this.state.askDownloading && !this.state.downloading
|
||||
&&
|
||||
<RaisedButton
|
||||
href={`magnet:?xt=urn:btih:${this.torrent.hash}`}
|
||||
target="_self"
|
||||
label={__('Download')}
|
||||
backgroundColor='#00C853'
|
||||
labelColor='white'
|
||||
style={{marginTop: 8}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
this.setState({askDownloading: true})
|
||||
window.torrentSocket.emit('download', this.torrent)
|
||||
}}
|
||||
icon={
|
||||
<svg viewBox="0 0 56 56" fill='white'>
|
||||
<g>
|
||||
<path d="M35.586,41.586L31,46.172V28c0-1.104-0.896-2-2-2s-2,0.896-2,2v18.172l-4.586-4.586c-0.781-0.781-2.047-0.781-2.828,0
|
||||
href={`magnet:?xt=urn:btih:${this.torrent.hash}`}
|
||||
target="_self"
|
||||
label={__('Download')}
|
||||
backgroundColor='#00C853'
|
||||
labelColor='white'
|
||||
style={{marginTop: 8}}
|
||||
onClick={(e) => {
|
||||
e.preventDefault();
|
||||
this.setState({askDownloading: true})
|
||||
window.torrentSocket.emit('download', this.torrent)
|
||||
}}
|
||||
icon={
|
||||
<svg viewBox="0 0 56 56" fill='white'>
|
||||
<g>
|
||||
<path d="M35.586,41.586L31,46.172V28c0-1.104-0.896-2-2-2s-2,0.896-2,2v18.172l-4.586-4.586c-0.781-0.781-2.047-0.781-2.828,0
|
||||
s-0.781,2.047,0,2.828l7.999,7.999c0.093,0.094,0.196,0.177,0.307,0.251c0.047,0.032,0.099,0.053,0.148,0.081
|
||||
c0.065,0.036,0.127,0.075,0.196,0.103c0.065,0.027,0.133,0.042,0.2,0.062c0.058,0.017,0.113,0.04,0.173,0.051
|
||||
C28.738,52.986,28.869,53,29,53s0.262-0.014,0.392-0.04c0.06-0.012,0.115-0.034,0.173-0.051c0.067-0.02,0.135-0.035,0.2-0.062
|
||||
c0.069-0.028,0.131-0.067,0.196-0.103c0.05-0.027,0.101-0.049,0.148-0.081c0.11-0.074,0.213-0.157,0.307-0.251l7.999-7.999
|
||||
c0.781-0.781,0.781-2.047,0-2.828S36.367,40.805,35.586,41.586z"/>
|
||||
<path d="M47.835,18.986c-0.137-0.019-2.457-0.335-4.684,0.002C43.1,18.996,43.049,19,42.999,19c-0.486,0-0.912-0.354-0.987-0.85
|
||||
<path d="M47.835,18.986c-0.137-0.019-2.457-0.335-4.684,0.002C43.1,18.996,43.049,19,42.999,19c-0.486,0-0.912-0.354-0.987-0.85
|
||||
c-0.083-0.546,0.292-1.056,0.838-1.139c1.531-0.233,3.062-0.196,4.083-0.124C46.262,9.135,39.83,3,32.085,3
|
||||
C27.388,3,22.667,5.379,19.8,9.129C21.754,10.781,23,13.246,23,16c0,0.553-0.447,1-1,1s-1-0.447-1-1
|
||||
c0-2.462-1.281-4.627-3.209-5.876c-0.227-0.147-0.462-0.277-0.702-0.396c-0.069-0.034-0.139-0.069-0.21-0.101
|
||||
@ -391,120 +391,120 @@ export default class TorrentPage extends Page {
|
||||
l0.012,0.21l-0.009,0.16C7.008,16.744,7,16.873,7,17v0.63l-0.567,0.271C2.705,19.688,0,24,0,28.154C0,34.135,4.865,39,10.845,39H25
|
||||
V28c0-2.209,1.791-4,4-4s4,1.791,4,4v11h2.353c0.059,0,0.116-0.005,0.174-0.009l0.198-0.011l0.271,0.011
|
||||
C36.053,38.995,36.11,39,36.169,39h9.803C51.501,39,56,34.501,56,28.972C56,24.161,52.49,19.872,47.835,18.986z"/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
/>
|
||||
}
|
||||
{
|
||||
this.state.downloading
|
||||
}
|
||||
{
|
||||
this.state.downloading
|
||||
&&
|
||||
<div className='column center pad0-75' style={{width: '300px'}}>
|
||||
<div className='fs0-75' style={{color: 'rgb(0, 188, 212)'}}>{__('downloading')} {this.state.downloadProgress && (this.state.downloadProgress.progress * 100).toFixed(1)}%</div>
|
||||
<LinearProgress
|
||||
style={{marginTop: 3}}
|
||||
mode="determinate"
|
||||
value={this.state.downloadProgress && (this.state.downloadProgress.progress ? this.state.downloadProgress.progress : 0) * 100}
|
||||
/>
|
||||
<FlatButton
|
||||
onClick={() => {
|
||||
window.torrentSocket.emit('downloadCancel', this.torrent.hash)
|
||||
}}
|
||||
label={__('Cancel download')}
|
||||
secondary={true}
|
||||
icon={<svg fill='rgb(255, 64, 129)' viewBox="0 0 18 18"><path d="M9 1C4.58 1 1 4.58 1 9s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4 10.87L11.87 13 9 10.13 6.13 13 5 11.87 7.87 9 5 6.13 6.13 5 9 7.87 11.87 5 13 6.13 10.13 9 13 11.87z"/></svg>}
|
||||
/>
|
||||
<div className='fs0-75' style={{color: 'rgb(0, 188, 212)'}}>{__('downloading')} {this.state.downloadProgress && (this.state.downloadProgress.progress * 100).toFixed(1)}%</div>
|
||||
<LinearProgress
|
||||
style={{marginTop: 3}}
|
||||
mode="determinate"
|
||||
value={this.state.downloadProgress && (this.state.downloadProgress.progress ? this.state.downloadProgress.progress : 0) * 100}
|
||||
/>
|
||||
<FlatButton
|
||||
onClick={() => {
|
||||
window.torrentSocket.emit('downloadCancel', this.torrent.hash)
|
||||
}}
|
||||
label={__('Cancel download')}
|
||||
secondary={true}
|
||||
icon={<svg fill='rgb(255, 64, 129)' viewBox="0 0 18 18"><path d="M9 1C4.58 1 1 4.58 1 9s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4 10.87L11.87 13 9 10.13 6.13 13 5 11.87 7.87 9 5 6.13 6.13 5 9 7.87 11.87 5 13 6.13 10.13 9 13 11.87z"/></svg>}
|
||||
/>
|
||||
</div>
|
||||
}
|
||||
<div className='fs0-75 pad0-75 center column' style={{color: 'rgba(0, 0, 0, 0.541176)'}}><div>BTIH:</div><div>{this.torrent.hash}</div></div>
|
||||
{
|
||||
this.torrent.seeders || this.torrent.leechers || this.torrent.completed
|
||||
?
|
||||
<div className='fs0-85 pad0-75 center column'>
|
||||
<div className='pad0-25' style={{color: '#00C853'}}>{__('seeders')}: {this.torrent.seeders}</div>
|
||||
<div className='pad0-25' style={{color: '#AA00FF'}}>{__('leechers')}: {this.torrent.leechers}</div>
|
||||
<div className='pad0-25' style={{color: '#FF6D00'}}>{__('completed')}: {this.torrent.completed}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
!this.state.voted && !this.state.voting
|
||||
?
|
||||
<div className='row pad0-25'>
|
||||
<RaisedButton
|
||||
label={__('Good') + ` (${this.torrent.good})`}
|
||||
labelColor="white"
|
||||
backgroundColor="#00C853"
|
||||
icon={
|
||||
<svg viewBox="0 0 489.543 489.543" fill="white">
|
||||
<g>
|
||||
<path d="M270.024,0c-22.6,0-15,48.3-15,48.3s-48.3,133.2-94.5,168.7c-9.9,10.4-16.1,21.9-20,31.3l0,0l0,0
|
||||
}
|
||||
<div className='fs0-75 pad0-75 center column' style={{color: 'rgba(0, 0, 0, 0.541176)'}}><div>BTIH:</div><div>{this.torrent.hash}</div></div>
|
||||
{
|
||||
this.torrent.seeders || this.torrent.leechers || this.torrent.completed
|
||||
?
|
||||
<div className='fs0-85 pad0-75 center column'>
|
||||
<div className='pad0-25' style={{color: '#00C853'}}>{__('seeders')}: {this.torrent.seeders}</div>
|
||||
<div className='pad0-25' style={{color: '#AA00FF'}}>{__('leechers')}: {this.torrent.leechers}</div>
|
||||
<div className='pad0-25' style={{color: '#FF6D00'}}>{__('completed')}: {this.torrent.completed}</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
!this.state.voted && !this.state.voting
|
||||
?
|
||||
<div className='row pad0-25'>
|
||||
<RaisedButton
|
||||
label={__('Good') + ` (${this.torrent.good})`}
|
||||
labelColor="white"
|
||||
backgroundColor="#00C853"
|
||||
icon={
|
||||
<svg viewBox="0 0 489.543 489.543" fill="white">
|
||||
<g>
|
||||
<path d="M270.024,0c-22.6,0-15,48.3-15,48.3s-48.3,133.2-94.5,168.7c-9.9,10.4-16.1,21.9-20,31.3l0,0l0,0
|
||||
c-0.9,2.3-1.7,4.5-2.4,6.5c-3.1,6.3-9.7,16-23.8,24.5l46.2,200.9c0,0,71.5,9.3,143.2,7.8c28.7,2.3,59.1,2.5,83.3-2.7
|
||||
c82.2-17.5,61.6-74.8,61.6-74.8c44.3-33.3,19.1-74.9,19.1-74.9c39.4-41.1,0.7-75.6,0.7-75.6s21.3-33.2-6.2-58.3
|
||||
c-34.3-31.4-127.4-10.5-127.4-10.5l0,0c-6.5,1.1-13.4,2.5-20.8,4.3c0,0-32.2,15,0-82.7C346.324,15.1,292.624,0,270.024,0z"/>
|
||||
<path d="M127.324,465.7l-35-166.3c-2-9.5-11.6-17.3-21.3-17.3h-66.8l-0.1,200.8h109.1C123.024,483,129.324,475.2,127.324,465.7z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
onClick={() => this.vote(true)}
|
||||
/>
|
||||
<RaisedButton
|
||||
style={{marginLeft: '9px'}}
|
||||
label={__('Bad') + ` (${this.torrent.bad})`}
|
||||
labelColor="white"
|
||||
backgroundColor="#D50000"
|
||||
icon={
|
||||
<svg viewBox="0 0 487.643 487.643" fill="white">
|
||||
<g>
|
||||
<path d="M113.869,209.443l46-200.1c0,0,71.2-9.3,142.6-7.8c28.5-2.3,58.9-2.5,83,2.7c81.9,17.4,61.4,74.5,61.4,74.5
|
||||
<path d="M127.324,465.7l-35-166.3c-2-9.5-11.6-17.3-21.3-17.3h-66.8l-0.1,200.8h109.1C123.024,483,129.324,475.2,127.324,465.7z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
onClick={() => this.vote(true)}
|
||||
/>
|
||||
<RaisedButton
|
||||
style={{marginLeft: '9px'}}
|
||||
label={__('Bad') + ` (${this.torrent.bad})`}
|
||||
labelColor="white"
|
||||
backgroundColor="#D50000"
|
||||
icon={
|
||||
<svg viewBox="0 0 487.643 487.643" fill="white">
|
||||
<g>
|
||||
<path d="M113.869,209.443l46-200.1c0,0,71.2-9.3,142.6-7.8c28.5-2.3,58.9-2.5,83,2.7c81.9,17.4,61.4,74.5,61.4,74.5
|
||||
c44.2,33.2,19,74.6,19,74.6c39.2,41,0.7,75.3,0.7,75.3s21.2,33-6.1,58c-34.2,31.2-126.9,10.5-126.9,10.5l0,0
|
||||
c-6.4-1.1-13.3-2.5-20.7-4.2c0,0-32.1-15,0,82.4s-21.4,112.3-43.9,112.3s-15-48.1-15-48.1s-48.1-132.7-94.1-168
|
||||
c-9.9-10.4-16.1-21.8-19.9-31.2l0,0l0,0c-0.9-2.3-1.7-4.5-2.4-6.5C134.469,227.543,127.869,217.843,113.869,209.443z
|
||||
M70.869,206.643c9.7,0,19.2-7.7,21.2-17.2l34.8-165.6c2-9.5-4.3-17.2-14-17.2H4.169l0.1,200H70.869z"/>
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
onClick={() => this.vote(false)}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
this.state.voting
|
||||
?
|
||||
<div>voting...</div>
|
||||
:
|
||||
<div>Thank you for voting!</div>
|
||||
}
|
||||
{
|
||||
this.torrent.good > 0 || this.torrent.bad > 0
|
||||
?
|
||||
<div className='w100p' style={{padding: '7px 35px', marginTop: '10px'}}>
|
||||
<LinearProgress
|
||||
mode="determinate"
|
||||
value={torrentRating}
|
||||
color={torrentRating >= 50 ? '#00E676' : '#FF3D00'}
|
||||
style={{
|
||||
height: '5px',
|
||||
}}
|
||||
/>
|
||||
<div className='row center pad0-75 fs0-85' style={{color: torrentRating >= 50 ? '#00E676' : '#FF3D00'}}>{__('Torrent rating')}: {torrentRating}%</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab label={__('Files')} value="files" >
|
||||
<TorrentFiles torrent={this.torrent} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
</g>
|
||||
</svg>
|
||||
}
|
||||
onClick={() => this.vote(false)}
|
||||
/>
|
||||
</div>
|
||||
:
|
||||
this.state.voting
|
||||
?
|
||||
<div>voting...</div>
|
||||
:
|
||||
<div>Thank you for voting!</div>
|
||||
}
|
||||
{
|
||||
this.torrent.good > 0 || this.torrent.bad > 0
|
||||
?
|
||||
<div className='w100p' style={{padding: '7px 35px', marginTop: '10px'}}>
|
||||
<LinearProgress
|
||||
mode="determinate"
|
||||
value={torrentRating}
|
||||
color={torrentRating >= 50 ? '#00E676' : '#FF3D00'}
|
||||
style={{
|
||||
height: '5px',
|
||||
}}
|
||||
/>
|
||||
<div className='row center pad0-75 fs0-85' style={{color: torrentRating >= 50 ? '#00E676' : '#FF3D00'}}>{__('Torrent rating')}: {torrentRating}%</div>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Tab>
|
||||
<Tab label={__('Files')} value="files" >
|
||||
<TorrentFiles torrent={this.torrent} />
|
||||
</Tab>
|
||||
</Tabs>
|
||||
:
|
||||
null
|
||||
}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -2,37 +2,37 @@ import React, { Component } from 'react';
|
||||
import formatBytes from './format-bytes'
|
||||
|
||||
export default class TorrentsStatistic extends Component {
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
|
||||
this.stats = props.stats || {}
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
this.newTorrentFunc = (torrent) => {
|
||||
this.stats.size += torrent.size;
|
||||
this.stats.torrents++;
|
||||
this.stats.files += torrent.files;
|
||||
this.forceUpdate()
|
||||
}
|
||||
this.stats = props.stats || {}
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
this.newTorrentFunc = (torrent) => {
|
||||
this.stats.size += torrent.size;
|
||||
this.stats.torrents++;
|
||||
this.stats.files += torrent.files;
|
||||
this.forceUpdate()
|
||||
}
|
||||
|
||||
window.torrentSocket.on('newTorrent', this.newTorrentFunc);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.newTorrentFunc)
|
||||
window.torrentSocket.off('newTorrent', this.newTorrentFunc);
|
||||
}
|
||||
render()
|
||||
{
|
||||
return (
|
||||
<div style={{position: 'relative', width: '100%', height: 0}}>
|
||||
<div className='column w100p counter-statistic' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4, marginTop: 2}}>
|
||||
<div className='row w100p' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4}}>
|
||||
<div className='row inline' style={{color: '#e5f442', fontSize: '1.15em', fill: '#e5f442'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<path d="M35,0C23.849,0,14.43,2.588,11.215,6.475C4.669,8.077,0.884,10.775,0.146,13.51C0.062,13.657,0,13.818,0,14v0.5V26v0.5V27
|
||||
window.torrentSocket.on('newTorrent', this.newTorrentFunc);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.newTorrentFunc)
|
||||
window.torrentSocket.off('newTorrent', this.newTorrentFunc);
|
||||
}
|
||||
render()
|
||||
{
|
||||
return (
|
||||
<div style={{position: 'relative', width: '100%', height: 0}}>
|
||||
<div className='column w100p counter-statistic' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4, marginTop: 2}}>
|
||||
<div className='row w100p' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4}}>
|
||||
<div className='row inline' style={{color: '#e5f442', fontSize: '1.15em', fill: '#e5f442'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<path d="M35,0C23.849,0,14.43,2.588,11.215,6.475C4.669,8.077,0.884,10.775,0.146,13.51C0.062,13.657,0,13.818,0,14v0.5V26v0.5V27
|
||||
v11v0.5V39v12c0,0.162,0.043,0.315,0.117,0.451C1.298,56.346,11.864,60,25,60c11.24,0,20.579-2.68,23.786-6.518
|
||||
c6.359-1.546,10.366-4.076,11.09-7C59.955,46.34,60,46.175,60,46V34v-0.5V22v-0.5v-12C60,4.895,51.238,0,35,0z M47.805,39.348
|
||||
c-0.04,0.099-0.089,0.198-0.143,0.297c-0.067,0.123-0.142,0.246-0.231,0.369c-0.066,0.093-0.141,0.185-0.219,0.277
|
||||
@ -128,115 +128,115 @@ export default class TorrentsStatistic extends Component {
|
||||
c-0.317,1.941-3.314,3.891-7.972,5.255C49.999,51.063,50,51.031,50,51v-9.828c0.043-0.012,0.083-0.025,0.126-0.037
|
||||
c0.4-0.112,0.79-0.227,1.168-0.346c0.004-0.001,0.009-0.003,0.013-0.004c2.961-0.936,5.22-2.099,6.693-3.427v8.346
|
||||
C57.986,45.747,57.976,45.792,57.968,45.838z"/>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{ formatBytes(this.stats.size, 1) } {__('data')}</div>
|
||||
</div>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{ formatBytes(this.stats.size, 1) } {__('data')}</div>
|
||||
</div>
|
||||
|
||||
<div className='row inline' style={{color: '#f48641', fontSize: '1.15em', fill: '#f48641', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<g>
|
||||
<path d="M60,8.311c0-0.199-0.052-0.382-0.131-0.551c-0.027-0.209-0.112-0.412-0.254-0.579L53.46,0H6.54L0.384,7.182
|
||||
<div className='row inline' style={{color: '#f48641', fontSize: '1.15em', fill: '#f48641', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<g>
|
||||
<path d="M60,8.311c0-0.199-0.052-0.382-0.131-0.551c-0.027-0.209-0.112-0.412-0.254-0.579L53.46,0H6.54L0.384,7.182
|
||||
C0.242,7.348,0.157,7.55,0.131,7.76C0.052,7.929,0,8.112,0,8.311V19h3v41h54V19h3V8.311z M7.46,2h45.08l4.286,5H3.174L7.46,2z
|
||||
M55,58H5V19h50V58z M58,17h-1H3H2V9h56V17z"/>
|
||||
<path d="M42,23H18v10h24V23z M40,31H20v-6h20V31z"/>
|
||||
<path d="M45,38H15v14h30V38z M43,50H17V40h26V50z"/>
|
||||
<path d="M22,48h5c0.552,0,1-0.447,1-1s-0.448-1-1-1h-5c-0.552,0-1,0.447-1,1S21.448,48,22,48z"/>
|
||||
<path d="M27,44h11c0.552,0,1-0.447,1-1s-0.448-1-1-1H27c-0.552,0-1,0.447-1,1S26.448,44,27,44z"/>
|
||||
<path d="M22,44c0.26,0,0.52-0.11,0.71-0.29C22.89,43.52,23,43.26,23,43c0-0.261-0.11-0.521-0.29-0.71c-0.38-0.37-1.04-0.37-1.42,0
|
||||
<path d="M42,23H18v10h24V23z M40,31H20v-6h20V31z"/>
|
||||
<path d="M45,38H15v14h30V38z M43,50H17V40h26V50z"/>
|
||||
<path d="M22,48h5c0.552,0,1-0.447,1-1s-0.448-1-1-1h-5c-0.552,0-1,0.447-1,1S21.448,48,22,48z"/>
|
||||
<path d="M27,44h11c0.552,0,1-0.447,1-1s-0.448-1-1-1H27c-0.552,0-1,0.447-1,1S26.448,44,27,44z"/>
|
||||
<path d="M22,44c0.26,0,0.52-0.11,0.71-0.29C22.89,43.52,23,43.26,23,43c0-0.261-0.11-0.521-0.29-0.71c-0.38-0.37-1.04-0.37-1.42,0
|
||||
C21.11,42.479,21,42.739,21,43c0,0.27,0.11,0.52,0.29,0.71C21.48,43.89,21.73,44,22,44z"/>
|
||||
<path d="M31.29,46.29C31.11,46.479,31,46.739,31,47c0,0.26,0.11,0.52,0.29,0.71C31.48,47.89,31.74,48,32,48
|
||||
<path d="M31.29,46.29C31.11,46.479,31,46.739,31,47c0,0.26,0.11,0.52,0.29,0.71C31.48,47.89,31.74,48,32,48
|
||||
c0.26,0,0.52-0.11,0.71-0.29C32.89,47.52,33,47.26,33,47c0-0.261-0.11-0.521-0.29-0.71C32.34,45.92,31.66,45.92,31.29,46.29z"/>
|
||||
<path d="M38,46h-1c-0.552,0-1,0.447-1,1s0.448,1,1,1h1c0.552,0,1-0.447,1-1S38.552,46,38,46z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{this.stats.torrents} {__('torrents')}</div>
|
||||
</div>
|
||||
<path d="M38,46h-1c-0.552,0-1,0.447-1,1s0.448,1,1,1h1c0.552,0,1-0.447,1-1S38.552,46,38,46z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{this.stats.torrents} {__('torrents')}</div>
|
||||
</div>
|
||||
|
||||
<div className='row inline' style={{color: '#f441e2', fontSize: '1.15em', fill: '#f441e2', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<g>
|
||||
<path d="M42.5,22h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,22,42.5,22z"/>
|
||||
<path d="M17.5,16h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S16.948,16,17.5,16z"/>
|
||||
<path d="M42.5,30h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,30,42.5,30z"/>
|
||||
<path d="M42.5,38h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,38,42.5,38z"/>
|
||||
<path d="M42.5,46h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,46,42.5,46z"/>
|
||||
<path d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{this.stats.files} {__('files')}</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className='row inline' style={{color: '#f441e2', fontSize: '1.15em', fill: '#f441e2', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 60 60">
|
||||
<g>
|
||||
<path d="M42.5,22h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,22,42.5,22z"/>
|
||||
<path d="M17.5,16h10c0.552,0,1-0.447,1-1s-0.448-1-1-1h-10c-0.552,0-1,0.447-1,1S16.948,16,17.5,16z"/>
|
||||
<path d="M42.5,30h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,30,42.5,30z"/>
|
||||
<path d="M42.5,38h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,38,42.5,38z"/>
|
||||
<path d="M42.5,46h-25c-0.552,0-1,0.447-1,1s0.448,1,1,1h25c0.552,0,1-0.447,1-1S43.052,46,42.5,46z"/>
|
||||
<path d="M38.914,0H6.5v60h47V14.586L38.914,0z M39.5,3.414L50.086,14H39.5V3.414z M8.5,58V2h29v14h14v42H8.5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{this.stats.files} {__('files')}</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className='row w100p' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4, marginTop: 5}}>
|
||||
<div className='row inline' style={{color: window.peers > 0 ? '#19c632' : 'white', fontSize: '1.15em', fill: window.peers > 0 ? '#19c632' : 'white'}}>
|
||||
<svg viewBox="0 0 47 47">
|
||||
<g>
|
||||
<path d="M17.567,15.938l-2.859-2.702c0.333-0.605,0.539-1.29,0.539-2.029c0-2.342-1.897-4.239-4.24-4.239
|
||||
<div className='row w100p' style={{backgroundColor: 'rgba(0,0,0,0.7)', padding: 8, borderRadius: 4, marginTop: 5}}>
|
||||
<div className='row inline' style={{color: window.peers > 0 ? '#19c632' : 'white', fontSize: '1.15em', fill: window.peers > 0 ? '#19c632' : 'white'}}>
|
||||
<svg viewBox="0 0 47 47">
|
||||
<g>
|
||||
<path d="M17.567,15.938l-2.859-2.702c0.333-0.605,0.539-1.29,0.539-2.029c0-2.342-1.897-4.239-4.24-4.239
|
||||
c-2.343,0-4.243,1.896-4.243,4.239c0,2.343,1.9,4.241,4.243,4.241c0.826,0,1.59-0.246,2.242-0.654l2.855,2.699
|
||||
C16.536,16.922,17.023,16.399,17.567,15.938z"/>
|
||||
<path d="M29.66,15.6l3.799-6.393c0.374,0.107,0.762,0.184,1.169,0.184c2.347,0,4.244-1.898,4.244-4.241
|
||||
<path d="M29.66,15.6l3.799-6.393c0.374,0.107,0.762,0.184,1.169,0.184c2.347,0,4.244-1.898,4.244-4.241
|
||||
c0-2.342-1.897-4.239-4.244-4.239c-2.343,0-4.239,1.896-4.239,4.239c0,1.163,0.469,2.214,1.227,2.981l-3.787,6.375
|
||||
C28.48,14.801,29.094,15.169,29.66,15.6z"/>
|
||||
<path d="M42.762,20.952c-1.824,0-3.369,1.159-3.968,2.775l-5.278-0.521c0,0.04,0.006,0.078,0.006,0.117
|
||||
<path d="M42.762,20.952c-1.824,0-3.369,1.159-3.968,2.775l-5.278-0.521c0,0.04,0.006,0.078,0.006,0.117
|
||||
c0,0.688-0.076,1.36-0.213,2.009l5.276,0.521c0.319,2.024,2.062,3.576,4.177,3.576c2.342,0,4.238-1.896,4.238-4.238
|
||||
C47,22.85,45.104,20.952,42.762,20.952z"/>
|
||||
<path d="M28.197,37.624l-1.18-5.156c-0.666,0.232-1.359,0.398-2.082,0.481l1.182,5.157c-1.355,0.709-2.29,2.11-2.29,3.746
|
||||
<path d="M28.197,37.624l-1.18-5.156c-0.666,0.232-1.359,0.398-2.082,0.481l1.182,5.157c-1.355,0.709-2.29,2.11-2.29,3.746
|
||||
c0,2.342,1.896,4.237,4.243,4.237c2.342,0,4.238-1.896,4.238-4.237C32.311,39.553,30.479,37.692,28.197,37.624z"/>
|
||||
<path d="M14.357,25.37l-6.57,2.201c-0.758-1.158-2.063-1.926-3.548-1.926C1.896,25.645,0,27.542,0,29.884
|
||||
<path d="M14.357,25.37l-6.57,2.201c-0.758-1.158-2.063-1.926-3.548-1.926C1.896,25.645,0,27.542,0,29.884
|
||||
c0,2.345,1.896,4.242,4.239,4.242c2.341,0,4.242-1.897,4.242-4.242c0-0.098-0.021-0.188-0.029-0.284l6.591-2.207
|
||||
C14.746,26.752,14.51,26.077,14.357,25.37z"/>
|
||||
<circle cx="23.83" cy="23.323" r="7.271"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{window.peers} {__('peers')}</div>
|
||||
</div>
|
||||
<circle cx="23.83" cy="23.323" r="7.271"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{window.peers} {__('peers')}</div>
|
||||
</div>
|
||||
|
||||
<div className='row inline' style={{color: window.peersTorrents > 0 ? '#19c687' : 'white', fontSize: '1.15em', fill: window.peersTorrents > 0 ? '#19c687' : 'white', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 481.6 481.6">
|
||||
<g>
|
||||
<path d="M381.6,309.4c-27.7,0-52.4,13.2-68.2,33.6l-132.3-73.9c3.1-8.9,4.8-18.5,4.8-28.4c0-10-1.7-19.5-4.9-28.5l132.2-73.8
|
||||
<div className='row inline' style={{color: window.peersTorrents > 0 ? '#19c687' : 'white', fontSize: '1.15em', fill: window.peersTorrents > 0 ? '#19c687' : 'white', marginLeft: '20px'}}>
|
||||
<svg viewBox="0 0 481.6 481.6">
|
||||
<g>
|
||||
<path d="M381.6,309.4c-27.7,0-52.4,13.2-68.2,33.6l-132.3-73.9c3.1-8.9,4.8-18.5,4.8-28.4c0-10-1.7-19.5-4.9-28.5l132.2-73.8
|
||||
c15.7,20.5,40.5,33.8,68.3,33.8c47.4,0,86.1-38.6,86.1-86.1S429,0,381.5,0s-86.1,38.6-86.1,86.1c0,10,1.7,19.6,4.9,28.5
|
||||
l-132.1,73.8c-15.7-20.6-40.5-33.8-68.3-33.8c-47.4,0-86.1,38.6-86.1,86.1s38.7,86.1,86.2,86.1c27.8,0,52.6-13.3,68.4-33.9
|
||||
l132.2,73.9c-3.2,9-5,18.7-5,28.7c0,47.4,38.6,86.1,86.1,86.1s86.1-38.6,86.1-86.1S429.1,309.4,381.6,309.4z M381.6,27.1
|
||||
c32.6,0,59.1,26.5,59.1,59.1s-26.5,59.1-59.1,59.1s-59.1-26.5-59.1-59.1S349.1,27.1,381.6,27.1z M100,299.8
|
||||
c-32.6,0-59.1-26.5-59.1-59.1s26.5-59.1,59.1-59.1s59.1,26.5,59.1,59.1S132.5,299.8,100,299.8z M381.6,454.5
|
||||
c-32.6,0-59.1-26.5-59.1-59.1c0-32.6,26.5-59.1,59.1-59.1s59.1,26.5,59.1,59.1C440.7,428,414.2,454.5,381.6,454.5z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{window.peersTorrents} {__('remote torrents')}</div>
|
||||
</div>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{window.peersTorrents} {__('remote torrents')}</div>
|
||||
</div>
|
||||
|
||||
<div className='row inline' style={{color: window.p2pStatus == 2 ? '#78c619' : (window.p2pStatus == 1 ? '#c68319' : '#c6194a'), fontSize: '1.15em', fill: window.p2pStatus == 2 ? '#78c619' : (window.p2pStatus == 1 ? '#c68319' : '#c6194a'), marginLeft: '20px'}}>
|
||||
{
|
||||
window.p2pStatus == 0
|
||||
<div className='row inline' style={{color: window.p2pStatus == 2 ? '#78c619' : (window.p2pStatus == 1 ? '#c68319' : '#c6194a'), fontSize: '1.15em', fill: window.p2pStatus == 2 ? '#78c619' : (window.p2pStatus == 1 ? '#c68319' : '#c6194a'), marginLeft: '20px'}}>
|
||||
{
|
||||
window.p2pStatus == 0
|
||||
&&
|
||||
<div className='row inline w100p'>
|
||||
<svg viewBox="0 0 54.908 54.908">
|
||||
<g>
|
||||
<path d="M54.615,19.123c-7.243-7.244-16.89-11.233-27.161-11.233S7.537,11.878,0.293,19.123c-0.391,0.391-0.391,1.023,0,1.414
|
||||
<svg viewBox="0 0 54.908 54.908">
|
||||
<g>
|
||||
<path d="M54.615,19.123c-7.243-7.244-16.89-11.233-27.161-11.233S7.537,11.878,0.293,19.123c-0.391,0.391-0.391,1.023,0,1.414
|
||||
s1.023,0.391,1.414,0C8.573,13.67,17.717,9.889,27.454,9.889s18.881,3.781,25.747,10.647c0.195,0.195,0.451,0.293,0.707,0.293
|
||||
s0.512-0.098,0.707-0.293C55.006,20.146,55.006,19.513,54.615,19.123z"/>
|
||||
<path d="M6.171,25c-0.391,0.391-0.391,1.023,0,1.414c0.195,0.195,0.451,0.293,0.707,0.293s0.512-0.098,0.707-0.293
|
||||
<path d="M6.171,25c-0.391,0.391-0.391,1.023,0,1.414c0.195,0.195,0.451,0.293,0.707,0.293s0.512-0.098,0.707-0.293
|
||||
c10.955-10.956,28.781-10.956,39.737,0c0.391,0.391,1.023,0.391,1.414,0s0.391-1.023,0-1.414C37.002,13.266,17.907,13.264,6.171,25
|
||||
z"/>
|
||||
<path d="M27.454,24.508c-5.825,0-11.295,2.263-15.404,6.371c-0.391,0.391-0.391,1.023,0,1.414s1.023,0.391,1.414,0
|
||||
<path d="M27.454,24.508c-5.825,0-11.295,2.263-15.404,6.371c-0.391,0.391-0.391,1.023,0,1.414s1.023,0.391,1.414,0
|
||||
c3.731-3.73,8.699-5.785,13.99-5.785c5.291,0,10.259,2.055,13.99,5.785c0.195,0.195,0.451,0.293,0.707,0.293
|
||||
s0.512-0.098,0.707-0.293c0.391-0.391,0.391-1.023,0-1.414C38.75,26.771,33.279,24.508,27.454,24.508z"/>
|
||||
<path d="M27.454,33.916c-3.612,0-6.551,2.939-6.551,6.552s2.939,6.552,6.551,6.552c3.613,0,6.552-2.939,6.552-6.552
|
||||
<path d="M27.454,33.916c-3.612,0-6.551,2.939-6.551,6.552s2.939,6.552,6.551,6.552c3.613,0,6.552-2.939,6.552-6.552
|
||||
S31.067,33.916,27.454,33.916z M27.454,45.019c-2.51,0-4.551-2.042-4.551-4.552s2.042-4.552,4.551-4.552s4.552,2.042,4.552,4.552
|
||||
S29.964,45.019,27.454,45.019z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('not available')}</div>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('not available')}</div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
window.p2pStatus == 1
|
||||
}
|
||||
{
|
||||
window.p2pStatus == 1
|
||||
&&
|
||||
<div className='row inline w100p'>
|
||||
<svg viewBox="0 0 611.989 611.988">
|
||||
<g>
|
||||
<path d="M305.994,417.769c-30.85,0-55.887,25.037-55.887,55.887s25.038,55.887,55.887,55.887s55.887-25.037,55.887-55.887
|
||||
<svg viewBox="0 0 611.989 611.988">
|
||||
<g>
|
||||
<path d="M305.994,417.769c-30.85,0-55.887,25.037-55.887,55.887s25.038,55.887,55.887,55.887s55.887-25.037,55.887-55.887
|
||||
S336.843,417.769,305.994,417.769z M605.436,222.369C530.697,133.434,421.549,82.446,305.994,82.446
|
||||
S81.309,133.434,6.551,222.369c-9.93,11.811-8.402,29.434,3.428,39.363c5.234,4.396,11.587,6.558,17.939,6.558
|
||||
c7.973,0,15.891-3.391,21.423-9.967c64.084-76.248,157.639-119.989,256.652-119.989c99.013,0,192.568,43.741,256.651,119.971
|
||||
@ -249,18 +249,18 @@ export default class TorrentsStatistic extends Component {
|
||||
c7.973,0,15.891-3.39,21.405-9.966c21.368-25.429,52.552-40.016,85.544-40.016s64.177,14.587,85.544,40.016
|
||||
c5.533,6.595,13.45,9.966,21.405,9.966c6.353,0,12.724-2.142,17.958-6.557c11.83-9.93,13.357-27.553,3.428-39.363
|
||||
C402.324,327.846,355.546,305.994,305.994,305.994z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('redirect')}</div>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('redirect')}</div>
|
||||
</div>
|
||||
}
|
||||
{
|
||||
window.p2pStatus == 2
|
||||
}
|
||||
{
|
||||
window.p2pStatus == 2
|
||||
&&
|
||||
<div className='row inline w100p'>
|
||||
<svg viewBox="0 0 611.989 611.988">
|
||||
<g>
|
||||
<path d="M305.994,417.769c-30.85,0-55.887,25.037-55.887,55.887s25.038,55.887,55.887,55.887s55.887-25.037,55.887-55.887
|
||||
<svg viewBox="0 0 611.989 611.988">
|
||||
<g>
|
||||
<path d="M305.994,417.769c-30.85,0-55.887,25.037-55.887,55.887s25.038,55.887,55.887,55.887s55.887-25.037,55.887-55.887
|
||||
S336.843,417.769,305.994,417.769z M605.436,222.369C530.697,133.434,421.549,82.446,305.994,82.446
|
||||
S81.309,133.434,6.551,222.369c-9.93,11.811-8.402,29.434,3.428,39.363c5.234,4.396,11.587,6.558,17.939,6.558
|
||||
c7.973,0,15.891-3.391,21.423-9.967c64.084-76.248,157.639-119.989,256.652-119.989c99.013,0,192.568,43.741,256.651,119.971
|
||||
@ -273,16 +273,16 @@ export default class TorrentsStatistic extends Component {
|
||||
c7.973,0,15.891-3.39,21.405-9.966c21.368-25.429,52.552-40.016,85.544-40.016s64.177,14.587,85.544,40.016
|
||||
c5.533,6.595,13.45,9.966,21.405,9.966c6.353,0,12.724-2.142,17.958-6.557c11.83-9.93,13.357-27.553,3.428-39.363
|
||||
C402.324,327.846,355.546,305.994,305.994,305.994z"/>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('direct')}</div>
|
||||
</g>
|
||||
</svg>
|
||||
<div style={{marginLeft: '5px'}}>{__('direct')}</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
@ -11,12 +11,12 @@ import LinearProgress from 'material-ui/LinearProgress';
|
||||
let rating = require('./rating');
|
||||
|
||||
const contentIcon = (type, category, fill = 'grey') => {
|
||||
if(category == 'xxx')
|
||||
{
|
||||
return (
|
||||
<svg viewBox="0 0 18.282 18.282" fill={fill}>
|
||||
<g>
|
||||
<path d="M16.435,3.832H1.847C0.827,3.832,0,4.659,0,5.678v6.925c0,1.021,0.827,1.848,1.847,1.848h14.588
|
||||
if(category == 'xxx')
|
||||
{
|
||||
return (
|
||||
<svg viewBox="0 0 18.282 18.282" fill={fill}>
|
||||
<g>
|
||||
<path d="M16.435,3.832H1.847C0.827,3.832,0,4.659,0,5.678v6.925c0,1.021,0.827,1.848,1.847,1.848h14.588
|
||||
c1.021,0,1.847-0.827,1.847-1.848V5.678C18.282,4.659,17.455,3.832,16.435,3.832z M3.194,7.123H2.583v4.042h0.611v0.54H1.876V6.583
|
||||
h1.318V7.123z M6.197,10.986l-0.392-0.784C5.644,9.9,5.541,9.676,5.419,9.425H5.406c-0.09,0.251-0.199,0.476-0.334,0.777
|
||||
l-0.36,0.784H3.593l1.254-2.191L3.638,6.654h1.125l0.379,0.791C5.27,7.709,5.367,7.921,5.47,8.165h0.013
|
||||
@ -27,87 +27,87 @@ const contentIcon = (type, category, fill = 'grey') => {
|
||||
c-0.16-0.302-0.263-0.526-0.386-0.777h-0.012c-0.091,0.251-0.2,0.476-0.335,0.777l-0.36,0.784h-1.117l1.253-2.191l-1.209-2.141
|
||||
h1.125l0.379,0.791c0.129,0.264,0.226,0.476,0.328,0.72h0.013c0.104-0.276,0.187-0.47,0.296-0.72l0.366-0.791h1.118l-1.221,2.114
|
||||
l1.286,2.218C15.071,10.986,13.94,10.986,13.94,10.986z M16.756,11.705h-1.311v-0.54h0.611V7.116h-0.611v-0.54h1.311V11.705z"/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
|
||||
switch(type)
|
||||
{
|
||||
case 'video':
|
||||
return (
|
||||
<svg viewBox="0 0 491.858 491.858" fill={fill}>
|
||||
<path d="M357.714,423.331c0,9.328-10.676,16.891-23.847,16.891H23.847C10.676,440.222,0,432.659,0,423.331V203.735
|
||||
switch(type)
|
||||
{
|
||||
case 'video':
|
||||
return (
|
||||
<svg viewBox="0 0 491.858 491.858" fill={fill}>
|
||||
<path d="M357.714,423.331c0,9.328-10.676,16.891-23.847,16.891H23.847C10.676,440.222,0,432.659,0,423.331V203.735
|
||||
c0-9.33,10.676-16.892,23.847-16.892h310.02c13.171,0,23.847,7.564,23.847,16.892V423.331L357.714,423.331z"/>
|
||||
<circle cx="89.428" cy="118.706" r="59.619"/>
|
||||
<circle cx="253.381" cy="103.801" r="74.524"/>
|
||||
<path d="M491.858,447.677c0,0-1.986,14.904-15.899,14.904c-13.912,0-103.34-83.42-103.34-94.397V258.882
|
||||
<circle cx="89.428" cy="118.706" r="59.619"/>
|
||||
<circle cx="253.381" cy="103.801" r="74.524"/>
|
||||
<path d="M491.858,447.677c0,0-1.986,14.904-15.899,14.904c-13.912,0-103.34-83.42-103.34-94.397V258.882
|
||||
c0-10.976,87.443-94.398,103.34-94.398c15.899,0,15.899,14.905,15.899,14.905V447.677z"/>
|
||||
</svg>
|
||||
)
|
||||
case 'audio':
|
||||
return (
|
||||
<svg viewBox="0 0 46 46" fill={fill}>
|
||||
<path d="M28.38,0c-0.551,0-1.097,0.153-1.579,0.444c-0.046,0.027-0.09,0.059-0.13,0.093L13.121,12H2.487c-0.553,0-1,0.447-1,1v19
|
||||
</svg>
|
||||
)
|
||||
case 'audio':
|
||||
return (
|
||||
<svg viewBox="0 0 46 46" fill={fill}>
|
||||
<path d="M28.38,0c-0.551,0-1.097,0.153-1.579,0.444c-0.046,0.027-0.09,0.059-0.13,0.093L13.121,12H2.487c-0.553,0-1,0.447-1,1v19
|
||||
c0,0.553,0.447,1,1,1h10.61L26.64,45.436c0.05,0.046,0.104,0.086,0.161,0.12C27.284,45.847,27.83,46,28.38,46
|
||||
c1.713,0,3.106-1.416,3.106-3.156V3.156C31.487,1.416,30.093,0,28.38,0z M14.487,31c0,0.553-0.447,1-1,1s-1-0.447-1-1v-4
|
||||
c0-0.553,0.447-1,1-1s1,0.447,1,1V31z M14.487,18c0,0.553-0.447,1-1,1s-1-0.447-1-1v-4c0-0.553,0.447-1,1-1s1,0.447,1,1V18z"/>
|
||||
<path d="M44.513,22.5c0-5.972-4.009-11.302-9.749-12.962c-0.533-0.151-1.084,0.152-1.238,0.684
|
||||
<path d="M44.513,22.5c0-5.972-4.009-11.302-9.749-12.962c-0.533-0.151-1.084,0.152-1.238,0.684
|
||||
c-0.153,0.53,0.152,1.085,0.684,1.238c4.889,1.413,8.304,5.953,8.304,11.04s-3.415,9.627-8.304,11.04
|
||||
c-0.531,0.153-0.837,0.708-0.684,1.238c0.127,0.438,0.526,0.723,0.961,0.723c0.092,0,0.185-0.013,0.277-0.039
|
||||
C40.504,33.802,44.513,28.472,44.513,22.5z"/>
|
||||
</svg>
|
||||
</svg>
|
||||
|
||||
)
|
||||
case 'pictures':
|
||||
return (
|
||||
<svg viewBox="0 0 58 58" fill={fill}>
|
||||
<path d="M57,6H1C0.448,6,0,6.447,0,7v44c0,0.553,0.448,1,1,1h56c0.552,0,1-0.447,1-1V7C58,6.447,57.552,6,57,6z M16,17
|
||||
)
|
||||
case 'pictures':
|
||||
return (
|
||||
<svg viewBox="0 0 58 58" fill={fill}>
|
||||
<path d="M57,6H1C0.448,6,0,6.447,0,7v44c0,0.553,0.448,1,1,1h56c0.552,0,1-0.447,1-1V7C58,6.447,57.552,6,57,6z M16,17
|
||||
c3.071,0,5.569,2.498,5.569,5.569c0,3.07-2.498,5.568-5.569,5.568s-5.569-2.498-5.569-5.568C10.431,19.498,12.929,17,16,17z
|
||||
M52.737,35.676c-0.373,0.406-1.006,0.435-1.413,0.062L40.063,25.414l-9.181,10.054l4.807,4.807c0.391,0.391,0.391,1.023,0,1.414
|
||||
s-1.023,0.391-1.414,0L23.974,31.389L7.661,45.751C7.471,45.918,7.235,46,7,46c-0.277,0-0.553-0.114-0.751-0.339
|
||||
c-0.365-0.415-0.325-1.047,0.09-1.412l17.017-14.982c0.396-0.348,0.994-0.329,1.368,0.044l4.743,4.743l9.794-10.727
|
||||
c0.179-0.196,0.429-0.313,0.694-0.325c0.264-0.006,0.524,0.083,0.72,0.262l12,11C53.083,34.636,53.11,35.269,52.737,35.676z"/>
|
||||
</svg>
|
||||
)
|
||||
case 'application':
|
||||
return (
|
||||
<svg viewBox="0 0 483.85 483.85" fill={fill}>
|
||||
<path d="M471.325,211.856l-56.9-56.9c-23.4-23.4-9.1-48.1,16.4-49.6c42-2.6,65.6-47.4,31.3-84.7c-37.3-34.2-81.9-10.7-84.5,31.2
|
||||
</svg>
|
||||
)
|
||||
case 'application':
|
||||
return (
|
||||
<svg viewBox="0 0 483.85 483.85" fill={fill}>
|
||||
<path d="M471.325,211.856l-56.9-56.9c-23.4-23.4-9.1-48.1,16.4-49.6c42-2.6,65.6-47.4,31.3-84.7c-37.3-34.2-81.9-10.7-84.5,31.2
|
||||
c-1.6,25.5-26.5,39.9-49.8,16.6l-55.7-55.7c-16.7-16.7-43.8-16.7-60.5,0l-56.4,56.4c-23.4,23.4-48.2,8.9-49.8-16.6
|
||||
c-2.6-42-47.6-65.9-84.9-31.6c-34.4,37.4-10.5,82.4,31.5,85c25.5,1.6,40,26.5,16.7,49.9l-56.2,56.1c-16.7,16.7-16.7,43.8,0,60.5
|
||||
l55.7,55.7c23.4,23.3,9.5,47.6-16,49.2c-42,2.6-65.5,47.3-31.2,84.6c37.3,34.3,81.8,10.9,84.4-31.1c1.6-25.5,26-39.5,49.4-16.2
|
||||
l56.2,56.2c17,17,44.8,17,61.8,0.1l39.4-39.4l16.9-16.9c22.1-23.1,7.8-47.4-17.4-49c-42-2.6-65.8-47.6-31.5-84.9
|
||||
c37.3-34.3,82.3-10.4,84.9,31.6c1.6,25.2,25.8,39.4,48.9,17.3l15.3-15.3l41.2-41.2c0.1-0.1,0.1-0.1,0.2-0.2l0.6-0.6
|
||||
C488.025,255.656,488.025,228.556,471.325,211.856z"/>
|
||||
</svg>
|
||||
)
|
||||
case 'books':
|
||||
return (
|
||||
<svg viewBox="0 0 296.999 296.999" fill={fill}>
|
||||
<g>
|
||||
<path d="M45.432,35.049c-0.008,0-0.017,0-0.025,0c-2.809,0-5.451,1.095-7.446,3.085c-2.017,2.012-3.128,4.691-3.128,7.543
|
||||
</svg>
|
||||
)
|
||||
case 'books':
|
||||
return (
|
||||
<svg viewBox="0 0 296.999 296.999" fill={fill}>
|
||||
<g>
|
||||
<path d="M45.432,35.049c-0.008,0-0.017,0-0.025,0c-2.809,0-5.451,1.095-7.446,3.085c-2.017,2.012-3.128,4.691-3.128,7.543
|
||||
v159.365c0,5.844,4.773,10.61,10.641,10.625c24.738,0.059,66.184,5.215,94.776,35.136V84.023c0-1.981-0.506-3.842-1.461-5.382
|
||||
C115.322,40.849,70.226,35.107,45.432,35.049z"/>
|
||||
<path d="M262.167,205.042V45.676c0-2.852-1.111-5.531-3.128-7.543c-1.995-1.99-4.639-3.085-7.445-3.085c-0.009,0-0.018,0-0.026,0
|
||||
<path d="M262.167,205.042V45.676c0-2.852-1.111-5.531-3.128-7.543c-1.995-1.99-4.639-3.085-7.445-3.085c-0.009,0-0.018,0-0.026,0
|
||||
c-24.793,0.059-69.889,5.801-93.357,43.593c-0.955,1.54-1.46,3.401-1.46,5.382v166.779
|
||||
c28.592-29.921,70.038-35.077,94.776-35.136C257.394,215.651,262.167,210.885,262.167,205.042z"/>
|
||||
<path d="M286.373,71.801h-7.706v133.241c0,14.921-12.157,27.088-27.101,27.125c-20.983,0.05-55.581,4.153-80.084,27.344
|
||||
<path d="M286.373,71.801h-7.706v133.241c0,14.921-12.157,27.088-27.101,27.125c-20.983,0.05-55.581,4.153-80.084,27.344
|
||||
c42.378-10.376,87.052-3.631,112.512,2.171c3.179,0.724,6.464-0.024,9.011-2.054c2.538-2.025,3.994-5.052,3.994-8.301V82.427
|
||||
C297,76.568,292.232,71.801,286.373,71.801z"/>
|
||||
<path d="M18.332,205.042V71.801h-7.706C4.768,71.801,0,76.568,0,82.427v168.897c0,3.25,1.456,6.276,3.994,8.301
|
||||
<path d="M18.332,205.042V71.801h-7.706C4.768,71.801,0,76.568,0,82.427v168.897c0,3.25,1.456,6.276,3.994,8.301
|
||||
c2.545,2.029,5.827,2.78,9.011,2.054c25.46-5.803,70.135-12.547,112.511-2.171c-24.502-23.19-59.1-27.292-80.083-27.342
|
||||
C30.49,232.13,18.332,219.963,18.332,205.042z"/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
case 'archive':
|
||||
return (
|
||||
<svg viewBox="0 0 390 390" fill={fill}>
|
||||
<g>
|
||||
<path d="M182.681,205.334c0,5.21,4.227,9.436,9.436,9.436h5.765c5.21,0,9.436-4.226,9.436-9.436c0-5.211-4.226-9.438-9.436-9.438
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
case 'archive':
|
||||
return (
|
||||
<svg viewBox="0 0 390 390" fill={fill}>
|
||||
<g>
|
||||
<path d="M182.681,205.334c0,5.21,4.227,9.436,9.436,9.436h5.765c5.21,0,9.436-4.226,9.436-9.436c0-5.211-4.226-9.438-9.436-9.438
|
||||
h-5.765C186.908,195.897,182.681,200.123,182.681,205.334z"/>
|
||||
<path d="M383.889,126.058c-4.478-5.191-10.868-8.314-17.674-8.686V64.899c0-25.562-20.797-46.359-46.361-46.359h-75.278
|
||||
<path d="M383.889,126.058c-4.478-5.191-10.868-8.314-17.674-8.686V64.899c0-25.562-20.797-46.359-46.361-46.359h-75.278
|
||||
c-25.052,0-38.351,10.578-48.062,18.303c-7.807,6.208-12.518,9.955-22.626,9.955H65.099c-22.78,0-41.313,18.062-41.313,40.264
|
||||
v30.311c-6.806,0.371-13.196,3.494-17.674,8.686c-4.78,5.541-6.912,12.888-5.839,20.125l30.194,203.803
|
||||
c1.828,12.338,12.417,21.475,24.89,21.475h279.286c12.473,0,23.063-9.137,24.891-21.475l30.195-203.802
|
||||
@ -123,115 +123,115 @@ const contentIcon = (type, category, fill = 'grey') => {
|
||||
h-32.443c-2.399,0-4.345-1.944-4.345-4.345V279.28c0-2.4,1.946-4.346,4.345-4.346h32.443c2.399,0,4.345,1.945,4.345,4.346V289.708z
|
||||
M335.919,117.333H54.081V87.062c0-6.239,5.602-9.968,11.019-9.968h108.788c20.687,0,32.219-9.173,41.484-16.542
|
||||
c8.552-6.803,14.732-11.717,29.204-11.717h75.278c8.858,0,16.066,7.206,16.066,16.064V117.333z"/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
case 'disc':
|
||||
return (
|
||||
<svg viewBox="0 0 49.652 49.652" fill={fill}>
|
||||
<g>
|
||||
<circle cx="24.826" cy="24.825" r="3.529"/>
|
||||
<path d="M42.381,7.271C37.693,2.582,31.458,0,24.826,0C18.195,0,11.96,2.583,7.271,7.271c-9.68,9.68-9.68,25.43,0,35.11
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
case 'disc':
|
||||
return (
|
||||
<svg viewBox="0 0 49.652 49.652" fill={fill}>
|
||||
<g>
|
||||
<circle cx="24.826" cy="24.825" r="3.529"/>
|
||||
<path d="M42.381,7.271C37.693,2.582,31.458,0,24.826,0C18.195,0,11.96,2.583,7.271,7.271c-9.68,9.68-9.68,25.43,0,35.11
|
||||
c4.689,4.688,10.923,7.271,17.555,7.271c6.632,0,12.867-2.582,17.555-7.271C52.061,32.701,52.061,16.951,42.381,7.271z
|
||||
M24.86,45.002l0.039-12.587c-1.967,0.019-3.941-0.719-5.442-2.22c-2.965-2.965-2.964-7.772,0-10.737
|
||||
c0.022-0.022,0.047-0.04,0.069-0.062l-8.935-8.936c4.059-4.072,9.234-6.027,14.363-5.91l-0.039,12.689
|
||||
c1.915,0.022,3.82,0.759,5.28,2.219c2.942,2.942,2.96,7.699,0.063,10.668l8.967,8.968C35.166,43.164,29.99,45.119,24.86,45.002z"
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<svg viewBox="0 0 123.769 123.769" fill={fill}>
|
||||
<g>
|
||||
<path d="M76.05,1.568l-10.101,9.3c-2.3,2.1-5.8,2.1-8.1,0l-10.2-9.2c-3.1-2.8-8-1.7-9.6,2.1l-8.3,20h64.2l-8.3-20.1
|
||||
/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
default:
|
||||
return (
|
||||
<svg viewBox="0 0 123.769 123.769" fill={fill}>
|
||||
<g>
|
||||
<path d="M76.05,1.568l-10.101,9.3c-2.3,2.1-5.8,2.1-8.1,0l-10.2-9.2c-3.1-2.8-8-1.7-9.6,2.1l-8.3,20h64.2l-8.3-20.1
|
||||
C84.05-0.131,79.149-1.231,76.05,1.568z"/>
|
||||
<path d="M10.749,42.068c-2.9,1.4-1.8,5.7,1.3,5.7h49.8h49.701c3.199,0,4.199-4.3,1.399-5.7l-12.2-6.3h-77.8L10.749,42.068z"/>
|
||||
<path d="M0.549,90.168l5.3,28.801c0.5,2.899,3,4.8,5.9,4.8h50.1h50.201c2.899,0,5.399-2,5.899-4.8l5.3-28.801
|
||||
<path d="M10.749,42.068c-2.9,1.4-1.8,5.7,1.3,5.7h49.8h49.701c3.199,0,4.199-4.3,1.399-5.7l-12.2-6.3h-77.8L10.749,42.068z"/>
|
||||
<path d="M0.549,90.168l5.3,28.801c0.5,2.899,3,4.8,5.9,4.8h50.1h50.201c2.899,0,5.399-2,5.899-4.8l5.3-28.801
|
||||
c0.5-2.8-1-5.6-3.699-6.699c-12.801-5-26.2-7.7-36.801-9.301c-2.699-0.399-5.3,1.101-6.3,3.5l-10.1,22.9c-1.8,4-7.5,4-9.201-0.1
|
||||
l-9.8-22.7c-1.1-2.5-3.7-4-6.4-3.601c-10.6,1.5-24,4.301-36.7,9.301C1.549,84.469-0.051,87.269,0.549,90.168z"/>
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
</g>
|
||||
</svg>
|
||||
)
|
||||
}
|
||||
};
|
||||
export {contentIcon}
|
||||
|
||||
export default class Torrent extends Component {
|
||||
state = {
|
||||
downloading: false,
|
||||
askDownloading: false,
|
||||
downloadProgress: {}
|
||||
downloading: false,
|
||||
askDownloading: false,
|
||||
downloadProgress: {}
|
||||
}
|
||||
constructor(props)
|
||||
{
|
||||
super(props)
|
||||
if(props.download)
|
||||
{
|
||||
const { progress, downloaded, speed } = props.download
|
||||
this.state.downloadProgress = {
|
||||
progress, downloaded, speed
|
||||
}
|
||||
}
|
||||
super(props)
|
||||
if(props.download)
|
||||
{
|
||||
const { progress, downloaded, speed } = props.download
|
||||
this.state.downloadProgress = {
|
||||
progress, downloaded, speed
|
||||
}
|
||||
}
|
||||
}
|
||||
componentDidMount()
|
||||
{
|
||||
this.downloading = (hash) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
this.downloading = (hash) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({downloading: true})
|
||||
}
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
this.setState({downloading: true})
|
||||
}
|
||||
window.torrentSocket.on('downloading', this.downloading);
|
||||
|
||||
this.downloadDone = (hash, canceled) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
this.downloadDone = (hash, canceled) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({
|
||||
downloading: false,
|
||||
askDownloading: !canceled
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
this.setState({
|
||||
downloading: false,
|
||||
askDownloading: !canceled
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadDone', this.downloadDone);
|
||||
|
||||
this.downloadProgress = (hash, progress) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
this.downloadProgress = (hash, progress) => {
|
||||
if(this.props.torrent.hash != hash)
|
||||
return;
|
||||
|
||||
this.setState({
|
||||
downloading: true,
|
||||
askDownloading: true,
|
||||
downloadProgress: progress
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadProgress', this.downloadProgress);
|
||||
this.setState({
|
||||
downloading: true,
|
||||
askDownloading: true,
|
||||
downloadProgress: progress
|
||||
})
|
||||
}
|
||||
window.torrentSocket.on('downloadProgress', this.downloadProgress);
|
||||
}
|
||||
componentWillUnmount()
|
||||
{
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
if(this.downloadProgress)
|
||||
window.torrentSocket.off('downloadProgress', this.downloadProgress);
|
||||
if(this.downloading)
|
||||
window.torrentSocket.off('downloading', this.downloading);
|
||||
if(this.downloadDone)
|
||||
window.torrentSocket.off('downloadDone', this.downloadDone);
|
||||
if(this.downloadProgress)
|
||||
window.torrentSocket.off('downloadProgress', this.downloadProgress);
|
||||
}
|
||||
render()
|
||||
{
|
||||
const torrent = this.props.torrent;
|
||||
let torrentRating = -1
|
||||
if(torrent.good > 0 || torrent.bad > 0)
|
||||
torrentRating = Math.round(rating(torrent.good, torrent.bad) * 100);
|
||||
const torrent = this.props.torrent;
|
||||
let torrentRating = -1
|
||||
if(torrent.good > 0 || torrent.bad > 0)
|
||||
torrentRating = Math.round(rating(torrent.good, torrent.bad) * 100);
|
||||
|
||||
return (
|
||||
<div>
|
||||
<ListItem
|
||||
onClick={(e) => {
|
||||
const link = '/torrent/' + torrent.hash;
|
||||
if(e.button === 1)
|
||||
return false;
|
||||
return (
|
||||
<div>
|
||||
<ListItem
|
||||
onClick={(e) => {
|
||||
const link = '/torrent/' + torrent.hash;
|
||||
if(e.button === 1)
|
||||
return false;
|
||||
|
||||
/*
|
||||
/*
|
||||
if(e.ctrlKey && e.button === 0) {
|
||||
let win = window.open(link, '_blank');
|
||||
//win.focus();
|
||||
@ -239,105 +239,105 @@ export default class Torrent extends Component {
|
||||
}
|
||||
*/
|
||||
|
||||
PagesPie.instance().open(TorrentPage, {replace: 'all', hash: torrent.hash, peer: torrent.peer})
|
||||
}}
|
||||
primaryText={
|
||||
<a href={'/torrent/' + torrent.hash} ref={(node) => {
|
||||
if(node)
|
||||
node.onclick = () => { return false }
|
||||
}}>
|
||||
<span className='break-word' style={{
|
||||
color: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}}>
|
||||
{torrent.name}
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
secondaryText={
|
||||
<a href={'/torrent/' + torrent.hash} ref={(node) => {
|
||||
if(node)
|
||||
node.onclick = () => { return false }
|
||||
}}>
|
||||
<div className='column' style={{height: 'auto', whiteSpace: 'normal', paddingTop: '0.30em'}}>
|
||||
<div className='row w100p inline'>
|
||||
<div style={{color: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5252d1' : 'black') : (torrent.peer ? '#9083e2' : 'grey')}}>
|
||||
{
|
||||
formatBytes(torrent.size, 1) + ' (' + torrent.files + ' files)'
|
||||
}
|
||||
</div>
|
||||
{
|
||||
this.state.downloading
|
||||
PagesPie.instance().open(TorrentPage, {replace: 'all', hash: torrent.hash, peer: torrent.peer})
|
||||
}}
|
||||
primaryText={
|
||||
<a href={'/torrent/' + torrent.hash} ref={(node) => {
|
||||
if(node)
|
||||
node.onclick = () => { return false }
|
||||
}}>
|
||||
<span className='break-word' style={{
|
||||
color: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}}>
|
||||
{torrent.name}
|
||||
</span>
|
||||
</a>
|
||||
}
|
||||
secondaryText={
|
||||
<a href={'/torrent/' + torrent.hash} ref={(node) => {
|
||||
if(node)
|
||||
node.onclick = () => { return false }
|
||||
}}>
|
||||
<div className='column' style={{height: 'auto', whiteSpace: 'normal', paddingTop: '0.30em'}}>
|
||||
<div className='row w100p inline'>
|
||||
<div style={{color: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5252d1' : 'black') : (torrent.peer ? '#9083e2' : 'grey')}}>
|
||||
{
|
||||
formatBytes(torrent.size, 1) + ' (' + torrent.files + ' files)'
|
||||
}
|
||||
</div>
|
||||
{
|
||||
this.state.downloading
|
||||
&&
|
||||
<LinearProgress
|
||||
style={{width: '44%', marginLeft: 20}}
|
||||
mode="determinate"
|
||||
value={this.state.downloadProgress && (this.state.downloadProgress.progress ? this.state.downloadProgress.progress : 0) * 100}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
torrent.path && torrent.path.length > 0
|
||||
?
|
||||
torrent.path.map((path, index) => {
|
||||
return <div key={index} className='break-word fs0-75' style={{paddingTop: '0.3em', marginLeft: '0.6em'}}>{path}</div>
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
torrent.seeders || torrent.leechers || torrent.completed
|
||||
?
|
||||
<div className='break-word fs0-85' style={{paddingTop: '0.35em'}}>
|
||||
<span style={{color: (torrent.seeders > 0 ? '#00C853' : 'grey')}}>{torrent.seeders} {__('seeders')}</span>
|
||||
<span style={{color: (torrent.leechers > 0 ? '#AA00FF' : 'grey'), marginLeft: '12px'}}>{torrent.leechers} {__('leechers')}</span>
|
||||
<span style={{color: (torrent.completed > 0 ? '#FF6D00' : 'grey'), marginLeft: '12px'}}>{torrent.completed} {__('completed')}</span>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
(torrent.good > 0 || torrent.bad > 0)
|
||||
style={{width: '44%', marginLeft: 20}}
|
||||
mode="determinate"
|
||||
value={this.state.downloadProgress && (this.state.downloadProgress.progress ? this.state.downloadProgress.progress : 0) * 100}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
{
|
||||
torrent.path && torrent.path.length > 0
|
||||
?
|
||||
torrent.path.map((path, index) => {
|
||||
return <div key={index} className='break-word fs0-75' style={{paddingTop: '0.3em', marginLeft: '0.6em'}}>{path}</div>
|
||||
})
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
torrent.seeders || torrent.leechers || torrent.completed
|
||||
?
|
||||
<div className='break-word fs0-85' style={{paddingTop: '0.35em'}}>
|
||||
<span style={{color: (torrent.seeders > 0 ? '#00C853' : 'grey')}}>{torrent.seeders} {__('seeders')}</span>
|
||||
<span style={{color: (torrent.leechers > 0 ? '#AA00FF' : 'grey'), marginLeft: '12px'}}>{torrent.leechers} {__('leechers')}</span>
|
||||
<span style={{color: (torrent.completed > 0 ? '#FF6D00' : 'grey'), marginLeft: '12px'}}>{torrent.completed} {__('completed')}</span>
|
||||
</div>
|
||||
:
|
||||
null
|
||||
}
|
||||
{
|
||||
(torrent.good > 0 || torrent.bad > 0)
|
||||
&&
|
||||
<div className='row w100p inline' style={{maxWidth: 600}}>
|
||||
<LinearProgress
|
||||
mode="determinate"
|
||||
value={torrentRating}
|
||||
color={torrentRating >= 50 ? '#00E676' : '#FF3D00'}
|
||||
style={{
|
||||
height: '5px',
|
||||
}}
|
||||
/>
|
||||
<div className='row center pad0-5 fs0-85 text-nowrap' style={{color: torrentRating >= 50 ? '#00E676' : '#FF3D00', width: '190px'}}>{__('Torrent rating')}: {torrentRating}%</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
leftIcon={contentIcon(torrent.contentType, torrent.contentCategory, torrent.contentCategory != 'xxx' ? (torrent.peer ? '#6f5ee0' : 'grey') : (torrent.peer ? '#9083e2' : '#d3d3d3'))}
|
||||
rightIcon={
|
||||
<div className='row inline' style={{width: 63}}>
|
||||
{
|
||||
!this.state.askDownloading && !this.state.downloading
|
||||
?
|
||||
<a href={`magnet:?xt=urn:btih:${torrent.hash}`}>
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
marginRight: 12,
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setState({askDownloading: true})
|
||||
window.torrentSocket.emit('download', torrent)
|
||||
}} viewBox="0 0 56 56">
|
||||
<g>
|
||||
<path d="M35.586,41.586L31,46.172V28c0-1.104-0.896-2-2-2s-2,0.896-2,2v18.172l-4.586-4.586c-0.781-0.781-2.047-0.781-2.828,0
|
||||
<LinearProgress
|
||||
mode="determinate"
|
||||
value={torrentRating}
|
||||
color={torrentRating >= 50 ? '#00E676' : '#FF3D00'}
|
||||
style={{
|
||||
height: '5px',
|
||||
}}
|
||||
/>
|
||||
<div className='row center pad0-5 fs0-85 text-nowrap' style={{color: torrentRating >= 50 ? '#00E676' : '#FF3D00', width: '190px'}}>{__('Torrent rating')}: {torrentRating}%</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
</a>
|
||||
}
|
||||
leftIcon={contentIcon(torrent.contentType, torrent.contentCategory, torrent.contentCategory != 'xxx' ? (torrent.peer ? '#6f5ee0' : 'grey') : (torrent.peer ? '#9083e2' : '#d3d3d3'))}
|
||||
rightIcon={
|
||||
<div className='row inline' style={{width: 63}}>
|
||||
{
|
||||
!this.state.askDownloading && !this.state.downloading
|
||||
?
|
||||
<a href={`magnet:?xt=urn:btih:${torrent.hash}`}>
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
marginRight: 12,
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
this.setState({askDownloading: true})
|
||||
window.torrentSocket.emit('download', torrent)
|
||||
}} viewBox="0 0 56 56">
|
||||
<g>
|
||||
<path d="M35.586,41.586L31,46.172V28c0-1.104-0.896-2-2-2s-2,0.896-2,2v18.172l-4.586-4.586c-0.781-0.781-2.047-0.781-2.828,0
|
||||
s-0.781,2.047,0,2.828l7.999,7.999c0.093,0.094,0.196,0.177,0.307,0.251c0.047,0.032,0.099,0.053,0.148,0.081
|
||||
c0.065,0.036,0.127,0.075,0.196,0.103c0.065,0.027,0.133,0.042,0.2,0.062c0.058,0.017,0.113,0.04,0.173,0.051
|
||||
C28.738,52.986,28.869,53,29,53s0.262-0.014,0.392-0.04c0.06-0.012,0.115-0.034,0.173-0.051c0.067-0.02,0.135-0.035,0.2-0.062
|
||||
c0.069-0.028,0.131-0.067,0.196-0.103c0.05-0.027,0.101-0.049,0.148-0.081c0.11-0.074,0.213-0.157,0.307-0.251l7.999-7.999
|
||||
c0.781-0.781,0.781-2.047,0-2.828S36.367,40.805,35.586,41.586z"/>
|
||||
<path d="M47.835,18.986c-0.137-0.019-2.457-0.335-4.684,0.002C43.1,18.996,43.049,19,42.999,19c-0.486,0-0.912-0.354-0.987-0.85
|
||||
<path d="M47.835,18.986c-0.137-0.019-2.457-0.335-4.684,0.002C43.1,18.996,43.049,19,42.999,19c-0.486,0-0.912-0.354-0.987-0.85
|
||||
c-0.083-0.546,0.292-1.056,0.838-1.139c1.531-0.233,3.062-0.196,4.083-0.124C46.262,9.135,39.83,3,32.085,3
|
||||
C27.388,3,22.667,5.379,19.8,9.129C21.754,10.781,23,13.246,23,16c0,0.553-0.447,1-1,1s-1-0.447-1-1
|
||||
c0-2.462-1.281-4.627-3.209-5.876c-0.227-0.147-0.462-0.277-0.702-0.396c-0.069-0.034-0.139-0.069-0.21-0.101
|
||||
@ -346,39 +346,39 @@ export default class Torrent extends Component {
|
||||
l0.012,0.21l-0.009,0.16C7.008,16.744,7,16.873,7,17v0.63l-0.567,0.271C2.705,19.688,0,24,0,28.154C0,34.135,4.865,39,10.845,39H25
|
||||
V28c0-2.209,1.791-4,4-4s4,1.791,4,4v11h2.353c0.059,0,0.116-0.005,0.174-0.009l0.198-0.011l0.271,0.011
|
||||
C36.053,38.995,36.11,39,36.169,39h9.803C51.501,39,56,34.501,56,28.972C56,24.161,52.49,19.872,47.835,18.986z"/>
|
||||
</g>
|
||||
</g>
|
||||
|
||||
</svg>
|
||||
</a>
|
||||
:
|
||||
this.state.askDownloading && !this.state.downloading
|
||||
?
|
||||
<img src={Spinner24} />
|
||||
:
|
||||
this.state.askDownloading && this.state.downloading
|
||||
</svg>
|
||||
</a>
|
||||
:
|
||||
this.state.askDownloading && !this.state.downloading
|
||||
?
|
||||
<img src={Spinner24} />
|
||||
:
|
||||
this.state.askDownloading && this.state.downloading
|
||||
&&
|
||||
<a href={`magnet:?xt=urn:btih:${torrent.hash}`}>
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
window.torrentSocket.emit('downloadCancel', torrent.hash)
|
||||
}} viewBox="0 0 18 18"><path d="M9 1C4.58 1 1 4.58 1 9s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4 10.87L11.87 13 9 10.13 6.13 13 5 11.87 7.87 9 5 6.13 6.13 5 9 7.87 11.87 5 13 6.13 10.13 9 13 11.87z"/></svg>
|
||||
</a>
|
||||
}
|
||||
<a style={{float: 'right'}} href={`magnet:?xt=urn:btih:${torrent.hash}`}>
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var win = window.open(`magnet:?xt=urn:btih:${torrent.hash}`, '_self');
|
||||
}} viewBox="0 0 24 24">
|
||||
<path d="M15.82 10.736l-5.451 6.717c-.561.691-1.214 1.042-1.94 1.042-1.144
|
||||
window.torrentSocket.emit('downloadCancel', torrent.hash)
|
||||
}} viewBox="0 0 18 18"><path d="M9 1C4.58 1 1 4.58 1 9s3.58 8 8 8 8-3.58 8-8-3.58-8-8-8zm4 10.87L11.87 13 9 10.13 6.13 13 5 11.87 7.87 9 5 6.13 6.13 5 9 7.87 11.87 5 13 6.13 10.13 9 13 11.87z"/></svg>
|
||||
</a>
|
||||
}
|
||||
<a style={{float: 'right'}} href={`magnet:?xt=urn:btih:${torrent.hash}`}>
|
||||
<svg style={{
|
||||
height: '24px',
|
||||
fill: torrent.contentCategory != 'xxx' ? (torrent.peer ? '#5643db' : 'black') : (torrent.peer ? '#9083e2' : 'grey')
|
||||
}} onClick={(e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
var win = window.open(`magnet:?xt=urn:btih:${torrent.hash}`, '_self');
|
||||
}} viewBox="0 0 24 24">
|
||||
<path d="M15.82 10.736l-5.451 6.717c-.561.691-1.214 1.042-1.94 1.042-1.144
|
||||
0-2.327-.899-2.753-2.091-.214-.6-.386-1.76.865-2.784 3.417-2.794 6.716-5.446
|
||||
6.716-5.446l-3.363-4.174s-4.532 3.657-6.771 5.487c-2.581 2.108-3.123 4.468-3.123
|
||||
6.075 0 4.416 4.014 8.438 8.42 8.438 1.604 0 3.963-.543 6.084-3.128 1.835-2.237
|
||||
@ -390,12 +390,12 @@ export default class Torrent extends Component {
|
||||
4.151zm6.152-7.934l4.318-2.88-1.575-.638 1.889-2.414-4.421 2.788 1.716.695-1.927
|
||||
2.449zm-7.292-7.186l4.916-1.667-1.356-1.022 2.448-2.006-4.991 1.712
|
||||
1.478 1.114-2.495 1.869z"/></svg>
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</div>
|
||||
)
|
||||
</a>
|
||||
</div>
|
||||
}
|
||||
/>
|
||||
<Divider />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
}
|
144
src/app/touch.js
144
src/app/touch.js
@ -2,94 +2,94 @@ import ReactDOM from 'react-dom';
|
||||
|
||||
let listenSwipe = (component, handlers) =>
|
||||
{
|
||||
let element = ReactDOM.findDOMNode(component),
|
||||
startX,
|
||||
startY,
|
||||
distanceX,
|
||||
distanceY,
|
||||
threshold = 110,
|
||||
allowedTime = 280,
|
||||
thresholdAlternativeAxis = 145,
|
||||
elapsedTime,
|
||||
startTime;
|
||||
let element = ReactDOM.findDOMNode(component),
|
||||
startX,
|
||||
startY,
|
||||
distanceX,
|
||||
distanceY,
|
||||
threshold = 110,
|
||||
allowedTime = 280,
|
||||
thresholdAlternativeAxis = 145,
|
||||
elapsedTime,
|
||||
startTime;
|
||||
|
||||
let touchFunctions = {
|
||||
touchstart : (e) => {
|
||||
let touchObject = e.changedTouches[0]
|
||||
let touchFunctions = {
|
||||
touchstart : (e) => {
|
||||
let touchObject = e.changedTouches[0]
|
||||
|
||||
distanceX = 0;
|
||||
distanceY = 0;
|
||||
distanceX = 0;
|
||||
distanceY = 0;
|
||||
|
||||
startX = touchObject.pageX
|
||||
startY = touchObject.pageY
|
||||
startX = touchObject.pageX
|
||||
startY = touchObject.pageY
|
||||
|
||||
startTime = new Date().getTime()
|
||||
startTime = new Date().getTime()
|
||||
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
|
||||
if(handlers && handlers.initSwipe)
|
||||
handlers.initSwipe.call(component);
|
||||
},
|
||||
touchmove : (e) => {
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
},
|
||||
touchend : (e) => {
|
||||
let touchObject = e.changedTouches[0];
|
||||
if(handlers && handlers.initSwipe)
|
||||
handlers.initSwipe.call(component);
|
||||
},
|
||||
touchmove : (e) => {
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
},
|
||||
touchend : (e) => {
|
||||
let touchObject = e.changedTouches[0];
|
||||
|
||||
distanceX = touchObject.pageX - startX;
|
||||
distanceY = touchObject.pageY - startY;
|
||||
distanceX = touchObject.pageX - startX;
|
||||
distanceY = touchObject.pageY - startY;
|
||||
|
||||
elapsedTime = new Date().getTime() - startTime; // get time elapsed
|
||||
elapsedTime = new Date().getTime() - startTime; // get time elapsed
|
||||
|
||||
let params = {
|
||||
startX,
|
||||
startY,
|
||||
endX: touchObject.pageX,
|
||||
endY: touchObject.pageY,
|
||||
distanceX,
|
||||
distanceY
|
||||
};
|
||||
let params = {
|
||||
startX,
|
||||
startY,
|
||||
endX: touchObject.pageX,
|
||||
endY: touchObject.pageY,
|
||||
distanceX,
|
||||
distanceY
|
||||
};
|
||||
|
||||
if (elapsedTime <= allowedTime)
|
||||
{
|
||||
if(distanceX >= threshold && Math.abs(distanceY) <= thresholdAlternativeAxis)
|
||||
{
|
||||
if(handlers && handlers.left)
|
||||
handlers.left.call(component, params);
|
||||
} else
|
||||
if(-distanceX >= threshold && Math.abs(distanceY) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.right)
|
||||
handlers.right.call(component, params);
|
||||
} else
|
||||
if(distanceY >= threshold && Math.abs(distanceX) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.top)
|
||||
handlers.top.call(component, params);
|
||||
} else
|
||||
if(-distanceY >= threshold && Math.abs(distanceX) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.bottom)
|
||||
handlers.bottom.call(component, params);
|
||||
}
|
||||
}
|
||||
if (elapsedTime <= allowedTime)
|
||||
{
|
||||
if(distanceX >= threshold && Math.abs(distanceY) <= thresholdAlternativeAxis)
|
||||
{
|
||||
if(handlers && handlers.left)
|
||||
handlers.left.call(component, params);
|
||||
} else
|
||||
if(-distanceX >= threshold && Math.abs(distanceY) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.right)
|
||||
handlers.right.call(component, params);
|
||||
} else
|
||||
if(distanceY >= threshold && Math.abs(distanceX) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.top)
|
||||
handlers.top.call(component, params);
|
||||
} else
|
||||
if(-distanceY >= threshold && Math.abs(distanceX) <= thresholdAlternativeAxis) {
|
||||
if(handlers && handlers.bottom)
|
||||
handlers.bottom.call(component, params);
|
||||
}
|
||||
}
|
||||
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
if(handlers && handlers.preventDefault)
|
||||
e.preventDefault();
|
||||
}
|
||||
};
|
||||
|
||||
element.addEventListener('touchstart', touchFunctions.touchstart, false);
|
||||
element.addEventListener('touchmove', touchFunctions.touchmove, false);
|
||||
element.addEventListener('touchend', touchFunctions.touchend, false);
|
||||
element.addEventListener('touchstart', touchFunctions.touchstart, false);
|
||||
element.addEventListener('touchmove', touchFunctions.touchmove, false);
|
||||
element.addEventListener('touchend', touchFunctions.touchend, false);
|
||||
|
||||
return touchFunctions;
|
||||
return touchFunctions;
|
||||
}
|
||||
|
||||
let removeSwipeListener = (component, touchFunctions) => {
|
||||
let element = ReactDOM.findDOMNode(component);
|
||||
element.removeEventListener('touchstart', touchFunctions.touchstart);
|
||||
element.removeEventListener('touchmove', touchFunctions.touchmove);
|
||||
element.removeEventListener('touchend', touchFunctions.touchend);
|
||||
let element = ReactDOM.findDOMNode(component);
|
||||
element.removeEventListener('touchstart', touchFunctions.touchstart);
|
||||
element.removeEventListener('touchmove', touchFunctions.touchmove);
|
||||
element.removeEventListener('touchend', touchFunctions.touchend);
|
||||
}
|
||||
|
||||
export { listenSwipe, removeSwipeListener }
|
Reference in New Issue
Block a user