From 8d1201f0e8e322e0960196f3bb44c936d642456c Mon Sep 17 00:00:00 2001 From: Anthony RAYMOND Date: Thu, 2 Nov 2023 21:14:34 +0100 Subject: [PATCH] update ui --- src/main/resources/public/asset-manifest.json | 6 +++--- src/main/resources/public/index.html | 2 +- ...precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js} | 8 ++++---- src/main/resources/public/service-worker.js | 2 +- .../resources/public/static/js/main.54cbbbea.chunk.js | 2 ++ .../resources/public/static/js/main.54cbbbea.chunk.js.map | 1 + .../resources/public/static/js/main.fa028525.chunk.js | 2 -- .../resources/public/static/js/main.fa028525.chunk.js.map | 1 - 8 files changed, 12 insertions(+), 12 deletions(-) rename src/main/resources/public/{precache-manifest.f171241417ad9521f2c66ce9c69afc15.js => precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js} (95%) create mode 100644 src/main/resources/public/static/js/main.54cbbbea.chunk.js create mode 100644 src/main/resources/public/static/js/main.54cbbbea.chunk.js.map delete mode 100644 src/main/resources/public/static/js/main.fa028525.chunk.js delete mode 100644 src/main/resources/public/static/js/main.fa028525.chunk.js.map diff --git a/src/main/resources/public/asset-manifest.json b/src/main/resources/public/asset-manifest.json index a46a68b..7cb1c58 100644 --- a/src/main/resources/public/asset-manifest.json +++ b/src/main/resources/public/asset-manifest.json @@ -1,15 +1,15 @@ { "files": { "main.css": "./static/css/main.e1aa03ba.chunk.css", - "main.js": "./static/js/main.fa028525.chunk.js", - "main.js.map": "./static/js/main.fa028525.chunk.js.map", + "main.js": "./static/js/main.54cbbbea.chunk.js", + "main.js.map": "./static/js/main.54cbbbea.chunk.js.map", "runtime~main.js": "./static/js/runtime~main.d653cc00.js", "runtime~main.js.map": "./static/js/runtime~main.d653cc00.js.map", "static/css/2.cffeb17f.chunk.css": "./static/css/2.cffeb17f.chunk.css", "static/js/2.430fe565.chunk.js": "./static/js/2.430fe565.chunk.js", "static/js/2.430fe565.chunk.js.map": "./static/js/2.430fe565.chunk.js.map", "index.html": "./index.html", - "precache-manifest.f171241417ad9521f2c66ce9c69afc15.js": "./precache-manifest.f171241417ad9521f2c66ce9c69afc15.js", + "precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js": "./precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js", "service-worker.js": "./service-worker.js", "static/css/2.cffeb17f.chunk.css.map": "./static/css/2.cffeb17f.chunk.css.map", "static/css/main.e1aa03ba.chunk.css.map": "./static/css/main.e1aa03ba.chunk.css.map", diff --git a/src/main/resources/public/index.html b/src/main/resources/public/index.html index 2b6c8c6..bc076b2 100644 --- a/src/main/resources/public/index.html +++ b/src/main/resources/public/index.html @@ -1 +1 @@ -JOAL ui
\ No newline at end of file +JOAL ui
\ No newline at end of file diff --git a/src/main/resources/public/precache-manifest.f171241417ad9521f2c66ce9c69afc15.js b/src/main/resources/public/precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js similarity index 95% rename from src/main/resources/public/precache-manifest.f171241417ad9521f2c66ce9c69afc15.js rename to src/main/resources/public/precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js index 3202ac7..a9ff3a1 100644 --- a/src/main/resources/public/precache-manifest.f171241417ad9521f2c66ce9c69afc15.js +++ b/src/main/resources/public/precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js @@ -1,6 +1,6 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ { - "revision": "fc53095bdf83655d5b692c3fcef2cdc3", + "revision": "929af4125297f8e1b45d090a2fca7150", "url": "./index.html" }, { @@ -8,7 +8,7 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "./static/css/2.cffeb17f.chunk.css" }, { - "revision": "33b6437844a71db9285c", + "revision": "5664e68d0e3c23292a6e", "url": "./static/css/main.e1aa03ba.chunk.css" }, { @@ -16,8 +16,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([ "url": "./static/js/2.430fe565.chunk.js" }, { - "revision": "33b6437844a71db9285c", - "url": "./static/js/main.fa028525.chunk.js" + "revision": "5664e68d0e3c23292a6e", + "url": "./static/js/main.54cbbbea.chunk.js" }, { "revision": "8c97409f0ee389fe75da", diff --git a/src/main/resources/public/service-worker.js b/src/main/resources/public/service-worker.js index a3c4647..3f9fc3c 100644 --- a/src/main/resources/public/service-worker.js +++ b/src/main/resources/public/service-worker.js @@ -14,7 +14,7 @@ importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js"); importScripts( - "./precache-manifest.f171241417ad9521f2c66ce9c69afc15.js" + "./precache-manifest.84ae3b5cfc2435bec1907eadb0fb698b.js" ); self.addEventListener('message', (event) => { diff --git a/src/main/resources/public/static/js/main.54cbbbea.chunk.js b/src/main/resources/public/static/js/main.54cbbbea.chunk.js new file mode 100644 index 0000000..fcb9592 --- /dev/null +++ b/src/main/resources/public/static/js/main.54cbbbea.chunk.js @@ -0,0 +1,2 @@ +(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{166:function(e,t,n){e.exports=n(207)},18:function(e,t,n){"use strict";n.d(t,"e",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"c",function(){return o}),n.d(t,"b",function(){return i}),n.d(t,"d",function(){return c}),n.d(t,"f",function(){return s}),n.d(t,"g",function(){return l}),n.d(t,"m",function(){return u}),n.d(t,"h",function(){return d}),n.d(t,"j",function(){return f}),n.d(t,"i",function(){return p}),n.d(t,"l",function(){return m}),n.d(t,"k",function(){return h}),n.d(t,"n",function(){return b});var a="@@api/stompClient/IS_CONNECTING",r="@@api/stompClient/HAS_CONNECTED",o="@@api/stompClient/HAS_FAILED_TO_CONNECT",i="@@api/stompClient/HAS_DROP_CONNECTION",c="@@api/stompClient/INIT_OVER",s="@@api/stompClient/RECEIVED_ERROR_MESSAGE",l="@@reset/RESET_STOMP_STATE",u=function(){return{type:a}},d=function(){return{type:r}},f=function(){return{type:o}},p=function(){return{type:i}},m=function(){return{type:c}},h=function(e){return{type:s,message:e}},b=function(){return{type:l}}},181:function(e,t){},182:function(e,t,n){"use strict";n.r(t),n.d(t,"getConfig",function(){return a}),n.d(t,"saveConfig",function(){return r});var a=function(){var e=localStorage.getItem("guiConfig");return e?JSON.parse(e):(console.log("Returning a mocked config to prevent exception from NullPointer"),{host:window.location.hostname,port:window.location.port||"80",pathPrefix:window.location.pathname.substring(1,window.location.pathname.lastIndexOf("/ui"))||"",secretToken:""})},r=function(e){localStorage.setItem("guiConfig",JSON.stringify(e))}},183:function(e,t,n){"use strict";var a;n.r(t),n.d(t,"getConfig",function(){return r}),n.d(t,"saveConfig",function(){return o});var r=function(){if(!a){var e=localStorage.getItem("guiConfig");a=e?JSON.parse(e):{host:window.location.hostname,port:window.location.port||"80",pathPrefix:"",secretToken:""}}return a},o=function(e){localStorage.setItem("guiConfig",JSON.stringify(e)),a=e}},184:function(e,t,n){},206:function(e,t,n){"use strict";n.r(t);var a=n(0),r=n.n(a),o=n(13),i=n(152),c=n(287),s=n(102),l=n.n(s),u=n(103),d=n.n(u),f=n(256),p=function(e){return Object(i.a)({palette:{primary:{light:l.a[300],main:l.a[500],dark:l.a[700]},secondary:{light:d.a[300],main:d.a[500],dark:d.a[700]},type:e}})},m=function(e){var t=e.children,n=e.themeType;return r.a.createElement(c.a,{theme:p(n)},r.a.createElement(f.a,null),t)},h=Object(o.c)(function(e){return{themeType:e.theme.palette.type}})(m),b=n(258),g=n(130),v=n.n(g),E=n(131),y=n.n(E),O=function(e){var t=e.palette,n=e.onClickChangeThemeType;return r.a.createElement("div",null,r.a.createElement(b.a,{"aria-label":"Switch theme type",onClick:n},"light"===t.type?r.a.createElement(v.a,{htmlColor:"#fff"}):r.a.createElement(y.a,{htmlColor:"#fff"})))},C=n(85),j=Object(o.c)(function(e){return{palette:e.theme.palette}},function(e){return{onClickChangeThemeType:function(){return e(Object(C.b)())}}})(O),S=n(87),N=n(64),k=n(269),x=n(209),w=n(288),T=n(88),R=n.n(T),I=n(6),P=n(132),_=n.n(P),D=n(276),B=n(145),A=n.n(B),F=n(40),L=n(290),H=n(275),U=n(260),M=n(211),G=n(259),W=n(136),J=n.n(W),V=n(135),q=n.n(V),z=n(155),K=n(133),Y=n.n(K),X=n(134),Z=n.n(X),Q=n(68),$=n.n(Q),ee=n(15),te=n.n(ee),ne=Object(x.a)(function(e){return Object(w.a)({container:{padding:15},leftIcon:{marginRight:e.spacing(1)},playPauseButton:{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[100],boxShadow:e.shadows[2],"&:focusVisible":{boxShadow:e.shadows[6]},"&:active":{boxShadow:e.shadows[8]},"&:disabled":{color:e.palette.action.disabled,boxShadow:e.shadows[0],backgroundColor:e.palette.action.disabledBackground},"&:hover":{backgroundColor:"dark"===e.palette.type?e.palette.grey[800]:e.palette.grey[300],"@media (hover: none)":{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[300]},"&:disabled":{backgroundColor:e.palette.action.disabledBackground}}},redTextButton:{color:Y.a[400]},greenTextButton:{color:Z.a[400]}})}),ae=function(e){var t=ne(),n=e.className,a=e.client,o=e.overallUploadSpeed,i=e.isStarted,c=e.onClickStart,s=e.onClickStop,l=e.numberOfQueuedTorrents,u=i?"Running":"Paused";return r.a.createElement(M.a,{elevation:2,className:te()(t.container,n)},r.a.createElement(z.a,{align:"center",variant:"h5",gutterBottom:!0},u),r.a.createElement(G.a,{color:"primary",fullWidth:!0,variant:"contained",className:i?t.redTextButton:t.greenTextButton,classes:{contained:t.playPauseButton},onClick:i?s:c},i?r.a.createElement(q.a,{className:t.leftIcon}):r.a.createElement(J.a,{className:t.leftIcon}),i?"stop":"start"),r.a.createElement(U.a,{style:{marginTop:20,marginBottom:10}}),r.a.createElement(z.a,{align:"center",variant:"body2",gutterBottom:!0},r.a.createElement("b",null,a)),r.a.createElement(z.a,{align:"left",variant:"body2",gutterBottom:!0},"Overall speed : ".concat($()(o,{base:10}),"/s")),r.a.createElement(z.a,{align:"left",variant:"body2",gutterBottom:!0},"Torrents in queue : ".concat(l)))};ae.defaultProps={className:""};var re=ae,oe=n(31),ie=function(e){for(var t=0,n=0,a=Object.values(e);n65535&&(t="A port that big, seriously ?")),this.setState({port:e,portErr:t})}},{key:"handlePathPrefixChange",value:function(e){var t=""===e?"Required field":"";this.setState({pathPrefix:e,pathPrefixErr:t})}},{key:"handleSecretTokenChange",value:function(e){var t=""===e?"Required field":"";this.setState({secretToken:e,secretTokenErr:t})}},{key:"discardChangesAndClose",value:function(){var e=this.props.config;this.setState(Object(pe.a)({},e,{isModalVisible:!1}))}},{key:"saveConfig",value:function(){var e=this.props.saveNewConf,t=this.state,n=t.host,a=t.port,r=t.pathPrefix,o=t.secretToken;this.hasError()||(e({host:n,port:a,pathPrefix:r,secretToken:o}),this.setState({isModalVisible:!1}))}},{key:"hasError",value:function(){var e=this.state,t=e.host,n=e.port,a=e.pathPrefix,r=e.secretToken,o=e.hostErr,i=e.portErr,c=e.pathPrefixErr,s=e.secretTokenErr;return!(t&&n&&a&&r)||!!(o||i||c||s)}},{key:"render",value:function(){var e=this,t=this.props,n=t.classes,a=t.isConnected,o=t.style,i=this.state,c=i.isModalVisible,s=i.host,l=i.port,u=i.pathPrefix,d=i.secretToken,f=i.hostErr,p=i.portErr,m=i.pathPrefixErr,h=i.secretTokenErr;return r.a.createElement("div",{style:o},r.a.createElement(G.a,{variant:"contained",fullWidth:!0,onClick:function(){return e.setState({isModalVisible:!0})},className:a?"":n.redButton,classes:{contained:n.changeConfigButton}},"Change connection settings"),r.a.createElement(je.a,{open:c,onClose:function(){return e.discardChangesAndClose()},"aria-labelledby":"form-dialog-connection-settings",scroll:"paper"},r.a.createElement(ke.a,{id:"form-dialog-connection-settings"},"Connection settings"),r.a.createElement(Ne.a,null,r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"server-address-text"},r.a.createElement(Ce.a,{htmlFor:"server-address"},"Server address"),r.a.createElement(Oe.a,{id:"server-address",placeholder:"host",value:s,onChange:function(t){return e.handleHostChange(t.target.value)}}),r.a.createElement(ye.a,{id:"server-address-text"},f)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"server-port-text"},r.a.createElement(Ce.a,{htmlFor:"server-port"},"Server port"),r.a.createElement(Oe.a,{id:"server-port",placeholder:"port",type:"number",value:l,onChange:function(t){return e.handlePortChange(t.target.value)}}),r.a.createElement(ye.a,{id:"server-port-text"},p)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"path-prefix-text"},r.a.createElement(Ce.a,{htmlFor:"path-prefix"},"Path prefix"),r.a.createElement(Oe.a,{id:"path-prefix",placeholder:"Obfuscation path prefix",value:u,onChange:function(t){return e.handlePathPrefixChange(t.target.value)}}),r.a.createElement(ye.a,{id:"path-prefix-text"},m)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"secret-token-text"},r.a.createElement(Ce.a,{htmlFor:"secret-token"},"Secret token"),r.a.createElement(Oe.a,{id:"secret-token",placeholder:"Your secret token",value:d,onChange:function(t){return e.handleSecretTokenChange(t.target.value)}}),r.a.createElement(ye.a,{id:"secret-token-text"},h))),r.a.createElement(Se.a,null,r.a.createElement(G.a,{onClick:function(){return e.discardChangesAndClose()}},"Cancel"),r.a.createElement(G.a,{variant:"contained",color:"primary",disabled:this.hasError(),onClick:function(){return e.saveConfig()}},"Save"))))}}]),t}(a.Component);we.defaultProps={style:{}};var Te=Object(xe.a)(function(e){return Object(w.a)({changeConfigButton:{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[100],boxShadow:e.shadows[2],"&:focusVisible":{boxShadow:e.shadows[6]},"&:active":{boxShadow:e.shadows[8]},"&:disabled":{color:e.palette.action.disabled,boxShadow:e.shadows[0],backgroundColor:e.palette.action.disabledBackground},"&:hover":{backgroundColor:"dark"===e.palette.type?e.palette.grey[800]:e.palette.grey[300],"@media (hover: none)":{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[300]},"&:disabled":{backgroundColor:e.palette.action.disabledBackground}}},redButton:{color:e.palette.getContrastText(e.palette.error.main),backgroundColor:e.palette.error.main,"&:hover":{backgroundColor:e.palette.error.dark}},formControl:{margin:e.spacing(1)}})})(we),Re=n(55);var Ie=Object(o.c)(function(e){return{isConnected:e.api.stomp.isConnected,config:Object(Re.a)(),saveNewConf:function(e){Object(Re.b)(e),Object(oe.c)()}}})(Te),Pe=n(99),_e=n(52),De=n(214),Be=n(282),Ae=n(292),Fe=n(273),Le=n(140),He=n.n(Le),Ue=n(142),Me=n.n(Ue),Ge=n(143),We=n.n(Ge),Je=n(144),Ve=n.n(Je),qe=n(139),ze=n.n(qe),Ke=n(272),Ye=n(138),Xe=Object(x.a)(function(e){return Object(w.a)({root:{},leechers:{color:e.palette.primary.light,marginRight:12},seeders:{color:e.palette.primary.light}})}),Ze=function(e){var t=Xe(),n=e.className,a=e.leechers,o=e.seeders,i=null===a||void 0===a?"?":a,c=null===o||void 0===o?"?":o;return r.a.createElement(k.a,{container:!0,direction:"row",className:te()(t.root,n)},r.a.createElement(k.a,{item:!0},r.a.createElement(L.a,{title:"leechers","aria-label":"leechers",placement:"top"},r.a.createElement("span",{className:t.leechers,"data-for":"leechers","data-tip":"Leechers"},r.a.createElement("i",{className:"fa fa-cloud-download","aria-hidden":"true"})," ".concat(i))),r.a.createElement(L.a,{title:"seeders","aria-label":"seeders",placement:"top"},r.a.createElement("span",{className:t.seeders,"data-for":"seeders","data-tip":"Seeders"},r.a.createElement("i",{className:"fa fa-cloud-upload","aria-hidden":"true"})," ".concat(c)))))};Ze.defaultProps={className:"",leechers:void 0,seeders:void 0};var Qe=Ze,$e=function(e){var t=e.className,n=e.speedInBytesPerSeconds;return r.a.createElement(z.a,{variant:"caption",className:t},void 0===n?"? B/s":"".concat($()(n,{base:10}),"/s"))};$e.defaultProps={className:""};var et=$e,tt=Object(o.c)(function(e,t){var n=e.api.speed[t.infoHash];return{speedInBytesPerSeconds:null===n||void 0===n?void 0:n.bytesPerSecond}},function(){return{}})(et),nt=n(271),at=Object(x.a)(function(e){return Object(w.a)({progressBar:{}})}),rt=function(e){var t=at(),n=e.className;return r.a.createElement(nt.a,{color:"primary",className:te()(t.progressBar,n)})};rt.defaultProps={className:""};var ot=rt,it=Object(x.a)(function(e){return Object(w.a)({progressBar:{}})}),ct=function(e){var t=it(),n=e.className,a=r.a.useState(function(){return Math.round((Date.now()-Date.parse(e.lastAnnouncedDate))/10/e.interval)}),o=Object(_e.a)(a,2),i=o[0],c=o[1];return r.a.useEffect(function(){var t=setInterval(function(){return c(function(e){return Math.min(e+1,100)})},10*e.interval);return function(){return clearInterval(t)}},[e.lastAnnouncedDate,e.interval]),r.a.createElement(nt.a,{variant:"determinate",value:i,className:te()(t.progressBar,n)})};ct.defaultProps={className:""};var st=ct,lt=Object(x.a)(function(e){return Object(w.a)({root:{paddingTop:e.spacing(1),paddingLeft:e.spacing(2),paddingRight:e.spacing(2),paddingBottom:e.spacing(.5)},title:{marginTop:3,lineHeight:1.2,wordBreak:"break-word"},uploadSpeedContainer:{bottom:5,fontSize:18,position:"absolute",right:e.spacing(2)},peersStats:{fontSize:14},deleteButton:{color:e.palette.error.main,"&:hover":{backgroundColor:Object(Ye.fade)(e.palette.error.main,e.palette.action.hoverOpacity)},position:"absolute",right:2,top:2,padding:0,height:35,width:42},announceProgressBar:{position:"absolute",left:0,right:0,bottom:0,height:4}})}),ut=function(e){var t=lt(),n=e.width,a=e.className,o=e.announcer,i=e.onClickDeleteTorrent,c="xs"===n||"sm"===n?70:175,s=o.torrentName;return o.torrentName.length>c&&(s="".concat(o.torrentName.substring(0,c),"...")),r.a.createElement(M.a,{elevation:2,style:{position:"relative"},className:te()(t.root,a)},r.a.createElement(k.a,{container:!0,direction:"row"},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(z.a,{align:"left",className:t.title,variant:"body2",gutterBottom:!0},"".concat(s," (").concat($()(o.torrentSize,{standard:"iec"}),")"))),r.a.createElement(k.a,{item:!0,style:{width:42}},r.a.createElement(L.a,{title:"Delete this torrent",placement:"left"},r.a.createElement(b.a,{className:t.deleteButton,"aria-label":"Delete",onClick:function(){return i(o.infoHash)}},r.a.createElement(ze.a,null))))),r.a.createElement(k.a,{container:!0,direction:"row"},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(Qe,{className:t.peersStats,leechers:o.lastKnownLeechers,seeders:o.lastKnownSeeders})),r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement("div",{className:t.uploadSpeedContainer},r.a.createElement(tt,{infoHash:o.infoHash})))),o.isFetching||void 0===o.lastAnnouncedAt?r.a.createElement(ot,{className:t.announceProgressBar}):r.a.createElement(st,{className:t.announceProgressBar,lastAnnouncedDate:o.lastAnnouncedAt,interval:o.lastKnownInterval}))};ut.defaultProps={className:""};var dt=Object(Ke.a)()(ut);function ft(e,t,n){return t[n]e[n]?1:0}var pt=function(e,t){return""===t||void 0===t?function(e,t){return 0}:"desc"===e?function(e,n){return ft(e,n,t)}:function(e,n){return-ft(e,n,t)}},mt=function(e){return""===e||void 0===e?function(e){return!0}:function(t){return t.torrentName.toLowerCase().includes(e.toLowerCase())}},ht=Object(x.a)(function(e){var t;return{searchBarPaper:{padding:"2px 4px",display:"flex",alignItems:"center"},searchBar:{marginLeft:8,flex:1},searchBarIcon:{padding:10},sortActionsContainer:(t={},Object(I.a)(t,e.breakpoints.down("xs"),{width:"100%"}),Object(I.a)(t,"width","none"),t),sortButtonGroup:function(e){return{backgroundColor:e.hasSortSelected?"":"transparent"}},toogleButtonWhenNoSortSelection:{borderColor:"transparent"}}});function bt(e){var t=e.search,n=e.onRequestSearch,a=e.order,o=e.orderBy,i=e.onRequestSort,c=ht({hasSortSelected:void 0!==o});return r.a.createElement(k.a,{container:!0,spacing:1},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(M.a,{className:c.searchBarPaper,elevation:1},r.a.createElement(De.a,{className:c.searchBar,value:t,onChange:function(e){return n(e.target.value)},placeholder:"Filter by name"}),r.a.createElement(b.a,{className:c.searchBarIcon,"aria-label":"Search"},r.a.createElement(He.a,null)))),r.a.createElement(k.a,{item:!0,className:c.sortActionsContainer},r.a.createElement(Ae.a,{className:"".concat(c.sortButtonGroup),selected:void 0!==o,value:o,exclusive:!0,onChange:function(e,t){var n;o===(n=t)||null===n?"asc"!==a?"desc"!==a||i("asc",void 0):i("desc",o):i("asc",n)}},r.a.createElement(L.a,{title:"Sort by name",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"torrentName"===o,value:"torrentName"},r.a.createElement(Me.a,null))),r.a.createElement(L.a,{title:"Sort by leechers",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"lastKnownLeechers"===o,value:"lastKnownLeechers"},r.a.createElement(We.a,null))),r.a.createElement(L.a,{title:"Sort by seeders",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"lastKnownSeeders"===o,value:"lastKnownSeeders"},r.a.createElement(Ve.a,null))))))}var gt=function(){return r.a.createElement("div",null,"")},vt=Object(x.a)(function(e){var t;return Object(w.a)({announersList:Object(I.a)({marginTop:e.spacing(1)},e.breakpoints.up("md"),{marginLeft:e.spacing(2)}),announcer:(t={},Object(I.a)(t,e.breakpoints.down("md"),{marginBottom:e.spacing(2)}),Object(I.a)(t,e.breakpoints.up("md"),{marginBottom:e.spacing(1)}),t)})});var Et=function(e){var t=vt(),n=r.a.useState(""),a=Object(_e.a)(n,2),o=a[0],i=a[1],c=r.a.useState("asc"),s=Object(_e.a)(c,2),l=s[0],u=s[1],d=r.a.useState(void 0),f=Object(_e.a)(d,2),p=f[0],m=f[1],h=r.a.useState(0),b=Object(_e.a)(h,2),g=b[0],v=b[1],E=r.a.useState(10),y=Object(_e.a)(E,2),O=y[0],C=y[1],j=e.announcers,S=e.onClickDeleteTorrent;return r.a.useEffect(function(){g>Math.ceil(j.length/O)-1&&v(0)},[g,j.length,O]),r.a.createElement("div",null,r.a.createElement(gt,null),r.a.createElement(bt,{search:o,onRequestSearch:i,order:l,orderBy:p,onRequestSort:function(e,t){u(e),m(t)}}),r.a.createElement(k.a,{container:!0,spacing:1},r.a.createElement(k.a,{item:!0,xs:12,className:t.announersList},j.filter(mt(o)).sort(pt(l,p)).slice(g*O,g*O+O).map(function(e){return r.a.createElement("div",{key:e.infoHash},r.a.createElement(dt,{className:t.announcer,announcer:e,onClickDeleteTorrent:S}))})),r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement(Be.a,{rowsPerPageOptions:[10,25,50],component:"div",count:j.length,rowsPerPage:O,page:g,backIconButtonProps:{"aria-label":"Previous Page"},nextIconButtonProps:{"aria-label":"Next Page"},onChangePage:function(e,t){v(t)},onChangeRowsPerPage:function(e){C(+e.target.value)}}))))},yt=n(70),Ot=n(114),Ct=Object(Ot.a)([function(e){return e.app.torrentsTable.searchFilter},function(e){return e.api.announcers}],function(e,t){if(0===e.trim().length)return t;var n=e.toLowerCase();return t.filter(function(e){return e.torrentName.toLowerCase().includes(n)})}),jt=Object(Ot.a)([function(e){return e.app.torrentsTable.sortProperty},function(e){return e.app.torrentsTable.sortDirection},Ct],function(e,t,n){return""===e||void 0===e||null===e?n:Object(Pe.a)(n).sort(function(n,a){return n[e]0?.1:1},helperText:"Set to -1.0 for indefinite seeding. Note: Uploaded amount resets to 0 upon Joal restart.",value:s.uploadRatioTarget,onChange:function(e){var t=""===e.target.value?"":e.target.value;u({uploadRatioTarget:t})}})),r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement("div",{className:t.formInput},r.a.createElement(It.a,{control:r.a.createElement(Rt.a,{style:{paddingBottom:0,paddingTop:0},color:"primary",checked:s.keepTorrentWithZeroLeechers,onChange:function(e,t){return u({keepTorrentWithZeroLeechers:t})}}),label:"Keep seeding torrents even with no peers"}),r.a.createElement(ye.a,{style:{marginTop:0}},"If checked, when a torrent reach 0 peers it will seed at 0 kB/s. Otherwise, when a torrent reach 0 peers it will be removed.")))),r.a.createElement(k.a,{container:!0,direction:"row",justify:"flex-end",alignItems:"center"},r.a.createElement(k.a,{item:!0},l&&r.a.createElement(G.a,{variant:"outlined",onClick:function(){return a()},color:"secondary",className:t.discardChangesButton},"Discard"),r.a.createElement(G.a,{variant:"contained",onClick:function(){return i(s)},color:"secondary"},"Save"))))))},Ft=n(71);var Lt=Object(o.c)(function(e){return{isLocalConfigChanged:void 0!==e.app.config.localConfig,config:e.app.config.localConfig||e.api.settings.config,availableClients:e.api.settings.availableClients,isConnectedToWebSocket:e.api.stomp.isConnected}},function(e){return{discardLocalConfigChanges:function(){return e(Object(Ft.c)())},onSettingsChange:function(t){return e(Object(Ft.d)(t))},onClickSave:function(e){return Object(oe.d)(e)}}})(At),Ht=n(146),Ut=n.n(Ht),Mt=n(147),Gt=n.n(Mt),Wt=Object(x.a)(function(e){return Object(w.a)({container:{textAlign:"center",marginTop:100,height:"100%"}})}),Jt=function(e){e.events;var t=Wt();return r.a.createElement(k.a,{container:!0,className:t.container},r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement(Ut.a,{viewBox:"0 0 24 20",style:{color:Gt.a[500],height:200,width:166}})),r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement("b",null,"Hey it looks like you discovered the super secret tab !")),r.a.createElement(k.a,{item:!0,xs:12},"This tab will tell you what was the last actions JOAL has performed. Unfortunately this is still under development, check it back later ;)"))};var Vt=Object(o.c)(function(){return{events:[]}})(Jt),qt=n(278),zt=n(279),Kt=n(148),Yt=n.n(Kt),Xt=n(149),Zt=n.n(Xt),Qt=n(150),$t=n.n(Qt),en=function(e){var t,n=e.currentPath,a=e.onClickDashboard,o=e.onClickSettings,i=e.onClickLogs;return r.a.createElement(M.a,{elevation:1},r.a.createElement(qt.a,{showLabels:!0,value:(t=n,"/"===t?0:"/settings"===t?1:2),onChange:function(e,t){0===t?a():1===t?o():2===t&&i()}},r.a.createElement(zt.a,{label:"dashboard",icon:r.a.createElement(Yt.a,null)}),r.a.createElement(zt.a,{label:"configuration",icon:r.a.createElement(Zt.a,null)}),r.a.createElement(zt.a,{label:"history",icon:r.a.createElement($t.a,null)})))},tn=n(24),nn=Object(o.c)(function(e){return{currentPath:e.router.location.pathname}},function(e){return{onClickDashboard:function(){return e(Object(tn.d)("/"))},onClickSettings:function(){return e(Object(tn.d)("/settings"))},onClickLogs:function(){return e(Object(tn.d)("/history"))}}})(en),an=n(153),rn=Object(x.a)(function(e){return Object(w.a)({dropzone:{position:"absolute",top:0,bottom:0,left:0,right:0},overlay:{zIndex:16777270,position:"fixed",top:0,right:0,bottom:0,left:0,backgroundColor:"rgba(156, 155, 155, 0.86)",color:"rgba(130, 130, 130, 0.75)",display:"flex",alignItems:"center",justifyContent:"center"}})}),on=function(e){var t=rn(),n=e.children,a=Object(an.a)({onDrop:function(t,n){return e.onDrop(t,n)},noClick:!0,noKeyboard:!0,multiple:!0}),o=a.getRootProps,i=a.getInputProps,c=a.isDragActive,s=o({onClick:function(e){e.stopPropagation()}});return r.a.createElement("div",Object.assign({},s,{className:t.dropzone}),r.a.createElement("input",i()),n,c&&r.a.createElement("div",{className:t.overlay},r.a.createElement("i",{className:te()("fa","fa-download","fa-5x"),"aria-hidden":"true"})))},cn=n(280),sn=n(274),ln=Object(x.a)(function(e){return Object(w.a)({root:{flexGrow:1},grow:{flexGrow:1},menuButton:{marginLeft:-12,marginRight:20}})}),un=function(e){var t=ln(),n=e.className;return r.a.createElement("div",{className:te()(t.root,n)},r.a.createElement(cn.a,{position:"static"},r.a.createElement(sn.a,null,r.a.createElement(z.a,{variant:"h6",color:"inherit",className:t.grow},"Joal"),r.a.createElement(j,null))))};un.defaultProps={className:{}};var dn=un,fn=n(74),pn=function(e){var t=e.className,n=e.children;return r.a.createElement("svg",{className:t,xmlns:"http://www.w3.org/2000/svg",width:"24",height:"24",viewBox:"0 0 24 24",fill:"none",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",style:{minWidth:24}},n)};pn.defaultProps={className:""};var mn=pn,hn=Object(x.a)(function(e){return Object(w.a)({icon:{stroke:"#2E9AFE"}})}),bn=function(e){var t=hn(),n=e.className;return r.a.createElement(mn,{className:te()(t.icon,n)},r.a.createElement("circle",{cx:"12",cy:"12",r:"10"}),r.a.createElement("line",{x1:"12",y1:"16",x2:"12",y2:"12"}),r.a.createElement("line",{x1:"12",y1:"8",x2:"12",y2:"8"}))};bn.defaultProps={className:""};var gn=bn,vn=Object(x.a)(function(e){return Object(w.a)({icon:{stroke:"#31B404"}})}),En=function(e){var t=vn(),n=e.className;return r.a.createElement(mn,{className:te()(t.icon,n)},r.a.createElement("path",{d:"M22 11.08V12a10 10 0 1 1-5.93-9.14"}),r.a.createElement("polyline",{points:"22 4 12 14.01 9 11.01"}))};En.defaultProps={className:""};var yn=En,On=Object(x.a)(function(e){return Object(w.a)({icon:{stroke:"#FF0040"}})}),Cn=function(e){var t=On(),n=e.className;return r.a.createElement(mn,{className:te()(t.icon,n)},r.a.createElement("circle",{cx:"12",cy:"12",r:"10"}),r.a.createElement("line",{x1:"12",y1:"8",x2:"12",y2:"12"}),r.a.createElement("line",{x1:"12",y1:"16",x2:"12",y2:"16"}))};Cn.defaultProps={className:""};var jn=Cn,Sn=Object(x.a)(function(e){return Object(w.a)({icon:{stroke:"#000000"}})}),Nn=function(e){var t=Sn(),n=e.className;return r.a.createElement(mn,{className:te()(t.icon,n)},r.a.createElement("line",{x1:"18",y1:"6",x2:"6",y2:"18"}),r.a.createElement("line",{x1:"6",y1:"6",x2:"18",y2:"18"}))};Nn.defaultProps={className:""};var kn=Nn,xn=Object(x.a)(function(e){var t;return Object(w.a)({alert:(t={backgroundColor:"".concat("dark"===e.palette.type?"#333":"#fff"),borderRadius:3,padding:10,display:"flex",justifyContent:"space-between",alignItems:"center",boxShadow:"0px 2px 2px 2px rgba(0, 0, 0, 0.03)",fontFamily:"Arial",fontSize:11,width:350},Object(I.a)(t,e.breakpoints.down("xs"),{width:"75vw"}),Object(I.a)(t,"boxSizing","border-box"),Object(I.a)(t,"position","relative"),t),message:{color:"".concat("dark"===e.palette.type?"#fff":"#333"),paddingRight:40,textAlign:"center",textTransform:"uppercase"},statusIcon:{marginRight:15},closeButton:{padding:0,display:"flex",alignItems:"center",justifyContent:"center",position:"absolute",right:0,top:0,bottom:0,width:40,border:"none",backgroundColor:"dark"===e.palette.type?"#444":"#f3f3f3",cursor:"pointer"},closeIconOverride:{stroke:"dark"===e.palette.type?"#BBB":"#000"}})}),wn=function(e){var t=xn(),n=e.message,a=e.options,o=e.style,i=e.close;return r.a.createElement("div",{className:t.alert,style:o},"success"===a.type&&r.a.createElement(yn,{className:t.statusIcon}),"info"===a.type&&r.a.createElement(gn,{className:t.statusIcon}),"error"===a.type&&r.a.createElement(jn,{className:t.statusIcon}),r.a.createElement("span",{className:t.message,style:{flex:2}},n),r.a.createElement("button",{className:t.closeButton,onClick:i,type:"button"},r.a.createElement(kn,{className:t.closeIconOverride})))},Tn=n(86),Rn=function(e){function t(){return Object(me.a)(this,t),Object(be.a)(this,Object(ge.a)(t).apply(this,arguments))}return Object(ve.a)(t,e),Object(he.a)(t,[{key:"shouldComponentUpdate",value:function(e){var t=this.props,n=t.notifs,a=t.shouldShowDirtyConfNotif;return n!==e.notifs||a!==e.shouldShowDirtyConfNotif}},{key:"componentDidUpdate",value:function(e){var t=this,n=this.props,a=n.shouldShowDirtyConfNotif,r=n.alert,o=n.notifs;e.shouldShowDirtyConfNotif!==a&&!0===a&&r.info("Config wont be refreshed until you restart JOAL"),o!==e.notifs&&o.forEach(function(n){-1===e.notifs.findIndex(function(e){return e.id===n.id})&&t.showNotification(n)})}},{key:"showNotification",value:function(e){var t=this.props,n=t.alert,a=t.onMessageClosed,o=Object.assign({},e,{onClose:function(){return a(e.id)}}),i=o.text;switch(o.type){case"ERROR":n.error(r.a.createElement("span",null,i),o);break;case"SUCCESS":n.success(i,o);break;case"INFO":n.info(i,o);break;default:console.error("Unknown AlertMessage type: ".concat(o.type))}}},{key:"render",value:function(){return r.a.createElement("span",null)}}]),t}(a.Component);var In=Object(fn.d)()(Object(o.c)(function(e){var t=e.alerts;return{notifs:t.notifs,shouldShowDirtyConfNotif:t.shouldShowDirtyConfNotif}},function(e){return{onMessageClosed:function(t){return e(Object(Tn.b)(t))}}})(Rn)),Pn=Object(Ke.a)()(function(e){var t=e.width;return r.a.createElement(fn.a,{template:wn,offset:Object(Ke.b)("sm",t)?"10px":"6px",position:fn.b.TOP_RIGHT,timeout:0,transition:fn.c.FADE,containerStyle:{zIndex:14e6}},r.a.createElement(In,null))}),_n=Object(x.a)(function(e){return Object(w.a)({root:{flexGrow:1,padding:e.spacing(2)},navigationBarWrapper:{position:"fixed",left:0,right:0,bottom:0}})}),Dn=Object(o.c)(function(){return{onFileDrop:function(e){Object(oe.g)(e)}}})(function(e){var t=e.onFileDrop,n=e.history,a=_n();return r.a.createElement("div",null,r.a.createElement(Pn,null),r.a.createElement(on,{onDrop:t},r.a.createElement("header",null,r.a.createElement(dn,null)),r.a.createElement(k.a,{container:!0,className:a.root},r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement("main",null,r.a.createElement(N.a,{history:n},r.a.createElement(S.c,null,r.a.createElement(S.a,{exact:!0,path:"/history",component:Vt}),r.a.createElement(S.a,{exact:!0,path:"/settings",component:Lt}),r.a.createElement(S.a,{exact:!0,path:"/",component:wt})))),r.a.createElement("footer",{className:a.navigationBarWrapper},r.a.createElement(nn,null))))))});t.default=function(e){var t=e.store,n=e.history;return r.a.createElement(o.a,{store:t},r.a.createElement(h,null,r.a.createElement(Dn,{history:n})))}},207:function(e,t,n){"use strict";n.r(t);var a,r,o,i,c,s,l,u,d,f=n(0),p=n.n(f),m=n(10),h=n.n(m),b=(n(109),n(99)),g=n(17),v=n(48),E=n(122),y=(n(171),n(25)),O=n(64),C=n(6),j=n(70),S=Object(g.b)({searchFilter:"",sortProperty:"",sortDirection:"",currentPage:1,torrentsPerPage:10},(a={},Object(C.a)(a,j.a,function(e,t){e.searchFilter=t.text}),Object(C.a)(a,j.b,function(e,t){e.sortProperty=t.sortProperty,e.sortDirection=t.sortDirection}),a)),N=n(71),k=n(28),x={localConfig:void 0},w=Object(g.b)(x,(r={},Object(C.a)(r,N.b,function(e,t){e.localConfig=t.config}),Object(C.a)(r,N.a,function(e){e.localConfig=void 0}),Object(C.a)(r,k.b,function(){return x}),Object(C.a)(r,k.a,function(){return x}),r)),T=n(85),R={palette:{type:localStorage.getItem("themeType")||"light"}},I=Object(g.b)(R,Object(C.a)({},T.a,function(e){var t="light"===e.palette.type?"dark":"light";localStorage.setItem("themeType",t),e.palette.type=t})),P=n(41),_=[],D=Object(g.b)(_,(o={},Object(C.a)(o,P.c,function(e,t){var n=e.filter(function(e){return e.infoHash!==t.payload.infoHash});return n.push(t.payload),n}),Object(C.a)(o,P.d,function(e,t){return e.filter(function(e){return e.infoHash!==t.payload.infoHash})}),Object(C.a)(o,P.a,function(e){return e}),Object(C.a)(o,P.b,function(){return _}),o)),B=n(42),A={isFetching:!0,isStarted:!1,name:""},F=Object(g.b)(A,(i={},Object(C.a)(i,B.a,function(e,t){e.isFetching=!1,e.isStarted=!0,e.name=t.payload.client}),Object(C.a)(i,B.b,function(e){e.isFetching=!1,e.isStarted=!1,e.name=""}),Object(C.a)(i,B.d,function(e){e.isFetching=!0}),Object(C.a)(i,B.e,function(e){e.isFetching=!0}),Object(C.a)(i,B.c,function(){return A}),i)),L={isDirty:!1,errMessage:void 0,config:{minUploadRate:0,maxUploadRate:0,simultaneousSeed:0,client:"",keepTorrentWithZeroLeechers:!1,uploadRatioTarget:-1},availableClients:[]},H=Object(g.b)(L,(c={},Object(C.a)(c,k.b,function(e,t){e.isDirty=!0,e.config=t.payload.config,e.errMessage=void 0}),Object(C.a)(c,k.c,function(e,t){e.errMessage=t.payload.error}),Object(C.a)(c,k.a,function(e,t){e.isDirty=!1,e.config=t.payload.config,e.errMessage=void 0}),Object(C.a)(c,k.d,function(e,t){e.availableClients=t.payload.clients}),Object(C.a)(c,k.e,function(){return L}),c)),U=n(78),M={},G=Object(g.b)(M,(s={},Object(C.a)(s,U.b,function(e,t){var n={},a=!0,r=!1,o=void 0;try{for(var i,c=t.payload.speeds[Symbol.iterator]();!(a=(i=c.next()).done);a=!0){var s=i.value;n[s.infoHash]=s}}catch(l){r=!0,o=l}finally{try{a||null==c.return||c.return()}finally{if(r)throw o}}return n}),Object(C.a)(s,U.a,function(){return M}),s)),W=n(51),J=[],V=Object(g.b)(J,(l={},Object(C.a)(l,W.a,function(e,t){if(e.find(function(e){return e.infoHash===t.payload.infoHash}))return e.map(function(e){return e.infoHash===t.payload.infoHash?Object.assign({},e,{isFetching:!1},t.payload):e});e.push(Object.assign({},{isFetching:!1},t.payload))}),Object(C.a)(l,W.c,function(e,t){return"STOPPED"===t.payload.requestEvent?e.filter(function(e){return e.infoHash!==t.payload.infoHash}):e.find(function(e){return e.infoHash===t.payload.infoHash})?e.map(function(e){return e.infoHash===t.payload.infoHash?Object.assign({},e,{isFetching:!1},t.payload):e}):void e.push(Object.assign({},{isFetching:!1},t.payload))}),Object(C.a)(l,W.d,function(e,t){return e.filter(function(e){return e.infoHash!==t.payload.infoHash})}),Object(C.a)(l,W.e,function(e,t){if(e.find(function(e){return e.infoHash===t.payload.infoHash}))return e.map(function(e){return e.infoHash===t.payload.infoHash?Object.assign({},e,{isFetching:!0},t.payload):e});e.push(Object.assign({},{isFetching:!0},t.payload))}),Object(C.a)(l,W.b,function(){return J}),l)),q=n(18),z={isConnected:!1,isFullyInit:!1},K=Object(g.b)(z,(u={},Object(C.a)(u,q.e,function(e){e.isFullyInit=!1}),Object(C.a)(u,q.a,function(e){e.isConnected=!0}),Object(C.a)(u,q.c,function(e){e.isConnected=!1,e.isFullyInit=!1}),Object(C.a)(u,q.b,function(e){e.isConnected=!1,e.isFullyInit=!1}),Object(C.a)(u,q.d,function(e){e.isFullyInit=!0}),Object(C.a)(u,q.g,function(){return z}),u)),Y=Object(y.combineReducers)({torrentFiles:D,client:F,announcers:V,settings:H,speed:G,stomp:K}),X=n(86),Z=function(){return([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})},Q=!1,$=Object(g.b)({shouldShowDirtyConfNotif:!1,notifs:[]},(d={},Object(C.a)(d,q.d,function(e){return Q=!0,e}),Object(C.a)(d,q.a,function(e){Q=!1;var t={id:Z(),text:"Connected to JOAL",timeout:6e3,type:"SUCCESS"};e.notifs.push(t)}),Object(C.a)(d,q.b,function(e){var t={id:Z(),text:"Lost connection to JOAL, auto-reconnect in 8 seconds.",timeout:6e3,type:"ERROR"};e.notifs.push(t)}),Object(C.a)(d,q.c,function(e){var t={id:Z(),text:"Failed to connect to JOAL, retry in 8 seconds.",timeout:6e3,type:"ERROR"};e.notifs.push(t)}),Object(C.a)(d,X.a,function(e,t){e.notifs=e.notifs.filter(function(e){return e.id!==t.payload})}),Object(C.a)(d,k.b,function(e){e.shouldShowDirtyConfNotif=!0}),Object(C.a)(d,k.a,function(e){e.shouldShowDirtyConfNotif=!1}),Object(C.a)(d,k.c,function(e,t){var n={id:Z(),text:"Invalid config: ".concat(t.payload.error),timeout:6e3,type:"ERROR"};e.notifs.push(n)}),Object(C.a)(d,P.c,function(e,t){if(!Q)return e;var n={id:Z(),text:"".concat(t.payload.name," added"),timeout:6e3,type:"SUCCESS"};e.notifs.push(n)}),Object(C.a)(d,P.a,function(e,t){var n={id:Z(),text:"".concat(t.payload.fileName," was rejected by server: ").concat(t.payload.error),timeout:6e3,type:"ERROR"};e.notifs.push(n)}),Object(C.a)(d,q.f,function(e,t){var n={id:Z(),text:t.message,timeout:8e3,type:"ERROR"};e.notifs.push(n)}),d)),ee=function(e){return Object(y.combineReducers)({api:Y,app:Object(y.combineReducers)({config:w,torrentsTable:S}),theme:I,alerts:$,router:Object(O.b)(e)})},te=Object(v.a)();var ne=n(55),ae=n(31);Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));n(184),n(185);var re=function(e){var t=ee(te),n=[Object(E.a)(te)].concat(Object(b.a)(Object(g.c)()));return Object(g.a)({reducer:t,middleware:n,devTools:!1,preloadedState:e})}();!function(){if(window.location.search&&window.location.search.includes("ui_credentials")){var e=new URLSearchParams(window.location.search),t=e.get("ui_credentials");if(null!==t)try{var n=JSON.parse(decodeURIComponent(t));Object(ne.b)(n)}catch(r){console.error("Failed to extract uiConfig from url params.",r)}finally{e.delete("ui_credentials");var a=window.location.pathname;!1===e.keys().next().done&&(a+="?".concat(e.toString())),window.location.hash&&(a+=window.location.hash),window.history.replaceState({},document.title,a)}}}(),Object(ae.a)(re);var oe=document.getElementById("root");!function(){var e=n(206).default;h.a.render(p.a.createElement(e,{store:re,history:te}),oe)}(),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(e){e.unregister()})},28:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"c",function(){return r}),n.d(t,"a",function(){return o}),n.d(t,"d",function(){return i}),n.d(t,"e",function(){return c}),n.d(t,"g",function(){return s}),n.d(t,"f",function(){return l});var a="@@api/listener/CONFIG_IS_IN_DIRTY_STATE",r="@@api/listener/INVALID_CONFIG",o="@@api/listener/CONFIG_HAS_BEEN_LOADED",i="@@api/listener/LIST_OF_CLIENT_FILES",c="@@reset/RESET_CONFIG",s=function(e){return{type:"@@api/send/SEND_CONFIG",config:e}},l=function(){return{type:c}}},31:function(e,t,n){"use strict";var a,r,o=n(65),i=n(66),c=n(128),s=n.n(c),l=n(55),u=n(18),d=function(){function e(t,n){Object(o.a)(this,e),this.reconnectTimeout=void 0,this.reduxStore=void 0,this.onDisconnectCallback=void 0,this.subscriptions=void 0,this.stompClient=void 0,this.reconnectTimeout=void 0,this.reduxStore=t,this.onDisconnectCallback=n,this.subscriptions=[],this.stompClient={}}return Object(i.a)(e,[{key:"send",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.stompClient&&this.stompClient.connected?this.stompClient.send(e,t,n):console.error("You can not send message to JOAL when not connected through WebSocket.")}},{key:"connect",value:function(){var e=this,t=Object(l.a)(),n="https:"===window.location.protocol?"wss":"ws",a="".concat(n,"://").concat(t.host,":").concat(t.port,"/").concat(t.pathPrefix),r=t.secretToken;this._dispatchOnConnect(),this.stompClient=s.a.client(a,{debug:!1,protocols:["v12.stomp","v11.stomp"]}),this.stompClient.connect({"X-Joal-Auth-Token":r,"X-Joal-Username":([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})},function(){e._dispatchHasConnected(),e.stompClient.subscribe("/joal/initialize-me",function(t){JSON.parse(t.body).forEach(function(t){e.onReceiveMessage(t)}),e._dispatchIsReady(),t.ack(),e.stompClient.unsubscribe("/initialize-me")}),["/global","/announce","/config","/torrents","/speed"].forEach(function(t){var n=e.stompClient.subscribe(t,function(t){t.ack(),e.onReceiveMessage(JSON.parse(t.body))},{ack:"client"});e.subscriptions.push(n)})},function(t){(console.log("error message from websocket",t),t instanceof CloseEvent)?(e.subscriptions.length>0?e._dispatchHasDropConnection():e._dispatchHasFailedToConnect(),e.onDisconnectCallback&&e.onDisconnectCallback(),e._reconnectAfterTimeout(8e3)):e.reduxStore.dispatch(Object(u.k)(t.headers.message||"Undefined error"))})}},{key:"_dispatchIsReady",value:function(){this.reduxStore.dispatch(Object(u.l)())}},{key:"_dispatchOnConnect",value:function(){this.reduxStore.dispatch(Object(u.m)())}},{key:"_dispatchHasConnected",value:function(){this.reduxStore.dispatch(Object(u.h)())}},{key:"_dispatchHasDropConnection",value:function(){this.reduxStore.dispatch(Object(u.i)())}},{key:"_dispatchHasFailedToConnect",value:function(){this.reduxStore.dispatch(Object(u.j)())}},{key:"onReceiveMessage",value:function(e){var t=e.type,n=e.payload;this.reduxStore.dispatch({type:"@@api/listener/".concat(t),payload:n})}},{key:"_reconnectAfterTimeout",value:function(e){var t=this;this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions=[],void 0===this.reconnectTimeout&&(this.reconnectTimeout=window.setTimeout(function(){t.connect(),t.reconnectTimeout=void 0},e))}},{key:"disconnect",value:function(){this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions=[],this.stompClient&&this.stompClient.connected&&this.stompClient.disconnect(),this.onDisconnectCallback&&this.onDisconnectCallback()}},{key:"disconnectAndReconnect",value:function(){clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.disconnect(),this.connect()}}]),e}(),f=n(51),p=n(42),m=n(28),h=n(41),b=n(78);n.d(t,"a",function(){return g}),n.d(t,"c",function(){return v}),n.d(t,"e",function(){return E}),n.d(t,"f",function(){return y}),n.d(t,"d",function(){return O}),n.d(t,"g",function(){return C}),n.d(t,"b",function(){return j});var g=function(e){(r=new d(a=e,function(){a.dispatch(Object(u.n)()),a.dispatch(Object(m.f)()),a.dispatch(Object(p.f)()),a.dispatch(Object(f.f)()),a.dispatch(Object(h.e)()),a.dispatch(Object(b.c)())})).connect()},v=function(){r.disconnectAndReconnect()},E=function(){a.dispatch(Object(p.g)()),r.send("/joal/global/start")},y=function(){a.dispatch(Object(p.h)()),r.send("/joal/global/stop")},O=function(e){a.dispatch(Object(m.g)(e)),r.send("/joal/config/save",JSON.stringify(e))},C=function(e){var t=new FileReader;!function n(){var a,o=e.pop();void 0!==o&&(a=o,t.onload=function(){if(null!=t.result){var e=t.result.replace(/data:.+?,/,"");r.send("/joal/torrents/upload",JSON.stringify({fileName:a.name,b64String:e})),setTimeout(n,1300)}},t.onabort=function(){return console.log("file reading was aborted for [".concat(a.name,"]"))},t.onerror=function(){return console.log("file reading has failed for [".concat(a.name,"]"))},t.readAsDataURL(a))}()},j=function(e){r.send("/joal/torrents/delete",e)}},41:function(e,t,n){"use strict";n.d(t,"c",function(){return a}),n.d(t,"d",function(){return r}),n.d(t,"a",function(){return o}),n.d(t,"b",function(){return i}),n.d(t,"e",function(){return c});var a="@@api/listener/TORRENT_FILE_ADDED",r="@@api/listener/TORRENT_FILE_DELETED",o="@@api/listener/FAILED_TO_ADD_TORRENT_FILE",i="@@reset/RESET_TORRENT_FILES_STATE",c=function(){return{type:i}}},42:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"e",function(){return i}),n.d(t,"c",function(){return c}),n.d(t,"g",function(){return s}),n.d(t,"h",function(){return l}),n.d(t,"f",function(){return u});var a="@@api/listener/GLOBAL_SEED_STARTED",r="@@api/listener/GLOBAL_SEED_STOPPED",o="@@api/send/SEND_START_TO_SERVER",i="@@api/send/SEND_STOP_TO_SERVER",c="@@reset/RESET_CLIENT_STATE";function s(){return{type:o}}function l(){return{type:i}}var u=function(){return{type:c}}},51:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"c",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"e",function(){return i}),n.d(t,"b",function(){return c}),n.d(t,"f",function(){return s});var a="@@api/listener/FAILED_TO_ANNOUNCE",r="@@api/listener/SUCCESSFULLY_ANNOUNCE",o="@@api/listener/TOO_MANY_ANNOUNCES_FAILED",i="@@api/listener/WILL_ANNOUNCE",c="@@reset/RESET_ANNOUNCER_STATE",s=function(){return{type:c}}},55:function(e,t,n){"use strict";n.d(t,"a",function(){return i}),n.d(t,"b",function(){return c});var a,r=n(88),o=n.n(r);n(181);a=o()()?n(182):n(183);var i=function(){return a.getConfig()},c=function(e){return a.saveConfig(e)}},70:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r}),n.d(t,"c",function(){return o}),n.d(t,"d",function(){return i});var a="@@ui/torrents-table/TORRENT_SEARCH_FILTER_TEXT_CHANGED",r="@@ui/torrents-table/TORRENT_SORT_CHANGED";function o(e){return{type:a,text:e}}function i(e,t){return{type:r,sortProperty:e,sortDirection:t}}},71:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"c",function(){return i});var a="@@ui/LOCAL_CONFIG_HAS_CHANGED",r="@@ui/DISCARD_LOCAL_CONFIG",o=function(e){return{type:a,config:e}},i=function(){return{type:r}}},78:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"c",function(){return o});var a="@@api/listener/SEEDING_SPEED_HAS_CHANGED",r="@@reset/RESET_SPEED_STATE",o=function(){return{type:r}}},85:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r});var a="@@ui/theme/CHANGE_THEME_TYPE";function r(){return{type:a}}},86:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r});var a="@@notifications/REMOVE_NOTIFICATION",r=function(e){return{type:a,payload:e}}}},[[166,1,2]]]); +//# sourceMappingURL=main.54cbbbea.chunk.js.map \ No newline at end of file diff --git a/src/main/resources/public/static/js/main.54cbbbea.chunk.js.map b/src/main/resources/public/static/js/main.54cbbbea.chunk.js.map new file mode 100644 index 0000000..13c57f7 --- /dev/null +++ b/src/main/resources/public/static/js/main.54cbbbea.chunk.js.map @@ -0,0 +1 @@ +{"version":3,"sources":["modules/joal-api/stomp/stomp.actions.ts","utils/ConfigProvider/ElectronConfigProvider.ts","utils/ConfigProvider/WebBrowserConfigProvider.ts","modules/theme/provider/theme-provider.component.tsx","modules/theme/provider/theme-provider.container.ts","modules/theme/theme-modifier/theme-modifier.component.tsx","modules/theme/theme-modifier/theme-modifier.container.ts","components/ClientInfo/clientInfo.component.tsx","components/ClientInfo/clientInfo.container.ts","components/ClientInfo/index.ts","components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator.tsx","components/UiConfigChanger/uiConfigChanger.component.tsx","components/UiConfigChanger/uiConfigChanger.container.ts","components/UiConfigChanger/index.ts","components/TorrentsTable/Announcer/Peers/Peers.tsx","components/TorrentsTable/Announcer/Peers/index.ts","components/TorrentsTable/Announcer/UploadSpeed/uploadSpeed.component.tsx","components/TorrentsTable/Announcer/UploadSpeed/index.ts","components/TorrentsTable/Announcer/UploadSpeed/uploadSpeed.container.ts","components/TorrentsTable/Announcer/ProgressBar/AnnouncingProgressBar.component.tsx","components/TorrentsTable/Announcer/ProgressBar/TimeUntilAnnounceProgressBar.component.tsx","components/TorrentsTable/Announcer/Announcer.tsx","components/TorrentsTable/Announcer/index.ts","components/TorrentsTable/torrentsTable.component.tsx","components/TorrentsTable/torrentsTable.container.ts","components/TorrentsTable/index.ts","pages/dashboard/dashboard.component.tsx","pages/dashboard/dashboard.container.ts","pages/dashboard/index.ts","pages/settings/settings.component.tsx","pages/settings/settings.container.ts","pages/settings/index.ts","pages/event-history/event-history.component.tsx","pages/event-history/event-history.container.ts","pages/event-history/index.ts","components/NavigationBar/navigationBar.component.tsx","components/NavigationBar/index.ts","components/NavigationBar/navigationBar.container.ts","components/TorrentDropZone.tsx","components/AppBar/appbar.component.tsx","components/AppBar/index.ts","modules/alerts/alert-template/icons/BaseIcon.tsx","modules/alerts/alert-template/icons/InfoIcon.tsx","modules/alerts/alert-template/icons/SuccessIcon.tsx","modules/alerts/alert-template/icons/ErrorIcon.tsx","modules/alerts/alert-template/icons/CloseIcon.tsx","modules/alerts/alert-template/alert-template.component.tsx","modules/alerts/alert-template/index.ts","modules/alerts/alerts-displayer.component.tsx","modules/alerts/index.ts","modules/alerts/alerts-provider.component.tsx","App.tsx","Root.tsx","components/TorrentsTable/torrentsTable.reducer.ts","pages/settings/settings.reducer.ts","modules/theme/theme-modifier/theme-modifier.reducer.ts","modules/joal-api/torrentFiles/torrentFiles.reducer.ts","modules/joal-api/client/client.reducer.ts","modules/joal-api/settings/settings.reducer.ts","modules/joal-api/speed/speed.reducer.ts","modules/joal-api/announcers/announcers.reducer.ts","modules/joal-api/stomp/stomp.reducer.ts","modules/joal-api/joal-api.reducer.ts","modules/alerts/alerts.reducer.ts","reducers/index.ts","store/configureAppStore.ts","serviceWorker.ts","index.tsx","modules/joal-api/settings/settings.actions.ts","modules/joal-api/index.ts","modules/joal-api/JoalStompClient.ts","modules/joal-api/torrentFiles/torrentFile.actions.ts","modules/joal-api/client/client.actions.ts","modules/joal-api/announcers/announcers.actions.ts","utils/ConfigProvider/index.ts","components/TorrentsTable/torrentsTable.actions.ts","pages/settings/settings.actions.ts","modules/joal-api/speed/speed.actions.ts","modules/theme/theme-modifier/theme-modifier.actions.ts","modules/alerts/alerts.actions.ts"],"names":["__webpack_require__","d","__webpack_exports__","IS_CONNECTING","HAS_CONNECTED","HAS_FAILED_TO_CONNECT","HAS_DROP_CONNECTION","INIT_OVER","RECEIVED_ERROR_MESSAGE","RESET_STOMP_STATE","isConnecting","hasConnected","hasFailedToConnect","hasDropConnection","initOver","hasReceivedError","resetStompState","type","message","r","getConfig","saveConfig","localStorageConf","localStorage","getItem","JSON","parse","console","log","host","window","location","hostname","port","pathPrefix","pathname","substring","lastIndexOf","secretToken","newConfig","setItem","stringify","cachedConf","materialUiThemeCreator","themeType","createMuiTheme","palette","primary","light","main","dark","secondary","ThemeProvider","props","children","react_default","a","createElement","MuiThemeProvider","theme","CssBaseline","connect","state","ThemeProviderComponent","ThemeModifier","onClickChangeThemeType","IconButton","aria-label","onClick","Brightness2Outlined_default","htmlColor","Brightness2_default","dispatch","changeThemeType","useStyles","makeStyles","createStyles","container","padding","leftIcon","marginRight","spacing","playPauseButton","backgroundColor","grey","boxShadow","shadows","&:focusVisible","&:active","&:disabled","color","action","disabled","disabledBackground","&:hover","@media (hover: none)","redTextButton","red","greenTextButton","green","ClientInfo","classes","classNameProps","className","client","overallUploadSpeed","isStarted","onClickStart","onClickStop","numberOfQueuedTorrents","stateText","Paper","elevation","classnames","Typography","align","variant","gutterBottom","Button","fullWidth","contained","PauseCircleFilled_default","PlayCircleFilled_default","Divider","style","marginTop","marginBottom","concat","filesize","base","defaultProps","calculateGobalSpeed","speeds","totalSpeed","_i","_Object$values","Object","values","length","bytesPerSecond","ClientInfoContainer","api","name","speed","torrentFiles","announcers","sendStartSession","sendStopSession","ClientInfoComponent","position","top","bottom","left","right","zIndex","display","alignItems","justifyContent","AbsoluteOverlayFetchingIndicator","containerStyle","active","rest","objectWithoutProperties","CircularProgress","assign","width","height","UiConfigChanger","_this","classCallCheck","this","possibleConstructorReturn","getPrototypeOf","call","config","isModalVisible","hostErr","portErr","pathPrefixErr","secretTokenErr","setState","intPort","parseInt","isNaN","objectSpread","saveNewConf","_this$state","hasError","_this$state2","_this2","_this$props","isConnected","_this$state3","redButton","changeConfigButton","Dialog","open","onClose","discardChangesAndClose","aria-labelledby","scroll","DialogTitle","id","DialogContent","FormControl","formControl","error","aria-describedby","InputLabel","htmlFor","Input","placeholder","value","onChange","e","handleHostChange","target","FormHelperText","handlePortChange","handlePathPrefixChange","handleSecretTokenChange","DialogActions","Component","withStyles","getContrastText","margin","stomp","getGUIConfig","saveGUIConfig","disconnectAndReconnect","root","leechers","seeders","PeerStats","leechersText","undefined","seedersText","Grid","direction","item","Tooltip","title","placement","data-for","data-tip","aria-hidden","Peers","UploadSpeed","speedInBytesPerSeconds","ownProps","foundSpeed","infoHash","progressBar","AnnouncingProgressBar","LinearProgress","TimeUntilAnnounceProgressBar","_React$useState","React","useState","Math","round","Date","now","lastAnnouncedDate","interval","_React$useState2","slicedToArray","percent","setPercent","useEffect","intervalId","setInterval","p","min","clearInterval","paddingTop","paddingLeft","paddingRight","paddingBottom","lineHeight","wordBreak","uploadSpeedContainer","fontSize","peersStats","deleteButton","fade","hoverOpacity","announceProgressBar","Announcer","componentBreakpoint","announcer","onClickDeleteTorrent","maxAllowedTorrentNameLength","trimedTorrentName","torrentName","xs","torrentSize","standard","DeleteOutlined_default","Announcer_Peers","lastKnownLeechers","lastKnownSeeders","Announcer_UploadSpeed","isFetching","lastAnnouncedAt","AnnouncingProgressBar_component","TimeUntilAnnounceProgressBar_component","lastKnownInterval","withWidth","desc","b","orderBy","getSorting","order","getFiltering","searchFilter","toLowerCase","includes","tableHeadUseStyles","_sortActionsContainer","searchBarPaper","searchBar","marginLeft","flex","searchBarIcon","sortActionsContainer","defineProperty","breakpoints","down","sortButtonGroup","hasSortSelected","toogleButtonWhenNoSortSelection","borderColor","EnhancedTableHead","search","onRequestSearch","onRequestSort","InputBase","Search_default","ToggleButtonGroup","selected","exclusive","v","property","ToggleButton","SortByAlpha_default","CloudDownloadOutlined_default","CloudUploadOutlined_default","EnhancedTableToolbar","_announcer","announersList","up","EnhancedTable","setSearch","_React$useState3","_React$useState4","setOrder","_React$useState5","_React$useState6","setOrderBy","_React$useState7","_React$useState8","page","setPage","_React$useState9","_React$useState10","rowsPerPage","setRowsPerPage","ceil","torrentsTable_component_EnhancedTableToolbar","filter","sort","slice","map","key","TorrentsTable_Announcer","TablePagination","rowsPerPageOptions","component","count","backIconButtonProps","nextIconButtonProps","onChangePage","event","newPage","onChangeRowsPerPage","getFilteredAnnouncers","createSelector","app","torrentsTable","trim","filterText","getSortedAndFilteredAnnouncers","sortProperty","sortDirection","filteredAnnouncers","toConsumableArray","t1","t2","TorrentsTableContainer","onFilterTextChange","text","changeSearchFilterText","onSortChange","changeTorrentSort","deleteTorrent","Announcers","relative","addButton","addButtonInput","Dashboard","shouldDisplayConfigChangerButton","isConnectedToWebSocket","isClientGlobalStatePending","uploadTorrentFiles","md","lg","components_UiConfigChanger","FetchingIndicator_AbsoluteOverlayFetchingIndicator","components_ClientInfo","TorrentsTable","dist_default","place","effect","accept","multiple","files","Array","from","Zoom","in","timeout","enter","transitions","duration","enteringScreen","exit","leavingScreen","transitionDelay","unmountOnExit","Fab","Add_default","withTheme","isElectron","uploadTorrents","discardChangesButton","formInput","minWidth","rightSpaced","MenuProps","PaperProps","maxHeight","ITEM_HEIGHT","Settings","discardLocalConfigChanges","onSettingsChange","onClickSave","availableClients","isLocalConfigChanged","valueHasChanged","newValue","justify","TextField","label","inputProps","minUploadRate","maxUploadRate","Select","input","MenuItem","simultaneousSeed","step","uploadRatioTarget","helperText","FormControlLabel","control","Checkbox","checked","keepTorrentWithZeroLeechers","localConfig","settings","localConfigHasChanged","sendConfigToServer","SettingsComponent","textAlign","EventHistory","_ref","events","Warning_default","viewBox","orange","EventHistoryContainer","EventHistoryComponent","NavigationBar","whichPath","currentPath","onClickDashboard","onClickSettings","onClickLogs","BottomNavigation","showLabels","index","BottomNavigationAction","icon","Dashboard_default","Settings_default","Sms_default","NavigationBarContainer","router","push","dropzone","overlay","TorrentDropZone","_useDropzone","useDropzone","onDrop","accepted","rejected","noClick","noKeyboard","getRootProps","getInputProps","isDragActive","rootProps","stopPropagation","flexGrow","grow","menuButton","JoalAppBar","AppBar","Toolbar","theme_modifier_container","BaseIcon","xmlns","fill","strokeWidth","strokeLinecap","strokeLinejoin","stroke","InfoIcon","icons_BaseIcon","cx","cy","x1","y1","x2","y2","SuccessIcon","points","ErrorIcon","CloseIcon","_alert","alert","borderRadius","fontFamily","textTransform","statusIcon","closeButton","border","cursor","closeIconOverride","AlertTemplate","options","close","icons_SuccessIcon","icons_InfoIcon","icons_ErrorIcon","icons_CloseIcon","JoalAlertDisplayer","nextProps","currentNotifs","notifs","currentShouldShowDirtyConfNotif","shouldShowDirtyConfNotif","prevProps","_this$props2","info","forEach","newNotif","findIndex","n","showNotification","notification","_this$props3","onMessageClosed","notifCopy","success","withAlert","_state$alerts","alerts","removeNotification","JoalAlertProvider","react_alert","template","offset","isWidthUp","positions","TOP_RIGHT","transition","FADE","alerts_displayer_component","navigationBarWrapper","onFileDrop","history","components_TorrentDropZone","components_AppBar","esm","react_router","exact","path","Historypage","SettingsPage","DashboardPage","components_NavigationBar","Root","store","es","theme_provider_container","src_App","createReducer","currentPage","torrentsPerPage","_createReducer","TORRENT_SEARCH_FILTER_TEXT_CHANGED","TORRENT_SORT_CHANGED","initialState","settings_reducer_createReducer","LOCAL_CONFIG_HAS_CHANGED","DISCARD_LOCAL_CONFIG","API___CONFIG_IS_IN_DIRTY_STATE","API____CONFIG_HAS_BEEN_LOADED","CHANGE_THEME_TYPE","newTheme","torrentFiles_reducer_createReducer","TORRENT_FILE_ADDED","newState","tf","payload","TORRENT_FILE_DELETED","FAILED_TO_ADD_TORRENT_FILE","RESET_TORRENT_FILES_STATE","client_reducer_createReducer","GLOBAL_SEED_STARTED","GLOBAL_SEED_STOPPED","SEND_START_TO_SERVER","SEND_STOP_TO_SERVER","RESET_CLIENT_STATE","isDirty","errMessage","settings_settings_reducer_createReducer","CONFIG_IS_IN_DIRTY_STATE","INVALID_CONFIG","CONFIG_HAS_BEEN_LOADED","LIST_OF_CLIENT_FILES","clients","RESET_CONFIG","speed_reducer_createReducer","SEEDING_SPEED_HAS_CHANGED","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","Symbol","iterator","next","done","currentSpeed","err","return","RESET_SPEED_STATE","announcers_reducer_createReducer","FAILED_TO_ANNOUNCE","find","SUCCESSFULLY_ANNOUNCE","requestEvent","TOO_MANY_ANNOUNCES_FAILED","WILL_ANNOUNCE","RESET_ANNOUNCER_STATE","isFullyInit","stomp_reducer_createReducer","combineReducers","apiTorrentFileReducer","apiClientReducer","apiAnnouncersReducer","apiSettingsReducer","apiSpeedReducer","apiStompReducer","uuidv4","replace","c","crypto","getRandomValues","Uint8Array","toString","isAppInit","alerts_reducer_createReducer","notif","REMOVE_NOTIFICATION","fileName","reducers","apiReducer","uiConfigReducer","torrentsTableReducer","themeReducer","alertReducer","connectRouter","createHashHistory","Boolean","match","rootReducer","createRootReducer","middlewares","routerMiddleware","getDefaultMiddleware","configureStore","reducer","middleware","devTools","preloadedState","configureAppStore","uRLSearchParams","URLSearchParams","credentialsUriEncoded","get","decodeURIComponent","delete","cleanUri","keys","hash","replaceState","document","attemptToGetUiConfigFromQuerySearchParam","connectStomp","rootEl","getElementById","require","default","ReactDOM","render","navigator","serviceWorker","ready","then","registration","unregister","sendConfig","resetConfig","stompClient","JoalStompClient","reduxStore","onDisconnectCallback","reconnectTimeout","subscriptions","body","arguments","headers","connected","send","guiConf","urlScheme","protocol","url","_dispatchOnConnect","Webstomp","debug","protocols","X-Joal-Auth-Token","X-Joal-Username","_dispatchHasConnected","subscribe","msg","onReceiveMessage","_dispatchIsReady","ack","unsubscribe","subscribesPath","subscribtion","CloseEvent","_dispatchHasDropConnection","_dispatchHasFailedToConnect","_reconnectAfterTimeout","sub","setTimeout","disconnect","clearTimeout","joal_api_connectStomp","joal_api_sendStartSession","joal_api_sendStopSession","joal_api_sendConfigToServer","appStore","resetClientState","resetAnnouncerState","resetTorrentFilesState","resetSpeedState","sendStartToServer","sendStopToServer","reader","FileReader","processOne","file","singleFile","pop","onload","result","b64Encoded","b64String","onabort","onerror","readAsDataURL","torrentInfoHash","selectedConfProvider","is_electron__WEBPACK_IMPORTED_MODULE_0__","is_electron__WEBPACK_IMPORTED_MODULE_0___default"],"mappings":"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","file":"static/js/main.54cbbbea.chunk.js","sourcesContent":["export const IS_CONNECTING = '@@api/stompClient/IS_CONNECTING';\r\nexport const HAS_CONNECTED = '@@api/stompClient/HAS_CONNECTED';\r\nexport const HAS_FAILED_TO_CONNECT = '@@api/stompClient/HAS_FAILED_TO_CONNECT';\r\nexport const HAS_DROP_CONNECTION = '@@api/stompClient/HAS_DROP_CONNECTION';\r\nexport const INIT_OVER = '@@api/stompClient/INIT_OVER';\r\nexport const RECEIVED_ERROR_MESSAGE = '@@api/stompClient/RECEIVED_ERROR_MESSAGE';\r\n\r\nexport const RESET_STOMP_STATE = '@@reset/RESET_STOMP_STATE';\r\n\r\n\r\nexport const isConnecting = () => ({\r\n type: IS_CONNECTING\r\n});\r\n\r\nexport const hasConnected = () => ({\r\n type: HAS_CONNECTED\r\n});\r\n\r\nexport const hasFailedToConnect = () => ({\r\n type: HAS_FAILED_TO_CONNECT\r\n});\r\n\r\nexport const hasDropConnection = () => ({\r\n type: HAS_DROP_CONNECTION\r\n});\r\n\r\nexport const initOver = () => ({\r\n type: INIT_OVER\r\n});\r\n\r\nexport const hasReceivedError = (message: string) => ({\r\n type: RECEIVED_ERROR_MESSAGE,\r\n message\r\n});\r\n\r\n\r\nexport const resetStompState = () => (\r\n { type: RESET_STOMP_STATE }\r\n);\r\n","/* eslint-disable import/no-unresolved, global-require, import/no-absolute-path */\r\n\r\nimport { GuiConfig } from './types';\r\n\r\nexport const getConfig = (): GuiConfig => {\r\n const localStorageConf = localStorage.getItem('guiConfig');\r\n if (!localStorageConf) {\r\n console.log('Returning a mocked config to prevent exception from NullPointer');\r\n return {\r\n host: window.location.hostname, // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n port: window.location.port || '80', // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n pathPrefix: window.location.pathname.substring(1, window.location.pathname.lastIndexOf('/ui')) || '',\r\n secretToken: ''\r\n };\r\n }\r\n\r\n // We do not cache the config here. When running in electron the config is injected in a way that is subject to race condition.\r\n // If we read the value too early, we're going to cache the old config.\r\n return JSON.parse(localStorageConf);\r\n};\r\n\r\nexport const saveConfig = (newConfig: GuiConfig) => {\r\n localStorage.setItem('guiConfig', JSON.stringify(newConfig));\r\n};\r\n","import { GuiConfig } from './types';\r\n\r\nlet cachedConf: GuiConfig;\r\n\r\nexport const getConfig = (): GuiConfig => {\r\n if (!cachedConf) {\r\n const localStorageConf = localStorage.getItem('guiConfig');\r\n if (!localStorageConf) {\r\n cachedConf = {\r\n host: window.location.hostname, // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n port: window.location.port || '80', // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n pathPrefix: '',\r\n secretToken: ''\r\n };\r\n } else {\r\n cachedConf = JSON.parse(localStorageConf);\r\n }\r\n }\r\n return cachedConf;\r\n};\r\n\r\nexport const saveConfig = (newConfig: GuiConfig) => {\r\n localStorage.setItem('guiConfig', JSON.stringify(newConfig));\r\n cachedConf = newConfig;\r\n};\r\n","import React, { ReactNode } from 'react';\r\nimport { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';\r\nimport primary from '@material-ui/core/colors/blue';\r\nimport secondary from '@material-ui/core/colors/lightGreen';\r\nimport CssBaseline from '@material-ui/core/CssBaseline';\r\n\r\n\r\nconst materialUiThemeCreator = (themeType: 'light' | 'dark') => createMuiTheme({\r\n palette: {\r\n primary: {\r\n light: primary[300],\r\n main: primary[500],\r\n dark: primary[700],\r\n },\r\n secondary: {\r\n light: secondary[300],\r\n main: secondary[500],\r\n dark: secondary[700],\r\n },\r\n type: themeType\r\n }\r\n});\r\n\r\ntype Props = {\r\n children: ReactNode,\r\n themeType: 'light' | 'dark'\r\n};\r\n\r\nconst ThemeProvider = (props: Props) => {\r\n const { children, themeType } = props;\r\n return (\r\n \r\n {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nexport default ThemeProvider;\r\n","import { connect } from 'react-redux';\r\nimport ThemeProviderComponent from './theme-provider.component';\r\n\r\nimport { JoalState } from '../../../reducers/types';\r\n\r\nconst mapStateToProps= (state: JoalState) => {\r\n return {\r\n themeType: state.theme.palette.type\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(ThemeProviderComponent);\r\n","import React from 'react';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport LightModeOnIcon from '@material-ui/icons/Brightness2Outlined';\r\nimport DarkModeOnIcon from '@material-ui/icons/Brightness2';\r\n\r\nimport { Palette } from '../types';\r\n\r\n\r\ninterface ThemeModifierProps {\r\n palette: Palette,\r\n onClickChangeThemeType: () => void\r\n}\r\n\r\nconst ThemeModifier: React.FC = (props) => {\r\n const { palette, onClickChangeThemeType } = props;\r\n\r\n return (\r\n
\r\n \r\n {palette.type === 'light'\r\n ? \r\n : \r\n }\r\n \r\n
\r\n );\r\n}\r\n\r\nexport default ThemeModifier;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport ThemeModifier from './theme-modifier.component';\r\nimport { changeThemeType } from './theme-modifier.actions';\r\n\r\nimport { JoalState } from '../../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState) => ({\r\n palette: state.theme.palette\r\n});\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => ({\r\n onClickChangeThemeType: () => dispatch(changeThemeType()),\r\n});\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(ThemeModifier);\r\n","import React from 'react';\r\nimport Divider from '@material-ui/core/Divider';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Button from '@material-ui/core/Button';\r\nimport PlayIcon from '@material-ui/icons/PlayCircleFilled';\r\nimport PauseIcon from '@material-ui/icons/PauseCircleFilled';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport red from '@material-ui/core/colors/red';\r\nimport green from '@material-ui/core/colors/green';\r\nimport filesize from 'filesize';\r\nimport classnames from 'classnames';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n padding: 15\r\n },\r\n leftIcon: {\r\n marginRight: theme.spacing(1),\r\n },\r\n playPauseButton: {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[100],\r\n boxShadow: theme.shadows[2],\r\n '&:focusVisible': {\r\n boxShadow: theme.shadows[6],\r\n },\r\n '&:active': {\r\n boxShadow: theme.shadows[8],\r\n },\r\n '&:disabled': {\r\n color: theme.palette.action.disabled,\r\n boxShadow: theme.shadows[0],\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n '&:hover': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[800] : theme.palette.grey[300],\r\n // Reset on touch devices, it doesn't add specificity\r\n '@media (hover: none)': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[300],\r\n },\r\n '&:disabled': {\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n },\r\n },\r\n redTextButton: {\r\n color: red[400]\r\n },\r\n greenTextButton: {\r\n color: green[400]\r\n }\r\n })\r\n);\r\n\r\ntype ClientInfoProps = {\r\n className?: string,\r\n client: string,\r\n overallUploadSpeed: number,\r\n isStarted: boolean,\r\n numberOfQueuedTorrents: number,\r\n onClickStart: () => void,\r\n onClickStop: () => void\r\n};\r\n\r\nconst ClientInfo: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps,\r\n client, overallUploadSpeed, isStarted, onClickStart, onClickStop, numberOfQueuedTorrents\r\n } = props;\r\n const stateText = isStarted ? 'Running' : 'Paused';\r\n\r\n return (\r\n \r\n \r\n {stateText}\r\n \r\n \r\n {isStarted ? : }\r\n {isStarted ? 'stop' : 'start'}\r\n \r\n\r\n \r\n \r\n {client}\r\n \r\n \r\n {`Overall speed : ${filesize(overallUploadSpeed, { base: 10 })}/s`}\r\n \r\n \r\n {`Torrents in queue : ${numberOfQueuedTorrents}`}\r\n \r\n \r\n );\r\n};\r\nClientInfo.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default ClientInfo;\r\n","import { connect } from 'react-redux';\r\nimport ClientInfoComponent from './clientInfo.component';\r\nimport { sendStartSession, sendStopSession } from '../../modules/joal-api';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { SpeedsArray } from '../../modules/joal-api/types';\r\n\r\nconst calculateGobalSpeed = (speeds: SpeedsArray) => {\r\n let totalSpeed = 0\r\n for (let speed of Object.values(speeds)) {\r\n totalSpeed += speed.bytesPerSecond;\r\n }\r\n return totalSpeed;\r\n};\r\n\r\nconst mapStateToProps = (state: JoalState) => {\r\n return {\r\n client: state.api.client.name,\r\n overallUploadSpeed: calculateGobalSpeed(state.api.speed),\r\n isStarted: state.api.client.isStarted,\r\n numberOfQueuedTorrents: state.api.torrentFiles.length - state.api.announcers.length,\r\n onClickStart: () => sendStartSession(),\r\n onClickStop: () => sendStopSession()\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(ClientInfoComponent);\r\n","import ClientInfoContainer from './clientInfo.container';\r\n\r\nexport default ClientInfoContainer;\r\n","import React from 'react';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n position: 'absolute',\r\n top: 0,\r\n bottom: 0,\r\n left: 0,\r\n right: 0,\r\n backgroundColor: 'rgba(200, 200, 200, 0.63)',\r\n zIndex: 1200,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }\r\n })\r\n);\r\n\r\ntype AbsoluteOverlayFetchingIndicatorProps = {\r\n style?: object,\r\n containerStyle?: object,\r\n active: boolean\r\n};\r\n\r\nconst AbsoluteOverlayFetchingIndicator: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n style, containerStyle, active, ...rest\r\n } = props;\r\n if (!active) {\r\n return (
);\r\n }\r\n return (\r\n
\r\n {active && }\r\n
\r\n );\r\n};\r\nAbsoluteOverlayFetchingIndicator.defaultProps = {\r\n style: {},\r\n containerStyle: {}\r\n};\r\n\r\nexport default AbsoluteOverlayFetchingIndicator;\r\n","import React, { Component } from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport Input from '@material-ui/core/Input';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport Dialog from '@material-ui/core/Dialog';\r\nimport DialogActions from '@material-ui/core/DialogActions';\r\nimport DialogContent from '@material-ui/core/DialogContent';\r\nimport DialogTitle from '@material-ui/core/DialogTitle';\r\nimport { withStyles, createStyles, Theme } from '@material-ui/core/styles';\r\nimport { GuiConfig } from '../../utils/ConfigProvider/types';\r\n\r\n\r\nconst styles = (theme: Theme) => createStyles({\r\n changeConfigButton: {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[100],\r\n boxShadow: theme.shadows[2],\r\n '&:focusVisible': {\r\n boxShadow: theme.shadows[6],\r\n },\r\n '&:active': {\r\n boxShadow: theme.shadows[8],\r\n },\r\n '&:disabled': {\r\n color: theme.palette.action.disabled,\r\n boxShadow: theme.shadows[0],\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n '&:hover': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[800] : theme.palette.grey[300],\r\n // Reset on touch devices, it doesn't add specificity\r\n '@media (hover: none)': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[300],\r\n },\r\n '&:disabled': {\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n },\r\n },\r\n redButton: {\r\n color: theme.palette.getContrastText(theme.palette.error.main),\r\n backgroundColor: theme.palette.error.main,\r\n '&:hover': {\r\n backgroundColor: theme.palette.error.dark\r\n }\r\n },\r\n formControl: {\r\n margin: theme.spacing(1)\r\n }\r\n});\r\n\r\ninterface UiConfigChangerProps {\r\n classes: any,\r\n isConnected: boolean,\r\n config: GuiConfig,\r\n saveNewConf: (config: GuiConfig) => void,\r\n style?: any\r\n}\r\n\r\ninterface UiConfigChangerState {\r\n isModalVisible: boolean,\r\n host: string,\r\n port: string,\r\n pathPrefix: string,\r\n secretToken: string,\r\n hostErr: string,\r\n portErr: string,\r\n pathPrefixErr: string,\r\n secretTokenErr: string,\r\n}\r\n\r\nclass UiConfigChanger extends Component {\r\n static defaultProps = {\r\n style: {}\r\n }\r\n\r\n constructor(props: UiConfigChangerProps) {\r\n super(props);\r\n const { config } = props;\r\n\r\n this.state = {\r\n isModalVisible: false,\r\n host: config.host,\r\n port: config.port,\r\n pathPrefix: config.pathPrefix,\r\n secretToken: config.secretToken,\r\n hostErr: config.host !== '' ? '' : 'Required field',\r\n portErr: config.port !== '' ? '' : 'Required field',\r\n pathPrefixErr: config.pathPrefix !== '' ? '' : 'Required field',\r\n secretTokenErr: config.secretToken !== '' ? '' : 'Required field',\r\n };\r\n }\r\n\r\n handleHostChange(host: string) {\r\n const hostErr = host === '' ? 'Required field' : '';\r\n this.setState({ host, hostErr });\r\n }\r\n\r\n handlePortChange(port: string) {\r\n let portErr = '';\r\n const intPort = parseInt(port) - 0;\r\n if (isNaN(intPort)) { // eslint-disable-line no-restricted-globals\r\n portErr = 'You mad bro !';\r\n } else {\r\n if (intPort === 0) portErr = 'Port is required';\r\n if (intPort > 65535) portErr = 'A port that big, seriously ?';\r\n }\r\n this.setState({ port, portErr });\r\n }\r\n\r\n handlePathPrefixChange(pathPrefix: string) {\r\n const pathPrefixErr = pathPrefix === '' ? 'Required field' : '';\r\n this.setState({ pathPrefix, pathPrefixErr });\r\n }\r\n\r\n handleSecretTokenChange(secretToken: string) {\r\n const secretTokenErr = secretToken === '' ? 'Required field' : '';\r\n this.setState({ secretToken, secretTokenErr });\r\n }\r\n\r\n discardChangesAndClose() {\r\n const { config } = this.props;\r\n this.setState({ ...(config), isModalVisible: false });\r\n }\r\n\r\n saveConfig() {\r\n const { saveNewConf } = this.props;\r\n const {\r\n host, port, pathPrefix, secretToken\r\n } = this.state;\r\n\r\n if (this.hasError()) {\r\n return;\r\n }\r\n\r\n saveNewConf({\r\n host, port, pathPrefix, secretToken\r\n });\r\n this.setState({ isModalVisible: false });\r\n }\r\n\r\n hasError() {\r\n const {\r\n host, port, pathPrefix, secretToken, hostErr, portErr, pathPrefixErr, secretTokenErr\r\n } = this.state;\r\n\r\n if (!host || !port || !pathPrefix || !secretToken) {\r\n return true;\r\n }\r\n if (hostErr || portErr || pathPrefixErr || secretTokenErr) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n render() {\r\n const { classes, isConnected, style } = this.props;\r\n const {\r\n isModalVisible,\r\n host, port, pathPrefix, secretToken,\r\n hostErr, portErr, pathPrefixErr, secretTokenErr\r\n } = this.state;\r\n return (\r\n
\r\n this.setState({ isModalVisible: true })}\r\n className={isConnected ? '' : classes.redButton}\r\n classes={{ contained: classes.changeConfigButton }}\r\n >\r\n Change connection settings\r\n \r\n this.discardChangesAndClose()}\r\n aria-labelledby=\"form-dialog-connection-settings\"\r\n scroll=\"paper\"\r\n >\r\n Connection settings\r\n \r\n 0}\r\n aria-describedby=\"server-address-text\"\r\n >\r\n Server address\r\n this.handleHostChange(e.target.value)} />\r\n {hostErr}\r\n \r\n 0}\r\n aria-describedby=\"server-port-text\"\r\n >\r\n Server port\r\n this.handlePortChange(e.target.value)} />\r\n {portErr}\r\n \r\n 0}\r\n aria-describedby=\"path-prefix-text\"\r\n >\r\n Path prefix\r\n this.handlePathPrefixChange(e.target.value)} />\r\n {pathPrefixErr}\r\n \r\n 0}\r\n aria-describedby=\"secret-token-text\"\r\n >\r\n Secret token\r\n this.handleSecretTokenChange(e.target.value)} />\r\n {secretTokenErr}\r\n \r\n \r\n \r\n this.discardChangesAndClose()}\r\n >\r\n Cancel\r\n \r\n this.saveConfig()}\r\n >\r\n Save\r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default withStyles(styles)(UiConfigChanger);\r\n","import { connect } from 'react-redux';\r\nimport UiConfigChanger from './uiConfigChanger.component';\r\nimport { getGUIConfig, saveGUIConfig } from '../../utils/ConfigProvider';\r\nimport { disconnectAndReconnect } from '../../modules/joal-api';\r\nimport { GuiConfig } from '../../utils/ConfigProvider/types';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n isConnected: state.api.stomp.isConnected,\r\n config: getGUIConfig(),\r\n saveNewConf: (config: GuiConfig) => {\r\n saveGUIConfig(config);\r\n disconnectAndReconnect();\r\n }\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(UiConfigChanger);\r\n","import UiConfigChanger from './uiConfigChanger.container';\r\n\r\nexport default UiConfigChanger;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport classnames from 'classnames';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n },\r\n leechers: {\r\n color: theme.palette.primary.light,\r\n marginRight: 12\r\n },\r\n seeders: {\r\n color: theme.palette.primary.light\r\n }\r\n })\r\n);\r\n\r\ntype PeerStatsProps = {\r\n className?: string,\r\n leechers?: number,\r\n seeders?: number\r\n};\r\n\r\nconst PeerStats: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps, leechers, seeders\r\n } = props;\r\n const leechersText = (leechers === null || leechers === undefined) ? '?' : leechers;\r\n const seedersText = (seeders === null || seeders === undefined) ? '?' : seeders;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {` ${leechersText}`}\r\n \r\n \r\n \r\n \r\n \r\n {` ${seedersText}`}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\nPeerStats.defaultProps = {\r\n className: '',\r\n leechers: undefined,\r\n seeders: undefined\r\n};\r\n\r\nexport default PeerStats;\r\n","import Peers from './Peers';\r\n\r\nexport default Peers;\r\n","import React from 'react';\r\nimport filesize from 'filesize';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\ninterface UploadSpeedProps {\r\n className?: string,\r\n speedInBytesPerSeconds?: number\r\n};\r\n\r\nconst UploadSpeed: React.FC = (props) => {\r\n const { className: classNameProps, speedInBytesPerSeconds } = props;\r\n\r\n return (\r\n \r\n {speedInBytesPerSeconds === undefined ? '? B/s' : `${filesize(speedInBytesPerSeconds, { base: 10 })}/s`}\r\n \r\n );\r\n};\r\nUploadSpeed.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default UploadSpeed;\r\n","import UploadSpeed from './uploadSpeed.container';\r\n\r\nexport default UploadSpeed;\r\n","import { connect } from 'react-redux';\r\nimport UploadSpeed from './uploadSpeed.component';\r\n\r\nimport { JoalState } from '../../../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState, ownProps: { infoHash: string }) => {\r\n const foundSpeed = state.api.speed[ownProps.infoHash];\r\n\r\n return {\r\n speedInBytesPerSeconds: foundSpeed === null || foundSpeed === undefined ? undefined : foundSpeed.bytesPerSecond\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = () => ({});\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(UploadSpeed);\r\n","import React from 'react';\r\nimport LinearProgress from '@material-ui/core/LinearProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n progressBar: {\r\n }\r\n })\r\n);\r\n\r\ntype AnnouncingProgressBarProps = {\r\n className?: string\r\n}\r\n\r\nconst AnnouncingProgressBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n );\r\n}\r\nAnnouncingProgressBar.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default AnnouncingProgressBar;","import React from 'react';\r\nimport LinearProgress from '@material-ui/core/LinearProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n progressBar: {\r\n }\r\n })\r\n);\r\n\r\ntype TimeUntilAnnounceProgressBarProps = {\r\n className?: string,\r\n lastAnnouncedDate: string,\r\n interval: number\r\n}\r\n\r\nconst TimeUntilAnnounceProgressBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n \r\n const [ percent, setPercent ] = React.useState(() => \r\n Math.round((Date.now() - Date.parse(props.lastAnnouncedDate)) / 10 / props.interval)\r\n );\r\n \r\n React.useEffect(() => {\r\n const intervalId = setInterval(\r\n () =>setPercent(p => Math.min(p + 1, 100)),\r\n props.interval * 10\r\n );\r\n\r\n return () => clearInterval(intervalId)\r\n }, [ props.lastAnnouncedDate, props.interval ])\r\n\r\n return (\r\n \r\n );\r\n}\r\nTimeUntilAnnounceProgressBar.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default TimeUntilAnnounceProgressBar;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport DeleteIcon from '@material-ui/icons/DeleteOutlined';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport withWidth, { WithWidthProps } from '@material-ui/core/withWidth';\r\nimport { fade } from '@material-ui/core/styles/colorManipulator';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport filesize from 'filesize';\r\nimport classnames from 'classnames';\r\nimport PeerStats from './Peers';\r\nimport UploadSpeed from './UploadSpeed';\r\nimport AnnouncingProgressBar from './ProgressBar/AnnouncingProgressBar.component';\r\nimport TimeUntilAnnounceProgressBar from './ProgressBar/TimeUntilAnnounceProgressBar.component';\r\n\r\nimport { Announcer as AnnouncerType } from '../../../modules/joal-api/types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n paddingTop: theme.spacing(1),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(2),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n title: {\r\n marginTop: 3,\r\n lineHeight: 1.2,\r\n wordBreak: 'break-word'\r\n },\r\n uploadSpeedContainer: {\r\n bottom: 5,\r\n fontSize: 18,\r\n position: 'absolute',\r\n right: theme.spacing(2)\r\n },\r\n peersStats: {\r\n fontSize: 14\r\n },\r\n deleteButton: {\r\n color: theme.palette.error.main,\r\n '&:hover': {\r\n backgroundColor: fade(theme.palette.error.main, theme.palette.action.hoverOpacity)\r\n },\r\n position: 'absolute',\r\n right: 2,\r\n top: 2,\r\n padding: 0,\r\n height: 35,\r\n width: 42\r\n },\r\n announceProgressBar: {\r\n position: 'absolute',\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n height: 4\r\n }\r\n })\r\n);\r\n\r\ninterface AnnouncerProps extends WithWidthProps {\r\n className?: string,\r\n announcer: AnnouncerType,\r\n onClickDeleteTorrent: (infoHash: string) => void\r\n};\r\n\r\nconst Announcer: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n width: componentBreakpoint, className: classNameProps, announcer, onClickDeleteTorrent\r\n } = props;\r\n\r\n\r\n const maxAllowedTorrentNameLength = (componentBreakpoint === 'xs' || componentBreakpoint === 'sm') ? 70 : 175;\r\n let trimedTorrentName = announcer.torrentName;\r\n if (announcer.torrentName.length > maxAllowedTorrentNameLength) {\r\n trimedTorrentName = `${announcer.torrentName.substring(0, maxAllowedTorrentNameLength)}...`;\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {`${trimedTorrentName} (${filesize(announcer.torrentSize, { standard: 'iec' })})`}\r\n \r\n \r\n \r\n \r\n onClickDeleteTorrent(announcer.infoHash)}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n {announcer.isFetching || announcer.lastAnnouncedAt === undefined ? (\r\n \r\n ) : (\r\n \r\n )}\r\n
\r\n );\r\n};\r\nAnnouncer.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default withWidth()(Announcer);\r\n","import Announcer from './Announcer';\r\n\r\nexport default Announcer;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport {\r\n Grid,\r\n Paper,\r\n InputBase,\r\n IconButton,\r\n Tooltip,\r\n TablePagination\r\n} from '@material-ui/core';\r\nimport {\r\n ToggleButtonGroup,\r\n ToggleButton\r\n} from '@material-ui/lab';\r\nimport SearchIcon from '@material-ui/icons/Search';\r\nimport NameIcon from '@material-ui/icons/SortByAlpha';\r\nimport LeechersIcon from '@material-ui/icons/CloudDownloadOutlined';\r\nimport SeedersIcon from '@material-ui/icons/CloudUploadOutlined';\r\nimport Announcer from './Announcer';\r\n\r\nimport { Announcer as AnnouncerType } from '../../modules/joal-api/types'\r\n\r\n\r\nfunction desc(a: T, b: T, orderBy: keyof T) {\r\n if (b[orderBy] < a[orderBy]) {\r\n return -1;\r\n }\r\n if (b[orderBy] > a[orderBy]) {\r\n return 1;\r\n }\r\n return 0;\r\n}\r\n\r\ntype Order = 'asc' | 'desc';\r\n\r\nconst getSorting = (\r\n order: Order,\r\n orderBy?: K\r\n): (a: AnnouncerType, b: AnnouncerType) => number => {\r\n if (orderBy === '' || orderBy === undefined) {\r\n return (a, b) => 0\r\n }\r\n return order === 'desc' ? (a, b) => desc(a, b, orderBy) : (a, b) => -desc(a, b, orderBy);\r\n}\r\n\r\nconst getFiltering = (searchFilter: string): (a: AnnouncerType) => boolean => {\r\n if (searchFilter === '' || searchFilter === undefined) {\r\n return a => true\r\n }\r\n return a => a.torrentName.toLowerCase().includes(searchFilter.toLowerCase())\r\n}\r\n\r\n\r\ninterface EnhancedTableHeadProps {\r\n search: string,\r\n onRequestSearch: (search: string) => void\r\n order: Order,\r\n orderBy?: keyof AnnouncerType\r\n onRequestSort: (order: Order, property?: keyof AnnouncerType) => void\r\n}\r\n\r\nconst tableHeadUseStyles = makeStyles((theme: Theme) => ({\r\n searchBarPaper: {\r\n padding: '2px 4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n },\r\n searchBar: {\r\n marginLeft: 8,\r\n flex: 1,\r\n },\r\n searchBarIcon: {\r\n padding: 10,\r\n },\r\n sortActionsContainer: {\r\n [theme.breakpoints.down('xs')]: {\r\n width: '100%',\r\n },\r\n width: 'none'\r\n },\r\n sortButtonGroup: (props: { hasSortSelected: boolean }) => ({\r\n backgroundColor: props.hasSortSelected ? '' : 'transparent'\r\n }),\r\n toogleButtonWhenNoSortSelection: {\r\n borderColor: 'transparent'\r\n }\r\n}));\r\n\r\nfunction EnhancedTableHead(props: EnhancedTableHeadProps) {\r\n const {\r\n search,\r\n onRequestSearch,\r\n order,\r\n orderBy,\r\n onRequestSort\r\n } = props;\r\n const classes = tableHeadUseStyles({ hasSortSelected: orderBy !== undefined });\r\n\r\n function onClickSort(event: React.MouseEvent, property?: keyof AnnouncerType) {\r\n // The value is null when the user clic one more time on the same tile\r\n if (orderBy !== property && property !== null) {\r\n onRequestSort('asc', property);\r\n return;\r\n }\r\n\r\n // User clicked the same property once again\r\n if (order === 'asc') {\r\n onRequestSort('desc', orderBy);\r\n return;\r\n }\r\n if (order === 'desc') {\r\n onRequestSort('asc', undefined);\r\n return; // eslint-disable-line no-useless-return\r\n }\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n onRequestSearch(e.target.value)} placeholder=\"Filter by name\" />\r\n \r\n \r\n \r\n \r\n \r\n \r\n onClickSort(e, v)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\n\r\nconst EnhancedTableToolbar = () => {\r\n\r\n return (\r\n
{''}
\r\n );\r\n};\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n announersList: {\r\n marginTop: theme.spacing(1),\r\n [theme.breakpoints.up('md')]: {\r\n marginLeft: theme.spacing(2),\r\n }\r\n },\r\n announcer: {\r\n [theme.breakpoints.down('md')]: {\r\n marginBottom: theme.spacing(2),\r\n },\r\n [theme.breakpoints.up('md')]: {\r\n marginBottom: theme.spacing(1),\r\n }\r\n }\r\n })\r\n);\r\n\r\ninterface AnnouncerTableProps {\r\n announcers: Array\r\n onClickDeleteTorrent: (infoHash: string) => void\r\n}\r\n\r\nfunction EnhancedTable(props: AnnouncerTableProps) {\r\n const classes = useStyles();\r\n const [search, setSearch] = React.useState('');\r\n const [order, setOrder] = React.useState('asc');\r\n const [orderBy, setOrderBy] = React.useState(undefined);\r\n const [page, setPage] = React.useState(0);\r\n const [rowsPerPage, setRowsPerPage] = React.useState(10);\r\n const { announcers, onClickDeleteTorrent } = props;\r\n\r\n React.useEffect(() => {\r\n // on refresh the number of announcers may have changed, so we may need to reset the page count to prevent page index to be out of bounds\r\n if (page > (Math.ceil(announcers.length / rowsPerPage) - 1)) {\r\n setPage(0);\r\n }\r\n }, [page, announcers.length, rowsPerPage]);\r\n\r\n function handleRequestSort(order: Order, property?: keyof AnnouncerType) {\r\n setOrder(order);\r\n setOrderBy(property);\r\n }\r\n\r\n function handleChangePage(event: unknown, newPage: number) {\r\n setPage(newPage);\r\n }\r\n\r\n function handleChangeRowsPerPage(event: React.ChangeEvent) {\r\n setRowsPerPage(+event.target.value);\r\n }\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n {announcers\r\n .filter(getFiltering(search))\r\n .sort(getSorting(order, orderBy))\r\n .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)\r\n .map(announcer => {\r\n return (\r\n \r\n \r\n
\r\n )\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default EnhancedTable;","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport Announcers from './torrentsTable.component';\r\nimport { changeSearchFilterText, changeTorrentSort } from './torrentsTable.actions';\r\nimport { deleteTorrent } from '../../modules/joal-api';\r\nimport { createSelector } from 'reselect'\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { Announcer as AnnouncerType } from '../../modules/joal-api/types';\r\n\r\nconst getSearchFilter = (state: JoalState) => state.app.torrentsTable.searchFilter;\r\nconst getAnnouncers = (state: JoalState) => state.api.announcers;\r\nconst getFilteredAnnouncers = createSelector(\r\n [ getSearchFilter, getAnnouncers ],\r\n (searchFilter: string, announcers: Array) => {\r\n if (searchFilter.trim().length === 0) {\r\n return announcers;\r\n }\r\n const filterText = searchFilter.toLowerCase();\r\n return announcers.filter(a => a.torrentName.toLowerCase().includes(filterText));\r\n }\r\n)\r\n\r\nconst getSortProperty = (state: JoalState) => state.app.torrentsTable.sortProperty;\r\nconst getSortDirection = (state: JoalState) => state.app.torrentsTable.sortDirection;\r\nconst getSortedAndFilteredAnnouncers = createSelector(\r\n [ getSortProperty, getSortDirection, getFilteredAnnouncers ],\r\n (sortProperty: string, sortDirection: string, filteredAnnouncers: Array) => {\r\n if (sortProperty === '' || sortProperty === undefined || sortProperty === null) {\r\n return filteredAnnouncers;\r\n }\r\n\r\n // Spread the array to sort on a copy of the original, it will prevent side effects on the original array\r\n return [...filteredAnnouncers].sort((t1: any, t2: any) => {\r\n if (t1[sortProperty] < t2[sortProperty]) return sortDirection === 'asc' ? -1 : 1;\r\n if (t1[sortProperty] === t2[sortProperty]) return 0;\r\n return sortDirection === 'asc' ? 1 : -1;\r\n });\r\n }\r\n)\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n announcers: getSortedAndFilteredAnnouncers(state),\r\n searchFilter: state.app.torrentsTable.searchFilter,\r\n sortProperty: state.app.torrentsTable.sortProperty,\r\n sortDirection: state.app.torrentsTable.sortDirection,\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => {\r\n return {\r\n onFilterTextChange: (text: string) => dispatch(changeSearchFilterText(text)),\r\n onSortChange: (sortProperty: string , sortDirection: string) => dispatch(changeTorrentSort(sortProperty, sortDirection)),\r\n onClickDeleteTorrent: (infoHash: string) => deleteTorrent(infoHash),\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Announcers);\r\n","import TorrentsTableContainer from './torrentsTable.container';\r\n\r\nexport default TorrentsTableContainer;\r\n","import React from 'react';\r\nimport ReactTooltip from 'react-tooltip';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Fab from '@material-ui/core/Fab';\r\nimport AddIcon from '@material-ui/icons/Add';\r\nimport { withTheme, createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport Zoom from '@material-ui/core/Zoom';\r\nimport ClientInfo from '../../components/ClientInfo';\r\nimport AbsoluteOverlayFetchingIndicator from '../../components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator';\r\nimport UiConfigChangerButton from '../../components/UiConfigChanger';\r\nimport TorrentsTable from '../../components/TorrentsTable';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n relative: {\r\n position: 'relative'\r\n },\r\n addButton: {\r\n position: 'fixed',\r\n bottom: 75,\r\n right: theme.spacing(2),\r\n [theme.breakpoints.down('sm')]: {\r\n bottom: 65,\r\n right: 6,\r\n },\r\n },\r\n addButtonInput: {\r\n display: 'none'\r\n },\r\n announcers: {\r\n marginBottom: 110\r\n }\r\n })\r\n);\r\n\r\n\r\ntype Props = {\r\n theme: Theme,\r\n className?: string,\r\n isStarted: boolean,\r\n isConnectedToWebSocket: boolean,\r\n isClientGlobalStatePending: boolean,\r\n shouldDisplayConfigChangerButton: boolean,\r\n uploadTorrentFiles: (files: Array) => void\r\n};\r\n\r\nconst Dashboard = (props: Props) => {\r\n const classes = useStyles()\r\n const {\r\n className: classNameProps,\r\n shouldDisplayConfigChangerButton, theme, isConnectedToWebSocket, isClientGlobalStatePending, isStarted,\r\n uploadTorrentFiles\r\n } = props;\r\n\r\n return (\r\n \r\n \r\n {shouldDisplayConfigChangerButton && }\r\n
\r\n \r\n \r\n
\r\n
\r\n {isStarted && (\r\n \r\n \r\n \r\n )}\r\n \r\n\r\n {\r\n if (e.target.files != null) {\r\n uploadTorrentFiles(Array.from(e.target.files))\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nDashboard.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default withTheme(Dashboard);\r\n","import { connect } from 'react-redux';\r\nimport isElectron from 'is-electron';\r\nimport Dashboard from './dashboard.component';\r\nimport { uploadTorrents } from '../../modules/joal-api';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n isStarted: state.api.client.isStarted,\r\n isConnectedToWebSocket: state.api.stomp.isConnected,\r\n isClientGlobalStatePending: state.api.client.isFetching,\r\n shouldDisplayConfigChangerButton: !isElectron()\r\n };\r\n}\r\nfunction mapDispatchToProps() {\r\n return {\r\n uploadTorrentFiles: (files: Array) => uploadTorrents(files)\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Dashboard);\r\n","import Dashboard from './dashboard.container';\r\n\r\nexport default Dashboard;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Button from '@material-ui/core/Button';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Checkbox from '@material-ui/core/Checkbox';\r\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport Select from '@material-ui/core/Select';\r\nimport Input from '@material-ui/core/Input';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\nimport AbsoluteOverlayFetchingIndicator from '../../components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n padding: theme.spacing(2),\r\n position: 'relative',\r\n },\r\n discardChangesButton: {\r\n marginRight: theme.spacing(2)\r\n },\r\n formInput: {\r\n marginBottom: theme.spacing(3),\r\n minWidth: 180\r\n },\r\n rightSpaced: {\r\n marginRight: theme.spacing(2)\r\n }\r\n })\r\n);\r\n\r\n\r\nconst ITEM_HEIGHT = 48;\r\nconst MenuProps = {\r\n PaperProps: {\r\n style: {\r\n maxHeight: ITEM_HEIGHT * 6\r\n },\r\n },\r\n};\r\n\r\ntype Props = {\r\n isLocalConfigChanged: boolean,\r\n config: any,\r\n availableClients: Array,\r\n isConnectedToWebSocket: boolean,\r\n discardLocalConfigChanges: () => void,\r\n onSettingsChange: (config: any) => void,\r\n onClickSave: (config: any) => void\r\n};\r\n\r\nconst Settings = (props: Props) => {\r\n const classes = useStyles();\r\n const {\r\n isConnectedToWebSocket,\r\n discardLocalConfigChanges, onSettingsChange, onClickSave,\r\n availableClients, config, isLocalConfigChanged\r\n } = props;\r\n\r\n const valueHasChanged = (newValue: any) => onSettingsChange(Object.assign(\r\n {},\r\n config,\r\n newValue\r\n ));\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ minUploadRate: value });\r\n }}\r\n />\r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ maxUploadRate: value });\r\n }}\r\n />\r\n \r\n \r\n \r\n Torrent client\r\n valueHasChanged({ client: event.target.value })}\r\n input={}\r\n MenuProps={MenuProps}\r\n >\r\n {availableClients.map(client => (\r\n \r\n {client.substring(0, client.lastIndexOf('.'))}\r\n \r\n ))}\r\n \r\n \r\n \r\n \r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ simultaneousSeed: value });\r\n }}\r\n />\r\n \r\n \r\n 0 ? 0.1 : 1 }}\r\n helperText=\"Set to -1.0 for indefinite seeding. Note: Uploaded amount resets to 0 upon Joal restart.\"\r\n value={config.uploadRatioTarget}\r\n onChange={(event) => {\r\n const value = event.target.value === '' ? '' : event.target.value;\r\n valueHasChanged({ uploadRatioTarget: value });\r\n }}\r\n />\r\n \r\n \r\n
\r\n valueHasChanged({ keepTorrentWithZeroLeechers: checked })}\r\n />\r\n )}\r\n label=\"Keep seeding torrents even with no peers\"\r\n />\r\n \r\n If checked, when a torrent reach 0 peers it will seed at 0 kB/s. Otherwise, when a torrent reach 0 peers it will be removed.\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n { isLocalConfigChanged && (\r\n discardLocalConfigChanges()}\r\n color=\"secondary\"\r\n className={classes.discardChangesButton}\r\n >\r\n Discard\r\n \r\n )}\r\n onClickSave(config)}\r\n color=\"secondary\"\r\n >\r\n Save\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default Settings;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport SettingsComponent from './settings.component';\r\nimport { localConfigHasChanged, discardLocalConfigChanges } from './settings.actions';\r\nimport { sendConfigToServer } from '../../modules/joal-api';\r\n\r\nimport { Config } from '../../modules/joal-api/types';\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n // if local config is set it means the user has modified the config, so we show it\r\n isLocalConfigChanged: state.app.config.localConfig !== undefined,\r\n config: state.app.config.localConfig || state.api.settings.config,\r\n availableClients: state.api.settings.availableClients,\r\n isConnectedToWebSocket: state.api.stomp.isConnected\r\n };\r\n}\r\n\r\nfunction mapDispatchToProps(dispatch: Dispatch) {\r\n return ({\r\n discardLocalConfigChanges: () => dispatch(discardLocalConfigChanges()),\r\n onSettingsChange: (config: Config) => dispatch(localConfigHasChanged(config)),\r\n onClickSave: (config: Config) => sendConfigToServer(config)\r\n });\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(SettingsComponent);\r\n","import Settings from './settings.container';\r\n\r\nexport default Settings;\r\n","import React from 'react';\r\nimport IconWarning from '@material-ui/icons/Warning';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport orange from '@material-ui/core/colors/orange';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n textAlign: 'center',\r\n marginTop: 100,\r\n height: '100%'\r\n }\r\n })\r\n);\r\n\r\n\r\ntype Props = {\r\n events: Array\r\n};\r\n\r\nconst EventHistory = ({ events }: Props) => {\r\n const classes = useStyles();\r\n if (events) {\r\n // TODO: implement me. this if is just a placeholder to prevent no-unused-params\r\n }\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n Hey it looks like you discovered the super secret tab !\r\n \r\n \r\n This tab will tell you what was the last actions JOAL has performed. Unfortunately this is still under development, check it back later ;)\r\n \r\n \r\n );\r\n};\r\n\r\nexport default EventHistory;\r\n","import { connect } from 'react-redux';\r\nimport EventHistoryComponent from './event-history.component';\r\n\r\nfunction mapStateToProps() {\r\n return {\r\n events: []\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(EventHistoryComponent);\r\n","import EventHistoryContainer from './event-history.container';\r\n\r\nexport default EventHistoryContainer;\r\n","import React from 'react';\r\nimport BottomNavigation from '@material-ui/core/BottomNavigation';\r\nimport BottomNavigationAction from '@material-ui/core/BottomNavigationAction';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport DashboardIcon from '@material-ui/icons/Dashboard';\r\nimport SettingsIcon from '@material-ui/icons/Settings';\r\nimport LogsIcon from '@material-ui/icons/Sms';\r\n\r\ntype NavigationBarProps = {\r\n currentPath: string,\r\n onClickDashboard: () => void,\r\n onClickSettings: () => void,\r\n onClickLogs: () => void\r\n};\r\n\r\nconst NavigationBar: React.FC = (props) => {\r\n const {\r\n currentPath,\r\n onClickDashboard,\r\n onClickSettings,\r\n onClickLogs\r\n } = props;\r\n\r\n const whichIndex = (whichPath: string) => {\r\n if (whichPath === '/') {\r\n return 0;\r\n }\r\n if (whichPath === '/settings') {\r\n return 1;\r\n }\r\n return 2;\r\n };\r\n\r\n const onChangeTab = (event: React.ChangeEvent<{}>, index: number) => {\r\n if (index === 0) onClickDashboard();\r\n else if (index === 1) onClickSettings();\r\n else if (index === 2) onClickLogs();\r\n };\r\n\r\n return (\r\n \r\n \r\n }\r\n />\r\n }\r\n />\r\n }\r\n />\r\n \r\n \r\n );\r\n};\r\n\r\nexport default NavigationBar;\r\n","import NavigationBarContainer from './navigationBar.container';\r\n\r\nexport default NavigationBarContainer;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport NavigationBar from './navigationBar.component';\r\nimport { push } from 'connected-react-router';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState) => {\r\n return {\r\n currentPath: state.router.location.pathname\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => {\r\n return {\r\n onClickDashboard: () => dispatch(push('/')),\r\n onClickSettings: () => dispatch(push('/settings')),\r\n onClickLogs: () => dispatch(push('/history'))\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(NavigationBar);\r\n","import React, { ReactNode } from 'react';\r\nimport { useDropzone } from 'react-dropzone'\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n dropzone: {\r\n position: 'absolute',\r\n top: 0,\r\n bottom: 0,\r\n left: 0,\r\n right: 0,\r\n },\r\n overlay: {\r\n zIndex: 16777270,\r\n position: 'fixed',\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n backgroundColor: 'rgba(156, 155, 155, 0.86)',\r\n color: 'rgba(130, 130, 130, 0.75)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }\r\n })\r\n);\r\n\r\ninterface TorrentDropZoneProps {\r\n onDrop: (acceptedFiles: Array, rejectedFiles:Array) => void,\r\n children: ReactNode,\r\n}\r\n\r\nconst TorrentDropZone: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { children } = props;\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop: (accepted, rejected) => props.onDrop(accepted, rejected),\r\n noClick: true,\r\n noKeyboard: true,\r\n multiple: true\r\n })\r\n \r\n const rootProps = getRootProps({\r\n onClick: (e) => { e.stopPropagation(); } // Prevent react dropzone to execute his own handler which contains a \"event.preventDefault\". Since the dropzone embed the whole page it would prevent other input click\r\n });\r\n\r\n return (\r\n
\r\n \r\n {children}\r\n {isDragActive && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n )\r\n}\r\n\r\nexport default TorrentDropZone;\r\n","import React from 'react';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\nimport { ThemeModifier } from '../../modules/theme';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n flexGrow: 1,\r\n },\r\n grow: {\r\n flexGrow: 1,\r\n },\r\n menuButton: {\r\n marginLeft: -12,\r\n marginRight: 20,\r\n }\r\n })\r\n);\r\n\r\ntype JoalAppBarProps = {\r\n className?: any\r\n}\r\n\r\nconst JoalAppBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps\r\n } = props;\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n Joal\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\nJoalAppBar.defaultProps = {\r\n className: {}\r\n};\r\n\r\nexport default JoalAppBar;\r\n","import JoalAppBar from './appbar.component';\r\n\r\nexport default JoalAppBar;\r\n","import React, { ReactNode } from 'react';\r\n\r\n\r\ntype BaseIconProps = {\r\n className?: string,\r\n children: ReactNode\r\n}\r\n\r\nconst BaseIcon: React.FC = (props) => {\r\n const { className: classNameProps, children } = props\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n}\r\nBaseIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default BaseIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#2E9AFE'\r\n }\r\n })\r\n);\r\n\r\ntype InfoIconProps = {\r\n className?: string\r\n}\r\n\r\nconst InfoIcon:React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\nInfoIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default InfoIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#31B404'\r\n }\r\n })\r\n);\r\n\r\ntype SuccessIconProps = {\r\n className?: string\r\n}\r\n\r\nconst SuccessIcon:React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\nSuccessIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default SuccessIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#FF0040'\r\n }\r\n })\r\n);\r\n\r\ntype ErrorIconProps = {\r\n className?: string\r\n}\r\n\r\nconst ErrorIcon: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\nErrorIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default ErrorIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#000000'\r\n }\r\n })\r\n);\r\n\r\ntype CloseIconProps = {\r\n className?: string\r\n}\r\n\r\nconst CloseIcon: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\nCloseIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default CloseIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport { AlertComponentPropsWithStyle } from 'react-alert';\r\nimport InfoIcon from './icons/InfoIcon';\r\nimport SuccessIcon from './icons/SuccessIcon';\r\nimport ErrorIcon from './icons/ErrorIcon';\r\nimport CloseIcon from './icons/CloseIcon';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n alert: {\r\n // boxShadow: '0 8px 12px 0 rgba(0,0,0,0.3)',\r\n backgroundColor: `${theme.palette.type === 'dark' ? '#333' : '#fff'}`,\r\n borderRadius: 3,\r\n padding: 10,\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n boxShadow: '0px 2px 2px 2px rgba(0, 0, 0, 0.03)',\r\n fontFamily: 'Arial',\r\n fontSize: 11,\r\n width: 350,\r\n [theme.breakpoints.down('xs')]: {\r\n width: '75vw'\r\n },\r\n boxSizing: 'border-box',\r\n position: 'relative'\r\n },\r\n message: {\r\n color: `${theme.palette.type === 'dark' ? '#fff' : '#333'}`,\r\n paddingRight: 40,\r\n textAlign: 'center',\r\n textTransform: 'uppercase',\r\n },\r\n statusIcon: {\r\n marginRight: 15\r\n },\r\n closeButton: {\r\n padding: 0,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n position: 'absolute',\r\n right: 0,\r\n top: 0,\r\n bottom: 0,\r\n width: 40,\r\n border: 'none',\r\n backgroundColor: theme.palette.type === 'dark' ? '#444' : '#f3f3f3',\r\n cursor: 'pointer',\r\n },\r\n closeIconOverride: {\r\n stroke: theme.palette.type === 'dark' ? '#BBB' : '#000'\r\n }\r\n })\r\n);\r\n\r\ninterface AlertTemplateProps extends AlertComponentPropsWithStyle {\r\n}\r\n\r\nconst AlertTemplate: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n message, options, style, close\r\n } = props;\r\n return (\r\n // the style contains only the margin given as offset\r\n // options contains all alert given options\r\n // message is the alert message...\r\n // close is a function that closes the alert\r\n
\r\n {options.type === 'success' && }\r\n {options.type === 'info' && }\r\n {options.type === 'error' && }\r\n {message}\r\n \r\n
\r\n );\r\n}\r\n\r\nexport default AlertTemplate;\r\n","import AlertTemplate from './alert-template.component';\r\n\r\nexport default AlertTemplate;\r\n","import React, { Component } from 'react';\r\nimport { Dispatch } from 'redux';\r\nimport { withAlert, AlertManager } from 'react-alert';\r\nimport { connect } from 'react-redux';\r\nimport { removeNotification } from './alerts.actions';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { Notification } from './types';\r\n\r\ninterface JoalAlertDisplayerProps {\r\n alert: AlertManager, // given by withAlert wrapper\r\n notifs: Array,\r\n shouldShowDirtyConfNotif: boolean,\r\n onMessageClosed: (id: string) => void\r\n}\r\n\r\nclass JoalAlertDisplayer extends Component {\r\n\r\n shouldComponentUpdate(nextProps: JoalAlertDisplayerProps) {\r\n const { notifs: currentNotifs, shouldShowDirtyConfNotif: currentShouldShowDirtyConfNotif } = this.props;\r\n return (currentNotifs !== nextProps.notifs || currentShouldShowDirtyConfNotif !== nextProps.shouldShowDirtyConfNotif);\r\n }\r\n\r\n componentDidUpdate(prevProps: JoalAlertDisplayerProps) {\r\n const { shouldShowDirtyConfNotif, alert, notifs } = this.props;\r\n if (prevProps.shouldShowDirtyConfNotif !== shouldShowDirtyConfNotif) {\r\n if (shouldShowDirtyConfNotif === true) {\r\n alert.info('Config wont be refreshed until you restart JOAL');\r\n }\r\n }\r\n\r\n if (notifs === prevProps.notifs) {\r\n return;\r\n }\r\n\r\n // Add new notifications\r\n notifs.forEach(newNotif => {\r\n if (prevProps.notifs.findIndex(n => n.id === newNotif.id) === -1) {\r\n this.showNotification(newNotif);\r\n }\r\n });\r\n }\r\n\r\n showNotification(notification: Notification) {\r\n const { alert, onMessageClosed } = this.props;\r\n const notifCopy = Object.assign({}, notification, {\r\n onClose: () => onMessageClosed(notification.id)\r\n });\r\n const { text } = notifCopy;\r\n switch (notifCopy.type) {\r\n case 'ERROR': {\r\n alert.error({text}, notifCopy);\r\n break;\r\n }\r\n case 'SUCCESS': {\r\n alert.success(text, notifCopy);\r\n break;\r\n }\r\n case 'INFO': {\r\n alert.info(text, notifCopy);\r\n break;\r\n }\r\n default: {\r\n console.error(`Unknown AlertMessage type: ${notifCopy.type}`);\r\n }\r\n }\r\n }\r\n\r\n render() {\r\n return (\r\n \r\n );\r\n }\r\n}\r\n\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n const { notifs, shouldShowDirtyConfNotif } = state.alerts;\r\n return {\r\n notifs,\r\n shouldShowDirtyConfNotif\r\n };\r\n}\r\n\r\nfunction mapDispatchToProps(dispatch: Dispatch) {\r\n return ({\r\n onMessageClosed: (id: string) => dispatch(removeNotification(id))\r\n });\r\n}\r\n\r\nexport default withAlert()(connect(mapStateToProps, mapDispatchToProps)(JoalAlertDisplayer));\r\n","import JoalAlertProvider from './alerts-provider.component';\r\n\r\nexport default JoalAlertProvider;\r\n","import React from 'react';\r\nimport { Provider as AlertProvider, positions, transitions } from 'react-alert';\r\nimport withWidth, { isWidthUp, WithWidth } from '@material-ui/core/withWidth';\r\nimport AlertTemplate from './alert-template';\r\nimport AlertsDisplayer from './alerts-displayer.component';\r\n\r\ninterface JoalAlertProviderProps extends WithWidth {\r\n}\r\n\r\nconst JoalAlertProvider: React.FC = ({ width }) => (\r\n \r\n \r\n \r\n);\r\n\r\nexport default withWidth()(JoalAlertProvider);\r\n","import React from 'react';\r\nimport { connect } from 'react-redux';\r\nimport { Route, Switch } from 'react-router-dom';\r\nimport { ConnectedRouter } from 'connected-react-router'\r\nimport Grid from '@material-ui/core/Grid';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport DashboardPage from './pages/dashboard';\r\nimport SettingsPage from './pages/settings';\r\nimport Historypage from './pages/event-history';\r\nimport NavigationBar from './components/NavigationBar';\r\nimport TorrentDropZone from './components/TorrentDropZone';\r\nimport JoalAppBar from './components/AppBar';\r\nimport Alerts from './modules/alerts';\r\nimport { uploadTorrents } from './modules/joal-api';\r\n\r\nimport { History } from 'history';\r\n\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n flexGrow: 1,\r\n padding: theme.spacing(2)\r\n },\r\n navigationBarWrapper: {\r\n position: 'fixed',\r\n left: 0,\r\n right: 0,\r\n bottom: 0\r\n }\r\n })\r\n);\r\n\r\n\r\ninterface AppProps {\r\n history: History,\r\n onFileDrop: (accepted: Array) => void,\r\n};\r\n\r\n\r\nconst App: React.FC = ({ onFileDrop, history }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\n\r\nconst mapStateToProps = () => ({\r\n onFileDrop: (accepted: Array) => {\r\n uploadTorrents(accepted);\r\n }\r\n});\r\n\r\nexport default connect(mapStateToProps)(App);\r\n","import React from 'react';\r\nimport { Provider } from 'react-redux';\r\nimport { ThemeProvider } from './modules/theme';\r\nimport App from './App';\r\n\r\nimport { History } from 'history';\r\nimport { Store } from 'redux';\r\n\r\ninterface RootProps {\r\n store: Store,\r\n history: History\r\n};\r\n\r\nconst Root: React.FC = ({ store, history }) => (\r\n \r\n \r\n \r\n \r\n \r\n);\r\n\r\nexport default Root;\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n TORRENT_SEARCH_FILTER_TEXT_CHANGED,\r\n TORRENT_SORT_CHANGED\r\n} from './torrentsTable.actions';\r\n\r\nconst initialState = {\r\n searchFilter: '',\r\n sortProperty: '',\r\n sortDirection: '',\r\n currentPage: 1,\r\n torrentsPerPage: 10\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [TORRENT_SEARCH_FILTER_TEXT_CHANGED]: (state, action) => {\r\n state.searchFilter = action.text\r\n },\r\n [TORRENT_SORT_CHANGED]: (state, action) => {\r\n state.sortProperty = action.sortProperty;\r\n state.sortDirection = action.sortDirection;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n LOCAL_CONFIG_HAS_CHANGED,\r\n DISCARD_LOCAL_CONFIG\r\n} from './settings.actions';\r\nimport {\r\n CONFIG_IS_IN_DIRTY_STATE as API___CONFIG_IS_IN_DIRTY_STATE,\r\n CONFIG_HAS_BEEN_LOADED as API____CONFIG_HAS_BEEN_LOADED\r\n} from '../../modules/joal-api/settings/settings.actions';\r\n\r\nimport { LocalConfig } from '../../reducers/types';\r\n\r\nconst initialState: LocalConfig = {\r\n localConfig: undefined\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [LOCAL_CONFIG_HAS_CHANGED]: (state, action) => {\r\n state.localConfig = action.config;\r\n },\r\n [DISCARD_LOCAL_CONFIG]: (state) => {\r\n state.localConfig = undefined;\r\n },\r\n // When the server send the new config we remove the local one\r\n [API___CONFIG_IS_IN_DIRTY_STATE]: () => {\r\n return initialState;\r\n },\r\n [API____CONFIG_HAS_BEEN_LOADED]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n CHANGE_THEME_TYPE\r\n} from './theme-modifier.actions';\r\n\r\n\r\nconst initialState = {\r\n palette: {\r\n type: localStorage.getItem('themeType') || 'light'\r\n }\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [CHANGE_THEME_TYPE]: (state) => {\r\n const newTheme = state.palette.type === 'light' ? 'dark' : 'light';\r\n localStorage.setItem('themeType', newTheme);\r\n\r\n state.palette.type = newTheme\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n TORRENT_FILE_ADDED,\r\n TORRENT_FILE_DELETED,\r\n FAILED_TO_ADD_TORRENT_FILE,\r\n RESET_TORRENT_FILES_STATE\r\n} from './torrentFile.actions';\r\n\r\nimport { TorrentFile } from '../types';\r\n\r\nconst initialState: Array = [];\r\n\r\nexport default createReducer(initialState, {\r\n [TORRENT_FILE_ADDED]: (state, action) => {\r\n const newState = state.filter(tf => tf.infoHash !== action.payload.infoHash);\r\n newState.push(action.payload);\r\n return newState;\r\n },\r\n [TORRENT_FILE_DELETED]: (state, action) => {\r\n return state.filter(tf => tf.infoHash !== action.payload.infoHash);\r\n },\r\n [FAILED_TO_ADD_TORRENT_FILE]: (state) => {\r\n // Do nothing, notifications reducer will handle it\r\n return state;\r\n },\r\n [RESET_TORRENT_FILES_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import {\r\n GLOBAL_SEED_STARTED,\r\n GLOBAL_SEED_STOPPED,\r\n SEND_START_TO_SERVER,\r\n SEND_STOP_TO_SERVER,\r\n RESET_CLIENT_STATE\r\n} from './client.actions';\r\nimport { createReducer } from 'redux-starter-kit';\r\n\r\nimport { Client } from '../types';\r\n\r\nconst initialState: Client = {\r\n isFetching: true,\r\n isStarted: false,\r\n name: ''\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [GLOBAL_SEED_STARTED]: (state, action) => {\r\n state.isFetching = false;\r\n state.isStarted = true;\r\n state.name = action.payload.client;\r\n },\r\n [GLOBAL_SEED_STOPPED]: (state) => {\r\n state.isFetching = false;\r\n state.isStarted = false;\r\n state.name = '';\r\n },\r\n [SEND_START_TO_SERVER]: (state) => {\r\n state.isFetching = true;\r\n },\r\n [SEND_STOP_TO_SERVER]: (state) => {\r\n state.isFetching = true;\r\n },\r\n [RESET_CLIENT_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n CONFIG_IS_IN_DIRTY_STATE,\r\n INVALID_CONFIG,\r\n CONFIG_HAS_BEEN_LOADED,\r\n LIST_OF_CLIENT_FILES,\r\n RESET_CONFIG\r\n} from './settings.actions';\r\n\r\nimport { Settings } from '../types';\r\n\r\nconst initialState: Settings = {\r\n isDirty: false,\r\n errMessage: undefined,\r\n config: {\r\n minUploadRate: 0,\r\n maxUploadRate: 0,\r\n simultaneousSeed: 0,\r\n client: '',\r\n keepTorrentWithZeroLeechers: false,\r\n uploadRatioTarget: -1\r\n },\r\n availableClients: []\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [CONFIG_IS_IN_DIRTY_STATE]: (state, action) => {\r\n state.isDirty = true;\r\n state.config = action.payload.config;\r\n state.errMessage = undefined;\r\n },\r\n [INVALID_CONFIG]: (state, action) => {\r\n state.errMessage = action.payload.error;\r\n },\r\n [CONFIG_HAS_BEEN_LOADED]: (state, action) => {\r\n state.isDirty = false;\r\n state.config = action.payload.config;\r\n state.errMessage = undefined;\r\n },\r\n [LIST_OF_CLIENT_FILES]: (state, action) => {\r\n state.availableClients = action.payload.clients;\r\n },\r\n [RESET_CONFIG]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n SEEDING_SPEED_HAS_CHANGED,\r\n RESET_SPEED_STATE\r\n} from './speed.actions';\r\n\r\nimport { SpeedsArray, Speed } from '../types';\r\n\r\nconst initialState: SpeedsArray = {};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [SEEDING_SPEED_HAS_CHANGED]: (state, action: { payload: { speeds: Array }}) => {\r\n const speeds: SpeedsArray = {};\r\n for (let currentSpeed of action.payload.speeds) {\r\n speeds[currentSpeed.infoHash] = currentSpeed;\r\n }\r\n return speeds;\r\n },\r\n [RESET_SPEED_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n FAILED_TO_ANNOUNCE,\r\n SUCCESSFULLY_ANNOUNCE,\r\n TOO_MANY_ANNOUNCES_FAILED,\r\n WILL_ANNOUNCE,\r\n RESET_ANNOUNCER_STATE\r\n} from './announcers.actions';\r\n\r\nimport { Announcer as AnnouncerType } from '../types';\r\n\r\nconst initialState: Array = [];\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [FAILED_TO_ANNOUNCE]: (state, action) => {\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: false }, action.payload));\r\n return;\r\n }\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: false },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [SUCCESSFULLY_ANNOUNCE]: (state, action) => {\r\n if (action.payload.requestEvent === 'STOPPED') {\r\n return state.filter(announcer => announcer.infoHash !== action.payload.infoHash);\r\n }\r\n\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: false }, action.payload));\r\n return;\r\n }\r\n\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: false },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [TOO_MANY_ANNOUNCES_FAILED]: (state, action) => {\r\n return state.filter(announcer => announcer.infoHash !== action.payload.infoHash);\r\n },\r\n [WILL_ANNOUNCE]: (state, action) => {\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: true }, action.payload));\r\n return;\r\n }\r\n\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: true },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [RESET_ANNOUNCER_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n IS_CONNECTING,\r\n HAS_CONNECTED,\r\n HAS_FAILED_TO_CONNECT,\r\n HAS_DROP_CONNECTION,\r\n INIT_OVER,\r\n RESET_STOMP_STATE\r\n} from './stomp.actions';\r\n\r\nimport { Stomp } from '../types';\r\n\r\nconst initialState: Stomp = {\r\n isConnected: false,\r\n isFullyInit: false\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [IS_CONNECTING]: (state) => {\r\n state.isFullyInit = false;\r\n },\r\n [HAS_CONNECTED]: (state) => {\r\n state.isConnected = true;\r\n },\r\n [HAS_FAILED_TO_CONNECT]: (state) => {\r\n state.isConnected = false;\r\n state.isFullyInit = false;\r\n },\r\n [HAS_DROP_CONNECTION]: (state) => {\r\n state.isConnected = false;\r\n state.isFullyInit = false;\r\n },\r\n [INIT_OVER]: (state) => {\r\n state.isFullyInit = true;\r\n },\r\n [RESET_STOMP_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { combineReducers } from 'redux';\r\nimport apiTorrentFileReducer from './torrentFiles/torrentFiles.reducer';\r\nimport apiClientReducer from './client/client.reducer';\r\nimport apiSettingsReducer from './settings/settings.reducer';\r\nimport apiSpeedReducer from './speed/speed.reducer';\r\nimport apiAnnouncersReducer from './announcers/announcers.reducer';\r\nimport apiStompReducer from './stomp/stomp.reducer';\r\n\r\nexport default combineReducers({\r\n torrentFiles: apiTorrentFileReducer,\r\n client: apiClientReducer,\r\n announcers: apiAnnouncersReducer,\r\n settings: apiSettingsReducer,\r\n speed: apiSpeedReducer,\r\n stomp: apiStompReducer\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport { CONFIG_IS_IN_DIRTY_STATE, CONFIG_HAS_BEEN_LOADED, INVALID_CONFIG } from '../joal-api/settings/settings.actions';\r\nimport { TORRENT_FILE_ADDED, FAILED_TO_ADD_TORRENT_FILE } from '../joal-api/torrentFiles/torrentFile.actions';\r\nimport {\r\n INIT_OVER,\r\n HAS_CONNECTED,\r\n HAS_DROP_CONNECTION,\r\n HAS_FAILED_TO_CONNECT,\r\n RECEIVED_ERROR_MESSAGE\r\n} from '../joal-api/stomp/stomp.actions';\r\nimport { REMOVE_NOTIFICATION } from './alerts.actions';\r\n\r\nimport { NotificationState, Notification } from './types';\r\n\r\n\r\nconst uuidv4 = () => (\r\n ([1e7] as any +-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c: number) => (// eslint-disable-line space-infix-ops\r\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) // eslint-disable-line implicit-arrow-linebreak, no-bitwise, no-mixed-operators\r\n ))\r\n);\r\n\r\nconst initialState: NotificationState = {\r\n shouldShowDirtyConfNotif: false,\r\n notifs: []\r\n};\r\nlet isAppInit = false;\r\n\r\nexport default createReducer(initialState, {\r\n [INIT_OVER]: (state) => {\r\n isAppInit = true;\r\n return state;\r\n },\r\n [HAS_CONNECTED]: (state) => {\r\n isAppInit = false;\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Connected to JOAL',\r\n timeout: 6000,\r\n type: 'SUCCESS'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [HAS_DROP_CONNECTION]: (state) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Lost connection to JOAL, auto-reconnect in 8 seconds.',\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [HAS_FAILED_TO_CONNECT]: (state) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Failed to connect to JOAL, retry in 8 seconds.',\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [REMOVE_NOTIFICATION]: (state, action) => {\r\n state.notifs = state.notifs.filter(notif => notif.id !== action.payload);\r\n },\r\n [CONFIG_IS_IN_DIRTY_STATE]: (state) => {\r\n state.shouldShowDirtyConfNotif = true;\r\n },\r\n [CONFIG_HAS_BEEN_LOADED]: (state) => {\r\n state.shouldShowDirtyConfNotif = false;\r\n },\r\n [INVALID_CONFIG]: (state, action) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `Invalid config: ${action.payload.error}`,\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [TORRENT_FILE_ADDED]: (state, action) => {\r\n if (!isAppInit) {\r\n // don't show notification if app is not inited\r\n return state;\r\n }\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `${action.payload.name} added`,\r\n timeout: 6000,\r\n type: 'SUCCESS'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [FAILED_TO_ADD_TORRENT_FILE]: (state, action) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `${action.payload.fileName} was rejected by server: ${action.payload.error}`,\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [RECEIVED_ERROR_MESSAGE]: (state, action) =>{\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: action.message,\r\n timeout: 8000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n }\r\n});\r\n","import { combineReducers } from 'redux';\r\nimport { connectRouter } from 'connected-react-router'\r\nimport torrentsTableReducer from '../components/TorrentsTable/torrentsTable.reducer';\r\nimport uiConfigReducer from '../pages/settings/settings.reducer';\r\nimport themeReducer from '../modules/theme/theme-modifier/theme-modifier.reducer';\r\nimport apiReducer from '../modules/joal-api/joal-api.reducer';\r\nimport alertReducer from '../modules/alerts/alerts.reducer';\r\n\r\nimport { History } from 'history';\r\n\r\nexport default (history: History) => combineReducers({\r\n api: apiReducer,\r\n app: combineReducers({\r\n config: uiConfigReducer,\r\n torrentsTable: torrentsTableReducer\r\n }),\r\n theme: themeReducer,\r\n alerts: alertReducer,\r\n router: connectRouter(history)\r\n});\r\n","import { configureStore, getDefaultMiddleware } from 'redux-starter-kit';\r\nimport { createHashHistory } from 'history';\r\nimport { routerMiddleware, routerActions } from 'connected-react-router';\r\nimport { createLogger } from 'redux-logger';\r\nimport createRootReducer from '../reducers';\r\n\r\nimport { EnhancerOptions } from 'redux-devtools-extension';\r\n\r\nexport const history = createHashHistory();\r\n\r\n\r\nexport default function configureAppStore (initialState?: any) {\r\n const rootReducer = createRootReducer(history);\r\n\r\n const middlewares = [\r\n routerMiddleware(history),\r\n ...getDefaultMiddleware()\r\n ]\r\n if (process.env.NODE_ENV !== 'production') {\r\n middlewares.unshift(createLogger({ level: 'info', collapsed: true }));\r\n }\r\n\r\n let devtools: boolean | EnhancerOptions = false;\r\n if (process.env.NODE_ENV !== 'production') {\r\n devtools = {\r\n actionCreators: {\r\n ...routerActions\r\n },\r\n trace: true\r\n };\r\n }\r\n\r\n const store = configureStore({\r\n reducer: rootReducer,\r\n middleware: middlewares,\r\n devTools: devtools,\r\n preloadedState: initialState\r\n })\r\n\r\n if (process.env.NODE_ENV !== 'production' && (module as any).hot) {\r\n (module as any).hot.accept('../reducers', () => store.replaceReducer(rootReducer))\r\n }\r\n\r\n return store;\r\n}\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\ntype Config = {\r\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\r\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\r\n};\r\n\r\nexport function register(config?: Config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(\r\n (process as { env: { [key: string]: string } }).env.PUBLIC_URL,\r\n window.location.href\r\n );\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: string, config?: Config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport configureAppStore, { history } from './store/configureAppStore';\r\nimport { saveGUIConfig } from './utils/ConfigProvider';\r\nimport { connectStomp } from './modules/joal-api';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport './index.css';\r\nimport 'typeface-roboto';\r\n\r\nconst attemptToGetUiConfigFromQuerySearchParam = () => {\r\n if (!window.location.search || !window.location.search.includes('ui_credentials')) {\r\n return;\r\n }\r\n const uRLSearchParams = new URLSearchParams(window.location.search); // eslint-disable-line compat/compat\r\n const credentialsUriEncoded = uRLSearchParams.get('ui_credentials');\r\n if (credentialsUriEncoded === null) {\r\n return;\r\n }\r\n\r\n try {\r\n const config = JSON.parse(decodeURIComponent(credentialsUriEncoded));\r\n saveGUIConfig(config);\r\n } catch (e) {\r\n console.error('Failed to extract uiConfig from url params.', e);\r\n } finally {\r\n // Remove url param from uri to make it cleaner in history tab\r\n uRLSearchParams.delete('ui_credentials');\r\n let cleanUri = window.location.pathname;\r\n if (uRLSearchParams.keys().next().done === false) { // if the url search param still contains uri parameters\r\n cleanUri += `?${uRLSearchParams.toString()}`;\r\n }\r\n if (window.location.hash) {\r\n cleanUri += window.location.hash;\r\n }\r\n window.history.replaceState({}, document.title, cleanUri);\r\n }\r\n};\r\n\r\nconst store = configureAppStore();\r\n\r\nattemptToGetUiConfigFromQuerySearchParam();\r\n\r\nconnectStomp(store);\r\n\r\nconst rootEl = document.getElementById('root');\r\n\r\n\r\nlet render = () => {\r\n // Dynamically import our main App component, and render it\r\n const Root = require('./Root').default; // eslint-disable-line global-require\r\n ReactDOM.render(, rootEl);\r\n};\r\n\r\nif ((module as any).hot) {\r\n // Support hot reloading of components\r\n // and display an overlay for runtime errors\r\n const renderApp = render;\r\n\r\n // In development, we wrap the rendering function to catch errors,\r\n // and if something breaks, log the error\r\n render = () => {\r\n renderApp();\r\n };\r\n\r\n // Whenever the App component file or one of its dependencies\r\n // is changed, re-import the updated component and re-render it\r\n (module as any).hot.accept('./Root', () => {\r\n setTimeout(render);\r\n });\r\n}\r\n\r\nrender();\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: http://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n","import { Config } from '../types';\r\n\r\nexport const CONFIG_IS_IN_DIRTY_STATE = '@@api/listener/CONFIG_IS_IN_DIRTY_STATE';\r\nexport const INVALID_CONFIG = '@@api/listener/INVALID_CONFIG';\r\nexport const CONFIG_HAS_BEEN_LOADED = '@@api/listener/CONFIG_HAS_BEEN_LOADED';\r\nexport const LIST_OF_CLIENT_FILES = '@@api/listener/LIST_OF_CLIENT_FILES';\r\n\r\nexport const SEND_CONFIG = '@@api/send/SEND_CONFIG';\r\n\r\nexport const RESET_CONFIG = '@@reset/RESET_CONFIG';\r\n\r\nexport const sendConfig = (config: Config) => ({\r\n type: SEND_CONFIG,\r\n config\r\n});\r\n\r\n\r\nexport const resetConfig = () => (\r\n { type: RESET_CONFIG }\r\n);\r\n","import JoalStompClient from './JoalStompClient';\r\nimport { resetAnnouncerState } from './announcers/announcers.actions';\r\nimport { sendStartToServer, sendStopToServer, resetClientState } from './client/client.actions';\r\nimport { sendConfig, resetConfig } from './settings/settings.actions';\r\nimport { resetStompState } from './stomp/stomp.actions';\r\nimport { resetTorrentFilesState } from './torrentFiles/torrentFile.actions';\r\nimport { resetSpeedState } from './speed/speed.actions';\r\n\r\nimport { Store } from 'redux';\r\nimport { Config } from './types';\r\n\r\nlet store: Store;\r\nlet stompClient: any;\r\n\r\nexport const connectStomp = (appStore: Store) => {\r\n store = appStore;\r\n stompClient = new JoalStompClient(store, () => {\r\n // On disconnect\r\n\r\n store.dispatch(resetStompState());\r\n store.dispatch(resetConfig());\r\n store.dispatch(resetClientState());\r\n store.dispatch(resetAnnouncerState());\r\n store.dispatch(resetTorrentFilesState());\r\n store.dispatch(resetSpeedState());\r\n });\r\n stompClient.connect();\r\n};\r\n\r\nexport const disconnectAndReconnect = () => {\r\n stompClient.disconnectAndReconnect();\r\n};\r\n\r\n\r\nexport const sendStartSession = () => {\r\n store.dispatch(sendStartToServer());\r\n stompClient.send('/joal/global/start');\r\n};\r\n\r\nexport const sendStopSession = () => {\r\n store.dispatch(sendStopToServer());\r\n stompClient.send('/joal/global/stop');\r\n};\r\n\r\nexport const sendConfigToServer = (config: Config) => {\r\n store.dispatch(sendConfig(config));\r\n stompClient.send('/joal/config/save', JSON.stringify(config));\r\n};\r\n\r\nexport const uploadTorrents = (files: Array) => {\r\n const reader = new FileReader();\r\n\r\n // Process files one by one (queue like) to reduce memory consuption when sender a lot of torrent files.\r\n const processOne = () => {\r\n const singleFile = files.pop();\r\n if (singleFile === undefined) {\r\n return;\r\n }\r\n\r\n ((file) => {\r\n reader.onload = () => {\r\n if (reader.result == null) {\r\n return\r\n }\r\n const b64Encoded = (reader.result as string).replace(/data:.+?,/, '');\r\n stompClient.send('/joal/torrents/upload', JSON.stringify({\r\n fileName: file.name,\r\n b64String: b64Encoded\r\n }));\r\n setTimeout(processOne, 1300);\r\n };\r\n reader.onabort = () => console.log(`file reading was aborted for [${file.name}]`);\r\n reader.onerror = () => console.log(`file reading has failed for [${file.name}]`);\r\n\r\n reader.readAsDataURL(file);\r\n })(singleFile);\r\n };\r\n\r\n processOne();\r\n};\r\n\r\nexport const deleteTorrent = (torrentInfoHash: string) => {\r\n stompClient.send('/joal/torrents/delete', torrentInfoHash);\r\n};\r\n","import { Store } from 'redux';\r\nimport Webstomp, { Client as WebStompClient, Subscription, Frame } from 'webstomp-client';\r\nimport { getGUIConfig } from '../../utils/ConfigProvider';\r\nimport {\r\n isConnecting,\r\n hasConnected,\r\n hasDropConnection,\r\n hasFailedToConnect,\r\n initOver,\r\n hasReceivedError\r\n} from './stomp/stomp.actions';\r\n\r\nconst uuidv4 = () => (\r\n ([1e7] as any +-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c: number) => (// eslint-disable-line space-infix-ops\r\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) // eslint-disable-line implicit-arrow-linebreak, no-bitwise, no-mixed-operators\r\n ))\r\n);\r\n\r\nexport type StompMessage = {\r\n type: string,\r\n payload: {}\r\n};\r\n\r\nexport default class JoalStompClient {\r\n reconnectTimeout?: number\r\n reduxStore: Store\r\n onDisconnectCallback: () => void\r\n subscriptions: Array\r\n stompClient: WebStompClient\r\n\r\n\r\n constructor(reduxStore: Store, onDisconnectCallback: () => void) {\r\n this.reconnectTimeout = undefined;\r\n this.reduxStore = reduxStore;\r\n this.onDisconnectCallback = onDisconnectCallback;\r\n this.subscriptions = [];\r\n this.stompClient = {} as WebStompClient;\r\n }\r\n\r\n send(path: string, body: string = '', headers: {} = {}) {\r\n if (!this.stompClient || !this.stompClient.connected) {\r\n console.error('You can not send message to JOAL when not connected through WebSocket.');\r\n return;\r\n }\r\n this.stompClient.send(\r\n path,\r\n body,\r\n headers\r\n );\r\n }\r\n\r\n connect() {\r\n const guiConf = getGUIConfig();\r\n const urlScheme = (window.location.protocol === 'https:' ? 'wss' : 'ws');\r\n const url = `${urlScheme}://${guiConf.host}:${guiConf.port}/${guiConf.pathPrefix}`;\r\n const { secretToken } = guiConf;\r\n this._dispatchOnConnect(); // eslint-disable-line no-underscore-dangle\r\n this.stompClient = Webstomp.client(url, { debug: false, protocols: ['v12.stomp', 'v11.stomp'] });\r\n\r\n this.stompClient.connect({ 'X-Joal-Auth-Token': secretToken, 'X-Joal-Username': uuidv4() }, (/* response */) => {\r\n this._dispatchHasConnected(); // eslint-disable-line no-underscore-dangle\r\n /* specific mapping that intentionally include the /joal prefix */\r\n this.stompClient.subscribe('/joal/initialize-me', (message) => {\r\n JSON.parse(message.body).forEach((msg: StompMessage) => {\r\n this.onReceiveMessage(msg);\r\n });\r\n // We consider that the app is inited when the replayable events has been played.\r\n this._dispatchIsReady(); // eslint-disable-line no-underscore-dangle\r\n message.ack();\r\n this.stompClient.unsubscribe('/initialize-me');\r\n });\r\n\r\n ['/global', '/announce', '/config', '/torrents', '/speed'].forEach(subscribesPath => {\r\n const subscribtion = this.stompClient.subscribe(subscribesPath, (message) => {\r\n message.ack();\r\n this.onReceiveMessage(JSON.parse(message.body));\r\n }, { ack: 'client' });\r\n this.subscriptions.push(subscribtion);\r\n });\r\n }, (error: CloseEvent | Frame) => {\r\n console.log('error message from websocket', error);\r\n\r\n if (error instanceof CloseEvent) {\r\n // if we had some subscriptions this is a connection drop.\r\n const isConnectionDropped = this.subscriptions.length > 0;\r\n\r\n if (isConnectionDropped) {\r\n this._dispatchHasDropConnection(); // eslint-disable-line no-underscore-dangle\r\n } else {\r\n this._dispatchHasFailedToConnect(); // eslint-disable-line no-underscore-dangle\r\n }\r\n if (this.onDisconnectCallback) this.onDisconnectCallback();\r\n this._reconnectAfterTimeout(8000); // eslint-disable-line no-underscore-dangle\r\n } else {\r\n this.reduxStore.dispatch(hasReceivedError(error.headers['message'] || 'Undefined error'));\r\n }\r\n });\r\n }\r\n\r\n _dispatchIsReady() {\r\n this.reduxStore.dispatch(initOver());\r\n }\r\n\r\n _dispatchOnConnect() {\r\n this.reduxStore.dispatch(isConnecting());\r\n }\r\n\r\n _dispatchHasConnected() {\r\n this.reduxStore.dispatch(hasConnected());\r\n }\r\n\r\n _dispatchHasDropConnection() {\r\n this.reduxStore.dispatch(hasDropConnection());\r\n }\r\n\r\n _dispatchHasFailedToConnect() {\r\n this.reduxStore.dispatch(hasFailedToConnect());\r\n }\r\n\r\n onReceiveMessage(message: StompMessage) {\r\n const { type, payload } = message;\r\n this.reduxStore.dispatch({ type: `@@api/listener/${type}`, payload });\r\n }\r\n\r\n _reconnectAfterTimeout(timeout: number) {\r\n this.subscriptions.forEach(sub => sub.unsubscribe()); // release resources\r\n this.subscriptions = [];\r\n // the reconnectTimeout = undefined will ensure we don't cause memory leak.\r\n if (this.reconnectTimeout === undefined) {\r\n this.reconnectTimeout = window.setTimeout(() => {\r\n this.connect();\r\n this.reconnectTimeout = undefined;\r\n }, timeout);\r\n }\r\n }\r\n\r\n disconnect() {\r\n this.subscriptions.forEach(sub => sub.unsubscribe()); // release resources\r\n this.subscriptions = [];\r\n if (this.stompClient && this.stompClient.connected) {\r\n this.stompClient.disconnect();\r\n }\r\n if (this.onDisconnectCallback) this.onDisconnectCallback();\r\n }\r\n\r\n disconnectAndReconnect() {\r\n clearTimeout(this.reconnectTimeout);\r\n this.reconnectTimeout = undefined;\r\n this.disconnect();\r\n this.connect();\r\n }\r\n}\r\n","export const TORRENT_FILE_ADDED = '@@api/listener/TORRENT_FILE_ADDED';\r\nexport const TORRENT_FILE_DELETED = '@@api/listener/TORRENT_FILE_DELETED';\r\nexport const FAILED_TO_ADD_TORRENT_FILE = '@@api/listener/FAILED_TO_ADD_TORRENT_FILE';\r\n\r\nexport const RESET_TORRENT_FILES_STATE = '@@reset/RESET_TORRENT_FILES_STATE';\r\n\r\n\r\nexport const resetTorrentFilesState = () => (\r\n { type: RESET_TORRENT_FILES_STATE }\r\n);\r\n","export const GLOBAL_SEED_STARTED = '@@api/listener/GLOBAL_SEED_STARTED';\r\nexport const GLOBAL_SEED_STOPPED = '@@api/listener/GLOBAL_SEED_STOPPED';\r\n\r\nexport const SEND_START_TO_SERVER = '@@api/send/SEND_START_TO_SERVER';\r\nexport const SEND_STOP_TO_SERVER = '@@api/send/SEND_STOP_TO_SERVER';\r\n\r\nexport const RESET_CLIENT_STATE = '@@reset/RESET_CLIENT_STATE';\r\n\r\n\r\nexport function sendStartToServer() {\r\n return {\r\n type: SEND_START_TO_SERVER\r\n };\r\n}\r\n\r\nexport function sendStopToServer() {\r\n return {\r\n type: SEND_STOP_TO_SERVER,\r\n };\r\n}\r\n\r\n\r\nexport const resetClientState = () => (\r\n { type: RESET_CLIENT_STATE }\r\n);\r\n","export const FAILED_TO_ANNOUNCE = '@@api/listener/FAILED_TO_ANNOUNCE';\r\nexport const SUCCESSFULLY_ANNOUNCE = '@@api/listener/SUCCESSFULLY_ANNOUNCE';\r\nexport const TOO_MANY_ANNOUNCES_FAILED = '@@api/listener/TOO_MANY_ANNOUNCES_FAILED';\r\nexport const WILL_ANNOUNCE = '@@api/listener/WILL_ANNOUNCE';\r\n\r\nexport const RESET_ANNOUNCER_STATE = '@@reset/RESET_ANNOUNCER_STATE';\r\n\r\nexport const resetAnnouncerState = () => (\r\n { type: RESET_ANNOUNCER_STATE }\r\n);\r\n","import isElectron from 'is-electron';\r\n\r\nimport { GuiConfig } from './types';\r\n\r\ninterface ConfigProvider {\r\n getConfig: () => GuiConfig\r\n saveConfig: (config: GuiConfig) => void\r\n}\r\n\r\nlet selectedConfProvider: ConfigProvider;\r\nif (isElectron()) {\r\n selectedConfProvider = require('./ElectronConfigProvider'); // eslint-disable-line global-require\r\n} else {\r\n selectedConfProvider = require('./WebBrowserConfigProvider'); // eslint-disable-line global-require\r\n}\r\n\r\n\r\nexport const getGUIConfig = () => selectedConfProvider.getConfig();\r\nexport const saveGUIConfig = (config: GuiConfig) => selectedConfProvider.saveConfig(config);\r\n\r\nexport type GuiConfig = GuiConfig;\r\n","\r\nexport const TORRENT_SEARCH_FILTER_TEXT_CHANGED = '@@ui/torrents-table/TORRENT_SEARCH_FILTER_TEXT_CHANGED';\r\nexport const TORRENT_SORT_CHANGED = '@@ui/torrents-table/TORRENT_SORT_CHANGED';\r\n\r\nexport function changeSearchFilterText(text: string) {\r\n return {\r\n type: TORRENT_SEARCH_FILTER_TEXT_CHANGED,\r\n text\r\n };\r\n}\r\n\r\nexport function changeTorrentSort(sortProperty: string, sortDirection: string) {\r\n return {\r\n type: TORRENT_SORT_CHANGED,\r\n sortProperty,\r\n sortDirection\r\n };\r\n}\r\n","import { Config } from '../../modules/joal-api/types';\r\n\r\n\r\nexport const LOCAL_CONFIG_HAS_CHANGED = '@@ui/LOCAL_CONFIG_HAS_CHANGED';\r\nexport const DISCARD_LOCAL_CONFIG = '@@ui/DISCARD_LOCAL_CONFIG';\r\n\r\n\r\nexport const localConfigHasChanged = (config: Config) => {\r\n return {\r\n type: LOCAL_CONFIG_HAS_CHANGED,\r\n config\r\n };\r\n}\r\n\r\n\r\nexport const discardLocalConfigChanges = () => {\r\n return {\r\n type: DISCARD_LOCAL_CONFIG,\r\n };\r\n}\r\n","export const SEEDING_SPEED_HAS_CHANGED = '@@api/listener/SEEDING_SPEED_HAS_CHANGED';\r\n\r\nexport const RESET_SPEED_STATE = '@@reset/RESET_SPEED_STATE';\r\n\r\nexport const resetSpeedState = () => (\r\n { type: RESET_SPEED_STATE }\r\n);\r\n","export const CHANGE_THEME_TYPE = '@@ui/theme/CHANGE_THEME_TYPE';\r\n\r\nexport function changeThemeType() {\r\n return {\r\n type: CHANGE_THEME_TYPE\r\n };\r\n}\r\n","export const REMOVE_NOTIFICATION = '@@notifications/REMOVE_NOTIFICATION';\r\n\r\nexport const removeNotification = (id: string) => ({\r\n type: REMOVE_NOTIFICATION,\r\n payload: id\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file diff --git a/src/main/resources/public/static/js/main.fa028525.chunk.js b/src/main/resources/public/static/js/main.fa028525.chunk.js deleted file mode 100644 index 3f8b802..0000000 --- a/src/main/resources/public/static/js/main.fa028525.chunk.js +++ /dev/null @@ -1,2 +0,0 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[0],{166:function(e,t,n){e.exports=n(207)},18:function(e,t,n){"use strict";n.d(t,"e",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"c",function(){return o}),n.d(t,"b",function(){return i}),n.d(t,"d",function(){return c}),n.d(t,"f",function(){return s}),n.d(t,"g",function(){return l}),n.d(t,"m",function(){return u}),n.d(t,"h",function(){return d}),n.d(t,"j",function(){return f}),n.d(t,"i",function(){return p}),n.d(t,"l",function(){return m}),n.d(t,"k",function(){return h}),n.d(t,"n",function(){return b});var a="@@api/stompClient/IS_CONNECTING",r="@@api/stompClient/HAS_CONNECTED",o="@@api/stompClient/HAS_FAILED_TO_CONNECT",i="@@api/stompClient/HAS_DROP_CONNECTION",c="@@api/stompClient/INIT_OVER",s="@@api/stompClient/RECEIVED_ERROR_MESSAGE",l="@@reset/RESET_STOMP_STATE",u=function(){return{type:a}},d=function(){return{type:r}},f=function(){return{type:o}},p=function(){return{type:i}},m=function(){return{type:c}},h=function(e){return{type:s,message:e}},b=function(){return{type:l}}},181:function(e,t){},182:function(e,t,n){"use strict";n.r(t),n.d(t,"getConfig",function(){return a}),n.d(t,"saveConfig",function(){return r});var a=function(){var e=localStorage.getItem("guiConfig");return e?JSON.parse(e):(console.log("Returning a mocked config to prevent exception from NullPointer"),{host:window.location.hostname,port:window.location.port||"80",pathPrefix:window.location.pathname.substring(1,window.location.pathname.lastIndexOf("/ui"))||"",secretToken:""})},r=function(e){localStorage.setItem("guiConfig",JSON.stringify(e))}},183:function(e,t,n){"use strict";var a;n.r(t),n.d(t,"getConfig",function(){return r}),n.d(t,"saveConfig",function(){return o});var r=function(){if(!a){var e=localStorage.getItem("guiConfig");a=e?JSON.parse(e):{host:window.location.hostname,port:window.location.port||"80",pathPrefix:"",secretToken:""}}return a},o=function(e){localStorage.setItem("guiConfig",JSON.stringify(e)),a=e}},184:function(e,t,n){},206:function(e,t,n){"use strict";n.r(t);var a=n(0),r=n.n(a),o=n(13),i=n(152),c=n(287),s=n(102),l=n.n(s),u=n(103),d=n.n(u),f=n(256),p=function(e){return Object(i.a)({palette:{primary:{light:l.a[300],main:l.a[500],dark:l.a[700]},secondary:{light:d.a[300],main:d.a[500],dark:d.a[700]},type:e}})},m=function(e){var t=e.children,n=e.themeType;return r.a.createElement(c.a,{theme:p(n)},r.a.createElement(f.a,null),t)},h=Object(o.c)(function(e){return{themeType:e.theme.palette.type}})(m),b=n(258),g=n(130),v=n.n(g),E=n(131),y=n.n(E),O=function(e){var t=e.palette,n=e.onClickChangeThemeType;return r.a.createElement("div",null,r.a.createElement(b.a,{"aria-label":"Switch theme type",onClick:n},"light"===t.type?r.a.createElement(v.a,{htmlColor:"#fff"}):r.a.createElement(y.a,{htmlColor:"#fff"})))},C=n(85),j=Object(o.c)(function(e){return{palette:e.theme.palette}},function(e){return{onClickChangeThemeType:function(){return e(Object(C.b)())}}})(O),S=n(87),N=n(64),k=n(269),x=n(209),w=n(288),T=n(88),R=n.n(T),I=n(6),P=n(132),_=n.n(P),D=n(276),B=n(145),A=n.n(B),F=n(40),L=n(290),H=n(275),U=n(260),M=n(211),G=n(259),W=n(136),J=n.n(W),V=n(135),q=n.n(V),z=n(155),K=n(133),Y=n.n(K),X=n(134),Z=n.n(X),Q=n(68),$=n.n(Q),ee=n(15),te=n.n(ee),ne=Object(x.a)(function(e){return Object(w.a)({container:{padding:15},leftIcon:{marginRight:e.spacing(1)},playPauseButton:{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[100],boxShadow:e.shadows[2],"&:focusVisible":{boxShadow:e.shadows[6]},"&:active":{boxShadow:e.shadows[8]},"&:disabled":{color:e.palette.action.disabled,boxShadow:e.shadows[0],backgroundColor:e.palette.action.disabledBackground},"&:hover":{backgroundColor:"dark"===e.palette.type?e.palette.grey[800]:e.palette.grey[300],"@media (hover: none)":{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[300]},"&:disabled":{backgroundColor:e.palette.action.disabledBackground}}},redTextButton:{color:Y.a[400]},greenTextButton:{color:Z.a[400]}})}),ae=function(e){var t=ne(),n=e.className,a=e.client,o=e.overallUploadSpeed,i=e.isStarted,c=e.onClickStart,s=e.onClickStop,l=e.numberOfQueuedTorrents,u=i?"Running":"Paused";return r.a.createElement(M.a,{elevation:2,className:te()(t.container,n)},r.a.createElement(z.a,{align:"center",variant:"h5",gutterBottom:!0},u),r.a.createElement(G.a,{color:"primary",fullWidth:!0,variant:"contained",className:i?t.redTextButton:t.greenTextButton,classes:{contained:t.playPauseButton},onClick:i?s:c},i?r.a.createElement(q.a,{className:t.leftIcon}):r.a.createElement(J.a,{className:t.leftIcon}),i?"stop":"start"),r.a.createElement(U.a,{style:{marginTop:20,marginBottom:10}}),r.a.createElement(z.a,{align:"center",variant:"body2",gutterBottom:!0},r.a.createElement("b",null,a)),r.a.createElement(z.a,{align:"left",variant:"body2",gutterBottom:!0},"Overall speed : ".concat($()(o,{base:10}),"/s")),r.a.createElement(z.a,{align:"left",variant:"body2",gutterBottom:!0},"Torrents in queue : ".concat(l)))};ae.defaultProps={className:""};var re=ae,oe=n(31),ie=function(e){for(var t=0,n=0,a=Object.values(e);n65535&&(t="A port that big, seriously ?")),this.setState({port:e,portErr:t})}},{key:"handlePathPrefixChange",value:function(e){var t=""===e?"Required field":"";this.setState({pathPrefix:e,pathPrefixErr:t})}},{key:"handleSecretTokenChange",value:function(e){var t=""===e?"Required field":"";this.setState({secretToken:e,secretTokenErr:t})}},{key:"discardChangesAndClose",value:function(){var e=this.props.config;this.setState(Object(pe.a)({},e,{isModalVisible:!1}))}},{key:"saveConfig",value:function(){var e=this.props.saveNewConf,t=this.state,n=t.host,a=t.port,r=t.pathPrefix,o=t.secretToken;this.hasError()||(e({host:n,port:a,pathPrefix:r,secretToken:o}),this.setState({isModalVisible:!1}))}},{key:"hasError",value:function(){var e=this.state,t=e.host,n=e.port,a=e.pathPrefix,r=e.secretToken,o=e.hostErr,i=e.portErr,c=e.pathPrefixErr,s=e.secretTokenErr;return!(t&&n&&a&&r)||!!(o||i||c||s)}},{key:"render",value:function(){var e=this,t=this.props,n=t.classes,a=t.isConnected,o=t.style,i=this.state,c=i.isModalVisible,s=i.host,l=i.port,u=i.pathPrefix,d=i.secretToken,f=i.hostErr,p=i.portErr,m=i.pathPrefixErr,h=i.secretTokenErr;return r.a.createElement("div",{style:o},r.a.createElement(G.a,{variant:"contained",fullWidth:!0,onClick:function(){return e.setState({isModalVisible:!0})},className:a?"":n.redButton,classes:{contained:n.changeConfigButton}},"Change connection settings"),r.a.createElement(je.a,{open:c,onClose:function(){return e.discardChangesAndClose()},"aria-labelledby":"form-dialog-connection-settings",scroll:"paper"},r.a.createElement(ke.a,{id:"form-dialog-connection-settings"},"Connection settings"),r.a.createElement(Ne.a,null,r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"server-address-text"},r.a.createElement(Ce.a,{htmlFor:"server-address"},"Server address"),r.a.createElement(Oe.a,{id:"server-address",placeholder:"host",value:s,onChange:function(t){return e.handleHostChange(t.target.value)}}),r.a.createElement(ye.a,{id:"server-address-text"},f)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"server-port-text"},r.a.createElement(Ce.a,{htmlFor:"server-port"},"Server port"),r.a.createElement(Oe.a,{id:"server-port",placeholder:"port",type:"number",value:l,onChange:function(t){return e.handlePortChange(t.target.value)}}),r.a.createElement(ye.a,{id:"server-port-text"},p)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"path-prefix-text"},r.a.createElement(Ce.a,{htmlFor:"path-prefix"},"Path prefix"),r.a.createElement(Oe.a,{id:"path-prefix",placeholder:"Obfuscation path prefix",value:u,onChange:function(t){return e.handlePathPrefixChange(t.target.value)}}),r.a.createElement(ye.a,{id:"path-prefix-text"},m)),r.a.createElement(Ee.a,{className:n.formControl,error:f.length>0,"aria-describedby":"secret-token-text"},r.a.createElement(Ce.a,{htmlFor:"secret-token"},"Secret token"),r.a.createElement(Oe.a,{id:"secret-token",placeholder:"Your secret token",value:d,onChange:function(t){return e.handleSecretTokenChange(t.target.value)}}),r.a.createElement(ye.a,{id:"secret-token-text"},h))),r.a.createElement(Se.a,null,r.a.createElement(G.a,{onClick:function(){return e.discardChangesAndClose()}},"Cancel"),r.a.createElement(G.a,{variant:"contained",color:"primary",disabled:this.hasError(),onClick:function(){return e.saveConfig()}},"Save"))))}}]),t}(a.Component);we.defaultProps={style:{}};var Te=Object(xe.a)(function(e){return Object(w.a)({changeConfigButton:{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[100],boxShadow:e.shadows[2],"&:focusVisible":{boxShadow:e.shadows[6]},"&:active":{boxShadow:e.shadows[8]},"&:disabled":{color:e.palette.action.disabled,boxShadow:e.shadows[0],backgroundColor:e.palette.action.disabledBackground},"&:hover":{backgroundColor:"dark"===e.palette.type?e.palette.grey[800]:e.palette.grey[300],"@media (hover: none)":{backgroundColor:"dark"===e.palette.type?e.palette.grey[700]:e.palette.grey[300]},"&:disabled":{backgroundColor:e.palette.action.disabledBackground}}},redButton:{color:e.palette.getContrastText(e.palette.error.main),backgroundColor:e.palette.error.main,"&:hover":{backgroundColor:e.palette.error.dark}},formControl:{margin:e.spacing(1)}})})(we),Re=n(55);var Ie=Object(o.c)(function(e){return{isConnected:e.api.stomp.isConnected,config:Object(Re.a)(),saveNewConf:function(e){Object(Re.b)(e),Object(oe.c)()}}})(Te),Pe=n(99),_e=n(52),De=n(214),Be=n(282),Ae=n(292),Fe=n(273),Le=n(140),He=n.n(Le),Ue=n(142),Me=n.n(Ue),Ge=n(143),We=n.n(Ge),Je=n(144),Ve=n.n(Je),qe=n(139),ze=n.n(qe),Ke=n(272),Ye=n(138),Xe=Object(x.a)(function(e){return Object(w.a)({root:{},leechers:{color:e.palette.primary.light,marginRight:12},seeders:{color:e.palette.primary.light}})}),Ze=function(e){var t=Xe(),n=e.className,a=e.leechers,o=e.seeders,i=null===a||void 0===a?"?":a,c=null===o||void 0===o?"?":o;return r.a.createElement(k.a,{container:!0,direction:"row",className:te()(t.root,n)},r.a.createElement(k.a,{item:!0},r.a.createElement(L.a,{title:"leechers","aria-label":"leechers",placement:"top"},r.a.createElement("span",{className:t.leechers,"data-for":"leechers","data-tip":"Leechers"},r.a.createElement("i",{className:"fa fa-cloud-download","aria-hidden":"true"})," ".concat(i))),r.a.createElement(L.a,{title:"seeders","aria-label":"seeders",placement:"top"},r.a.createElement("span",{className:t.seeders,"data-for":"seeders","data-tip":"Seeders"},r.a.createElement("i",{className:"fa fa-cloud-upload","aria-hidden":"true"})," ".concat(c)))))};Ze.defaultProps={className:"",leechers:void 0,seeders:void 0};var Qe=Ze,$e=function(e){var t=e.className,n=e.speedInBytesPerSeconds;return r.a.createElement(z.a,{variant:"caption",className:t},void 0===n?"? B/s":"".concat($()(n,{base:10}),"/s"))};$e.defaultProps={className:""};var et=$e,tt=Object(o.c)(function(e,t){var n=e.api.speed[t.infoHash];return{speedInBytesPerSeconds:null===n||void 0===n?void 0:n.bytesPerSecond}},function(){return{}})(et),nt=n(271),at=Object(x.a)(function(e){return Object(w.a)({progressBar:{}})}),rt=function(e){var t=at(),n=e.className;return r.a.createElement(nt.a,{color:"primary",className:te()(t.progressBar,n)})};rt.defaultProps={className:""};var ot=rt,it=Object(x.a)(function(e){return Object(w.a)({progressBar:{}})}),ct=function(e){var t=it(),n=e.className,a=r.a.useState(function(){return Math.round((Date.now()-Date.parse(e.lastAnnouncedDate))/10/e.interval)}),o=Object(_e.a)(a,2),i=o[0],c=o[1];return r.a.useEffect(function(){var t=setInterval(function(){return c(function(e){return Math.min(e+1,100)})},10*e.interval);return function(){return clearInterval(t)}},[e.lastAnnouncedDate,e.interval]),r.a.createElement(nt.a,{variant:"determinate",value:i,className:te()(t.progressBar,n)})};ct.defaultProps={className:""};var st=ct,lt=Object(x.a)(function(e){return Object(w.a)({root:{paddingTop:e.spacing(1),paddingLeft:e.spacing(2),paddingRight:e.spacing(2),paddingBottom:e.spacing(.5)},title:{marginTop:3,lineHeight:1.2,wordBreak:"break-word"},uploadSpeedContainer:{bottom:5,fontSize:18,position:"absolute",right:e.spacing(2)},peersStats:{fontSize:14},deleteButton:{color:e.palette.error.main,"&:hover":{backgroundColor:Object(Ye.fade)(e.palette.error.main,e.palette.action.hoverOpacity)},position:"absolute",right:2,top:2,padding:0,height:35,width:42},announceProgressBar:{position:"absolute",left:0,right:0,bottom:0,height:4}})}),ut=function(e){var t=lt(),n=e.width,a=e.className,o=e.announcer,i=e.onClickDeleteTorrent,c="xs"===n||"sm"===n?70:175,s=o.torrentName;return o.torrentName.length>c&&(s="".concat(o.torrentName.substring(0,c),"...")),r.a.createElement(M.a,{elevation:2,style:{position:"relative"},className:te()(t.root,a)},r.a.createElement(k.a,{container:!0,direction:"row"},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(z.a,{align:"left",className:t.title,variant:"body2",gutterBottom:!0},"".concat(s," (").concat($()(o.torrentSize,{standard:"iec"}),")"))),r.a.createElement(k.a,{item:!0,style:{width:42}},r.a.createElement(L.a,{title:"Delete this torrent",placement:"left"},r.a.createElement(b.a,{className:t.deleteButton,"aria-label":"Delete",onClick:function(){return i(o.infoHash)}},r.a.createElement(ze.a,null))))),r.a.createElement(k.a,{container:!0,direction:"row"},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(Qe,{className:t.peersStats,leechers:o.lastKnownLeechers,seeders:o.lastKnownSeeders})),r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement("div",{className:t.uploadSpeedContainer},r.a.createElement(tt,{infoHash:o.infoHash})))),o.isFetching||void 0===o.lastAnnouncedAt?r.a.createElement(ot,{className:t.announceProgressBar}):r.a.createElement(st,{className:t.announceProgressBar,lastAnnouncedDate:o.lastAnnouncedAt,interval:o.lastKnownInterval}))};ut.defaultProps={className:""};var dt=Object(Ke.a)()(ut);function ft(e,t,n){return t[n]e[n]?1:0}var pt=function(e,t){return""===t||void 0===t?function(e,t){return 0}:"desc"===e?function(e,n){return ft(e,n,t)}:function(e,n){return-ft(e,n,t)}},mt=function(e){return""===e||void 0===e?function(e){return!0}:function(t){return t.torrentName.toLowerCase().includes(e.toLowerCase())}},ht=Object(x.a)(function(e){var t;return{searchBarPaper:{padding:"2px 4px",display:"flex",alignItems:"center"},searchBar:{marginLeft:8,flex:1},searchBarIcon:{padding:10},sortActionsContainer:(t={},Object(I.a)(t,e.breakpoints.down("xs"),{width:"100%"}),Object(I.a)(t,"width","none"),t),sortButtonGroup:function(e){return{backgroundColor:e.hasSortSelected?"":"transparent"}},toogleButtonWhenNoSortSelection:{borderColor:"transparent"}}});function bt(e){var t=e.search,n=e.onRequestSearch,a=e.order,o=e.orderBy,i=e.onRequestSort,c=ht({hasSortSelected:void 0!==o});return r.a.createElement(k.a,{container:!0,spacing:1},r.a.createElement(k.a,{item:!0,xs:!0},r.a.createElement(M.a,{className:c.searchBarPaper,elevation:1},r.a.createElement(De.a,{className:c.searchBar,value:t,onChange:function(e){return n(e.target.value)},placeholder:"Filter by name"}),r.a.createElement(b.a,{className:c.searchBarIcon,"aria-label":"Search"},r.a.createElement(He.a,null)))),r.a.createElement(k.a,{item:!0,className:c.sortActionsContainer},r.a.createElement(Ae.a,{className:"".concat(c.sortButtonGroup),selected:void 0!==o,value:o,exclusive:!0,onChange:function(e,t){var n;o===(n=t)||null===n?"asc"!==a?"desc"!==a||i("asc",void 0):i("desc",o):i("asc",n)}},r.a.createElement(L.a,{title:"Sort by name",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"torrentName"===o,value:"torrentName"},r.a.createElement(Me.a,null))),r.a.createElement(L.a,{title:"Sort by leechers",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"lastKnownLeechers"===o,value:"lastKnownLeechers"},r.a.createElement(We.a,null))),r.a.createElement(L.a,{title:"Sort by seeders",placement:"top"},r.a.createElement(Fe.a,{classes:void 0===o?{root:c.toogleButtonWhenNoSortSelection}:{},selected:"lastKnownSeeders"===o,value:"lastKnownSeeders"},r.a.createElement(Ve.a,null))))))}var gt=function(){return r.a.createElement("div",null,"")},vt=Object(x.a)(function(e){var t;return Object(w.a)({announersList:Object(I.a)({marginTop:e.spacing(1)},e.breakpoints.up("md"),{marginLeft:e.spacing(2)}),announcer:(t={},Object(I.a)(t,e.breakpoints.down("md"),{marginBottom:e.spacing(2)}),Object(I.a)(t,e.breakpoints.up("md"),{marginBottom:e.spacing(1)}),t)})});var Et=function(e){var t=vt(),n=r.a.useState(""),a=Object(_e.a)(n,2),o=a[0],i=a[1],c=r.a.useState("asc"),s=Object(_e.a)(c,2),l=s[0],u=s[1],d=r.a.useState(void 0),f=Object(_e.a)(d,2),p=f[0],m=f[1],h=r.a.useState(0),b=Object(_e.a)(h,2),g=b[0],v=b[1],E=r.a.useState(10),y=Object(_e.a)(E,2),O=y[0],C=y[1],j=e.announcers,S=e.onClickDeleteTorrent;return r.a.useEffect(function(){g>Math.ceil(j.length/O)-1&&v(0)},[g,j.length,O]),r.a.createElement("div",null,r.a.createElement(gt,null),r.a.createElement(bt,{search:o,onRequestSearch:i,order:l,orderBy:p,onRequestSort:function(e,t){u(e),m(t)}}),r.a.createElement(k.a,{container:!0,spacing:1},r.a.createElement(k.a,{item:!0,xs:12,className:t.announersList},j.filter(mt(o)).sort(pt(l,p)).slice(g*O,g*O+O).map(function(e){return r.a.createElement("div",{key:e.infoHash},r.a.createElement(dt,{className:t.announcer,announcer:e,onClickDeleteTorrent:S}))})),r.a.createElement(k.a,{item:!0,xs:12},r.a.createElement(Be.a,{rowsPerPageOptions:[10,25,50],component:"div",count:j.length,rowsPerPage:O,page:g,backIconButtonProps:{"aria-label":"Previous Page"},nextIconButtonProps:{"aria-label":"Next Page"},onChangePage:function(e,t){v(t)},onChangeRowsPerPage:function(e){C(+e.target.value)}}))))},yt=n(70),Ot=n(114),Ct=Object(Ot.a)([function(e){return e.app.torrentsTable.searchFilter},function(e){return e.api.announcers}],function(e,t){if(0===e.trim().length)return t;var n=e.toLowerCase();return t.filter(function(e){return e.torrentName.toLowerCase().includes(n)})}),jt=Object(Ot.a)([function(e){return e.app.torrentsTable.sortProperty},function(e){return e.app.torrentsTable.sortDirection},Ct],function(e,t,n){return""===e||void 0===e||null===e?n:Object(Pe.a)(n).sort(function(n,a){return n[e]>e/4).toString(16)})},Q=!1,$=Object(g.b)({shouldShowDirtyConfNotif:!1,notifs:[]},(d={},Object(C.a)(d,q.d,function(e){return Q=!0,e}),Object(C.a)(d,q.a,function(e){Q=!1;var t={id:Z(),text:"Connected to JOAL",timeout:6e3,type:"SUCCESS"};e.notifs.push(t)}),Object(C.a)(d,q.b,function(e){var t={id:Z(),text:"Lost connection to JOAL, auto-reconnect in 8 seconds.",timeout:6e3,type:"ERROR"};e.notifs.push(t)}),Object(C.a)(d,q.c,function(e){var t={id:Z(),text:"Failed to connect to JOAL, retry in 8 seconds.",timeout:6e3,type:"ERROR"};e.notifs.push(t)}),Object(C.a)(d,X.a,function(e,t){e.notifs=e.notifs.filter(function(e){return e.id!==t.payload})}),Object(C.a)(d,k.b,function(e){e.shouldShowDirtyConfNotif=!0}),Object(C.a)(d,k.a,function(e){e.shouldShowDirtyConfNotif=!1}),Object(C.a)(d,k.c,function(e,t){var n={id:Z(),text:"Invalid config: ".concat(t.payload.error),timeout:6e3,type:"ERROR"};e.notifs.push(n)}),Object(C.a)(d,P.c,function(e,t){if(!Q)return e;var n={id:Z(),text:"".concat(t.payload.name," added"),timeout:6e3,type:"SUCCESS"};e.notifs.push(n)}),Object(C.a)(d,P.a,function(e,t){var n={id:Z(),text:"".concat(t.payload.fileName," was rejected by server: ").concat(t.payload.error),timeout:6e3,type:"ERROR"};e.notifs.push(n)}),Object(C.a)(d,q.f,function(e,t){var n={id:Z(),text:t.message,timeout:8e3,type:"ERROR"};e.notifs.push(n)}),d)),ee=function(e){return Object(y.combineReducers)({api:Y,app:Object(y.combineReducers)({config:w,torrentsTable:S}),theme:I,alerts:$,router:Object(O.b)(e)})},te=Object(v.a)();var ne=n(55),ae=n(31);Boolean("localhost"===window.location.hostname||"[::1]"===window.location.hostname||window.location.hostname.match(/^127(?:\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/));n(184),n(185);var re=function(e){var t=ee(te),n=[Object(E.a)(te)].concat(Object(b.a)(Object(g.c)()));return Object(g.a)({reducer:t,middleware:n,devTools:!1,preloadedState:e})}();!function(){if(window.location.search&&window.location.search.includes("ui_credentials")){var e=new URLSearchParams(window.location.search),t=e.get("ui_credentials");if(null!==t)try{var n=JSON.parse(decodeURIComponent(t));Object(ne.b)(n)}catch(r){console.error("Failed to extract uiConfig from url params.",r)}finally{e.delete("ui_credentials");var a=window.location.pathname;!1===e.keys().next().done&&(a+="?".concat(e.toString())),window.location.hash&&(a+=window.location.hash),window.history.replaceState({},document.title,a)}}}(),Object(ae.a)(re);var oe=document.getElementById("root");!function(){var e=n(206).default;h.a.render(p.a.createElement(e,{store:re,history:te}),oe)}(),"serviceWorker"in navigator&&navigator.serviceWorker.ready.then(function(e){e.unregister()})},28:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"c",function(){return r}),n.d(t,"a",function(){return o}),n.d(t,"d",function(){return i}),n.d(t,"e",function(){return c}),n.d(t,"g",function(){return s}),n.d(t,"f",function(){return l});var a="@@api/listener/CONFIG_IS_IN_DIRTY_STATE",r="@@api/listener/INVALID_CONFIG",o="@@api/listener/CONFIG_HAS_BEEN_LOADED",i="@@api/listener/LIST_OF_CLIENT_FILES",c="@@reset/RESET_CONFIG",s=function(e){return{type:"@@api/send/SEND_CONFIG",config:e}},l=function(){return{type:c}}},31:function(e,t,n){"use strict";var a,r,o=n(65),i=n(66),c=n(128),s=n.n(c),l=n(55),u=n(18),d=function(){function e(t,n){Object(o.a)(this,e),this.reconnectTimeout=void 0,this.reduxStore=void 0,this.onDisconnectCallback=void 0,this.subscriptions=void 0,this.stompClient=void 0,this.reconnectTimeout=void 0,this.reduxStore=t,this.onDisconnectCallback=n,this.subscriptions=[],this.stompClient={}}return Object(i.a)(e,[{key:"send",value:function(e){var t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"",n=arguments.length>2&&void 0!==arguments[2]?arguments[2]:{};this.stompClient&&this.stompClient.connected?this.stompClient.send(e,t,n):console.error("You can not send message to JOAL when not connected through WebSocket.")}},{key:"connect",value:function(){var e=this,t=Object(l.a)(),n="https:"===window.location.protocol?"wss":"ws",a="".concat(n,"://").concat(t.host,":").concat(t.port,"/").concat(t.pathPrefix),r=t.secretToken;this._dispatchOnConnect(),this.stompClient=s.a.client(a,{debug:!1,protocols:["v12.stomp","v11.stomp"]}),this.stompClient.connect({"X-Joal-Auth-Token":r,"X-Joal-Username":([1e7]+-1e3+-4e3+-8e3+-1e11).replace(/[018]/g,function(e){return(e^crypto.getRandomValues(new Uint8Array(1))[0]&15>>e/4).toString(16)})},function(){e._dispatchHasConnected(),e.stompClient.subscribe("/joal/initialize-me",function(t){JSON.parse(t.body).forEach(function(t){e.onReceiveMessage(t)}),e._dispatchIsReady(),t.ack(),e.stompClient.unsubscribe("/initialize-me")}),["/global","/announce","/config","/torrents","/speed"].forEach(function(t){var n=e.stompClient.subscribe(t,function(t){t.ack(),e.onReceiveMessage(JSON.parse(t.body))},{ack:"client"});e.subscriptions.push(n)})},function(t){(console.log("error message from websocket",t),t instanceof CloseEvent)?(e.subscriptions.length>0?e._dispatchHasDropConnection():e._dispatchHasFailedToConnect(),e.onDisconnectCallback&&e.onDisconnectCallback(),e._reconnectAfterTimeout(8e3)):e.reduxStore.dispatch(Object(u.k)(t.headers.message||"Undefined error"))})}},{key:"_dispatchIsReady",value:function(){this.reduxStore.dispatch(Object(u.l)())}},{key:"_dispatchOnConnect",value:function(){this.reduxStore.dispatch(Object(u.m)())}},{key:"_dispatchHasConnected",value:function(){this.reduxStore.dispatch(Object(u.h)())}},{key:"_dispatchHasDropConnection",value:function(){this.reduxStore.dispatch(Object(u.i)())}},{key:"_dispatchHasFailedToConnect",value:function(){this.reduxStore.dispatch(Object(u.j)())}},{key:"onReceiveMessage",value:function(e){var t=e.type,n=e.payload;this.reduxStore.dispatch({type:"@@api/listener/".concat(t),payload:n})}},{key:"_reconnectAfterTimeout",value:function(e){var t=this;this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions=[],void 0===this.reconnectTimeout&&(this.reconnectTimeout=window.setTimeout(function(){t.connect(),t.reconnectTimeout=void 0},e))}},{key:"disconnect",value:function(){this.subscriptions.forEach(function(e){return e.unsubscribe()}),this.subscriptions=[],this.stompClient&&this.stompClient.connected&&this.stompClient.disconnect(),this.onDisconnectCallback&&this.onDisconnectCallback()}},{key:"disconnectAndReconnect",value:function(){clearTimeout(this.reconnectTimeout),this.reconnectTimeout=void 0,this.disconnect(),this.connect()}}]),e}(),f=n(51),p=n(42),m=n(28),h=n(41),b=n(78);n.d(t,"a",function(){return g}),n.d(t,"c",function(){return v}),n.d(t,"e",function(){return E}),n.d(t,"f",function(){return y}),n.d(t,"d",function(){return O}),n.d(t,"g",function(){return C}),n.d(t,"b",function(){return j});var g=function(e){(r=new d(a=e,function(){a.dispatch(Object(u.n)()),a.dispatch(Object(m.f)()),a.dispatch(Object(p.f)()),a.dispatch(Object(f.f)()),a.dispatch(Object(h.e)()),a.dispatch(Object(b.c)())})).connect()},v=function(){r.disconnectAndReconnect()},E=function(){a.dispatch(Object(p.g)()),r.send("/joal/global/start")},y=function(){a.dispatch(Object(p.h)()),r.send("/joal/global/stop")},O=function(e){a.dispatch(Object(m.g)(e)),r.send("/joal/config/save",JSON.stringify(e))},C=function(e){var t=new FileReader;!function n(){var a,o=e.pop();void 0!==o&&(a=o,t.onload=function(){if(null!=t.result){var e=t.result.replace(/data:.+?,/,"");r.send("/joal/torrents/upload",JSON.stringify({fileName:a.name,b64String:e})),setTimeout(n,1300)}},t.onabort=function(){return console.log("file reading was aborted for [".concat(a.name,"]"))},t.onerror=function(){return console.log("file reading has failed for [".concat(a.name,"]"))},t.readAsDataURL(a))}()},j=function(e){r.send("/joal/torrents/delete",e)}},41:function(e,t,n){"use strict";n.d(t,"c",function(){return a}),n.d(t,"d",function(){return r}),n.d(t,"a",function(){return o}),n.d(t,"b",function(){return i}),n.d(t,"e",function(){return c});var a="@@api/listener/TORRENT_FILE_ADDED",r="@@api/listener/TORRENT_FILE_DELETED",o="@@api/listener/FAILED_TO_ADD_TORRENT_FILE",i="@@reset/RESET_TORRENT_FILES_STATE",c=function(){return{type:i}}},42:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"e",function(){return i}),n.d(t,"c",function(){return c}),n.d(t,"g",function(){return s}),n.d(t,"h",function(){return l}),n.d(t,"f",function(){return u});var a="@@api/listener/GLOBAL_SEED_STARTED",r="@@api/listener/GLOBAL_SEED_STOPPED",o="@@api/send/SEND_START_TO_SERVER",i="@@api/send/SEND_STOP_TO_SERVER",c="@@reset/RESET_CLIENT_STATE";function s(){return{type:o}}function l(){return{type:i}}var u=function(){return{type:c}}},51:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"c",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"e",function(){return i}),n.d(t,"b",function(){return c}),n.d(t,"f",function(){return s});var a="@@api/listener/FAILED_TO_ANNOUNCE",r="@@api/listener/SUCCESSFULLY_ANNOUNCE",o="@@api/listener/TOO_MANY_ANNOUNCES_FAILED",i="@@api/listener/WILL_ANNOUNCE",c="@@reset/RESET_ANNOUNCER_STATE",s=function(){return{type:c}}},55:function(e,t,n){"use strict";n.d(t,"a",function(){return i}),n.d(t,"b",function(){return c});var a,r=n(88),o=n.n(r);n(181);a=o()()?n(182):n(183);var i=function(){return a.getConfig()},c=function(e){return a.saveConfig(e)}},70:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r}),n.d(t,"c",function(){return o}),n.d(t,"d",function(){return i});var a="@@ui/torrents-table/TORRENT_SEARCH_FILTER_TEXT_CHANGED",r="@@ui/torrents-table/TORRENT_SORT_CHANGED";function o(e){return{type:a,text:e}}function i(e,t){return{type:r,sortProperty:e,sortDirection:t}}},71:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"d",function(){return o}),n.d(t,"c",function(){return i});var a="@@ui/LOCAL_CONFIG_HAS_CHANGED",r="@@ui/DISCARD_LOCAL_CONFIG",o=function(e){return{type:a,config:e}},i=function(){return{type:r}}},78:function(e,t,n){"use strict";n.d(t,"b",function(){return a}),n.d(t,"a",function(){return r}),n.d(t,"c",function(){return o});var a="@@api/listener/SEEDING_SPEED_HAS_CHANGED",r="@@reset/RESET_SPEED_STATE",o=function(){return{type:r}}},85:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r});var a="@@ui/theme/CHANGE_THEME_TYPE";function r(){return{type:a}}},86:function(e,t,n){"use strict";n.d(t,"a",function(){return a}),n.d(t,"b",function(){return r});var a="@@notifications/REMOVE_NOTIFICATION",r=function(e){return{type:a,payload:e}}}},[[166,1,2]]]); -//# sourceMappingURL=main.fa028525.chunk.js.map \ No newline at end of file diff --git a/src/main/resources/public/static/js/main.fa028525.chunk.js.map b/src/main/resources/public/static/js/main.fa028525.chunk.js.map deleted file mode 100644 index 1e2cc0b..0000000 --- a/src/main/resources/public/static/js/main.fa028525.chunk.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["modules/joal-api/stomp/stomp.actions.ts","utils/ConfigProvider/ElectronConfigProvider.ts","utils/ConfigProvider/WebBrowserConfigProvider.ts","modules/theme/provider/theme-provider.component.tsx","modules/theme/provider/theme-provider.container.ts","modules/theme/theme-modifier/theme-modifier.component.tsx","modules/theme/theme-modifier/theme-modifier.container.ts","components/ClientInfo/clientInfo.component.tsx","components/ClientInfo/clientInfo.container.ts","components/ClientInfo/index.ts","components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator.tsx","components/UiConfigChanger/uiConfigChanger.component.tsx","components/UiConfigChanger/uiConfigChanger.container.ts","components/UiConfigChanger/index.ts","components/TorrentsTable/Announcer/Peers/Peers.tsx","components/TorrentsTable/Announcer/Peers/index.ts","components/TorrentsTable/Announcer/UploadSpeed/uploadSpeed.component.tsx","components/TorrentsTable/Announcer/UploadSpeed/index.ts","components/TorrentsTable/Announcer/UploadSpeed/uploadSpeed.container.ts","components/TorrentsTable/Announcer/ProgressBar/AnnouncingProgressBar.component.tsx","components/TorrentsTable/Announcer/ProgressBar/TimeUntilAnnounceProgressBar.component.tsx","components/TorrentsTable/Announcer/Announcer.tsx","components/TorrentsTable/Announcer/index.ts","components/TorrentsTable/torrentsTable.component.tsx","components/TorrentsTable/torrentsTable.container.ts","components/TorrentsTable/index.ts","pages/dashboard/dashboard.component.tsx","pages/dashboard/dashboard.container.ts","pages/dashboard/index.ts","pages/settings/settings.component.tsx","pages/settings/settings.container.ts","pages/settings/index.ts","pages/event-history/event-history.component.tsx","pages/event-history/event-history.container.ts","pages/event-history/index.ts","components/NavigationBar/navigationBar.component.tsx","components/NavigationBar/index.ts","components/NavigationBar/navigationBar.container.ts","components/TorrentDropZone.tsx","components/AppBar/appbar.component.tsx","components/AppBar/index.ts","modules/alerts/alert-template/icons/BaseIcon.tsx","modules/alerts/alert-template/icons/InfoIcon.tsx","modules/alerts/alert-template/icons/SuccessIcon.tsx","modules/alerts/alert-template/icons/ErrorIcon.tsx","modules/alerts/alert-template/icons/CloseIcon.tsx","modules/alerts/alert-template/alert-template.component.tsx","modules/alerts/alert-template/index.ts","modules/alerts/alerts-displayer.component.tsx","modules/alerts/index.ts","modules/alerts/alerts-provider.component.tsx","App.tsx","Root.tsx","components/TorrentsTable/torrentsTable.reducer.ts","pages/settings/settings.reducer.ts","modules/theme/theme-modifier/theme-modifier.reducer.ts","modules/joal-api/torrentFiles/torrentFiles.reducer.ts","modules/joal-api/client/client.reducer.ts","modules/joal-api/settings/settings.reducer.ts","modules/joal-api/speed/speed.reducer.ts","modules/joal-api/announcers/announcers.reducer.ts","modules/joal-api/stomp/stomp.reducer.ts","modules/joal-api/joal-api.reducer.ts","modules/alerts/alerts.reducer.ts","reducers/index.ts","store/configureAppStore.ts","serviceWorker.ts","index.tsx","modules/joal-api/settings/settings.actions.ts","modules/joal-api/index.ts","modules/joal-api/JoalStompClient.ts","modules/joal-api/torrentFiles/torrentFile.actions.ts","modules/joal-api/client/client.actions.ts","modules/joal-api/announcers/announcers.actions.ts","utils/ConfigProvider/index.ts","components/TorrentsTable/torrentsTable.actions.ts","pages/settings/settings.actions.ts","modules/joal-api/speed/speed.actions.ts","modules/theme/theme-modifier/theme-modifier.actions.ts","modules/alerts/alerts.actions.ts"],"names":["__webpack_require__","d","__webpack_exports__","IS_CONNECTING","HAS_CONNECTED","HAS_FAILED_TO_CONNECT","HAS_DROP_CONNECTION","INIT_OVER","RECEIVED_ERROR_MESSAGE","RESET_STOMP_STATE","isConnecting","hasConnected","hasFailedToConnect","hasDropConnection","initOver","hasReceivedError","resetStompState","type","message","r","getConfig","saveConfig","localStorageConf","localStorage","getItem","JSON","parse","console","log","host","window","location","hostname","port","pathPrefix","pathname","substring","lastIndexOf","secretToken","newConfig","setItem","stringify","cachedConf","materialUiThemeCreator","themeType","createMuiTheme","palette","primary","light","main","dark","secondary","ThemeProvider","props","children","react_default","a","createElement","MuiThemeProvider","theme","CssBaseline","connect","state","ThemeProviderComponent","ThemeModifier","onClickChangeThemeType","IconButton","aria-label","onClick","Brightness2Outlined_default","htmlColor","Brightness2_default","dispatch","changeThemeType","useStyles","makeStyles","createStyles","container","padding","leftIcon","marginRight","spacing","playPauseButton","backgroundColor","grey","boxShadow","shadows","&:focusVisible","&:active","&:disabled","color","action","disabled","disabledBackground","&:hover","@media (hover: none)","redTextButton","red","greenTextButton","green","ClientInfo","classes","classNameProps","className","client","overallUploadSpeed","isStarted","onClickStart","onClickStop","numberOfQueuedTorrents","stateText","Paper","elevation","classnames","Typography","align","variant","gutterBottom","Button","fullWidth","contained","PauseCircleFilled_default","PlayCircleFilled_default","Divider","style","marginTop","marginBottom","concat","filesize","base","defaultProps","calculateGobalSpeed","speeds","totalSpeed","_i","_Object$values","Object","values","length","bytesPerSecond","ClientInfoContainer","api","name","speed","torrentFiles","announcers","sendStartSession","sendStopSession","ClientInfoComponent","position","top","bottom","left","right","zIndex","display","alignItems","justifyContent","AbsoluteOverlayFetchingIndicator","containerStyle","active","rest","objectWithoutProperties","CircularProgress","assign","width","height","UiConfigChanger","_this","classCallCheck","this","possibleConstructorReturn","getPrototypeOf","call","config","isModalVisible","hostErr","portErr","pathPrefixErr","secretTokenErr","setState","intPort","parseInt","isNaN","objectSpread","saveNewConf","_this$state","hasError","_this$state2","_this2","_this$props","isConnected","_this$state3","redButton","changeConfigButton","Dialog","open","onClose","discardChangesAndClose","aria-labelledby","scroll","DialogTitle","id","DialogContent","FormControl","formControl","error","aria-describedby","InputLabel","htmlFor","Input","placeholder","value","onChange","e","handleHostChange","target","FormHelperText","handlePortChange","handlePathPrefixChange","handleSecretTokenChange","DialogActions","Component","withStyles","getContrastText","margin","stomp","getGUIConfig","saveGUIConfig","disconnectAndReconnect","root","leechers","seeders","PeerStats","leechersText","undefined","seedersText","Grid","direction","item","Tooltip","title","placement","data-for","data-tip","aria-hidden","Peers","UploadSpeed","speedInBytesPerSeconds","ownProps","foundSpeed","infoHash","progressBar","AnnouncingProgressBar","LinearProgress","TimeUntilAnnounceProgressBar","_React$useState","React","useState","Math","round","Date","now","lastAnnouncedDate","interval","_React$useState2","slicedToArray","percent","setPercent","useEffect","intervalId","setInterval","p","min","clearInterval","paddingTop","paddingLeft","paddingRight","paddingBottom","lineHeight","wordBreak","uploadSpeedContainer","fontSize","peersStats","deleteButton","fade","hoverOpacity","announceProgressBar","Announcer","componentBreakpoint","announcer","onClickDeleteTorrent","maxAllowedTorrentNameLength","trimedTorrentName","torrentName","xs","torrentSize","standard","DeleteOutlined_default","Announcer_Peers","lastKnownLeechers","lastKnownSeeders","Announcer_UploadSpeed","isFetching","lastAnnouncedAt","AnnouncingProgressBar_component","TimeUntilAnnounceProgressBar_component","lastKnownInterval","withWidth","desc","b","orderBy","getSorting","order","getFiltering","searchFilter","toLowerCase","includes","tableHeadUseStyles","_sortActionsContainer","searchBarPaper","searchBar","marginLeft","flex","searchBarIcon","sortActionsContainer","defineProperty","breakpoints","down","sortButtonGroup","hasSortSelected","toogleButtonWhenNoSortSelection","borderColor","EnhancedTableHead","search","onRequestSearch","onRequestSort","InputBase","Search_default","ToggleButtonGroup","selected","exclusive","v","property","ToggleButton","SortByAlpha_default","CloudDownloadOutlined_default","CloudUploadOutlined_default","EnhancedTableToolbar","_announcer","announersList","up","EnhancedTable","setSearch","_React$useState3","_React$useState4","setOrder","_React$useState5","_React$useState6","setOrderBy","_React$useState7","_React$useState8","page","setPage","_React$useState9","_React$useState10","rowsPerPage","setRowsPerPage","ceil","torrentsTable_component_EnhancedTableToolbar","filter","sort","slice","map","key","TorrentsTable_Announcer","TablePagination","rowsPerPageOptions","component","count","backIconButtonProps","nextIconButtonProps","onChangePage","event","newPage","onChangeRowsPerPage","getFilteredAnnouncers","createSelector","app","torrentsTable","trim","filterText","getSortedAndFilteredAnnouncers","sortProperty","sortDirection","filteredAnnouncers","toConsumableArray","t1","t2","TorrentsTableContainer","onFilterTextChange","text","changeSearchFilterText","onSortChange","changeTorrentSort","deleteTorrent","Announcers","relative","addButton","addButtonInput","Dashboard","shouldDisplayConfigChangerButton","isConnectedToWebSocket","isClientGlobalStatePending","uploadTorrentFiles","md","lg","components_UiConfigChanger","FetchingIndicator_AbsoluteOverlayFetchingIndicator","components_ClientInfo","TorrentsTable","dist_default","place","effect","accept","multiple","files","Array","from","Zoom","in","timeout","enter","transitions","duration","enteringScreen","exit","leavingScreen","transitionDelay","unmountOnExit","Fab","Add_default","withTheme","isElectron","uploadTorrents","discardChangesButton","formInput","minWidth","rightSpaced","MenuProps","PaperProps","maxHeight","ITEM_HEIGHT","Settings","discardLocalConfigChanges","onSettingsChange","onClickSave","availableClients","isLocalConfigChanged","valueHasChanged","newValue","justify","TextField","label","inputProps","minUploadRate","maxUploadRate","Select","input","MenuItem","simultaneousSeed","FormControlLabel","control","Checkbox","checked","keepTorrentWithZeroLeechers","localConfig","settings","localConfigHasChanged","sendConfigToServer","SettingsComponent","textAlign","EventHistory","_ref","events","Warning_default","viewBox","orange","EventHistoryContainer","EventHistoryComponent","NavigationBar","whichPath","currentPath","onClickDashboard","onClickSettings","onClickLogs","BottomNavigation","showLabels","index","BottomNavigationAction","icon","Dashboard_default","Settings_default","Sms_default","NavigationBarContainer","router","push","dropzone","overlay","TorrentDropZone","_useDropzone","useDropzone","onDrop","accepted","rejected","noClick","noKeyboard","getRootProps","getInputProps","isDragActive","rootProps","stopPropagation","flexGrow","grow","menuButton","JoalAppBar","AppBar","Toolbar","theme_modifier_container","BaseIcon","xmlns","fill","strokeWidth","strokeLinecap","strokeLinejoin","stroke","InfoIcon","icons_BaseIcon","cx","cy","x1","y1","x2","y2","SuccessIcon","points","ErrorIcon","CloseIcon","_alert","alert","borderRadius","fontFamily","textTransform","statusIcon","closeButton","border","cursor","closeIconOverride","AlertTemplate","options","close","icons_SuccessIcon","icons_InfoIcon","icons_ErrorIcon","icons_CloseIcon","JoalAlertDisplayer","nextProps","currentNotifs","notifs","currentShouldShowDirtyConfNotif","shouldShowDirtyConfNotif","prevProps","_this$props2","info","forEach","newNotif","findIndex","n","showNotification","notification","_this$props3","onMessageClosed","notifCopy","success","withAlert","_state$alerts","alerts","removeNotification","JoalAlertProvider","react_alert","template","offset","isWidthUp","positions","TOP_RIGHT","transition","FADE","alerts_displayer_component","navigationBarWrapper","onFileDrop","history","components_TorrentDropZone","components_AppBar","esm","react_router","exact","path","Historypage","SettingsPage","DashboardPage","components_NavigationBar","Root","store","es","theme_provider_container","src_App","createReducer","currentPage","torrentsPerPage","_createReducer","TORRENT_SEARCH_FILTER_TEXT_CHANGED","TORRENT_SORT_CHANGED","initialState","settings_reducer_createReducer","LOCAL_CONFIG_HAS_CHANGED","DISCARD_LOCAL_CONFIG","API___CONFIG_IS_IN_DIRTY_STATE","API____CONFIG_HAS_BEEN_LOADED","CHANGE_THEME_TYPE","newTheme","torrentFiles_reducer_createReducer","TORRENT_FILE_ADDED","newState","tf","payload","TORRENT_FILE_DELETED","FAILED_TO_ADD_TORRENT_FILE","RESET_TORRENT_FILES_STATE","client_reducer_createReducer","GLOBAL_SEED_STARTED","GLOBAL_SEED_STOPPED","SEND_START_TO_SERVER","SEND_STOP_TO_SERVER","RESET_CLIENT_STATE","isDirty","errMessage","settings_settings_reducer_createReducer","CONFIG_IS_IN_DIRTY_STATE","INVALID_CONFIG","CONFIG_HAS_BEEN_LOADED","LIST_OF_CLIENT_FILES","clients","RESET_CONFIG","speed_reducer_createReducer","SEEDING_SPEED_HAS_CHANGED","_iteratorNormalCompletion","_didIteratorError","_iteratorError","_step","_iterator","Symbol","iterator","next","done","currentSpeed","err","return","RESET_SPEED_STATE","announcers_reducer_createReducer","FAILED_TO_ANNOUNCE","find","SUCCESSFULLY_ANNOUNCE","requestEvent","TOO_MANY_ANNOUNCES_FAILED","WILL_ANNOUNCE","RESET_ANNOUNCER_STATE","isFullyInit","stomp_reducer_createReducer","combineReducers","apiTorrentFileReducer","apiClientReducer","apiAnnouncersReducer","apiSettingsReducer","apiSpeedReducer","apiStompReducer","uuidv4","replace","c","crypto","getRandomValues","Uint8Array","toString","isAppInit","alerts_reducer_createReducer","notif","REMOVE_NOTIFICATION","fileName","reducers","apiReducer","uiConfigReducer","torrentsTableReducer","themeReducer","alertReducer","connectRouter","createHashHistory","Boolean","match","rootReducer","createRootReducer","middlewares","routerMiddleware","getDefaultMiddleware","configureStore","reducer","middleware","devTools","preloadedState","configureAppStore","uRLSearchParams","URLSearchParams","credentialsUriEncoded","get","decodeURIComponent","delete","cleanUri","keys","hash","replaceState","document","attemptToGetUiConfigFromQuerySearchParam","connectStomp","rootEl","getElementById","require","default","ReactDOM","render","navigator","serviceWorker","ready","then","registration","unregister","sendConfig","resetConfig","stompClient","JoalStompClient","reduxStore","onDisconnectCallback","reconnectTimeout","subscriptions","body","arguments","headers","connected","send","guiConf","urlScheme","protocol","url","_dispatchOnConnect","Webstomp","debug","protocols","X-Joal-Auth-Token","X-Joal-Username","_dispatchHasConnected","subscribe","msg","onReceiveMessage","_dispatchIsReady","ack","unsubscribe","subscribesPath","subscribtion","CloseEvent","_dispatchHasDropConnection","_dispatchHasFailedToConnect","_reconnectAfterTimeout","sub","setTimeout","disconnect","clearTimeout","joal_api_connectStomp","joal_api_sendStartSession","joal_api_sendStopSession","joal_api_sendConfigToServer","appStore","resetClientState","resetAnnouncerState","resetTorrentFilesState","resetSpeedState","sendStartToServer","sendStopToServer","reader","FileReader","processOne","file","singleFile","pop","onload","result","b64Encoded","b64String","onabort","onerror","readAsDataURL","torrentInfoHash","selectedConfProvider","is_electron__WEBPACK_IMPORTED_MODULE_0__","is_electron__WEBPACK_IMPORTED_MODULE_0___default"],"mappings":"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","file":"static/js/main.fa028525.chunk.js","sourcesContent":["export const IS_CONNECTING = '@@api/stompClient/IS_CONNECTING';\r\nexport const HAS_CONNECTED = '@@api/stompClient/HAS_CONNECTED';\r\nexport const HAS_FAILED_TO_CONNECT = '@@api/stompClient/HAS_FAILED_TO_CONNECT';\r\nexport const HAS_DROP_CONNECTION = '@@api/stompClient/HAS_DROP_CONNECTION';\r\nexport const INIT_OVER = '@@api/stompClient/INIT_OVER';\r\nexport const RECEIVED_ERROR_MESSAGE = '@@api/stompClient/RECEIVED_ERROR_MESSAGE';\r\n\r\nexport const RESET_STOMP_STATE = '@@reset/RESET_STOMP_STATE';\r\n\r\n\r\nexport const isConnecting = () => ({\r\n type: IS_CONNECTING\r\n});\r\n\r\nexport const hasConnected = () => ({\r\n type: HAS_CONNECTED\r\n});\r\n\r\nexport const hasFailedToConnect = () => ({\r\n type: HAS_FAILED_TO_CONNECT\r\n});\r\n\r\nexport const hasDropConnection = () => ({\r\n type: HAS_DROP_CONNECTION\r\n});\r\n\r\nexport const initOver = () => ({\r\n type: INIT_OVER\r\n});\r\n\r\nexport const hasReceivedError = (message: string) => ({\r\n type: RECEIVED_ERROR_MESSAGE,\r\n message\r\n});\r\n\r\n\r\nexport const resetStompState = () => (\r\n { type: RESET_STOMP_STATE }\r\n);\r\n","/* eslint-disable import/no-unresolved, global-require, import/no-absolute-path */\r\n\r\nimport { GuiConfig } from './types';\r\n\r\nexport const getConfig = (): GuiConfig => {\r\n const localStorageConf = localStorage.getItem('guiConfig');\r\n if (!localStorageConf) {\r\n console.log('Returning a mocked config to prevent exception from NullPointer');\r\n return {\r\n host: window.location.hostname, // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n port: window.location.port || '80', // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n pathPrefix: window.location.pathname.substring(1, window.location.pathname.lastIndexOf('/ui')) || '',\r\n secretToken: ''\r\n };\r\n }\r\n\r\n // We do not cache the config here. When running in electron the config is injected in a way that is subject to race condition.\r\n // If we read the value too early, we're going to cache the old config.\r\n return JSON.parse(localStorageConf);\r\n};\r\n\r\nexport const saveConfig = (newConfig: GuiConfig) => {\r\n localStorage.setItem('guiConfig', JSON.stringify(newConfig));\r\n};\r\n","import { GuiConfig } from './types';\r\n\r\nlet cachedConf: GuiConfig;\r\n\r\nexport const getConfig = (): GuiConfig => {\r\n if (!cachedConf) {\r\n const localStorageConf = localStorage.getItem('guiConfig');\r\n if (!localStorageConf) {\r\n cachedConf = {\r\n host: window.location.hostname, // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n port: window.location.port || '80', // this default settings is to prevent Firefox to crash with \"SecurityError: The operation is insecure.\" due to cross origin websocket\r\n pathPrefix: '',\r\n secretToken: ''\r\n };\r\n } else {\r\n cachedConf = JSON.parse(localStorageConf);\r\n }\r\n }\r\n return cachedConf;\r\n};\r\n\r\nexport const saveConfig = (newConfig: GuiConfig) => {\r\n localStorage.setItem('guiConfig', JSON.stringify(newConfig));\r\n cachedConf = newConfig;\r\n};\r\n","import React, { ReactNode } from 'react';\r\nimport { MuiThemeProvider, createMuiTheme } from '@material-ui/core/styles';\r\nimport primary from '@material-ui/core/colors/blue';\r\nimport secondary from '@material-ui/core/colors/lightGreen';\r\nimport CssBaseline from '@material-ui/core/CssBaseline';\r\n\r\n\r\nconst materialUiThemeCreator = (themeType: 'light' | 'dark') => createMuiTheme({\r\n palette: {\r\n primary: {\r\n light: primary[300],\r\n main: primary[500],\r\n dark: primary[700],\r\n },\r\n secondary: {\r\n light: secondary[300],\r\n main: secondary[500],\r\n dark: secondary[700],\r\n },\r\n type: themeType\r\n }\r\n});\r\n\r\ntype Props = {\r\n children: ReactNode,\r\n themeType: 'light' | 'dark'\r\n};\r\n\r\nconst ThemeProvider = (props: Props) => {\r\n const { children, themeType } = props;\r\n return (\r\n \r\n {/* CssBaseline kickstart an elegant, consistent, and simple baseline to build upon. */}\r\n \r\n {children}\r\n \r\n );\r\n};\r\n\r\nexport default ThemeProvider;\r\n","import { connect } from 'react-redux';\r\nimport ThemeProviderComponent from './theme-provider.component';\r\n\r\nimport { JoalState } from '../../../reducers/types';\r\n\r\nconst mapStateToProps= (state: JoalState) => {\r\n return {\r\n themeType: state.theme.palette.type\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(ThemeProviderComponent);\r\n","import React from 'react';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport LightModeOnIcon from '@material-ui/icons/Brightness2Outlined';\r\nimport DarkModeOnIcon from '@material-ui/icons/Brightness2';\r\n\r\nimport { Palette } from '../types';\r\n\r\n\r\ninterface ThemeModifierProps {\r\n palette: Palette,\r\n onClickChangeThemeType: () => void\r\n}\r\n\r\nconst ThemeModifier: React.FC = (props) => {\r\n const { palette, onClickChangeThemeType } = props;\r\n\r\n return (\r\n
\r\n \r\n {palette.type === 'light'\r\n ? \r\n : \r\n }\r\n \r\n
\r\n );\r\n}\r\n\r\nexport default ThemeModifier;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport ThemeModifier from './theme-modifier.component';\r\nimport { changeThemeType } from './theme-modifier.actions';\r\n\r\nimport { JoalState } from '../../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState) => ({\r\n palette: state.theme.palette\r\n});\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => ({\r\n onClickChangeThemeType: () => dispatch(changeThemeType()),\r\n});\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(ThemeModifier);\r\n","import React from 'react';\r\nimport Divider from '@material-ui/core/Divider';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Button from '@material-ui/core/Button';\r\nimport PlayIcon from '@material-ui/icons/PlayCircleFilled';\r\nimport PauseIcon from '@material-ui/icons/PauseCircleFilled';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport red from '@material-ui/core/colors/red';\r\nimport green from '@material-ui/core/colors/green';\r\nimport filesize from 'filesize';\r\nimport classnames from 'classnames';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n padding: 15\r\n },\r\n leftIcon: {\r\n marginRight: theme.spacing(1),\r\n },\r\n playPauseButton: {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[100],\r\n boxShadow: theme.shadows[2],\r\n '&:focusVisible': {\r\n boxShadow: theme.shadows[6],\r\n },\r\n '&:active': {\r\n boxShadow: theme.shadows[8],\r\n },\r\n '&:disabled': {\r\n color: theme.palette.action.disabled,\r\n boxShadow: theme.shadows[0],\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n '&:hover': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[800] : theme.palette.grey[300],\r\n // Reset on touch devices, it doesn't add specificity\r\n '@media (hover: none)': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[300],\r\n },\r\n '&:disabled': {\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n },\r\n },\r\n redTextButton: {\r\n color: red[400]\r\n },\r\n greenTextButton: {\r\n color: green[400]\r\n }\r\n })\r\n);\r\n\r\ntype ClientInfoProps = {\r\n className?: string,\r\n client: string,\r\n overallUploadSpeed: number,\r\n isStarted: boolean,\r\n numberOfQueuedTorrents: number,\r\n onClickStart: () => void,\r\n onClickStop: () => void\r\n};\r\n\r\nconst ClientInfo: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps,\r\n client, overallUploadSpeed, isStarted, onClickStart, onClickStop, numberOfQueuedTorrents\r\n } = props;\r\n const stateText = isStarted ? 'Running' : 'Paused';\r\n\r\n return (\r\n \r\n \r\n {stateText}\r\n \r\n \r\n {isStarted ? : }\r\n {isStarted ? 'stop' : 'start'}\r\n \r\n\r\n \r\n \r\n {client}\r\n \r\n \r\n {`Overall speed : ${filesize(overallUploadSpeed, { base: 10 })}/s`}\r\n \r\n \r\n {`Torrents in queue : ${numberOfQueuedTorrents}`}\r\n \r\n \r\n );\r\n};\r\nClientInfo.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default ClientInfo;\r\n","import { connect } from 'react-redux';\r\nimport ClientInfoComponent from './clientInfo.component';\r\nimport { sendStartSession, sendStopSession } from '../../modules/joal-api';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { SpeedsArray } from '../../modules/joal-api/types';\r\n\r\nconst calculateGobalSpeed = (speeds: SpeedsArray) => {\r\n let totalSpeed = 0\r\n for (let speed of Object.values(speeds)) {\r\n totalSpeed += speed.bytesPerSecond;\r\n }\r\n return totalSpeed;\r\n};\r\n\r\nconst mapStateToProps = (state: JoalState) => {\r\n return {\r\n client: state.api.client.name,\r\n overallUploadSpeed: calculateGobalSpeed(state.api.speed),\r\n isStarted: state.api.client.isStarted,\r\n numberOfQueuedTorrents: state.api.torrentFiles.length - state.api.announcers.length,\r\n onClickStart: () => sendStartSession(),\r\n onClickStop: () => sendStopSession()\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(ClientInfoComponent);\r\n","import ClientInfoContainer from './clientInfo.container';\r\n\r\nexport default ClientInfoContainer;\r\n","import React from 'react';\r\nimport CircularProgress from '@material-ui/core/CircularProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n position: 'absolute',\r\n top: 0,\r\n bottom: 0,\r\n left: 0,\r\n right: 0,\r\n backgroundColor: 'rgba(200, 200, 200, 0.63)',\r\n zIndex: 1200,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }\r\n })\r\n);\r\n\r\ntype AbsoluteOverlayFetchingIndicatorProps = {\r\n style?: object,\r\n containerStyle?: object,\r\n active: boolean\r\n};\r\n\r\nconst AbsoluteOverlayFetchingIndicator: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n style, containerStyle, active, ...rest\r\n } = props;\r\n if (!active) {\r\n return (
);\r\n }\r\n return (\r\n
\r\n {active && }\r\n
\r\n );\r\n};\r\nAbsoluteOverlayFetchingIndicator.defaultProps = {\r\n style: {},\r\n containerStyle: {}\r\n};\r\n\r\nexport default AbsoluteOverlayFetchingIndicator;\r\n","import React, { Component } from 'react';\r\nimport Button from '@material-ui/core/Button';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport Input from '@material-ui/core/Input';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport Dialog from '@material-ui/core/Dialog';\r\nimport DialogActions from '@material-ui/core/DialogActions';\r\nimport DialogContent from '@material-ui/core/DialogContent';\r\nimport DialogTitle from '@material-ui/core/DialogTitle';\r\nimport { withStyles, createStyles, Theme } from '@material-ui/core/styles';\r\nimport { GuiConfig } from '../../utils/ConfigProvider/types';\r\n\r\n\r\nconst styles = (theme: Theme) => createStyles({\r\n changeConfigButton: {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[100],\r\n boxShadow: theme.shadows[2],\r\n '&:focusVisible': {\r\n boxShadow: theme.shadows[6],\r\n },\r\n '&:active': {\r\n boxShadow: theme.shadows[8],\r\n },\r\n '&:disabled': {\r\n color: theme.palette.action.disabled,\r\n boxShadow: theme.shadows[0],\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n '&:hover': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[800] : theme.palette.grey[300],\r\n // Reset on touch devices, it doesn't add specificity\r\n '@media (hover: none)': {\r\n backgroundColor: theme.palette.type === 'dark' ? theme.palette.grey[700] : theme.palette.grey[300],\r\n },\r\n '&:disabled': {\r\n backgroundColor: theme.palette.action.disabledBackground,\r\n },\r\n },\r\n },\r\n redButton: {\r\n color: theme.palette.getContrastText(theme.palette.error.main),\r\n backgroundColor: theme.palette.error.main,\r\n '&:hover': {\r\n backgroundColor: theme.palette.error.dark\r\n }\r\n },\r\n formControl: {\r\n margin: theme.spacing(1)\r\n }\r\n});\r\n\r\ninterface UiConfigChangerProps {\r\n classes: any,\r\n isConnected: boolean,\r\n config: GuiConfig,\r\n saveNewConf: (config: GuiConfig) => void,\r\n style?: any\r\n}\r\n\r\ninterface UiConfigChangerState {\r\n isModalVisible: boolean,\r\n host: string,\r\n port: string,\r\n pathPrefix: string,\r\n secretToken: string,\r\n hostErr: string,\r\n portErr: string,\r\n pathPrefixErr: string,\r\n secretTokenErr: string,\r\n}\r\n\r\nclass UiConfigChanger extends Component {\r\n static defaultProps = {\r\n style: {}\r\n }\r\n\r\n constructor(props: UiConfigChangerProps) {\r\n super(props);\r\n const { config } = props;\r\n\r\n this.state = {\r\n isModalVisible: false,\r\n host: config.host,\r\n port: config.port,\r\n pathPrefix: config.pathPrefix,\r\n secretToken: config.secretToken,\r\n hostErr: config.host !== '' ? '' : 'Required field',\r\n portErr: config.port !== '' ? '' : 'Required field',\r\n pathPrefixErr: config.pathPrefix !== '' ? '' : 'Required field',\r\n secretTokenErr: config.secretToken !== '' ? '' : 'Required field',\r\n };\r\n }\r\n\r\n handleHostChange(host: string) {\r\n const hostErr = host === '' ? 'Required field' : '';\r\n this.setState({ host, hostErr });\r\n }\r\n\r\n handlePortChange(port: string) {\r\n let portErr = '';\r\n const intPort = parseInt(port) - 0;\r\n if (isNaN(intPort)) { // eslint-disable-line no-restricted-globals\r\n portErr = 'You mad bro !';\r\n } else {\r\n if (intPort === 0) portErr = 'Port is required';\r\n if (intPort > 65535) portErr = 'A port that big, seriously ?';\r\n }\r\n this.setState({ port, portErr });\r\n }\r\n\r\n handlePathPrefixChange(pathPrefix: string) {\r\n const pathPrefixErr = pathPrefix === '' ? 'Required field' : '';\r\n this.setState({ pathPrefix, pathPrefixErr });\r\n }\r\n\r\n handleSecretTokenChange(secretToken: string) {\r\n const secretTokenErr = secretToken === '' ? 'Required field' : '';\r\n this.setState({ secretToken, secretTokenErr });\r\n }\r\n\r\n discardChangesAndClose() {\r\n const { config } = this.props;\r\n this.setState({ ...(config), isModalVisible: false });\r\n }\r\n\r\n saveConfig() {\r\n const { saveNewConf } = this.props;\r\n const {\r\n host, port, pathPrefix, secretToken\r\n } = this.state;\r\n\r\n if (this.hasError()) {\r\n return;\r\n }\r\n\r\n saveNewConf({\r\n host, port, pathPrefix, secretToken\r\n });\r\n this.setState({ isModalVisible: false });\r\n }\r\n\r\n hasError() {\r\n const {\r\n host, port, pathPrefix, secretToken, hostErr, portErr, pathPrefixErr, secretTokenErr\r\n } = this.state;\r\n\r\n if (!host || !port || !pathPrefix || !secretToken) {\r\n return true;\r\n }\r\n if (hostErr || portErr || pathPrefixErr || secretTokenErr) {\r\n return true;\r\n }\r\n return false;\r\n }\r\n\r\n render() {\r\n const { classes, isConnected, style } = this.props;\r\n const {\r\n isModalVisible,\r\n host, port, pathPrefix, secretToken,\r\n hostErr, portErr, pathPrefixErr, secretTokenErr\r\n } = this.state;\r\n return (\r\n
\r\n this.setState({ isModalVisible: true })}\r\n className={isConnected ? '' : classes.redButton}\r\n classes={{ contained: classes.changeConfigButton }}\r\n >\r\n Change connection settings\r\n \r\n this.discardChangesAndClose()}\r\n aria-labelledby=\"form-dialog-connection-settings\"\r\n scroll=\"paper\"\r\n >\r\n Connection settings\r\n \r\n 0}\r\n aria-describedby=\"server-address-text\"\r\n >\r\n Server address\r\n this.handleHostChange(e.target.value)} />\r\n {hostErr}\r\n \r\n 0}\r\n aria-describedby=\"server-port-text\"\r\n >\r\n Server port\r\n this.handlePortChange(e.target.value)} />\r\n {portErr}\r\n \r\n 0}\r\n aria-describedby=\"path-prefix-text\"\r\n >\r\n Path prefix\r\n this.handlePathPrefixChange(e.target.value)} />\r\n {pathPrefixErr}\r\n \r\n 0}\r\n aria-describedby=\"secret-token-text\"\r\n >\r\n Secret token\r\n this.handleSecretTokenChange(e.target.value)} />\r\n {secretTokenErr}\r\n \r\n \r\n \r\n this.discardChangesAndClose()}\r\n >\r\n Cancel\r\n \r\n this.saveConfig()}\r\n >\r\n Save\r\n \r\n \r\n \r\n
\r\n );\r\n }\r\n}\r\n\r\nexport default withStyles(styles)(UiConfigChanger);\r\n","import { connect } from 'react-redux';\r\nimport UiConfigChanger from './uiConfigChanger.component';\r\nimport { getGUIConfig, saveGUIConfig } from '../../utils/ConfigProvider';\r\nimport { disconnectAndReconnect } from '../../modules/joal-api';\r\nimport { GuiConfig } from '../../utils/ConfigProvider/types';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n isConnected: state.api.stomp.isConnected,\r\n config: getGUIConfig(),\r\n saveNewConf: (config: GuiConfig) => {\r\n saveGUIConfig(config);\r\n disconnectAndReconnect();\r\n }\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(UiConfigChanger);\r\n","import UiConfigChanger from './uiConfigChanger.container';\r\n\r\nexport default UiConfigChanger;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport classnames from 'classnames';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n },\r\n leechers: {\r\n color: theme.palette.primary.light,\r\n marginRight: 12\r\n },\r\n seeders: {\r\n color: theme.palette.primary.light\r\n }\r\n })\r\n);\r\n\r\ntype PeerStatsProps = {\r\n className?: string,\r\n leechers?: number,\r\n seeders?: number\r\n};\r\n\r\nconst PeerStats: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps, leechers, seeders\r\n } = props;\r\n const leechersText = (leechers === null || leechers === undefined) ? '?' : leechers;\r\n const seedersText = (seeders === null || seeders === undefined) ? '?' : seeders;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n {` ${leechersText}`}\r\n \r\n \r\n \r\n \r\n \r\n {` ${seedersText}`}\r\n \r\n \r\n \r\n \r\n );\r\n};\r\nPeerStats.defaultProps = {\r\n className: '',\r\n leechers: undefined,\r\n seeders: undefined\r\n};\r\n\r\nexport default PeerStats;\r\n","import Peers from './Peers';\r\n\r\nexport default Peers;\r\n","import React from 'react';\r\nimport filesize from 'filesize';\r\nimport Typography from '@material-ui/core/Typography';\r\n\r\ninterface UploadSpeedProps {\r\n className?: string,\r\n speedInBytesPerSeconds?: number\r\n};\r\n\r\nconst UploadSpeed: React.FC = (props) => {\r\n const { className: classNameProps, speedInBytesPerSeconds } = props;\r\n\r\n return (\r\n \r\n {speedInBytesPerSeconds === undefined ? '? B/s' : `${filesize(speedInBytesPerSeconds, { base: 10 })}/s`}\r\n \r\n );\r\n};\r\nUploadSpeed.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default UploadSpeed;\r\n","import UploadSpeed from './uploadSpeed.container';\r\n\r\nexport default UploadSpeed;\r\n","import { connect } from 'react-redux';\r\nimport UploadSpeed from './uploadSpeed.component';\r\n\r\nimport { JoalState } from '../../../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState, ownProps: { infoHash: string }) => {\r\n const foundSpeed = state.api.speed[ownProps.infoHash];\r\n\r\n return {\r\n speedInBytesPerSeconds: foundSpeed === null || foundSpeed === undefined ? undefined : foundSpeed.bytesPerSecond\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = () => ({});\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(UploadSpeed);\r\n","import React from 'react';\r\nimport LinearProgress from '@material-ui/core/LinearProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n progressBar: {\r\n }\r\n })\r\n);\r\n\r\ntype AnnouncingProgressBarProps = {\r\n className?: string\r\n}\r\n\r\nconst AnnouncingProgressBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n );\r\n}\r\nAnnouncingProgressBar.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default AnnouncingProgressBar;","import React from 'react';\r\nimport LinearProgress from '@material-ui/core/LinearProgress';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n progressBar: {\r\n }\r\n })\r\n);\r\n\r\ntype TimeUntilAnnounceProgressBarProps = {\r\n className?: string,\r\n lastAnnouncedDate: string,\r\n interval: number\r\n}\r\n\r\nconst TimeUntilAnnounceProgressBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n \r\n const [ percent, setPercent ] = React.useState(() => \r\n Math.round((Date.now() - Date.parse(props.lastAnnouncedDate)) / 10 / props.interval)\r\n );\r\n \r\n React.useEffect(() => {\r\n const intervalId = setInterval(\r\n () =>setPercent(p => Math.min(p + 1, 100)),\r\n props.interval * 10\r\n );\r\n\r\n return () => clearInterval(intervalId)\r\n }, [ props.lastAnnouncedDate, props.interval ])\r\n\r\n return (\r\n \r\n );\r\n}\r\nTimeUntilAnnounceProgressBar.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default TimeUntilAnnounceProgressBar;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport IconButton from '@material-ui/core/IconButton';\r\nimport DeleteIcon from '@material-ui/icons/DeleteOutlined';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport withWidth, { WithWidthProps } from '@material-ui/core/withWidth';\r\nimport { fade } from '@material-ui/core/styles/colorManipulator';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport filesize from 'filesize';\r\nimport classnames from 'classnames';\r\nimport PeerStats from './Peers';\r\nimport UploadSpeed from './UploadSpeed';\r\nimport AnnouncingProgressBar from './ProgressBar/AnnouncingProgressBar.component';\r\nimport TimeUntilAnnounceProgressBar from './ProgressBar/TimeUntilAnnounceProgressBar.component';\r\n\r\nimport { Announcer as AnnouncerType } from '../../../modules/joal-api/types';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n paddingTop: theme.spacing(1),\r\n paddingLeft: theme.spacing(2),\r\n paddingRight: theme.spacing(2),\r\n paddingBottom: theme.spacing(0.5)\r\n },\r\n title: {\r\n marginTop: 3,\r\n lineHeight: 1.2,\r\n wordBreak: 'break-word'\r\n },\r\n uploadSpeedContainer: {\r\n bottom: 5,\r\n fontSize: 18,\r\n position: 'absolute',\r\n right: theme.spacing(2)\r\n },\r\n peersStats: {\r\n fontSize: 14\r\n },\r\n deleteButton: {\r\n color: theme.palette.error.main,\r\n '&:hover': {\r\n backgroundColor: fade(theme.palette.error.main, theme.palette.action.hoverOpacity)\r\n },\r\n position: 'absolute',\r\n right: 2,\r\n top: 2,\r\n padding: 0,\r\n height: 35,\r\n width: 42\r\n },\r\n announceProgressBar: {\r\n position: 'absolute',\r\n left: 0,\r\n right: 0,\r\n bottom: 0,\r\n height: 4\r\n }\r\n })\r\n);\r\n\r\ninterface AnnouncerProps extends WithWidthProps {\r\n className?: string,\r\n announcer: AnnouncerType,\r\n onClickDeleteTorrent: (infoHash: string) => void\r\n};\r\n\r\nconst Announcer: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n width: componentBreakpoint, className: classNameProps, announcer, onClickDeleteTorrent\r\n } = props;\r\n\r\n\r\n const maxAllowedTorrentNameLength = (componentBreakpoint === 'xs' || componentBreakpoint === 'sm') ? 70 : 175;\r\n let trimedTorrentName = announcer.torrentName;\r\n if (announcer.torrentName.length > maxAllowedTorrentNameLength) {\r\n trimedTorrentName = `${announcer.torrentName.substring(0, maxAllowedTorrentNameLength)}...`;\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n {`${trimedTorrentName} (${filesize(announcer.torrentSize, { standard: 'iec' })})`}\r\n \r\n \r\n \r\n \r\n onClickDeleteTorrent(announcer.infoHash)}\r\n >\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n \r\n
\r\n
\r\n
\r\n\r\n {announcer.isFetching || announcer.lastAnnouncedAt === undefined ? (\r\n \r\n ) : (\r\n \r\n )}\r\n
\r\n );\r\n};\r\nAnnouncer.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default withWidth()(Announcer);\r\n","import Announcer from './Announcer';\r\n\r\nexport default Announcer;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport {\r\n Grid,\r\n Paper,\r\n InputBase,\r\n IconButton,\r\n Tooltip,\r\n TablePagination\r\n} from '@material-ui/core';\r\nimport {\r\n ToggleButtonGroup,\r\n ToggleButton\r\n} from '@material-ui/lab';\r\nimport SearchIcon from '@material-ui/icons/Search';\r\nimport NameIcon from '@material-ui/icons/SortByAlpha';\r\nimport LeechersIcon from '@material-ui/icons/CloudDownloadOutlined';\r\nimport SeedersIcon from '@material-ui/icons/CloudUploadOutlined';\r\nimport Announcer from './Announcer';\r\n\r\nimport { Announcer as AnnouncerType } from '../../modules/joal-api/types'\r\n\r\n\r\nfunction desc(a: T, b: T, orderBy: keyof T) {\r\n if (b[orderBy] < a[orderBy]) {\r\n return -1;\r\n }\r\n if (b[orderBy] > a[orderBy]) {\r\n return 1;\r\n }\r\n return 0;\r\n}\r\n\r\ntype Order = 'asc' | 'desc';\r\n\r\nconst getSorting = (\r\n order: Order,\r\n orderBy?: K\r\n): (a: AnnouncerType, b: AnnouncerType) => number => {\r\n if (orderBy === '' || orderBy === undefined) {\r\n return (a, b) => 0\r\n }\r\n return order === 'desc' ? (a, b) => desc(a, b, orderBy) : (a, b) => -desc(a, b, orderBy);\r\n}\r\n\r\nconst getFiltering = (searchFilter: string): (a: AnnouncerType) => boolean => {\r\n if (searchFilter === '' || searchFilter === undefined) {\r\n return a => true\r\n }\r\n return a => a.torrentName.toLowerCase().includes(searchFilter.toLowerCase())\r\n}\r\n\r\n\r\ninterface EnhancedTableHeadProps {\r\n search: string,\r\n onRequestSearch: (search: string) => void\r\n order: Order,\r\n orderBy?: keyof AnnouncerType\r\n onRequestSort: (order: Order, property?: keyof AnnouncerType) => void\r\n}\r\n\r\nconst tableHeadUseStyles = makeStyles((theme: Theme) => ({\r\n searchBarPaper: {\r\n padding: '2px 4px',\r\n display: 'flex',\r\n alignItems: 'center',\r\n },\r\n searchBar: {\r\n marginLeft: 8,\r\n flex: 1,\r\n },\r\n searchBarIcon: {\r\n padding: 10,\r\n },\r\n sortActionsContainer: {\r\n [theme.breakpoints.down('xs')]: {\r\n width: '100%',\r\n },\r\n width: 'none'\r\n },\r\n sortButtonGroup: (props: { hasSortSelected: boolean }) => ({\r\n backgroundColor: props.hasSortSelected ? '' : 'transparent'\r\n }),\r\n toogleButtonWhenNoSortSelection: {\r\n borderColor: 'transparent'\r\n }\r\n}));\r\n\r\nfunction EnhancedTableHead(props: EnhancedTableHeadProps) {\r\n const {\r\n search,\r\n onRequestSearch,\r\n order,\r\n orderBy,\r\n onRequestSort\r\n } = props;\r\n const classes = tableHeadUseStyles({ hasSortSelected: orderBy !== undefined });\r\n\r\n function onClickSort(event: React.MouseEvent, property?: keyof AnnouncerType) {\r\n // The value is null when the user clic one more time on the same tile\r\n if (orderBy !== property && property !== null) {\r\n onRequestSort('asc', property);\r\n return;\r\n }\r\n\r\n // User clicked the same property once again\r\n if (order === 'asc') {\r\n onRequestSort('desc', orderBy);\r\n return;\r\n }\r\n if (order === 'desc') {\r\n onRequestSort('asc', undefined);\r\n return; // eslint-disable-line no-useless-return\r\n }\r\n }\r\n\r\n return (\r\n \r\n \r\n \r\n onRequestSearch(e.target.value)} placeholder=\"Filter by name\" />\r\n \r\n \r\n \r\n \r\n \r\n \r\n onClickSort(e, v)}>\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\n\r\nconst EnhancedTableToolbar = () => {\r\n\r\n return (\r\n
{''}
\r\n );\r\n};\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n announersList: {\r\n marginTop: theme.spacing(1),\r\n [theme.breakpoints.up('md')]: {\r\n marginLeft: theme.spacing(2),\r\n }\r\n },\r\n announcer: {\r\n [theme.breakpoints.down('md')]: {\r\n marginBottom: theme.spacing(2),\r\n },\r\n [theme.breakpoints.up('md')]: {\r\n marginBottom: theme.spacing(1),\r\n }\r\n }\r\n })\r\n);\r\n\r\ninterface AnnouncerTableProps {\r\n announcers: Array\r\n onClickDeleteTorrent: (infoHash: string) => void\r\n}\r\n\r\nfunction EnhancedTable(props: AnnouncerTableProps) {\r\n const classes = useStyles();\r\n const [search, setSearch] = React.useState('');\r\n const [order, setOrder] = React.useState('asc');\r\n const [orderBy, setOrderBy] = React.useState(undefined);\r\n const [page, setPage] = React.useState(0);\r\n const [rowsPerPage, setRowsPerPage] = React.useState(10);\r\n const { announcers, onClickDeleteTorrent } = props;\r\n\r\n React.useEffect(() => {\r\n // on refresh the number of announcers may have changed, so we may need to reset the page count to prevent page index to be out of bounds\r\n if (page > (Math.ceil(announcers.length / rowsPerPage) - 1)) {\r\n setPage(0);\r\n }\r\n }, [page, announcers.length, rowsPerPage]);\r\n\r\n function handleRequestSort(order: Order, property?: keyof AnnouncerType) {\r\n setOrder(order);\r\n setOrderBy(property);\r\n }\r\n\r\n function handleChangePage(event: unknown, newPage: number) {\r\n setPage(newPage);\r\n }\r\n\r\n function handleChangeRowsPerPage(event: React.ChangeEvent) {\r\n setRowsPerPage(+event.target.value);\r\n }\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n \r\n {announcers\r\n .filter(getFiltering(search))\r\n .sort(getSorting(order, orderBy))\r\n .slice(page * rowsPerPage, page * rowsPerPage + rowsPerPage)\r\n .map(announcer => {\r\n return (\r\n \r\n \r\n
\r\n )\r\n })\r\n }\r\n \r\n \r\n \r\n \r\n \r\n
\r\n );\r\n}\r\n\r\nexport default EnhancedTable;","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport Announcers from './torrentsTable.component';\r\nimport { changeSearchFilterText, changeTorrentSort } from './torrentsTable.actions';\r\nimport { deleteTorrent } from '../../modules/joal-api';\r\nimport { createSelector } from 'reselect'\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { Announcer as AnnouncerType } from '../../modules/joal-api/types';\r\n\r\nconst getSearchFilter = (state: JoalState) => state.app.torrentsTable.searchFilter;\r\nconst getAnnouncers = (state: JoalState) => state.api.announcers;\r\nconst getFilteredAnnouncers = createSelector(\r\n [ getSearchFilter, getAnnouncers ],\r\n (searchFilter: string, announcers: Array) => {\r\n if (searchFilter.trim().length === 0) {\r\n return announcers;\r\n }\r\n const filterText = searchFilter.toLowerCase();\r\n return announcers.filter(a => a.torrentName.toLowerCase().includes(filterText));\r\n }\r\n)\r\n\r\nconst getSortProperty = (state: JoalState) => state.app.torrentsTable.sortProperty;\r\nconst getSortDirection = (state: JoalState) => state.app.torrentsTable.sortDirection;\r\nconst getSortedAndFilteredAnnouncers = createSelector(\r\n [ getSortProperty, getSortDirection, getFilteredAnnouncers ],\r\n (sortProperty: string, sortDirection: string, filteredAnnouncers: Array) => {\r\n if (sortProperty === '' || sortProperty === undefined || sortProperty === null) {\r\n return filteredAnnouncers;\r\n }\r\n\r\n // Spread the array to sort on a copy of the original, it will prevent side effects on the original array\r\n return [...filteredAnnouncers].sort((t1: any, t2: any) => {\r\n if (t1[sortProperty] < t2[sortProperty]) return sortDirection === 'asc' ? -1 : 1;\r\n if (t1[sortProperty] === t2[sortProperty]) return 0;\r\n return sortDirection === 'asc' ? 1 : -1;\r\n });\r\n }\r\n)\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n announcers: getSortedAndFilteredAnnouncers(state),\r\n searchFilter: state.app.torrentsTable.searchFilter,\r\n sortProperty: state.app.torrentsTable.sortProperty,\r\n sortDirection: state.app.torrentsTable.sortDirection,\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => {\r\n return {\r\n onFilterTextChange: (text: string) => dispatch(changeSearchFilterText(text)),\r\n onSortChange: (sortProperty: string , sortDirection: string) => dispatch(changeTorrentSort(sortProperty, sortDirection)),\r\n onClickDeleteTorrent: (infoHash: string) => deleteTorrent(infoHash),\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Announcers);\r\n","import TorrentsTableContainer from './torrentsTable.container';\r\n\r\nexport default TorrentsTableContainer;\r\n","import React from 'react';\r\nimport ReactTooltip from 'react-tooltip';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Fab from '@material-ui/core/Fab';\r\nimport AddIcon from '@material-ui/icons/Add';\r\nimport { withTheme, createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport Tooltip from '@material-ui/core/Tooltip';\r\nimport Zoom from '@material-ui/core/Zoom';\r\nimport ClientInfo from '../../components/ClientInfo';\r\nimport AbsoluteOverlayFetchingIndicator from '../../components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator';\r\nimport UiConfigChangerButton from '../../components/UiConfigChanger';\r\nimport TorrentsTable from '../../components/TorrentsTable';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n relative: {\r\n position: 'relative'\r\n },\r\n addButton: {\r\n position: 'fixed',\r\n bottom: 75,\r\n right: theme.spacing(2),\r\n [theme.breakpoints.down('sm')]: {\r\n bottom: 65,\r\n right: 6,\r\n },\r\n },\r\n addButtonInput: {\r\n display: 'none'\r\n },\r\n announcers: {\r\n marginBottom: 110\r\n }\r\n })\r\n);\r\n\r\n\r\ntype Props = {\r\n theme: Theme,\r\n className?: string,\r\n isStarted: boolean,\r\n isConnectedToWebSocket: boolean,\r\n isClientGlobalStatePending: boolean,\r\n shouldDisplayConfigChangerButton: boolean,\r\n uploadTorrentFiles: (files: Array) => void\r\n};\r\n\r\nconst Dashboard = (props: Props) => {\r\n const classes = useStyles()\r\n const {\r\n className: classNameProps,\r\n shouldDisplayConfigChangerButton, theme, isConnectedToWebSocket, isClientGlobalStatePending, isStarted,\r\n uploadTorrentFiles\r\n } = props;\r\n\r\n return (\r\n \r\n \r\n {shouldDisplayConfigChangerButton && }\r\n
\r\n \r\n \r\n
\r\n
\r\n {isStarted && (\r\n \r\n \r\n \r\n )}\r\n \r\n\r\n {\r\n if (e.target.files != null) {\r\n uploadTorrentFiles(Array.from(e.target.files))\r\n }\r\n }}\r\n />\r\n \r\n \r\n \r\n \r\n );\r\n}\r\n\r\nDashboard.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default withTheme(Dashboard);\r\n","import { connect } from 'react-redux';\r\nimport isElectron from 'is-electron';\r\nimport Dashboard from './dashboard.component';\r\nimport { uploadTorrents } from '../../modules/joal-api';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n isStarted: state.api.client.isStarted,\r\n isConnectedToWebSocket: state.api.stomp.isConnected,\r\n isClientGlobalStatePending: state.api.client.isFetching,\r\n shouldDisplayConfigChangerButton: !isElectron()\r\n };\r\n}\r\nfunction mapDispatchToProps() {\r\n return {\r\n uploadTorrentFiles: (files: Array) => uploadTorrents(files)\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(Dashboard);\r\n","import Dashboard from './dashboard.container';\r\n\r\nexport default Dashboard;\r\n","import React from 'react';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport Button from '@material-ui/core/Button';\r\nimport TextField from '@material-ui/core/TextField';\r\nimport Checkbox from '@material-ui/core/Checkbox';\r\nimport FormControlLabel from '@material-ui/core/FormControlLabel';\r\nimport FormHelperText from '@material-ui/core/FormHelperText';\r\nimport Select from '@material-ui/core/Select';\r\nimport Input from '@material-ui/core/Input';\r\nimport InputLabel from '@material-ui/core/InputLabel';\r\nimport MenuItem from '@material-ui/core/MenuItem';\r\nimport FormControl from '@material-ui/core/FormControl';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\nimport AbsoluteOverlayFetchingIndicator from '../../components/Generics/FetchingIndicator/AbsoluteOverlayFetchingIndicator';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n padding: theme.spacing(2),\r\n position: 'relative',\r\n },\r\n discardChangesButton: {\r\n marginRight: theme.spacing(2)\r\n },\r\n formInput: {\r\n marginBottom: theme.spacing(3),\r\n minWidth: 180\r\n },\r\n rightSpaced: {\r\n marginRight: theme.spacing(2)\r\n }\r\n })\r\n);\r\n\r\n\r\nconst ITEM_HEIGHT = 48;\r\nconst MenuProps = {\r\n PaperProps: {\r\n style: {\r\n maxHeight: ITEM_HEIGHT * 6\r\n },\r\n },\r\n};\r\n\r\ntype Props = {\r\n isLocalConfigChanged: boolean,\r\n config: any,\r\n availableClients: Array,\r\n isConnectedToWebSocket: boolean,\r\n discardLocalConfigChanges: () => void,\r\n onSettingsChange: (config: any) => void,\r\n onClickSave: (config: any) => void\r\n};\r\n\r\nconst Settings = (props: Props) => {\r\n const classes = useStyles();\r\n const {\r\n isConnectedToWebSocket,\r\n discardLocalConfigChanges, onSettingsChange, onClickSave,\r\n availableClients, config, isLocalConfigChanged\r\n } = props;\r\n\r\n const valueHasChanged = (newValue: any) => onSettingsChange(Object.assign(\r\n {},\r\n config,\r\n newValue\r\n ));\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n \r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ minUploadRate: value });\r\n }}\r\n />\r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ maxUploadRate: value });\r\n }}\r\n />\r\n \r\n \r\n \r\n Torrent client\r\n valueHasChanged({ client: event.target.value })}\r\n input={}\r\n MenuProps={MenuProps}\r\n >\r\n {availableClients.map(client => (\r\n \r\n {client.substring(0, client.lastIndexOf('.'))}\r\n \r\n ))}\r\n \r\n \r\n \r\n \r\n {\r\n const value = event.target.value === '' ? '' : parseInt(event.target.value, 10);\r\n valueHasChanged({ simultaneousSeed: value });\r\n }}\r\n />\r\n \r\n \r\n
\r\n valueHasChanged({ keepTorrentWithZeroLeechers: checked })}\r\n />\r\n )}\r\n label=\"Keep seeding torrents even with no peers\"\r\n />\r\n \r\n If checked, when a torrent reach 0 peers it will seed at 0 kB/s. Otherwise, when a torrent reach 0 peers it will be removed.\r\n \r\n
\r\n
\r\n
\r\n \r\n \r\n { isLocalConfigChanged && (\r\n discardLocalConfigChanges()}\r\n color=\"secondary\"\r\n className={classes.discardChangesButton}\r\n >\r\n Discard\r\n \r\n )}\r\n onClickSave(config)}\r\n color=\"secondary\"\r\n >\r\n Save\r\n \r\n \r\n \r\n \r\n \r\n \r\n );\r\n};\r\n\r\nexport default Settings;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport SettingsComponent from './settings.component';\r\nimport { localConfigHasChanged, discardLocalConfigChanges } from './settings.actions';\r\nimport { sendConfigToServer } from '../../modules/joal-api';\r\n\r\nimport { Config } from '../../modules/joal-api/types';\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n return {\r\n // if local config is set it means the user has modified the config, so we show it\r\n isLocalConfigChanged: state.app.config.localConfig !== undefined,\r\n config: state.app.config.localConfig || state.api.settings.config,\r\n availableClients: state.api.settings.availableClients,\r\n isConnectedToWebSocket: state.api.stomp.isConnected\r\n };\r\n}\r\n\r\nfunction mapDispatchToProps(dispatch: Dispatch) {\r\n return ({\r\n discardLocalConfigChanges: () => dispatch(discardLocalConfigChanges()),\r\n onSettingsChange: (config: Config) => dispatch(localConfigHasChanged(config)),\r\n onClickSave: (config: Config) => sendConfigToServer(config)\r\n });\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(SettingsComponent);\r\n","import Settings from './settings.container';\r\n\r\nexport default Settings;\r\n","import React from 'react';\r\nimport IconWarning from '@material-ui/icons/Warning';\r\nimport Grid from '@material-ui/core/Grid';\r\nimport orange from '@material-ui/core/colors/orange';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n container: {\r\n textAlign: 'center',\r\n marginTop: 100,\r\n height: '100%'\r\n }\r\n })\r\n);\r\n\r\n\r\ntype Props = {\r\n events: Array\r\n};\r\n\r\nconst EventHistory = ({ events }: Props) => {\r\n const classes = useStyles();\r\n if (events) {\r\n // TODO: implement me. this if is just a placeholder to prevent no-unused-params\r\n }\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n Hey it looks like you discovered the super secret tab !\r\n \r\n \r\n This tab will tell you what was the last actions JOAL has performed. Unfortunately this is still under development, check it back later ;)\r\n \r\n \r\n );\r\n};\r\n\r\nexport default EventHistory;\r\n","import { connect } from 'react-redux';\r\nimport EventHistoryComponent from './event-history.component';\r\n\r\nfunction mapStateToProps() {\r\n return {\r\n events: []\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps)(EventHistoryComponent);\r\n","import EventHistoryContainer from './event-history.container';\r\n\r\nexport default EventHistoryContainer;\r\n","import React from 'react';\r\nimport BottomNavigation from '@material-ui/core/BottomNavigation';\r\nimport BottomNavigationAction from '@material-ui/core/BottomNavigationAction';\r\nimport Paper from '@material-ui/core/Paper';\r\nimport DashboardIcon from '@material-ui/icons/Dashboard';\r\nimport SettingsIcon from '@material-ui/icons/Settings';\r\nimport LogsIcon from '@material-ui/icons/Sms';\r\n\r\ntype NavigationBarProps = {\r\n currentPath: string,\r\n onClickDashboard: () => void,\r\n onClickSettings: () => void,\r\n onClickLogs: () => void\r\n};\r\n\r\nconst NavigationBar: React.FC = (props) => {\r\n const {\r\n currentPath,\r\n onClickDashboard,\r\n onClickSettings,\r\n onClickLogs\r\n } = props;\r\n\r\n const whichIndex = (whichPath: string) => {\r\n if (whichPath === '/') {\r\n return 0;\r\n }\r\n if (whichPath === '/settings') {\r\n return 1;\r\n }\r\n return 2;\r\n };\r\n\r\n const onChangeTab = (event: React.ChangeEvent<{}>, index: number) => {\r\n if (index === 0) onClickDashboard();\r\n else if (index === 1) onClickSettings();\r\n else if (index === 2) onClickLogs();\r\n };\r\n\r\n return (\r\n \r\n \r\n }\r\n />\r\n }\r\n />\r\n }\r\n />\r\n \r\n \r\n );\r\n};\r\n\r\nexport default NavigationBar;\r\n","import NavigationBarContainer from './navigationBar.container';\r\n\r\nexport default NavigationBarContainer;\r\n","import { Dispatch } from 'redux';\r\nimport { connect } from 'react-redux';\r\nimport NavigationBar from './navigationBar.component';\r\nimport { push } from 'connected-react-router';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\n\r\nconst mapStateToProps = (state: JoalState) => {\r\n return {\r\n currentPath: state.router.location.pathname\r\n };\r\n}\r\n\r\nconst mapDispatchToProps = (dispatch: Dispatch) => {\r\n return {\r\n onClickDashboard: () => dispatch(push('/')),\r\n onClickSettings: () => dispatch(push('/settings')),\r\n onClickLogs: () => dispatch(push('/history'))\r\n };\r\n}\r\n\r\nexport default connect(mapStateToProps, mapDispatchToProps)(NavigationBar);\r\n","import React, { ReactNode } from 'react';\r\nimport { useDropzone } from 'react-dropzone'\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n dropzone: {\r\n position: 'absolute',\r\n top: 0,\r\n bottom: 0,\r\n left: 0,\r\n right: 0,\r\n },\r\n overlay: {\r\n zIndex: 16777270,\r\n position: 'fixed',\r\n top: 0,\r\n right: 0,\r\n bottom: 0,\r\n left: 0,\r\n backgroundColor: 'rgba(156, 155, 155, 0.86)',\r\n color: 'rgba(130, 130, 130, 0.75)',\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center'\r\n }\r\n })\r\n);\r\n\r\ninterface TorrentDropZoneProps {\r\n onDrop: (acceptedFiles: Array, rejectedFiles:Array) => void,\r\n children: ReactNode,\r\n}\r\n\r\nconst TorrentDropZone: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { children } = props;\r\n\r\n const { getRootProps, getInputProps, isDragActive } = useDropzone({\r\n onDrop: (accepted, rejected) => props.onDrop(accepted, rejected),\r\n noClick: true,\r\n noKeyboard: true,\r\n multiple: true\r\n })\r\n \r\n const rootProps = getRootProps({\r\n onClick: (e) => { e.stopPropagation(); } // Prevent react dropzone to execute his own handler which contains a \"event.preventDefault\". Since the dropzone embed the whole page it would prevent other input click\r\n });\r\n\r\n return (\r\n
\r\n \r\n {children}\r\n {isDragActive && (\r\n
\r\n \r\n
\r\n )}\r\n
\r\n )\r\n}\r\n\r\nexport default TorrentDropZone;\r\n","import React from 'react';\r\nimport AppBar from '@material-ui/core/AppBar';\r\nimport Toolbar from '@material-ui/core/Toolbar';\r\nimport Typography from '@material-ui/core/Typography';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport classnames from 'classnames';\r\nimport { ThemeModifier } from '../../modules/theme';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n flexGrow: 1,\r\n },\r\n grow: {\r\n flexGrow: 1,\r\n },\r\n menuButton: {\r\n marginLeft: -12,\r\n marginRight: 20,\r\n }\r\n })\r\n);\r\n\r\ntype JoalAppBarProps = {\r\n className?: any\r\n}\r\n\r\nconst JoalAppBar: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n className: classNameProps\r\n } = props;\r\n\r\n return (\r\n
\r\n \r\n \r\n \r\n Joal\r\n \r\n \r\n \r\n \r\n
\r\n );\r\n};\r\nJoalAppBar.defaultProps = {\r\n className: {}\r\n};\r\n\r\nexport default JoalAppBar;\r\n","import JoalAppBar from './appbar.component';\r\n\r\nexport default JoalAppBar;\r\n","import React, { ReactNode } from 'react';\r\n\r\n\r\ntype BaseIconProps = {\r\n className?: string,\r\n children: ReactNode\r\n}\r\n\r\nconst BaseIcon: React.FC = (props) => {\r\n const { className: classNameProps, children } = props\r\n\r\n return (\r\n \r\n {children}\r\n \r\n );\r\n}\r\nBaseIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default BaseIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#2E9AFE'\r\n }\r\n })\r\n);\r\n\r\ntype InfoIconProps = {\r\n className?: string\r\n}\r\n\r\nconst InfoIcon:React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\nInfoIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default InfoIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#31B404'\r\n }\r\n })\r\n);\r\n\r\ntype SuccessIconProps = {\r\n className?: string\r\n}\r\n\r\nconst SuccessIcon:React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\nSuccessIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default SuccessIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#FF0040'\r\n }\r\n })\r\n);\r\n\r\ntype ErrorIconProps = {\r\n className?: string\r\n}\r\n\r\nconst ErrorIcon: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n \r\n );\r\n}\r\nErrorIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default ErrorIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport BaseIcon from './BaseIcon';\r\nimport classnames from 'classnames';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n icon: {\r\n stroke: '#000000'\r\n }\r\n })\r\n);\r\n\r\ntype CloseIconProps = {\r\n className?: string\r\n}\r\n\r\nconst CloseIcon: React.FC = (props) => {\r\n const classes = useStyles();\r\n const { className: classNameProps } = props;\r\n\r\n return (\r\n \r\n \r\n \r\n \r\n );\r\n}\r\nCloseIcon.defaultProps = {\r\n className: ''\r\n};\r\n\r\nexport default CloseIcon;\r\n","import React from 'react';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport { AlertComponentPropsWithStyle } from 'react-alert';\r\nimport InfoIcon from './icons/InfoIcon';\r\nimport SuccessIcon from './icons/SuccessIcon';\r\nimport ErrorIcon from './icons/ErrorIcon';\r\nimport CloseIcon from './icons/CloseIcon';\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n alert: {\r\n // boxShadow: '0 8px 12px 0 rgba(0,0,0,0.3)',\r\n backgroundColor: `${theme.palette.type === 'dark' ? '#333' : '#fff'}`,\r\n borderRadius: 3,\r\n padding: 10,\r\n display: 'flex',\r\n justifyContent: 'space-between',\r\n alignItems: 'center',\r\n boxShadow: '0px 2px 2px 2px rgba(0, 0, 0, 0.03)',\r\n fontFamily: 'Arial',\r\n fontSize: 11,\r\n width: 350,\r\n [theme.breakpoints.down('xs')]: {\r\n width: '75vw'\r\n },\r\n boxSizing: 'border-box',\r\n position: 'relative'\r\n },\r\n message: {\r\n color: `${theme.palette.type === 'dark' ? '#fff' : '#333'}`,\r\n paddingRight: 40,\r\n textAlign: 'center',\r\n textTransform: 'uppercase',\r\n },\r\n statusIcon: {\r\n marginRight: 15\r\n },\r\n closeButton: {\r\n padding: 0,\r\n display: 'flex',\r\n alignItems: 'center',\r\n justifyContent: 'center',\r\n position: 'absolute',\r\n right: 0,\r\n top: 0,\r\n bottom: 0,\r\n width: 40,\r\n border: 'none',\r\n backgroundColor: theme.palette.type === 'dark' ? '#444' : '#f3f3f3',\r\n cursor: 'pointer',\r\n },\r\n closeIconOverride: {\r\n stroke: theme.palette.type === 'dark' ? '#BBB' : '#000'\r\n }\r\n })\r\n);\r\n\r\ninterface AlertTemplateProps extends AlertComponentPropsWithStyle {\r\n}\r\n\r\nconst AlertTemplate: React.FC = (props) => {\r\n const classes = useStyles();\r\n const {\r\n message, options, style, close\r\n } = props;\r\n return (\r\n // the style contains only the margin given as offset\r\n // options contains all alert given options\r\n // message is the alert message...\r\n // close is a function that closes the alert\r\n
\r\n {options.type === 'success' && }\r\n {options.type === 'info' && }\r\n {options.type === 'error' && }\r\n {message}\r\n \r\n
\r\n );\r\n}\r\n\r\nexport default AlertTemplate;\r\n","import AlertTemplate from './alert-template.component';\r\n\r\nexport default AlertTemplate;\r\n","import React, { Component } from 'react';\r\nimport { Dispatch } from 'redux';\r\nimport { withAlert, AlertManager } from 'react-alert';\r\nimport { connect } from 'react-redux';\r\nimport { removeNotification } from './alerts.actions';\r\n\r\nimport { JoalState } from '../../reducers/types';\r\nimport { Notification } from './types';\r\n\r\ninterface JoalAlertDisplayerProps {\r\n alert: AlertManager, // given by withAlert wrapper\r\n notifs: Array,\r\n shouldShowDirtyConfNotif: boolean,\r\n onMessageClosed: (id: string) => void\r\n}\r\n\r\nclass JoalAlertDisplayer extends Component {\r\n\r\n shouldComponentUpdate(nextProps: JoalAlertDisplayerProps) {\r\n const { notifs: currentNotifs, shouldShowDirtyConfNotif: currentShouldShowDirtyConfNotif } = this.props;\r\n return (currentNotifs !== nextProps.notifs || currentShouldShowDirtyConfNotif !== nextProps.shouldShowDirtyConfNotif);\r\n }\r\n\r\n componentDidUpdate(prevProps: JoalAlertDisplayerProps) {\r\n const { shouldShowDirtyConfNotif, alert, notifs } = this.props;\r\n if (prevProps.shouldShowDirtyConfNotif !== shouldShowDirtyConfNotif) {\r\n if (shouldShowDirtyConfNotif === true) {\r\n alert.info('Config wont be refreshed until you restart JOAL');\r\n }\r\n }\r\n\r\n if (notifs === prevProps.notifs) {\r\n return;\r\n }\r\n\r\n // Add new notifications\r\n notifs.forEach(newNotif => {\r\n if (prevProps.notifs.findIndex(n => n.id === newNotif.id) === -1) {\r\n this.showNotification(newNotif);\r\n }\r\n });\r\n }\r\n\r\n showNotification(notification: Notification) {\r\n const { alert, onMessageClosed } = this.props;\r\n const notifCopy = Object.assign({}, notification, {\r\n onClose: () => onMessageClosed(notification.id)\r\n });\r\n const { text } = notifCopy;\r\n switch (notifCopy.type) {\r\n case 'ERROR': {\r\n alert.error({text}, notifCopy);\r\n break;\r\n }\r\n case 'SUCCESS': {\r\n alert.success(text, notifCopy);\r\n break;\r\n }\r\n case 'INFO': {\r\n alert.info(text, notifCopy);\r\n break;\r\n }\r\n default: {\r\n console.error(`Unknown AlertMessage type: ${notifCopy.type}`);\r\n }\r\n }\r\n }\r\n\r\n render() {\r\n return (\r\n \r\n );\r\n }\r\n}\r\n\r\n\r\nfunction mapStateToProps(state: JoalState) {\r\n const { notifs, shouldShowDirtyConfNotif } = state.alerts;\r\n return {\r\n notifs,\r\n shouldShowDirtyConfNotif\r\n };\r\n}\r\n\r\nfunction mapDispatchToProps(dispatch: Dispatch) {\r\n return ({\r\n onMessageClosed: (id: string) => dispatch(removeNotification(id))\r\n });\r\n}\r\n\r\nexport default withAlert()(connect(mapStateToProps, mapDispatchToProps)(JoalAlertDisplayer));\r\n","import JoalAlertProvider from './alerts-provider.component';\r\n\r\nexport default JoalAlertProvider;\r\n","import React from 'react';\r\nimport { Provider as AlertProvider, positions, transitions } from 'react-alert';\r\nimport withWidth, { isWidthUp, WithWidth } from '@material-ui/core/withWidth';\r\nimport AlertTemplate from './alert-template';\r\nimport AlertsDisplayer from './alerts-displayer.component';\r\n\r\ninterface JoalAlertProviderProps extends WithWidth {\r\n}\r\n\r\nconst JoalAlertProvider: React.FC = ({ width }) => (\r\n \r\n \r\n \r\n);\r\n\r\nexport default withWidth()(JoalAlertProvider);\r\n","import React from 'react';\r\nimport { connect } from 'react-redux';\r\nimport { Route, Switch } from 'react-router-dom';\r\nimport { ConnectedRouter } from 'connected-react-router'\r\nimport Grid from '@material-ui/core/Grid';\r\nimport { createStyles, makeStyles, Theme } from '@material-ui/core/styles';\r\nimport DashboardPage from './pages/dashboard';\r\nimport SettingsPage from './pages/settings';\r\nimport Historypage from './pages/event-history';\r\nimport NavigationBar from './components/NavigationBar';\r\nimport TorrentDropZone from './components/TorrentDropZone';\r\nimport JoalAppBar from './components/AppBar';\r\nimport Alerts from './modules/alerts';\r\nimport { uploadTorrents } from './modules/joal-api';\r\n\r\nimport { History } from 'history';\r\n\r\n\r\nconst useStyles = makeStyles((theme: Theme) => \r\n createStyles({\r\n root: {\r\n flexGrow: 1,\r\n padding: theme.spacing(2)\r\n },\r\n navigationBarWrapper: {\r\n position: 'fixed',\r\n left: 0,\r\n right: 0,\r\n bottom: 0\r\n }\r\n })\r\n);\r\n\r\n\r\ninterface AppProps {\r\n history: History,\r\n onFileDrop: (accepted: Array) => void,\r\n};\r\n\r\n\r\nconst App: React.FC = ({ onFileDrop, history }) => {\r\n const classes = useStyles();\r\n\r\n return (\r\n
\r\n \r\n \r\n
\r\n \r\n
\r\n \r\n \r\n
\r\n \r\n \r\n \r\n \r\n \r\n \r\n \r\n
\r\n
\r\n \r\n
\r\n
\r\n
\r\n
\r\n
\r\n );\r\n}\r\n\r\n\r\nconst mapStateToProps = () => ({\r\n onFileDrop: (accepted: Array) => {\r\n uploadTorrents(accepted);\r\n }\r\n});\r\n\r\nexport default connect(mapStateToProps)(App);\r\n","import React from 'react';\r\nimport { Provider } from 'react-redux';\r\nimport { ThemeProvider } from './modules/theme';\r\nimport App from './App';\r\n\r\nimport { History } from 'history';\r\nimport { Store } from 'redux';\r\n\r\ninterface RootProps {\r\n store: Store,\r\n history: History\r\n};\r\n\r\nconst Root: React.FC = ({ store, history }) => (\r\n \r\n \r\n \r\n \r\n \r\n);\r\n\r\nexport default Root;\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n TORRENT_SEARCH_FILTER_TEXT_CHANGED,\r\n TORRENT_SORT_CHANGED\r\n} from './torrentsTable.actions';\r\n\r\nconst initialState = {\r\n searchFilter: '',\r\n sortProperty: '',\r\n sortDirection: '',\r\n currentPage: 1,\r\n torrentsPerPage: 10\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [TORRENT_SEARCH_FILTER_TEXT_CHANGED]: (state, action) => {\r\n state.searchFilter = action.text\r\n },\r\n [TORRENT_SORT_CHANGED]: (state, action) => {\r\n state.sortProperty = action.sortProperty;\r\n state.sortDirection = action.sortDirection;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n LOCAL_CONFIG_HAS_CHANGED,\r\n DISCARD_LOCAL_CONFIG\r\n} from './settings.actions';\r\nimport {\r\n CONFIG_IS_IN_DIRTY_STATE as API___CONFIG_IS_IN_DIRTY_STATE,\r\n CONFIG_HAS_BEEN_LOADED as API____CONFIG_HAS_BEEN_LOADED\r\n} from '../../modules/joal-api/settings/settings.actions';\r\n\r\nimport { LocalConfig } from '../../reducers/types';\r\n\r\nconst initialState: LocalConfig = {\r\n localConfig: undefined\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [LOCAL_CONFIG_HAS_CHANGED]: (state, action) => {\r\n state.localConfig = action.config;\r\n },\r\n [DISCARD_LOCAL_CONFIG]: (state) => {\r\n state.localConfig = undefined;\r\n },\r\n // When the server send the new config we remove the local one\r\n [API___CONFIG_IS_IN_DIRTY_STATE]: () => {\r\n return initialState;\r\n },\r\n [API____CONFIG_HAS_BEEN_LOADED]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n CHANGE_THEME_TYPE\r\n} from './theme-modifier.actions';\r\n\r\n\r\nconst initialState = {\r\n palette: {\r\n type: localStorage.getItem('themeType') || 'light'\r\n }\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [CHANGE_THEME_TYPE]: (state) => {\r\n const newTheme = state.palette.type === 'light' ? 'dark' : 'light';\r\n localStorage.setItem('themeType', newTheme);\r\n\r\n state.palette.type = newTheme\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n TORRENT_FILE_ADDED,\r\n TORRENT_FILE_DELETED,\r\n FAILED_TO_ADD_TORRENT_FILE,\r\n RESET_TORRENT_FILES_STATE\r\n} from './torrentFile.actions';\r\n\r\nimport { TorrentFile } from '../types';\r\n\r\nconst initialState: Array = [];\r\n\r\nexport default createReducer(initialState, {\r\n [TORRENT_FILE_ADDED]: (state, action) => {\r\n const newState = state.filter(tf => tf.infoHash !== action.payload.infoHash);\r\n newState.push(action.payload);\r\n return newState;\r\n },\r\n [TORRENT_FILE_DELETED]: (state, action) => {\r\n return state.filter(tf => tf.infoHash !== action.payload.infoHash);\r\n },\r\n [FAILED_TO_ADD_TORRENT_FILE]: (state) => {\r\n // Do nothing, notifications reducer will handle it\r\n return state;\r\n },\r\n [RESET_TORRENT_FILES_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import {\r\n GLOBAL_SEED_STARTED,\r\n GLOBAL_SEED_STOPPED,\r\n SEND_START_TO_SERVER,\r\n SEND_STOP_TO_SERVER,\r\n RESET_CLIENT_STATE\r\n} from './client.actions';\r\nimport { createReducer } from 'redux-starter-kit';\r\n\r\nimport { Client } from '../types';\r\n\r\nconst initialState: Client = {\r\n isFetching: true,\r\n isStarted: false,\r\n name: ''\r\n};\r\n\r\nexport default createReducer(initialState, {\r\n [GLOBAL_SEED_STARTED]: (state, action) => {\r\n state.isFetching = false;\r\n state.isStarted = true;\r\n state.name = action.payload.client;\r\n },\r\n [GLOBAL_SEED_STOPPED]: (state) => {\r\n state.isFetching = false;\r\n state.isStarted = false;\r\n state.name = '';\r\n },\r\n [SEND_START_TO_SERVER]: (state) => {\r\n state.isFetching = true;\r\n },\r\n [SEND_STOP_TO_SERVER]: (state) => {\r\n state.isFetching = true;\r\n },\r\n [RESET_CLIENT_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n CONFIG_IS_IN_DIRTY_STATE,\r\n INVALID_CONFIG,\r\n CONFIG_HAS_BEEN_LOADED,\r\n LIST_OF_CLIENT_FILES,\r\n RESET_CONFIG\r\n} from './settings.actions';\r\n\r\nimport { Settings } from '../types';\r\n\r\nconst initialState: Settings = {\r\n isDirty: false,\r\n errMessage: undefined,\r\n config: {\r\n minUploadRate: 0,\r\n maxUploadRate: 0,\r\n simultaneousSeed: 0,\r\n client: '',\r\n keepTorrentWithZeroLeechers: false\r\n },\r\n availableClients: []\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [CONFIG_IS_IN_DIRTY_STATE]: (state, action) => {\r\n state.isDirty = true;\r\n state.config = action.payload.config;\r\n state.errMessage = undefined;\r\n },\r\n [INVALID_CONFIG]: (state, action) => {\r\n state.errMessage = action.payload.error;\r\n },\r\n [CONFIG_HAS_BEEN_LOADED]: (state, action) => {\r\n state.isDirty = false;\r\n state.config = action.payload.config;\r\n state.errMessage = undefined;\r\n },\r\n [LIST_OF_CLIENT_FILES]: (state, action) => {\r\n state.availableClients = action.payload.clients;\r\n },\r\n [RESET_CONFIG]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n SEEDING_SPEED_HAS_CHANGED,\r\n RESET_SPEED_STATE\r\n} from './speed.actions';\r\n\r\nimport { SpeedsArray, Speed } from '../types';\r\n\r\nconst initialState: SpeedsArray = {};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [SEEDING_SPEED_HAS_CHANGED]: (state, action: { payload: { speeds: Array }}) => {\r\n const speeds: SpeedsArray = {};\r\n for (let currentSpeed of action.payload.speeds) {\r\n speeds[currentSpeed.infoHash] = currentSpeed;\r\n }\r\n return speeds;\r\n },\r\n [RESET_SPEED_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n FAILED_TO_ANNOUNCE,\r\n SUCCESSFULLY_ANNOUNCE,\r\n TOO_MANY_ANNOUNCES_FAILED,\r\n WILL_ANNOUNCE,\r\n RESET_ANNOUNCER_STATE\r\n} from './announcers.actions';\r\n\r\nimport { Announcer as AnnouncerType } from '../types';\r\n\r\nconst initialState: Array = [];\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [FAILED_TO_ANNOUNCE]: (state, action) => {\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: false }, action.payload));\r\n return;\r\n }\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: false },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [SUCCESSFULLY_ANNOUNCE]: (state, action) => {\r\n if (action.payload.requestEvent === 'STOPPED') {\r\n return state.filter(announcer => announcer.infoHash !== action.payload.infoHash);\r\n }\r\n\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: false }, action.payload));\r\n return;\r\n }\r\n\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: false },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [TOO_MANY_ANNOUNCES_FAILED]: (state, action) => {\r\n return state.filter(announcer => announcer.infoHash !== action.payload.infoHash);\r\n },\r\n [WILL_ANNOUNCE]: (state, action) => {\r\n if (!state.find(announcer => announcer.infoHash === action.payload.infoHash)) {\r\n state.push(Object.assign({}, { isFetching: true }, action.payload));\r\n return;\r\n }\r\n\r\n return state.map(announcer => {\r\n if (announcer.infoHash === action.payload.infoHash) {\r\n return Object.assign(\r\n {},\r\n announcer,\r\n { isFetching: true },\r\n action.payload\r\n );\r\n }\r\n return announcer;\r\n });\r\n },\r\n [RESET_ANNOUNCER_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport {\r\n IS_CONNECTING,\r\n HAS_CONNECTED,\r\n HAS_FAILED_TO_CONNECT,\r\n HAS_DROP_CONNECTION,\r\n INIT_OVER,\r\n RESET_STOMP_STATE\r\n} from './stomp.actions';\r\n\r\nimport { Stomp } from '../types';\r\n\r\nconst initialState: Stomp = {\r\n isConnected: false,\r\n isFullyInit: false\r\n};\r\n\r\n\r\nexport default createReducer(initialState, {\r\n [IS_CONNECTING]: (state) => {\r\n state.isFullyInit = false;\r\n },\r\n [HAS_CONNECTED]: (state) => {\r\n state.isConnected = true;\r\n },\r\n [HAS_FAILED_TO_CONNECT]: (state) => {\r\n state.isConnected = false;\r\n state.isFullyInit = false;\r\n },\r\n [HAS_DROP_CONNECTION]: (state) => {\r\n state.isConnected = false;\r\n state.isFullyInit = false;\r\n },\r\n [INIT_OVER]: (state) => {\r\n state.isFullyInit = true;\r\n },\r\n [RESET_STOMP_STATE]: () => {\r\n return initialState;\r\n }\r\n});\r\n","import { combineReducers } from 'redux';\r\nimport apiTorrentFileReducer from './torrentFiles/torrentFiles.reducer';\r\nimport apiClientReducer from './client/client.reducer';\r\nimport apiSettingsReducer from './settings/settings.reducer';\r\nimport apiSpeedReducer from './speed/speed.reducer';\r\nimport apiAnnouncersReducer from './announcers/announcers.reducer';\r\nimport apiStompReducer from './stomp/stomp.reducer';\r\n\r\nexport default combineReducers({\r\n torrentFiles: apiTorrentFileReducer,\r\n client: apiClientReducer,\r\n announcers: apiAnnouncersReducer,\r\n settings: apiSettingsReducer,\r\n speed: apiSpeedReducer,\r\n stomp: apiStompReducer\r\n});\r\n","import { createReducer } from 'redux-starter-kit';\r\nimport { CONFIG_IS_IN_DIRTY_STATE, CONFIG_HAS_BEEN_LOADED, INVALID_CONFIG } from '../joal-api/settings/settings.actions';\r\nimport { TORRENT_FILE_ADDED, FAILED_TO_ADD_TORRENT_FILE } from '../joal-api/torrentFiles/torrentFile.actions';\r\nimport {\r\n INIT_OVER,\r\n HAS_CONNECTED,\r\n HAS_DROP_CONNECTION,\r\n HAS_FAILED_TO_CONNECT,\r\n RECEIVED_ERROR_MESSAGE\r\n} from '../joal-api/stomp/stomp.actions';\r\nimport { REMOVE_NOTIFICATION } from './alerts.actions';\r\n\r\nimport { NotificationState, Notification } from './types';\r\n\r\n\r\nconst uuidv4 = () => (\r\n ([1e7] as any +-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c: number) => (// eslint-disable-line space-infix-ops\r\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) // eslint-disable-line implicit-arrow-linebreak, no-bitwise, no-mixed-operators\r\n ))\r\n);\r\n\r\nconst initialState: NotificationState = {\r\n shouldShowDirtyConfNotif: false,\r\n notifs: []\r\n};\r\nlet isAppInit = false;\r\n\r\nexport default createReducer(initialState, {\r\n [INIT_OVER]: (state) => {\r\n isAppInit = true;\r\n return state;\r\n },\r\n [HAS_CONNECTED]: (state) => {\r\n isAppInit = false;\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Connected to JOAL',\r\n timeout: 6000,\r\n type: 'SUCCESS'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [HAS_DROP_CONNECTION]: (state) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Lost connection to JOAL, auto-reconnect in 8 seconds.',\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [HAS_FAILED_TO_CONNECT]: (state) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: 'Failed to connect to JOAL, retry in 8 seconds.',\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [REMOVE_NOTIFICATION]: (state, action) => {\r\n state.notifs = state.notifs.filter(notif => notif.id !== action.payload);\r\n },\r\n [CONFIG_IS_IN_DIRTY_STATE]: (state) => {\r\n state.shouldShowDirtyConfNotif = true;\r\n },\r\n [CONFIG_HAS_BEEN_LOADED]: (state) => {\r\n state.shouldShowDirtyConfNotif = false;\r\n },\r\n [INVALID_CONFIG]: (state, action) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `Invalid config: ${action.payload.error}`,\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [TORRENT_FILE_ADDED]: (state, action) => {\r\n if (!isAppInit) {\r\n // don't show notification if app is not inited\r\n return state;\r\n }\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `${action.payload.name} added`,\r\n timeout: 6000,\r\n type: 'SUCCESS'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [FAILED_TO_ADD_TORRENT_FILE]: (state, action) => {\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: `${action.payload.fileName} was rejected by server: ${action.payload.error}`,\r\n timeout: 6000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n },\r\n [RECEIVED_ERROR_MESSAGE]: (state, action) =>{\r\n const notif: Notification = {\r\n id: uuidv4(),\r\n text: action.message,\r\n timeout: 8000,\r\n type: 'ERROR'\r\n };\r\n\r\n state.notifs.push(notif);\r\n }\r\n});\r\n","import { combineReducers } from 'redux';\r\nimport { connectRouter } from 'connected-react-router'\r\nimport torrentsTableReducer from '../components/TorrentsTable/torrentsTable.reducer';\r\nimport uiConfigReducer from '../pages/settings/settings.reducer';\r\nimport themeReducer from '../modules/theme/theme-modifier/theme-modifier.reducer';\r\nimport apiReducer from '../modules/joal-api/joal-api.reducer';\r\nimport alertReducer from '../modules/alerts/alerts.reducer';\r\n\r\nimport { History } from 'history';\r\n\r\nexport default (history: History) => combineReducers({\r\n api: apiReducer,\r\n app: combineReducers({\r\n config: uiConfigReducer,\r\n torrentsTable: torrentsTableReducer\r\n }),\r\n theme: themeReducer,\r\n alerts: alertReducer,\r\n router: connectRouter(history)\r\n});\r\n","import { configureStore, getDefaultMiddleware } from 'redux-starter-kit';\r\nimport { createHashHistory } from 'history';\r\nimport { routerMiddleware, routerActions } from 'connected-react-router';\r\nimport { createLogger } from 'redux-logger';\r\nimport createRootReducer from '../reducers';\r\n\r\nimport { EnhancerOptions } from 'redux-devtools-extension';\r\n\r\nexport const history = createHashHistory();\r\n\r\n\r\nexport default function configureAppStore (initialState?: any) {\r\n const rootReducer = createRootReducer(history);\r\n\r\n const middlewares = [\r\n routerMiddleware(history),\r\n ...getDefaultMiddleware()\r\n ]\r\n if (process.env.NODE_ENV !== 'production') {\r\n middlewares.unshift(createLogger({ level: 'info', collapsed: true }));\r\n }\r\n\r\n let devtools: boolean | EnhancerOptions = false;\r\n if (process.env.NODE_ENV !== 'production') {\r\n devtools = {\r\n actionCreators: {\r\n ...routerActions\r\n },\r\n trace: true\r\n };\r\n }\r\n\r\n const store = configureStore({\r\n reducer: rootReducer,\r\n middleware: middlewares,\r\n devTools: devtools,\r\n preloadedState: initialState\r\n })\r\n\r\n if (process.env.NODE_ENV !== 'production' && (module as any).hot) {\r\n (module as any).hot.accept('../reducers', () => store.replaceReducer(rootReducer))\r\n }\r\n\r\n return store;\r\n}\r\n","// This optional code is used to register a service worker.\r\n// register() is not called by default.\r\n\r\n// This lets the app load faster on subsequent visits in production, and gives\r\n// it offline capabilities. However, it also means that developers (and users)\r\n// will only see deployed updates on subsequent visits to a page, after all the\r\n// existing tabs open on the page have been closed, since previously cached\r\n// resources are updated in the background.\r\n\r\n// To learn more about the benefits of this model and instructions on how to\r\n// opt-in, read https://bit.ly/CRA-PWA\r\n\r\nconst isLocalhost = Boolean(\r\n window.location.hostname === 'localhost' ||\r\n // [::1] is the IPv6 localhost address.\r\n window.location.hostname === '[::1]' ||\r\n // 127.0.0.1/8 is considered localhost for IPv4.\r\n window.location.hostname.match(\r\n /^127(?:\\.(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3}$/\r\n )\r\n);\r\n\r\ntype Config = {\r\n onSuccess?: (registration: ServiceWorkerRegistration) => void;\r\n onUpdate?: (registration: ServiceWorkerRegistration) => void;\r\n};\r\n\r\nexport function register(config?: Config) {\r\n if (process.env.NODE_ENV === 'production' && 'serviceWorker' in navigator) {\r\n // The URL constructor is available in all browsers that support SW.\r\n const publicUrl = new URL(\r\n (process as { env: { [key: string]: string } }).env.PUBLIC_URL,\r\n window.location.href\r\n );\r\n if (publicUrl.origin !== window.location.origin) {\r\n // Our service worker won't work if PUBLIC_URL is on a different origin\r\n // from what our page is served on. This might happen if a CDN is used to\r\n // serve assets; see https://github.com/facebook/create-react-app/issues/2374\r\n return;\r\n }\r\n\r\n window.addEventListener('load', () => {\r\n const swUrl = `${process.env.PUBLIC_URL}/service-worker.js`;\r\n\r\n if (isLocalhost) {\r\n // This is running on localhost. Let's check if a service worker still exists or not.\r\n checkValidServiceWorker(swUrl, config);\r\n\r\n // Add some additional logging to localhost, pointing developers to the\r\n // service worker/PWA documentation.\r\n navigator.serviceWorker.ready.then(() => {\r\n console.log(\r\n 'This web app is being served cache-first by a service ' +\r\n 'worker. To learn more, visit https://bit.ly/CRA-PWA'\r\n );\r\n });\r\n } else {\r\n // Is not localhost. Just register service worker\r\n registerValidSW(swUrl, config);\r\n }\r\n });\r\n }\r\n}\r\n\r\nfunction registerValidSW(swUrl: string, config?: Config) {\r\n navigator.serviceWorker\r\n .register(swUrl)\r\n .then(registration => {\r\n registration.onupdatefound = () => {\r\n const installingWorker = registration.installing;\r\n if (installingWorker == null) {\r\n return;\r\n }\r\n installingWorker.onstatechange = () => {\r\n if (installingWorker.state === 'installed') {\r\n if (navigator.serviceWorker.controller) {\r\n // At this point, the updated precached content has been fetched,\r\n // but the previous service worker will still serve the older\r\n // content until all client tabs are closed.\r\n console.log(\r\n 'New content is available and will be used when all ' +\r\n 'tabs for this page are closed. See https://bit.ly/CRA-PWA.'\r\n );\r\n\r\n // Execute callback\r\n if (config && config.onUpdate) {\r\n config.onUpdate(registration);\r\n }\r\n } else {\r\n // At this point, everything has been precached.\r\n // It's the perfect time to display a\r\n // \"Content is cached for offline use.\" message.\r\n console.log('Content is cached for offline use.');\r\n\r\n // Execute callback\r\n if (config && config.onSuccess) {\r\n config.onSuccess(registration);\r\n }\r\n }\r\n }\r\n };\r\n };\r\n })\r\n .catch(error => {\r\n console.error('Error during service worker registration:', error);\r\n });\r\n}\r\n\r\nfunction checkValidServiceWorker(swUrl: string, config?: Config) {\r\n // Check if the service worker can be found. If it can't reload the page.\r\n fetch(swUrl)\r\n .then(response => {\r\n // Ensure service worker exists, and that we really are getting a JS file.\r\n const contentType = response.headers.get('content-type');\r\n if (\r\n response.status === 404 ||\r\n (contentType != null && contentType.indexOf('javascript') === -1)\r\n ) {\r\n // No service worker found. Probably a different app. Reload the page.\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister().then(() => {\r\n window.location.reload();\r\n });\r\n });\r\n } else {\r\n // Service worker found. Proceed as normal.\r\n registerValidSW(swUrl, config);\r\n }\r\n })\r\n .catch(() => {\r\n console.log(\r\n 'No internet connection found. App is running in offline mode.'\r\n );\r\n });\r\n}\r\n\r\nexport function unregister() {\r\n if ('serviceWorker' in navigator) {\r\n navigator.serviceWorker.ready.then(registration => {\r\n registration.unregister();\r\n });\r\n }\r\n}\r\n","import React from 'react';\r\nimport ReactDOM from 'react-dom';\r\nimport configureAppStore, { history } from './store/configureAppStore';\r\nimport { saveGUIConfig } from './utils/ConfigProvider';\r\nimport { connectStomp } from './modules/joal-api';\r\nimport * as serviceWorker from './serviceWorker';\r\nimport './index.css';\r\nimport 'typeface-roboto';\r\n\r\nconst attemptToGetUiConfigFromQuerySearchParam = () => {\r\n if (!window.location.search || !window.location.search.includes('ui_credentials')) {\r\n return;\r\n }\r\n const uRLSearchParams = new URLSearchParams(window.location.search); // eslint-disable-line compat/compat\r\n const credentialsUriEncoded = uRLSearchParams.get('ui_credentials');\r\n if (credentialsUriEncoded === null) {\r\n return;\r\n }\r\n\r\n try {\r\n const config = JSON.parse(decodeURIComponent(credentialsUriEncoded));\r\n saveGUIConfig(config);\r\n } catch (e) {\r\n console.error('Failed to extract uiConfig from url params.', e);\r\n } finally {\r\n // Remove url param from uri to make it cleaner in history tab\r\n uRLSearchParams.delete('ui_credentials');\r\n let cleanUri = window.location.pathname;\r\n if (uRLSearchParams.keys().next().done === false) { // if the url search param still contains uri parameters\r\n cleanUri += `?${uRLSearchParams.toString()}`;\r\n }\r\n if (window.location.hash) {\r\n cleanUri += window.location.hash;\r\n }\r\n window.history.replaceState({}, document.title, cleanUri);\r\n }\r\n};\r\n\r\nconst store = configureAppStore();\r\n\r\nattemptToGetUiConfigFromQuerySearchParam();\r\n\r\nconnectStomp(store);\r\n\r\nconst rootEl = document.getElementById('root');\r\n\r\n\r\nlet render = () => {\r\n // Dynamically import our main App component, and render it\r\n const Root = require('./Root').default; // eslint-disable-line global-require\r\n ReactDOM.render(, rootEl);\r\n};\r\n\r\nif ((module as any).hot) {\r\n // Support hot reloading of components\r\n // and display an overlay for runtime errors\r\n const renderApp = render;\r\n\r\n // In development, we wrap the rendering function to catch errors,\r\n // and if something breaks, log the error\r\n render = () => {\r\n renderApp();\r\n };\r\n\r\n // Whenever the App component file or one of its dependencies\r\n // is changed, re-import the updated component and re-render it\r\n (module as any).hot.accept('./Root', () => {\r\n setTimeout(render);\r\n });\r\n}\r\n\r\nrender();\r\n// If you want your app to work offline and load faster, you can change\r\n// unregister() to register() below. Note this comes with some pitfalls.\r\n// Learn more about service workers: http://bit.ly/CRA-PWA\r\nserviceWorker.unregister();\r\n","import { Config } from '../types';\r\n\r\nexport const CONFIG_IS_IN_DIRTY_STATE = '@@api/listener/CONFIG_IS_IN_DIRTY_STATE';\r\nexport const INVALID_CONFIG = '@@api/listener/INVALID_CONFIG';\r\nexport const CONFIG_HAS_BEEN_LOADED = '@@api/listener/CONFIG_HAS_BEEN_LOADED';\r\nexport const LIST_OF_CLIENT_FILES = '@@api/listener/LIST_OF_CLIENT_FILES';\r\n\r\nexport const SEND_CONFIG = '@@api/send/SEND_CONFIG';\r\n\r\nexport const RESET_CONFIG = '@@reset/RESET_CONFIG';\r\n\r\nexport const sendConfig = (config: Config) => ({\r\n type: SEND_CONFIG,\r\n config\r\n});\r\n\r\n\r\nexport const resetConfig = () => (\r\n { type: RESET_CONFIG }\r\n);\r\n","import JoalStompClient from './JoalStompClient';\r\nimport { resetAnnouncerState } from './announcers/announcers.actions';\r\nimport { sendStartToServer, sendStopToServer, resetClientState } from './client/client.actions';\r\nimport { sendConfig, resetConfig } from './settings/settings.actions';\r\nimport { resetStompState } from './stomp/stomp.actions';\r\nimport { resetTorrentFilesState } from './torrentFiles/torrentFile.actions';\r\nimport { resetSpeedState } from './speed/speed.actions';\r\n\r\nimport { Store } from 'redux';\r\nimport { Config } from './types';\r\n\r\nlet store: Store;\r\nlet stompClient: any;\r\n\r\nexport const connectStomp = (appStore: Store) => {\r\n store = appStore;\r\n stompClient = new JoalStompClient(store, () => {\r\n // On disconnect\r\n\r\n store.dispatch(resetStompState());\r\n store.dispatch(resetConfig());\r\n store.dispatch(resetClientState());\r\n store.dispatch(resetAnnouncerState());\r\n store.dispatch(resetTorrentFilesState());\r\n store.dispatch(resetSpeedState());\r\n });\r\n stompClient.connect();\r\n};\r\n\r\nexport const disconnectAndReconnect = () => {\r\n stompClient.disconnectAndReconnect();\r\n};\r\n\r\n\r\nexport const sendStartSession = () => {\r\n store.dispatch(sendStartToServer());\r\n stompClient.send('/joal/global/start');\r\n};\r\n\r\nexport const sendStopSession = () => {\r\n store.dispatch(sendStopToServer());\r\n stompClient.send('/joal/global/stop');\r\n};\r\n\r\nexport const sendConfigToServer = (config: Config) => {\r\n store.dispatch(sendConfig(config));\r\n stompClient.send('/joal/config/save', JSON.stringify(config));\r\n};\r\n\r\nexport const uploadTorrents = (files: Array) => {\r\n const reader = new FileReader();\r\n\r\n // Process files one by one (queue like) to reduce memory consuption when sender a lot of torrent files.\r\n const processOne = () => {\r\n const singleFile = files.pop();\r\n if (singleFile === undefined) {\r\n return;\r\n }\r\n\r\n ((file) => {\r\n reader.onload = () => {\r\n if (reader.result == null) {\r\n return\r\n }\r\n const b64Encoded = (reader.result as string).replace(/data:.+?,/, '');\r\n stompClient.send('/joal/torrents/upload', JSON.stringify({\r\n fileName: file.name,\r\n b64String: b64Encoded\r\n }));\r\n setTimeout(processOne, 1300);\r\n };\r\n reader.onabort = () => console.log(`file reading was aborted for [${file.name}]`);\r\n reader.onerror = () => console.log(`file reading has failed for [${file.name}]`);\r\n\r\n reader.readAsDataURL(file);\r\n })(singleFile);\r\n };\r\n\r\n processOne();\r\n};\r\n\r\nexport const deleteTorrent = (torrentInfoHash: string) => {\r\n stompClient.send('/joal/torrents/delete', torrentInfoHash);\r\n};\r\n","import { Store } from 'redux';\r\nimport Webstomp, { Client as WebStompClient, Subscription, Frame } from 'webstomp-client';\r\nimport { getGUIConfig } from '../../utils/ConfigProvider';\r\nimport {\r\n isConnecting,\r\n hasConnected,\r\n hasDropConnection,\r\n hasFailedToConnect,\r\n initOver,\r\n hasReceivedError\r\n} from './stomp/stomp.actions';\r\n\r\nconst uuidv4 = () => (\r\n ([1e7] as any +-1e3+-4e3+-8e3+-1e11).replace(/[018]/g, (c: number) => (// eslint-disable-line space-infix-ops\r\n (c ^ crypto.getRandomValues(new Uint8Array(1))[0] & 15 >> c / 4).toString(16) // eslint-disable-line implicit-arrow-linebreak, no-bitwise, no-mixed-operators\r\n ))\r\n);\r\n\r\nexport type StompMessage = {\r\n type: string,\r\n payload: {}\r\n};\r\n\r\nexport default class JoalStompClient {\r\n reconnectTimeout?: number\r\n reduxStore: Store\r\n onDisconnectCallback: () => void\r\n subscriptions: Array\r\n stompClient: WebStompClient\r\n\r\n\r\n constructor(reduxStore: Store, onDisconnectCallback: () => void) {\r\n this.reconnectTimeout = undefined;\r\n this.reduxStore = reduxStore;\r\n this.onDisconnectCallback = onDisconnectCallback;\r\n this.subscriptions = [];\r\n this.stompClient = {} as WebStompClient;\r\n }\r\n\r\n send(path: string, body: string = '', headers: {} = {}) {\r\n if (!this.stompClient || !this.stompClient.connected) {\r\n console.error('You can not send message to JOAL when not connected through WebSocket.');\r\n return;\r\n }\r\n this.stompClient.send(\r\n path,\r\n body,\r\n headers\r\n );\r\n }\r\n\r\n connect() {\r\n const guiConf = getGUIConfig();\r\n const urlScheme = (window.location.protocol === 'https:' ? 'wss' : 'ws');\r\n const url = `${urlScheme}://${guiConf.host}:${guiConf.port}/${guiConf.pathPrefix}`;\r\n const { secretToken } = guiConf;\r\n this._dispatchOnConnect(); // eslint-disable-line no-underscore-dangle\r\n this.stompClient = Webstomp.client(url, { debug: false, protocols: ['v12.stomp', 'v11.stomp'] });\r\n\r\n this.stompClient.connect({ 'X-Joal-Auth-Token': secretToken, 'X-Joal-Username': uuidv4() }, (/* response */) => {\r\n this._dispatchHasConnected(); // eslint-disable-line no-underscore-dangle\r\n /* specific mapping that intentionally include the /joal prefix */\r\n this.stompClient.subscribe('/joal/initialize-me', (message) => {\r\n JSON.parse(message.body).forEach((msg: StompMessage) => {\r\n this.onReceiveMessage(msg);\r\n });\r\n // We consider that the app is inited when the replayable events has been played.\r\n this._dispatchIsReady(); // eslint-disable-line no-underscore-dangle\r\n message.ack();\r\n this.stompClient.unsubscribe('/initialize-me');\r\n });\r\n\r\n ['/global', '/announce', '/config', '/torrents', '/speed'].forEach(subscribesPath => {\r\n const subscribtion = this.stompClient.subscribe(subscribesPath, (message) => {\r\n message.ack();\r\n this.onReceiveMessage(JSON.parse(message.body));\r\n }, { ack: 'client' });\r\n this.subscriptions.push(subscribtion);\r\n });\r\n }, (error: CloseEvent | Frame) => {\r\n console.log('error message from websocket', error);\r\n\r\n if (error instanceof CloseEvent) {\r\n // if we had some subscriptions this is a connection drop.\r\n const isConnectionDropped = this.subscriptions.length > 0;\r\n\r\n if (isConnectionDropped) {\r\n this._dispatchHasDropConnection(); // eslint-disable-line no-underscore-dangle\r\n } else {\r\n this._dispatchHasFailedToConnect(); // eslint-disable-line no-underscore-dangle\r\n }\r\n if (this.onDisconnectCallback) this.onDisconnectCallback();\r\n this._reconnectAfterTimeout(8000); // eslint-disable-line no-underscore-dangle\r\n } else {\r\n this.reduxStore.dispatch(hasReceivedError(error.headers['message'] || 'Undefined error'));\r\n }\r\n });\r\n }\r\n\r\n _dispatchIsReady() {\r\n this.reduxStore.dispatch(initOver());\r\n }\r\n\r\n _dispatchOnConnect() {\r\n this.reduxStore.dispatch(isConnecting());\r\n }\r\n\r\n _dispatchHasConnected() {\r\n this.reduxStore.dispatch(hasConnected());\r\n }\r\n\r\n _dispatchHasDropConnection() {\r\n this.reduxStore.dispatch(hasDropConnection());\r\n }\r\n\r\n _dispatchHasFailedToConnect() {\r\n this.reduxStore.dispatch(hasFailedToConnect());\r\n }\r\n\r\n onReceiveMessage(message: StompMessage) {\r\n const { type, payload } = message;\r\n this.reduxStore.dispatch({ type: `@@api/listener/${type}`, payload });\r\n }\r\n\r\n _reconnectAfterTimeout(timeout: number) {\r\n this.subscriptions.forEach(sub => sub.unsubscribe()); // release resources\r\n this.subscriptions = [];\r\n // the reconnectTimeout = undefined will ensure we don't cause memory leak.\r\n if (this.reconnectTimeout === undefined) {\r\n this.reconnectTimeout = window.setTimeout(() => {\r\n this.connect();\r\n this.reconnectTimeout = undefined;\r\n }, timeout);\r\n }\r\n }\r\n\r\n disconnect() {\r\n this.subscriptions.forEach(sub => sub.unsubscribe()); // release resources\r\n this.subscriptions = [];\r\n if (this.stompClient && this.stompClient.connected) {\r\n this.stompClient.disconnect();\r\n }\r\n if (this.onDisconnectCallback) this.onDisconnectCallback();\r\n }\r\n\r\n disconnectAndReconnect() {\r\n clearTimeout(this.reconnectTimeout);\r\n this.reconnectTimeout = undefined;\r\n this.disconnect();\r\n this.connect();\r\n }\r\n}\r\n","export const TORRENT_FILE_ADDED = '@@api/listener/TORRENT_FILE_ADDED';\r\nexport const TORRENT_FILE_DELETED = '@@api/listener/TORRENT_FILE_DELETED';\r\nexport const FAILED_TO_ADD_TORRENT_FILE = '@@api/listener/FAILED_TO_ADD_TORRENT_FILE';\r\n\r\nexport const RESET_TORRENT_FILES_STATE = '@@reset/RESET_TORRENT_FILES_STATE';\r\n\r\n\r\nexport const resetTorrentFilesState = () => (\r\n { type: RESET_TORRENT_FILES_STATE }\r\n);\r\n","export const GLOBAL_SEED_STARTED = '@@api/listener/GLOBAL_SEED_STARTED';\r\nexport const GLOBAL_SEED_STOPPED = '@@api/listener/GLOBAL_SEED_STOPPED';\r\n\r\nexport const SEND_START_TO_SERVER = '@@api/send/SEND_START_TO_SERVER';\r\nexport const SEND_STOP_TO_SERVER = '@@api/send/SEND_STOP_TO_SERVER';\r\n\r\nexport const RESET_CLIENT_STATE = '@@reset/RESET_CLIENT_STATE';\r\n\r\n\r\nexport function sendStartToServer() {\r\n return {\r\n type: SEND_START_TO_SERVER\r\n };\r\n}\r\n\r\nexport function sendStopToServer() {\r\n return {\r\n type: SEND_STOP_TO_SERVER,\r\n };\r\n}\r\n\r\n\r\nexport const resetClientState = () => (\r\n { type: RESET_CLIENT_STATE }\r\n);\r\n","export const FAILED_TO_ANNOUNCE = '@@api/listener/FAILED_TO_ANNOUNCE';\r\nexport const SUCCESSFULLY_ANNOUNCE = '@@api/listener/SUCCESSFULLY_ANNOUNCE';\r\nexport const TOO_MANY_ANNOUNCES_FAILED = '@@api/listener/TOO_MANY_ANNOUNCES_FAILED';\r\nexport const WILL_ANNOUNCE = '@@api/listener/WILL_ANNOUNCE';\r\n\r\nexport const RESET_ANNOUNCER_STATE = '@@reset/RESET_ANNOUNCER_STATE';\r\n\r\nexport const resetAnnouncerState = () => (\r\n { type: RESET_ANNOUNCER_STATE }\r\n);\r\n","import isElectron from 'is-electron';\r\n\r\nimport { GuiConfig } from './types';\r\n\r\ninterface ConfigProvider {\r\n getConfig: () => GuiConfig\r\n saveConfig: (config: GuiConfig) => void\r\n}\r\n\r\nlet selectedConfProvider: ConfigProvider;\r\nif (isElectron()) {\r\n selectedConfProvider = require('./ElectronConfigProvider'); // eslint-disable-line global-require\r\n} else {\r\n selectedConfProvider = require('./WebBrowserConfigProvider'); // eslint-disable-line global-require\r\n}\r\n\r\n\r\nexport const getGUIConfig = () => selectedConfProvider.getConfig();\r\nexport const saveGUIConfig = (config: GuiConfig) => selectedConfProvider.saveConfig(config);\r\n\r\nexport type GuiConfig = GuiConfig;\r\n","\r\nexport const TORRENT_SEARCH_FILTER_TEXT_CHANGED = '@@ui/torrents-table/TORRENT_SEARCH_FILTER_TEXT_CHANGED';\r\nexport const TORRENT_SORT_CHANGED = '@@ui/torrents-table/TORRENT_SORT_CHANGED';\r\n\r\nexport function changeSearchFilterText(text: string) {\r\n return {\r\n type: TORRENT_SEARCH_FILTER_TEXT_CHANGED,\r\n text\r\n };\r\n}\r\n\r\nexport function changeTorrentSort(sortProperty: string, sortDirection: string) {\r\n return {\r\n type: TORRENT_SORT_CHANGED,\r\n sortProperty,\r\n sortDirection\r\n };\r\n}\r\n","import { Config } from '../../modules/joal-api/types';\r\n\r\n\r\nexport const LOCAL_CONFIG_HAS_CHANGED = '@@ui/LOCAL_CONFIG_HAS_CHANGED';\r\nexport const DISCARD_LOCAL_CONFIG = '@@ui/DISCARD_LOCAL_CONFIG';\r\n\r\n\r\nexport const localConfigHasChanged = (config: Config) => {\r\n return {\r\n type: LOCAL_CONFIG_HAS_CHANGED,\r\n config\r\n };\r\n}\r\n\r\n\r\nexport const discardLocalConfigChanges = () => {\r\n return {\r\n type: DISCARD_LOCAL_CONFIG,\r\n };\r\n}\r\n","export const SEEDING_SPEED_HAS_CHANGED = '@@api/listener/SEEDING_SPEED_HAS_CHANGED';\r\n\r\nexport const RESET_SPEED_STATE = '@@reset/RESET_SPEED_STATE';\r\n\r\nexport const resetSpeedState = () => (\r\n { type: RESET_SPEED_STATE }\r\n);\r\n","export const CHANGE_THEME_TYPE = '@@ui/theme/CHANGE_THEME_TYPE';\r\n\r\nexport function changeThemeType() {\r\n return {\r\n type: CHANGE_THEME_TYPE\r\n };\r\n}\r\n","export const REMOVE_NOTIFICATION = '@@notifications/REMOVE_NOTIFICATION';\r\n\r\nexport const removeNotification = (id: string) => ({\r\n type: REMOVE_NOTIFICATION,\r\n payload: id\r\n});\r\n"],"sourceRoot":""} \ No newline at end of file