From 6dec5cddac50ef93bf253e023b1acc386e8f6d51 Mon Sep 17 00:00:00 2001 From: John Furrow Date: Sun, 2 Sep 2018 20:43:35 -0700 Subject: [PATCH] Implements Prettier (#701) * Adds and configures prettier * Creates format script * Runs prettier * Adds npm scripts and checks for formatting in CI --- .prettierrc | 7 + .travis.yml | 1 + client/config/env.js | 4 +- client/config/paths.js | 2 +- client/config/webpack.config.dev.js | 28 +- client/config/webpack.config.prod.js | 20 +- client/config/webpackDevServer.config.js | 3 +- client/scripts/build.js | 21 +- client/scripts/deprecated-warning.js | 27 +- client/scripts/start.js | 12 +- client/src/javascript/actions/AuthActions.js | 224 +++++---- .../src/javascript/actions/ClientActions.js | 130 ++--- client/src/javascript/actions/FloodActions.js | 228 ++++----- .../src/javascript/actions/SettingsActions.js | 254 ++++++---- .../src/javascript/actions/TorrentActions.js | 423 +++++++++------- client/src/javascript/actions/UIActions.js | 28 +- client/src/javascript/app.js | 14 +- .../src/javascript/components/AppWrapper.js | 131 ++--- .../src/javascript/components/alerts/Alert.js | 8 +- .../javascript/components/alerts/Alerts.js | 10 +- .../javascript/components/auth/AuthForm.js | 39 +- .../javascript/components/general/Badge.js | 6 +- .../general/ClientConnectionInterruption.js | 84 ++-- .../components/general/CustomScrollbars.js | 18 +- .../javascript/components/general/Duration.js | 75 ++- .../general/GlobalContextMenuMountPoint.js | 55 +- .../components/general/ListViewport.js | 85 ++-- .../components/general/LoadingIndicator.js | 2 +- .../components/general/NavigationList.js | 21 +- .../javascript/components/general/Portal.js | 11 +- .../components/general/ProgressBar.js | 4 +- .../javascript/components/general/Ratio.js | 4 +- .../RtorrentConnectionTypeSelection.js | 66 ++- .../src/javascript/components/general/Size.js | 17 +- .../components/general/SortableList.js | 21 +- .../components/general/SortableListItem.js | 44 +- .../general/SortableListItemDragLayer.js | 10 +- .../javascript/components/general/Tooltip.js | 84 ++-- .../components/general/WindowTitle.js | 71 ++- .../general/filesystem/DirectoryFileList.js | 57 +-- .../general/filesystem/DirectoryTree.js | 19 +- .../general/filesystem/DirectoryTreeNode.js | 51 +- .../general/filesystem/FilesystemBrowser.js | 84 +--- .../general/filesystem/PriorityMeter.js | 30 +- .../general/filesystem/TorrentDestination.js | 50 +- .../general/form-elements/Dropdown.js | 52 +- .../general/form-elements/TextboxRepeater.js | 15 +- .../src/javascript/components/icons/Active.js | 5 +- client/src/javascript/components/icons/Add.js | 5 +- .../javascript/components/icons/AddMini.js | 5 +- client/src/javascript/components/icons/All.js | 5 +- .../javascript/components/icons/ArrowIcon.js | 3 +- .../javascript/components/icons/BaseIcon.js | 4 +- .../components/icons/CalendarCreatedIcon.js | 3 +- .../components/icons/CalendarIcon.js | 3 +- .../javascript/components/icons/Checkmark.js | 5 +- .../components/icons/ChevronLeftIcon.js | 5 +- .../components/icons/ChevronRightIcon.js | 5 +- .../components/icons/CircleCheckmarkIcon.js | 12 +- .../components/icons/CircleExclamationIcon.js | 12 +- .../javascript/components/icons/CircleIcon.js | 3 +- .../components/icons/ClipboardIcon.js | 13 +- .../javascript/components/icons/ClockIcon.js | 7 +- .../src/javascript/components/icons/Close.js | 5 +- .../components/icons/CommentIcon.js | 3 +- .../javascript/components/icons/Completed.js | 5 +- .../icons/DetailNotAvailableIcon.js | 3 +- .../src/javascript/components/icons/Disk.js | 5 +- .../javascript/components/icons/DiskIcon.js | 27 +- .../javascript/components/icons/DotsMini.js | 9 +- .../javascript/components/icons/Download.js | 7 +- .../components/icons/DownloadSmall.js | 5 +- .../components/icons/DownloadThickIcon.js | 5 +- client/src/javascript/components/icons/ETA.js | 13 +- .../javascript/components/icons/ErrorIcon.js | 5 +- .../javascript/components/icons/FeedIcon.js | 5 +- .../src/javascript/components/icons/File.js | 5 +- .../src/javascript/components/icons/Files.js | 18 +- .../components/icons/FolderClosedOutlined.js | 5 +- .../components/icons/FolderClosedSolid.js | 5 +- .../components/icons/FolderOpenOutlined.js | 5 +- .../components/icons/FolderOpenSolid.js | 5 +- .../javascript/components/icons/HashIcon.js | 3 +- .../javascript/components/icons/Inactive.js | 5 +- .../components/icons/InfinityIcon.js | 3 +- .../components/icons/InformationIcon.js | 15 +- .../src/javascript/components/icons/Limits.js | 29 +- .../components/icons/LoadingIndicatorDots.js | 18 +- .../javascript/components/icons/LockIcon.js | 9 +- .../src/javascript/components/icons/Logout.js | 3 +- .../components/icons/NotificationIcon.js | 5 +- .../javascript/components/icons/PeersIcon.js | 5 +- .../javascript/components/icons/RadarIcon.js | 3 +- .../javascript/components/icons/RadioDot.js | 3 +- .../src/javascript/components/icons/Ratio.js | 5 +- .../javascript/components/icons/RatioIcon.js | 5 +- .../src/javascript/components/icons/Remove.js | 5 +- .../javascript/components/icons/RemoveMini.js | 5 +- .../src/javascript/components/icons/Search.js | 13 +- .../javascript/components/icons/SeedsIcon.js | 5 +- .../components/icons/SettingsIcon.js | 5 +- .../components/icons/SpinnerIcon.js | 15 +- .../javascript/components/icons/StartIcon.js | 5 +- .../javascript/components/icons/StopIcon.js | 5 +- .../components/icons/TrackerMessageIcon.js | 3 +- .../src/javascript/components/icons/Upload.js | 7 +- .../components/icons/UploadThickIcon.js | 5 +- .../components/layout/ApplicationContent.js | 8 +- .../components/layout/ApplicationPanel.js | 12 +- .../components/layout/ApplicationView.js | 10 +- .../src/javascript/components/modals/Modal.js | 40 +- .../components/modals/ModalActions.js | 28 +- .../javascript/components/modals/ModalTabs.js | 13 +- .../javascript/components/modals/Modals.js | 22 +- .../add-torrents-modal/AddTorrentsActions.js | 18 +- .../add-torrents-modal/AddTorrentsByFile.js | 54 +- .../add-torrents-modal/AddTorrentsByURL.js | 31 +- .../add-torrents-modal/AddTorrentsModal.js | 12 +- .../modals/confirm-modal/ConfirmModal.js | 6 +- .../modals/feeds-modal/DownloadRulesTab.js | 267 +++++----- .../modals/feeds-modal/FeedsModal.js | 12 +- .../components/modals/feeds-modal/FeedsTab.js | 166 +++--- .../move-torrents-modal/MoveTorrentsModal.js | 33 +- .../RemoveTorrentsModal.js | 28 +- .../modals/set-tags-modal/SetTagsModal.js | 29 +- .../modals/settings-modal/AuthTab.js | 114 ++--- .../modals/settings-modal/BandwidthTab.js | 69 ++- .../modals/settings-modal/ConnectivityTab.js | 112 ++--- .../modals/settings-modal/ResourcesTab.js | 34 +- .../modals/settings-modal/SettingsModal.js | 92 ++-- .../components/modals/settings-modal/UITab.js | 74 ++- .../UITabSortableDetailColumns.js | 19 +- .../torrent-details-modal/NavigationList.js | 19 +- .../TorrentDetailsModal.js | 58 +-- .../torrent-details-modal/TorrentFiles.js | 135 ++--- .../TorrentGeneralInfo.js | 150 ++---- .../torrent-details-modal/TorrentHeading.js | 52 +- .../torrent-details-modal/TorrentMediainfo.js | 74 +-- .../torrent-details-modal/TorrentPeers.js | 54 +- .../torrent-details-modal/TorrentTrackers.js | 26 +- .../components/sidebar/FeedsButton.js | 8 +- .../components/sidebar/LogoutButton.js | 4 +- .../components/sidebar/NotificationsButton.js | 168 +++---- .../components/sidebar/SearchTorrents.js | 32 +- .../components/sidebar/SettingsButton.js | 8 +- .../javascript/components/sidebar/Sidebar.js | 11 +- .../components/sidebar/SidebarActions.js | 6 +- .../components/sidebar/SidebarFilter.js | 16 +- .../components/sidebar/SidebarItem.js | 12 +- .../components/sidebar/SpeedLimitDropdown.js | 68 +-- .../components/sidebar/StatusFilters.js | 68 ++- .../components/sidebar/TagFilters.js | 37 +- .../components/sidebar/TrackerFilters.js | 34 +- .../components/sidebar/TransferData.js | 83 ++- .../components/sidebar/TransferRateDetails.js | 63 +-- .../components/sidebar/TransferRateGraph.js | 68 ++- .../components/torrent-list/Action.js | 7 +- .../components/torrent-list/ActionBar.js | 46 +- .../components/torrent-list/SortDropdown.js | 25 +- .../components/torrent-list/TableHeading.js | 58 +-- .../components/torrent-list/Torrent.js | 111 ++-- .../components/torrent-list/TorrentDetail.js | 33 +- .../components/torrent-list/TorrentList.js | 414 +++++++-------- .../src/javascript/constants/ActionTypes.js | 2 +- client/src/javascript/constants/Alerts.js | 2 +- client/src/javascript/constants/EventTypes.js | 2 +- client/src/javascript/constants/Languages.js | 10 +- .../javascript/constants/PriorityLevels.js | 6 +- .../javascript/constants/TorrentProperties.js | 44 +- client/src/javascript/i18n/de.js | 2 +- client/src/javascript/i18n/en.js | 9 +- client/src/javascript/i18n/es.js | 8 +- client/src/javascript/i18n/fr.js | 32 +- client/src/javascript/i18n/nl.js | 2 +- client/src/javascript/stores/AlertStore.js | 8 +- client/src/javascript/stores/AuthStore.js | 8 +- .../javascript/stores/ClientStatusStore.js | 4 +- .../src/javascript/stores/FeedMonitorStore.js | 2 +- .../javascript/stores/NotificationStore.js | 4 +- client/src/javascript/stores/SettingsStore.js | 23 +- .../javascript/stores/TorrentFilterStore.js | 22 +- client/src/javascript/stores/TorrentStore.js | 50 +- .../javascript/stores/TransferDataStore.js | 12 +- client/src/javascript/stores/UIStore.js | 23 +- client/src/javascript/util/filterTorrents.js | 6 +- client/src/javascript/util/searchTorrents.js | 2 +- client/src/javascript/util/selectTorrents.js | 5 +- client/src/javascript/util/size.js | 16 +- client/src/javascript/util/sortTorrents.js | 2 +- .../javascript/util/torrentStatusClasses.js | 2 +- .../src/javascript/util/torrentStatusIcons.js | 9 +- package-lock.json | 39 +- package.json | 6 +- scripts/prettier.js | 87 ++++ server/app.js | 6 +- server/bin/enforce-prerequisites.js | 14 +- .../migrations/per-user-rtorrent-instances.js | 47 +- server/bin/migrations/run.js | 4 +- server/bin/start.js | 3 +- server/bin/web-server.js | 18 +- server/config/passport.js | 30 +- .../constants/clientGatewayServiceEvents.js | 6 +- server/constants/fileListPropMap.js | 66 +-- server/constants/historyServiceEvents.js | 16 +- server/constants/notificationServiceEvents.js | 4 +- server/constants/taxonomyServiceEvents.js | 4 +- server/constants/torrentListPropMap.js | 473 +++++++----------- server/constants/torrentServiceEvents.js | 6 +- server/constants/transferSummaryPropMap.js | 66 +-- server/middleware/clientActivityStream.js | 92 ++-- server/middleware/eventStream.js | 6 +- server/models/ClientRequest.js | 91 ++-- server/models/Feed.js | 2 +- server/models/Filesystem.js | 4 +- server/models/HistoryEra.js | 34 +- server/models/TemporaryStorage.js | 6 +- server/models/Users.js | 19 +- server/models/client.js | 113 +++-- server/models/settings.js | 81 ++- server/routes/auth.js | 49 +- server/routes/client.js | 31 +- server/services/BaseService.js | 2 +- server/services/clientGatewayService.js | 156 +++--- server/services/feedService.js | 164 +++--- server/services/historyService.js | 109 ++-- server/services/index.js | 8 +- server/services/notificationService.js | 23 +- server/services/taxonomyService.js | 55 +- server/services/torrentService.js | 160 +++--- server/util/ajaxUtil.js | 6 +- server/util/clientResponseUtil.js | 36 +- server/util/mediainfo.js | 36 +- server/util/methodCallUtil.js | 4 +- server/util/rTorrentPropMap.js | 4 +- server/util/scgiUtil.js | 13 +- shared/constants/clientSettingsMap.js | 4 +- shared/constants/diffActionTypes.js | 6 +- shared/constants/historySnapshotTypes.js | 2 +- shared/constants/serverEventTypes.js | 2 +- shared/constants/torrentFilePropsMap.js | 18 +- shared/constants/torrentPeerPropsMap.js | 6 +- shared/constants/torrentStatusMap.js | 6 +- shared/constants/torrentTrackerPropsMap.js | 18 +- shared/util/formatUtil.js | 18 +- shared/util/objectUtil.js | 14 +- shared/util/regEx.js | 2 +- shared/util/stringUtil.js | 4 +- 247 files changed, 3955 insertions(+), 4981 deletions(-) create mode 100644 .prettierrc create mode 100644 scripts/prettier.js diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 00000000..8ecde8a2 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,7 @@ +{ + "bracketSpacing": false, + "jsxBracketSameLine": true, + "printWidth": 120, + "singleQuote": true, + "trailingComma": "es5" +} diff --git a/.travis.yml b/.travis.yml index 02003f71..b0d248ec 100644 --- a/.travis.yml +++ b/.travis.yml @@ -11,6 +11,7 @@ matrix: before_script: - cp config.template.js config.js script: + - npm run check-source-formatting - npm run lint - npm run test - npm run build diff --git a/client/config/env.js b/client/config/env.js index b8385be4..688325be 100644 --- a/client/config/env.js +++ b/client/config/env.js @@ -46,7 +46,7 @@ function getClientEnvironment() { { NODE_ENV: environment, BASE_URI: environment !== 'development' ? paths.servedPath : '', - POLL_INTERVAL: userConfig.torrentClientPollInterval + POLL_INTERVAL: userConfig.torrentClientPollInterval, } ); // Stringify all values so we can feed into Webpack DefinePlugin @@ -57,7 +57,7 @@ function getClientEnvironment() { }, {}), }; - return { raw, stringified }; + return {raw, stringified}; } module.exports = getClientEnvironment; diff --git a/client/config/paths.js b/client/config/paths.js index 14232ec3..0504c19f 100644 --- a/client/config/paths.js +++ b/client/config/paths.js @@ -29,5 +29,5 @@ module.exports = { clientSrc: resolveApp('client/src'), testsSetup: resolveApp('tests/setupTests.js'), appNodeModules: resolveApp('node_modules'), - servedPath: ensureSlash(userConfig.baseURI || '/', true) + servedPath: ensureSlash(userConfig.baseURI || '/', true), }; diff --git a/client/config/webpack.config.dev.js b/client/config/webpack.config.dev.js index 15c0d009..af889e81 100644 --- a/client/config/webpack.config.dev.js +++ b/client/config/webpack.config.dev.js @@ -63,8 +63,7 @@ module.exports = { // This is the URL that app is served from. We use "/" in development. publicPath: publicPath, // Point sourcemap entries to original disk location (format as URL on Windows) - devtoolModuleFilenameTemplate: info => - path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'), + devtoolModuleFilenameTemplate: info => path.resolve(info.absoluteResourcePath).replace(/\\/g, '/'), }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. @@ -86,7 +85,7 @@ module.exports = { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web', - 'universally-shared-code': path.resolve('./shared') + 'universally-shared-code': path.resolve('./shared'), }, }, module: { @@ -105,7 +104,6 @@ module.exports = { { options: { formatter: eslintFormatter, - }, loader: require.resolve('eslint-loader'), }, @@ -122,17 +120,7 @@ module.exports = { // When you `import` an asset, you get its (virtual) filename. // In production, they would get copied to the `build` folder. { - exclude: [ - /\.html$/, - /\.(js|jsx)$/, - /\.css$/, - /\.scss$/, - /\.json$/, - /\.bmp$/, - /\.gif$/, - /\.jpe?g$/, - /\.png$/, - ], + exclude: [/\.html$/, /\.(js|jsx)$/, /\.css$/, /\.scss$/, /\.json$/, /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: require.resolve('file-loader'), options: { name: 'static/media/[name].[hash:8].[ext]', @@ -177,8 +165,8 @@ module.exports = { importLoaders: 1, }, options: { - sourceMap: true - } + sourceMap: true, + }, }, { loader: require.resolve('postcss-loader'), @@ -198,14 +186,14 @@ module.exports = { flexbox: 'no-2009', }), ], - sourceMap: true + sourceMap: true, }, }, { loader: require.resolve('sass-loader'), options: { - sourceMap: true - } + sourceMap: true, + }, }, ], }, diff --git a/client/config/webpack.config.prod.js b/client/config/webpack.config.prod.js index 29353842..d4a4bf48 100644 --- a/client/config/webpack.config.prod.js +++ b/client/config/webpack.config.prod.js @@ -55,10 +55,7 @@ module.exports = { // We inferred the "public path" (such as / or /my-project) from homepage. publicPath: publicPath, // Point sourcemap entries to original disk location (format as URL on Windows) - devtoolModuleFilenameTemplate: info => - path - .relative(paths.appSrc, info.absoluteResourcePath) - .replace(/\\/g, '/'), + devtoolModuleFilenameTemplate: info => path.relative(paths.appSrc, info.absoluteResourcePath).replace(/\\/g, '/'), }, resolve: { // This allows you to set a fallback for where Webpack should look for modules. @@ -80,7 +77,7 @@ module.exports = { // Support React Native Web // https://www.smashingmagazine.com/2016/08/a-glimpse-into-the-future-with-react-native-for-web/ 'react-native': 'react-native-web', - 'universally-shared-code': path.resolve('./shared') + 'universally-shared-code': path.resolve('./shared'), }, plugins: [ // Prevents users from importing files from outside of src/ (or node_modules/). @@ -107,7 +104,6 @@ module.exports = { { options: { formatter: eslintFormatter, - }, loader: require.resolve('eslint-loader'), }, @@ -123,17 +119,7 @@ module.exports = { // "file" loader makes sure those assets end up in the `build` folder. // When you `import` an asset, you get its filename. { - exclude: [ - /\.html$/, - /\.(js|jsx)$/, - /\.scss$/, - /\.css$/, - /\.json$/, - /\.bmp$/, - /\.gif$/, - /\.jpe?g$/, - /\.png$/, - ], + exclude: [/\.html$/, /\.(js|jsx)$/, /\.scss$/, /\.css$/, /\.json$/, /\.bmp$/, /\.gif$/, /\.jpe?g$/, /\.png$/], loader: require.resolve('file-loader'), options: { name: 'static/media/[name].[hash:8].[ext]', diff --git a/client/config/webpackDevServer.config.js b/client/config/webpackDevServer.config.js index ed47995b..cc629e5d 100644 --- a/client/config/webpackDevServer.config.js +++ b/client/config/webpackDevServer.config.js @@ -25,8 +25,7 @@ module.exports = function(proxy, allowedHost) { // So we will disable the host check normally, but enable it if you have // specified the `proxy` setting. Finally, we let you override it if you // really know what you're doing with a special environment variable. - disableHostCheck: - !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', + disableHostCheck: !proxy || process.env.DANGEROUSLY_DISABLE_HOST_CHECK === 'true', // Enable gzip compression of generated files. compress: true, // Silence WebpackDevServer's own logs since they're generally not useful. diff --git a/client/scripts/build.js b/client/scripts/build.js index 7ae6ac4c..be3618d2 100644 --- a/client/scripts/build.js +++ b/client/scripts/build.js @@ -25,8 +25,7 @@ const formatWebpackMessages = require('react-dev-utils/formatWebpackMessages'); const printHostingInstructions = require('react-dev-utils/printHostingInstructions'); const FileSizeReporter = require('react-dev-utils/FileSizeReporter'); -const measureFileSizesBeforeBuild = - FileSizeReporter.measureFileSizesBeforeBuild; +const measureFileSizesBeforeBuild = FileSizeReporter.measureFileSizesBeforeBuild; const printFileSizesAfterBuild = FileSizeReporter.printFileSizesAfterBuild; // These sizes are pretty large. We'll warn for bundles exceeding them. @@ -51,20 +50,14 @@ measureFileSizesBeforeBuild(paths.appBuild) return build(previousFileSizes); }) .then( - ({ stats, previousFileSizes, warnings }) => { + ({stats, previousFileSizes, warnings}) => { if (warnings.length) { console.log(chalk.yellow('Compiled with warnings.\n')); console.log(warnings.join('\n\n')); console.log( - '\nSearch for the ' + - chalk.underline(chalk.yellow('keywords')) + - ' to learn more about each warning.' - ); - console.log( - 'To ignore, add ' + - chalk.cyan('// eslint-disable-next-line') + - ' to the line before.\n' + '\nSearch for the ' + chalk.underline(chalk.yellow('keywords')) + ' to learn more about each warning.' ); + console.log('To ignore, add ' + chalk.cyan('// eslint-disable-next-line') + ' to the line before.\n'); } else { console.log(chalk.green('Compiled successfully.\n')); } @@ -101,14 +94,12 @@ function build(previousFileSizes) { } if ( process.env.CI && - (typeof process.env.CI !== 'string' || - process.env.CI.toLowerCase() !== 'false') && + (typeof process.env.CI !== 'string' || process.env.CI.toLowerCase() !== 'false') && messages.warnings.length ) { console.log( chalk.yellow( - '\nTreating warnings as errors because process.env.CI = true.\n' + - 'Most CI servers set it automatically.\n' + '\nTreating warnings as errors because process.env.CI = true.\n' + 'Most CI servers set it automatically.\n' ) ); return reject(new Error(messages.warnings.join('\n\n'))); diff --git a/client/scripts/deprecated-warning.js b/client/scripts/deprecated-warning.js index be190b32..87c5bffd 100644 --- a/client/scripts/deprecated-warning.js +++ b/client/scripts/deprecated-warning.js @@ -5,30 +5,27 @@ const chalk = require('chalk'); const messageDefs = [ { chalkStyles: ['black'], - message: 'This npm script has been deprecated!' + message: 'This npm script has been deprecated!', }, { chalkStyles: ['underline', 'black'], - message: `Use npm script \`${process.env.UPDATED_SCRIPT}\` instead.` - } -]; -const longestMessageLength = messageDefs.reduce( - (accumulator, messageDef) => { - if (messageDef.message.length > accumulator) { - accumulator = messageDef.message.length; - } - - return accumulator; + message: `Use npm script \`${process.env.UPDATED_SCRIPT}\` instead.`, }, - 0 -); +]; +const longestMessageLength = messageDefs.reduce((accumulator, messageDef) => { + if (messageDef.message.length > accumulator) { + accumulator = messageDef.message.length; + } + + return accumulator; +}, 0); const paddingLength = 5; const verticalPadding = paddingLength * 2 + longestMessageLength - 1; -const getSpaces = (numSpaces) => Array(numSpaces).join(' '); +const getSpaces = numSpaces => Array(numSpaces).join(' '); console.log('\n'); console.log(chalk.bgRed(getSpaces(verticalPadding))); -messageDefs.forEach((messageDef) => { +messageDefs.forEach(messageDef => { let leftPadding = paddingLength; let rightPadding = paddingLength; const lengthDiff = longestMessageLength - messageDef.message.length; diff --git a/client/scripts/start.js b/client/scripts/start.js index 10aa40d0..4b04d37c 100644 --- a/client/scripts/start.js +++ b/client/scripts/start.js @@ -20,12 +20,7 @@ const webpack = require('webpack'); const WebpackDevServer = require('webpack-dev-server'); const clearConsole = require('react-dev-utils/clearConsole'); const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); -const { - choosePort, - createCompiler, - prepareProxy, - prepareUrls, -} = require('react-dev-utils/WebpackDevServerUtils'); +const {choosePort, createCompiler, prepareProxy, prepareUrls} = require('react-dev-utils/WebpackDevServerUtils'); const openBrowser = require('react-dev-utils/openBrowser'); const paths = require('../config/paths'); const config = require('../config/webpack.config.dev'); @@ -58,10 +53,7 @@ choosePort(HOST, DEFAULT_PORT) // Load proxy config const proxyConfig = prepareProxy(userConfig.floodServerProxy, paths.appPublic); // Serve webpack assets generated by the compiler over a web sever. - const serverConfig = createDevServerConfig( - proxyConfig, - urls.lanUrlForConfig - ); + const serverConfig = createDevServerConfig(proxyConfig, urls.lanUrlForConfig); const devServer = new WebpackDevServer(compiler, serverConfig); // Launch WebpackDevServer. devServer.listen(port, HOST, err => { diff --git a/client/src/javascript/actions/AuthActions.js b/client/src/javascript/actions/AuthActions.js index 61e7c1c7..78bd6998 100644 --- a/client/src/javascript/actions/AuthActions.js +++ b/client/src/javascript/actions/AuthActions.js @@ -7,46 +7,54 @@ import ConfigStore from '../stores/ConfigStore'; const baseURI = ConfigStore.getBaseURI(); let AuthActions = { - authenticate: (credentials) => { - return axios.post(`${baseURI}auth/authenticate`, credentials) + authenticate: credentials => { + return axios + .post(`${baseURI}auth/authenticate`, credentials) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_LOGIN_SUCCESS, - data - }); - }, (error) => { - let errorMessage; + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_LOGIN_SUCCESS, + data, + }); + }, + error => { + let errorMessage; - if (error.response) { - errorMessage = error.response.data.message; - } else if (error.message) { - errorMessage = error.message; - } else { - errorMessage = 'An unknown error occurred.'; + if (error.response) { + errorMessage = error.response.data.message; + } else if (error.message) { + errorMessage = error.message; + } else { + errorMessage = 'An unknown error occurred.'; + } + + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_LOGIN_ERROR, + error: errorMessage, + }); } - - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_LOGIN_ERROR, - error: errorMessage - }); - }); + ); }, - createUser: (credentials) => { - return axios.put(`${baseURI}auth/users`, credentials) + createUser: credentials => { + return axios + .put(`${baseURI}auth/users`, credentials) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_CREATE_USER_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_CREATE_USER_ERROR, - error: error.response.data.message - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_CREATE_USER_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_CREATE_USER_ERROR, + error: error.response.data.message, + }); + } + ); }, updateUser: (username, connectionSettings) => { @@ -59,93 +67,113 @@ let AuthActions = { requestPayload.host = connectionSettings.rtorrentHost; } - return axios.patch(`${baseURI}auth/users/${encodeURIComponent(username)}`, requestPayload).then((json = {}) => json.data); + return axios + .patch(`${baseURI}auth/users/${encodeURIComponent(username)}`, requestPayload) + .then((json = {}) => json.data); }, - deleteUser: (username) => { - return axios.delete(`${baseURI}auth/users/${encodeURIComponent(username)}`) + deleteUser: username => { + return axios + .delete(`${baseURI}auth/users/${encodeURIComponent(username)}`) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_DELETE_USER_SUCCESS, - data: { - username, - ...data - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_DELETE_USER_ERROR, - error: { - username, - ...error - } - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_DELETE_USER_SUCCESS, + data: { + username, + ...data, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_DELETE_USER_ERROR, + error: { + username, + ...error, + }, + }); + } + ); }, fetchUsers: () => { - return axios.get(`${baseURI}auth/users`) + return axios + .get(`${baseURI}auth/users`) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_LIST_USERS_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_LIST_USERS_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_LIST_USERS_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_LIST_USERS_ERROR, + error, + }); + } + ); }, logout: () => { - return axios.get(`${baseURI}auth/logout`) - .then(() => { + return axios.get(`${baseURI}auth/logout`).then( + () => { AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_LOGOUT_SUCCESS + type: ActionTypes.AUTH_LOGOUT_SUCCESS, }); - }, (error) => { + }, + error => { AppDispatcher.dispatchServerAction({ type: ActionTypes.AUTH_LOGOUT_ERROR, - error + error, }); - }); + } + ); }, - register: (credentials) => { - return axios.post(`${baseURI}auth/register`, credentials) + register: credentials => { + return axios + .post(`${baseURI}auth/register`, credentials) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_REGISTER_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_REGISTER_ERROR, - error: error.response.data.message - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_REGISTER_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_REGISTER_ERROR, + error: error.response.data.message, + }); + } + ); }, verify: () => { // We need to prevent caching this endpoint. - return axios.get(`${baseURI}auth/verify?${Date.now()}`) + return axios + .get(`${baseURI}auth/verify?${Date.now()}`) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_VERIFY_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.AUTH_VERIFY_ERROR, - error - }); - }); - } + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_VERIFY_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.AUTH_VERIFY_ERROR, + error, + }); + } + ); + }, }; export default AuthActions; diff --git a/client/src/javascript/actions/ClientActions.js b/client/src/javascript/actions/ClientActions.js index ea75b21c..1bbaf9c0 100644 --- a/client/src/javascript/actions/ClientActions.js +++ b/client/src/javascript/actions/ClientActions.js @@ -7,86 +7,102 @@ import ConfigStore from '../stores/ConfigStore'; const baseURI = ConfigStore.getBaseURI(); let ClientActions = { - fetchSettings: (property) => { - return axios.get(`${baseURI}api/client/settings`, {params: {property}}) + fetchSettings: property => { + return axios + .get(`${baseURI}api/client/settings`, {params: {property}}) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SETTINGS_FETCH_REQUEST_ERROR, + error, + }); + } + ); }, saveSettings: (settings, options) => { - return axios.patch(`${baseURI}api/client/settings`, settings) + return axios + .patch(`${baseURI}api/client/settings`, settings) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SETTINGS_SAVE_SUCCESS, - data, - options - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SETTINGS_SAVE_ERROR, - error, - options - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SETTINGS_SAVE_SUCCESS, + data, + options, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SETTINGS_SAVE_ERROR, + error, + options, + }); + } + ); }, setThrottle: (direction, throttle) => { - return axios.put(`${baseURI}api/client/settings/speed-limits`, { + return axios + .put(`${baseURI}api/client/settings/speed-limits`, { direction, - throttle + throttle, }) .then((json = {}) => json.data) - .then((transferData) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_THROTTLE_SUCCESS, - data: { - transferData - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_THROTTLE_ERROR, - data: { - error - } - }); - }); + .then( + transferData => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_THROTTLE_SUCCESS, + data: { + transferData, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_THROTTLE_ERROR, + data: { + error, + }, + }); + } + ); }, - testClientConnectionSettings: (connectionSettings) => { + testClientConnectionSettings: connectionSettings => { const requestPayload = { host: connectionSettings.rtorrentHost, port: connectionSettings.rtorrentPort, - socketPath: connectionSettings.rtorrentSocketPath + socketPath: connectionSettings.rtorrentSocketPath, }; return axios.post(`${baseURI}api/client/connection-test`, requestPayload).then((json = {}) => json.data); }, testConnection: () => { - return axios.get(`${baseURI}api/client/connection-test`) + return axios + .get(`${baseURI}api/client/connection-test`) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_CONNECTION_TEST_SUCCESS - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_CONNECTION_TEST_ERROR - }); - }); - } + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_CONNECTION_TEST_SUCCESS, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_CONNECTION_TEST_ERROR, + }); + } + ); + }, }; export default ClientActions; diff --git a/client/src/javascript/actions/FloodActions.js b/client/src/javascript/actions/FloodActions.js index ffe646bd..b3908a80 100644 --- a/client/src/javascript/actions/FloodActions.js +++ b/client/src/javascript/actions/FloodActions.js @@ -19,10 +19,7 @@ const handleProlongedInactivity = () => { const handleWindowVisibilityChange = () => { if (global.document.hidden) { // After 30 seconds of inactivity, we stop the event stream. - visibilityChangeTimeout = global.setTimeout( - handleProlongedInactivity, - 1000 * 30 - ); + visibilityChangeTimeout = global.setTimeout(handleProlongedInactivity, 1000 * 30); } else { global.clearTimeout(visibilityChangeTimeout); @@ -32,31 +29,32 @@ const handleWindowVisibilityChange = () => { } }; -global.document.addEventListener( - 'visibilitychange', - handleWindowVisibilityChange -); +global.document.addEventListener('visibilitychange', handleWindowVisibilityChange); const FloodActions = { - clearNotifications: (options) => { - return axios.delete(`${baseURI}api/notifications`) + clearNotifications: options => { + return axios + .delete(`${baseURI}api/notifications`) .then((json = {}) => json.data) - .then((response = {}) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_CLEAR_NOTIFICATIONS_SUCCESS, - data: { - ...response, - ...options - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_CLEAR_NOTIFICATIONS_ERROR, - data: { - error - } - }); - }); + .then( + (response = {}) => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_CLEAR_NOTIFICATIONS_SUCCESS, + data: { + ...response, + ...options, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_CLEAR_NOTIFICATIONS_ERROR, + data: { + error, + }, + }); + } + ); }, closeActivityStream() { @@ -72,15 +70,9 @@ const FloodActions = { this.handleNotificationCountChange ); - activityStreamEventSource.removeEventListener( - serverEventTypes.TAXONOMY_DIFF_CHANGE, - this.handleTaxonomyDiffChange - ); + activityStreamEventSource.removeEventListener(serverEventTypes.TAXONOMY_DIFF_CHANGE, this.handleTaxonomyDiffChange); - activityStreamEventSource.removeEventListener( - serverEventTypes.TAXONOMY_FULL_UPDATE, - this.handleTaxonomyFullUpdate - ); + activityStreamEventSource.removeEventListener(serverEventTypes.TAXONOMY_FULL_UPDATE, this.handleTaxonomyFullUpdate); activityStreamEventSource.removeEventListener( serverEventTypes.TORRENT_LIST_DIFF_CHANGE, @@ -111,137 +103,149 @@ const FloodActions = { }, fetchDirectoryList: (options = {}) => { - return axios.get(`${baseURI}api/directory-list`, { - params: options + return axios + .get(`${baseURI}api/directory-list`, { + params: options, }) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, - data: { - ...options, - ...response - } - }); - }, (error = {}) => { - const {response: errorData} = error; + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, + data: { + ...options, + ...response, + }, + }); + }, + (error = {}) => { + const {response: errorData} = error; - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, - error: errorData - }); - }); - }, - - fetchMediainfo: (options) => { - return axios.get(`${baseURI}api/mediainfo`, { - params: { - hash: options.hash + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, + error: errorData, + }); } - }) - .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, - data: { - ...response, - ...options - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_MEDIAINFO_ERROR, - error - }); - }); + ); }, - fetchNotifications: (options) => { - return axios.get(`${baseURI}api/notifications`, { + fetchMediainfo: options => { + return axios + .get(`${baseURI}api/mediainfo`, { + params: { + hash: options.hash, + }, + }) + .then((json = {}) => json.data) + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, + data: { + ...response, + ...options, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_MEDIAINFO_ERROR, + error, + }); + } + ); + }, + + fetchNotifications: options => { + return axios + .get(`${baseURI}api/notifications`, { params: { limit: options.limit, - start: options.start - } + start: options.start, + }, }) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_NOTIFICATIONS_SUCCESS, - data: { - ...response, - ...options - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.FLOOD_FETCH_NOTIFICATIONS_ERROR, - data: { - error - } - }); - }); + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_NOTIFICATIONS_SUCCESS, + data: { + ...response, + ...options, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.FLOOD_FETCH_NOTIFICATIONS_ERROR, + data: { + error, + }, + }); + } + ); }, handleClientConnectivityStatusChange(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.CLIENT_CONNECTIVITY_STATUS_CHANGE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleNotificationCountChange(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.NOTIFICATION_COUNT_CHANGE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTorrentListDiffChange(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TORRENT_LIST_DIFF_CHANGE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTorrentListFullUpdate(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TORRENT_LIST_FULL_UPDATE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTaxonomyDiffChange(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TAXONOMY_DIFF_CHANGE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTaxonomyFullUpdate(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TAXONOMY_FULL_UPDATE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTransferSummaryDiffChange(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TRANSFER_SUMMARY_DIFF_CHANGE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTransferSummaryFullUpdate(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TRANSFER_SUMMARY_FULL_UPDATE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, handleTransferHistoryFullUpdate(event) { AppDispatcher.dispatchServerAction({ type: ActionTypes.TRANSFER_HISTORY_FULL_UPDATE, - data: JSON.parse(event.data) + data: JSON.parse(event.data), }); }, @@ -252,10 +256,8 @@ const FloodActions = { startActivityStream(options = {}) { const {historySnapshot = historySnapshotTypes.FIVE_MINUTE} = options; - const didHistorySnapshotChange = ( - lastActivityStreamOptions - && lastActivityStreamOptions.historySnapshot !== historySnapshot - ); + const didHistorySnapshotChange = + lastActivityStreamOptions && lastActivityStreamOptions.historySnapshot !== historySnapshot; lastActivityStreamOptions = options; @@ -268,9 +270,7 @@ const FloodActions = { // If the user requested a new history snapshot, or the event source has not // alraedy been created, we open the event stream. if (didHistorySnapshotChange || activityStreamEventSource === null) { - activityStreamEventSource = new EventSource( - `${baseURI}api/activity-stream?historySnapshot=${historySnapshot}` - ); + activityStreamEventSource = new EventSource(`${baseURI}api/activity-stream?historySnapshot=${historySnapshot}`); activityStreamEventSource.addEventListener( serverEventTypes.CLIENT_CONNECTIVITY_STATUS_CHANGE, @@ -282,15 +282,9 @@ const FloodActions = { this.handleNotificationCountChange ); - activityStreamEventSource.addEventListener( - serverEventTypes.TAXONOMY_DIFF_CHANGE, - this.handleTaxonomyDiffChange - ); + activityStreamEventSource.addEventListener(serverEventTypes.TAXONOMY_DIFF_CHANGE, this.handleTaxonomyDiffChange); - activityStreamEventSource.addEventListener( - serverEventTypes.TAXONOMY_FULL_UPDATE, - this.handleTaxonomyFullUpdate - ); + activityStreamEventSource.addEventListener(serverEventTypes.TAXONOMY_FULL_UPDATE, this.handleTaxonomyFullUpdate); activityStreamEventSource.addEventListener( serverEventTypes.TORRENT_LIST_DIFF_CHANGE, diff --git a/client/src/javascript/actions/SettingsActions.js b/client/src/javascript/actions/SettingsActions.js index b2e744ad..b353a989 100644 --- a/client/src/javascript/actions/SettingsActions.js +++ b/client/src/javascript/actions/SettingsActions.js @@ -7,140 +7,172 @@ import ConfigStore from '../stores/ConfigStore'; const baseURI = ConfigStore.getBaseURI(); let SettingsActions = { - addFeed: (feed) => { - return axios.put(`${baseURI}api/feed-monitor/feeds`, feed) + addFeed: feed => { + return axios + .put(`${baseURI}api/feed-monitor/feeds`, feed) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_FEED_ADD_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_FEED_ADD_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_FEED_ADD_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_FEED_ADD_ERROR, + error, + }); + } + ); }, - addRule: (rule) => { - return axios.put(`${baseURI}api/feed-monitor/rules`, rule) + addRule: rule => { + return axios + .put(`${baseURI}api/feed-monitor/rules`, rule) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_RULE_ADD_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_RULE_ADD_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_RULE_ADD_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_RULE_ADD_ERROR, + error, + }); + } + ); }, - fetchFeedMonitors: (query) => { - return axios.get(`${baseURI}api/feed-monitor`, query) + fetchFeedMonitors: query => { + return axios + .get(`${baseURI}api/feed-monitor`, query) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITORS_FETCH_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITORS_FETCH_ERROR, + error, + }); + } + ); }, - fetchFeeds: (query) => { - return axios.get(`${baseURI}api/feed-monitor/feeds`, query) + fetchFeeds: query => { + return axios + .get(`${baseURI}api/feed-monitor/feeds`, query) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_FEEDS_FETCH_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_FEEDS_FETCH_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_FEEDS_FETCH_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_FEEDS_FETCH_ERROR, + error, + }); + } + ); }, - fetchRules: (query) => { - return axios.get(`${baseURI}api/feed-monitor/rules`, query) + fetchRules: query => { + return axios + .get(`${baseURI}api/feed-monitor/rules`, query) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_RULES_FETCH_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_RULES_FETCH_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_RULES_FETCH_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_RULES_FETCH_ERROR, + error, + }); + } + ); }, - fetchSettings: (property) => { - return axios.get(`${baseURI}api/settings`, {params: {property}}) + fetchSettings: property => { + return axios + .get(`${baseURI}api/settings`, {params: {property}}) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FETCH_REQUEST_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FETCH_REQUEST_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FETCH_REQUEST_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FETCH_REQUEST_ERROR, + error, + }); + } + ); }, - removeFeedMonitor: (id) => { - return axios.delete(`${baseURI}api/feed-monitor/${id}`) + removeFeedMonitor: id => { + return axios + .delete(`${baseURI}api/feed-monitor/${id}`) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_REMOVE_SUCCESS, - data: { - ...data, - id - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_FEED_MONITOR_REMOVE_ERROR, - error: { - ...error, - id - } - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_REMOVE_SUCCESS, + data: { + ...data, + id, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_FEED_MONITOR_REMOVE_ERROR, + error: { + ...error, + id, + }, + }); + } + ); }, saveSettings: (settings, options = {}) => { - return axios.patch(`${baseURI}api/settings`, settings) + return axios + .patch(`${baseURI}api/settings`, settings) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_SAVE_REQUEST_SUCCESS, - data, - options - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.SETTINGS_SAVE_REQUEST_ERROR, - error - }); - }); - } + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_SAVE_REQUEST_SUCCESS, + data, + options, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.SETTINGS_SAVE_REQUEST_ERROR, + error, + }); + } + ); + }, }; export default SettingsActions; diff --git a/client/src/javascript/actions/TorrentActions.js b/client/src/javascript/actions/TorrentActions.js index 04b7c37c..66462d9d 100644 --- a/client/src/javascript/actions/TorrentActions.js +++ b/client/src/javascript/actions/TorrentActions.js @@ -7,246 +7,289 @@ import ConfigStore from '../stores/ConfigStore'; const baseURI = ConfigStore.getBaseURI(); let TorrentActions = { - addTorrentsByUrls: (options) => { - return axios.post(`${baseURI}api/client/add`, options) + addTorrentsByUrls: options => { + return axios + .post(`${baseURI}api/client/add`, options) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_ADD_TORRENT_SUCCESS, - data: { - count: options.urls.length, - destination: options.destination, - response - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_ADD_TORRENT_ERROR, - data: { - error - } - }); - }); + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_ADD_TORRENT_SUCCESS, + data: { + count: options.urls.length, + destination: options.destination, + response, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_ADD_TORRENT_ERROR, + data: { + error, + }, + }); + } + ); }, addTorrentsByFiles: (formData, destination) => { - return axios.post(`${baseURI}api/client/add-files`, formData) + return axios + .post(`${baseURI}api/client/add-files`, formData) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_ADD_TORRENT_SUCCESS, - data: { - count: formData.getAll('torrents').length, - destination, - response - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_ADD_TORRENT_ERROR, - data: { - error - } - }); - }); + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_ADD_TORRENT_SUCCESS, + data: { + count: formData.getAll('torrents').length, + destination, + response, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_ADD_TORRENT_ERROR, + data: { + error, + }, + }); + } + ); }, deleteTorrents: (hash, deleteData) => { - return axios.post(`${baseURI}api/client/torrents/delete`, {hash, deleteData}) + return axios + .post(`${baseURI}api/client/torrents/delete`, {hash, deleteData}) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_REMOVE_TORRENT_SUCCESS, - data: { - data, - count: hash.length, - deleteData - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_REMOVE_TORRENT_ERROR, - error: { - error, - count: hash.length - } - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_REMOVE_TORRENT_SUCCESS, + data: { + data, + count: hash.length, + deleteData, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_REMOVE_TORRENT_ERROR, + error: { + error, + count: hash.length, + }, + }); + } + ); }, - checkHash: (hash) => { - return axios.post(`${baseURI}api/client/torrents/check-hash`, {hash}) + checkHash: hash => { + return axios + .post(`${baseURI}api/client/torrents/check-hash`, {hash}) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_CHECK_HASH_SUCCESS, - data: { - data, - count: hash.length - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_CHECK_HASH_ERROR, - error: { - error, - count: hash.length - } - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_CHECK_HASH_SUCCESS, + data: { + data, + count: hash.length, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_CHECK_HASH_ERROR, + error: { + error, + count: hash.length, + }, + }); + } + ); }, - fetchTorrentDetails: (hash) => { - return axios.post(`${baseURI}api/client/torrent-details`, { - hash + fetchTorrentDetails: hash => { + return axios + .post(`${baseURI}api/client/torrent-details`, { + hash, }) .then((json = {}) => json.data) - .then((torrentDetails) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_FETCH_TORRENT_DETAILS_SUCCESS, - data: { - hash, - torrentDetails - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_FETCH_TORRENT_DETAILS_ERROR, - data: { - hash - } - }); - }); + .then( + torrentDetails => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_FETCH_TORRENT_DETAILS_SUCCESS, + data: { + hash, + torrentDetails, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_FETCH_TORRENT_DETAILS_ERROR, + data: { + hash, + }, + }); + } + ); }, moveTorrents: (hashes, options) => { let {destination, isBasePath, filenames, sources, moveFiles} = options; - return axios.post(`${baseURI}api/client/torrents/move`, - {hashes, destination, isBasePath, filenames, sources, moveFiles}) + return axios + .post(`${baseURI}api/client/torrents/move`, {hashes, destination, isBasePath, filenames, sources, moveFiles}) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_MOVE_TORRENTS_SUCCESS, - data: { - data, - count: hashes.length - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_MOVE_TORRENTS_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_MOVE_TORRENTS_SUCCESS, + data: { + data, + count: hashes.length, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_MOVE_TORRENTS_ERROR, + error, + }); + } + ); }, - startTorrents: (hashes) => { - return axios.post(`${baseURI}api/client/start`, { - hashes + startTorrents: hashes => { + return axios + .post(`${baseURI}api/client/start`, { + hashes, }) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_START_TORRENT_SUCCESS, - data: { - response - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_START_TORRENT_ERROR, - data: { - error - } - }); - }); + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_START_TORRENT_SUCCESS, + data: { + response, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_START_TORRENT_ERROR, + data: { + error, + }, + }); + } + ); }, - stopTorrents: (hashes) => { - return axios.post(`${baseURI}api/client/stop`, { - hashes + stopTorrents: hashes => { + return axios + .post(`${baseURI}api/client/stop`, { + hashes, }) .then((json = {}) => json.data) - .then((response) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_STOP_TORRENT_SUCCESS, - data: { - response - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_STOP_TORRENT_ERROR, - data: { - error - } - }); - }); + .then( + response => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_STOP_TORRENT_SUCCESS, + data: { + response, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_STOP_TORRENT_ERROR, + data: { + error, + }, + }); + } + ); }, setPriority: (hash, priority) => { - return axios.patch(`${baseURI}api/client/torrents/${hash}/priority`, { + return axios + .patch(`${baseURI}api/client/torrents/${hash}/priority`, { hash, - priority + priority, }) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_TORRENT_PRIORITY_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_TORRENT_PRIORITY_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_TORRENT_PRIORITY_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_TORRENT_PRIORITY_ERROR, + error, + }); + } + ); }, setFilePriority: (hash, fileIndices, priority) => { - return axios.patch(`${baseURI}api/client/torrents/${hash}/file-priority`, { + return axios + .patch(`${baseURI}api/client/torrents/${hash}/file-priority`, { hash, fileIndices, - priority + priority, }) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_FILE_PRIORITY_SUCCESS, - data: { - ...data, - hash, - fileIndices, - priority - } - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_FILE_PRIORITY_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_FILE_PRIORITY_SUCCESS, + data: { + ...data, + hash, + fileIndices, + priority, + }, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_FILE_PRIORITY_ERROR, + error, + }); + } + ); }, setTaxonomy: (hashes, tags, options = {}) => { - return axios.patch(`${baseURI}api/client/torrents/taxonomy`, { + return axios + .patch(`${baseURI}api/client/torrents/taxonomy`, { hashes, tags, - options + options, }) .then((json = {}) => json.data) - .then((data) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_TAXONOMY_SUCCESS, - data - }); - }, (error) => { - AppDispatcher.dispatchServerAction({ - type: ActionTypes.CLIENT_SET_TAXONOMY_ERROR, - error - }); - }); + .then( + data => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_TAXONOMY_SUCCESS, + data, + }); + }, + error => { + AppDispatcher.dispatchServerAction({ + type: ActionTypes.CLIENT_SET_TAXONOMY_ERROR, + error, + }); + } + ); }, }; diff --git a/client/src/javascript/actions/UIActions.js b/client/src/javascript/actions/UIActions.js index 3975d216..e8915303 100644 --- a/client/src/javascript/actions/UIActions.js +++ b/client/src/javascript/actions/UIActions.js @@ -7,70 +7,70 @@ let UIActions = { displayContextMenu: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_DISPLAY_CONTEXT_MENU, - data + data, }); }, displayDropdownMenu: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_DISPLAY_DROPDOWN_MENU, - data + data, }); }, displayModal: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_DISPLAY_MODAL, - data + data, }); }, - dismissContextMenu: (contextMenuID) => { + dismissContextMenu: contextMenuID => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_DISMISS_CONTEXT_MENU, - data: contextMenuID + data: contextMenuID, }); }, dismissModal: () => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_DISPLAY_MODAL, - data: null + data: null, }); }, handleDetailsClick: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_CLICK_TORRENT_DETAILS, - data + data, }); }, handleTorrentClick: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_CLICK_TORRENT, - data + data, }); }, setTorrentStatusFilter: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_SET_TORRENT_STATUS_FILTER, - data + data, }); }, setTorrentTagFilter: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_SET_TORRENT_TAG_FILTER, - data + data, }); }, setTorrentTrackerFilter: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_SET_TORRENT_TRACKER_FILTER, - data + data, }); }, @@ -78,7 +78,7 @@ let UIActions = { data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_SET_TORRENT_SEARCH_FILTER, - data + data, }); }, 250, @@ -88,9 +88,9 @@ let UIActions = { setTorrentsSort: data => { AppDispatcher.dispatchUIAction({ type: ActionTypes.UI_SET_TORRENT_SORT, - data + data, }); - } + }, }; export default UIActions; diff --git a/client/src/javascript/app.js b/client/src/javascript/app.js index f5f65176..b137e813 100644 --- a/client/src/javascript/app.js +++ b/client/src/javascript/app.js @@ -32,10 +32,10 @@ class FloodApp extends React.Component { super(); this.state = { - locale: SettingsStore.getFloodSettings('language') + locale: SettingsStore.getFloodSettings('language'), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -43,20 +43,14 @@ class FloodApp extends React.Component { } componentDidMount() { - SettingsStore.listen( - EventTypes.SETTINGS_CHANGE, - this.handleSettingsChange - ); + SettingsStore.listen(EventTypes.SETTINGS_CHANGE, this.handleSettingsChange); SettingsStore.fetchClientSettings(); SettingsStore.fetchFloodSettings(); } componentWillUnmount() { - SettingsStore.unlisten( - EventTypes.SETTINGS_CHANGE, - this.handleSettingsChange - ); + SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, this.handleSettingsChange); } handleSettingsChange() { diff --git a/client/src/javascript/components/AppWrapper.js b/client/src/javascript/components/AppWrapper.js index dd071c2b..b13a12a3 100644 --- a/client/src/javascript/components/AppWrapper.js +++ b/client/src/javascript/components/AppWrapper.js @@ -16,7 +16,7 @@ import UIStore from '../stores/UIStore'; import WindowTitle from './general/WindowTitle'; const ICONS = { - satisfied: + satisfied: , }; const METHODS_TO_BIND = [ @@ -26,12 +26,12 @@ const METHODS_TO_BIND = [ 'handleLoginSuccess', 'handleRegisterSuccess', 'handleUIDependenciesChange', - 'handleUIDependenciesLoaded' + 'handleUIDependenciesLoaded', ]; class AuthEnforcer extends React.Component { static propTypes = { - children: PropTypes.node + children: PropTypes.node, }; constructor() { @@ -42,98 +42,49 @@ class AuthEnforcer extends React.Component { dependencies: { authentication: { message: ( - + ), - satisfied: false - } + satisfied: false, + }, }, isAuthenticated: false, isClientConnected: false, - dependenciesLoaded: false + dependenciesLoaded: false, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - AuthStore.listen( - EventTypes.AUTH_REGISTER_SUCCESS, - this.handleRegisterSuccess - ); - AuthStore.listen( - EventTypes.AUTH_LOGIN_ERROR, - this.handleLoginError - ); - AuthStore.listen( - EventTypes.AUTH_LOGIN_SUCCESS, - this.handleLoginSuccess - ); - AuthStore.listen( - EventTypes.AUTH_VERIFY_ERROR, - this.handleVerifyError - ); - AuthStore.listen( - EventTypes.AUTH_VERIFY_SUCCESS, - this.handleVerifySuccess - ); - ClientStatusStore.listen( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); - UIStore.listen( - EventTypes.UI_DEPENDENCIES_LOADED, - this.handleUIDependenciesLoaded - ); - UIStore.listen( - EventTypes.UI_DEPENDENCIES_CHANGE, - this.handleUIDependenciesChange - ); + AuthStore.listen(EventTypes.AUTH_REGISTER_SUCCESS, this.handleRegisterSuccess); + AuthStore.listen(EventTypes.AUTH_LOGIN_ERROR, this.handleLoginError); + AuthStore.listen(EventTypes.AUTH_LOGIN_SUCCESS, this.handleLoginSuccess); + AuthStore.listen(EventTypes.AUTH_VERIFY_ERROR, this.handleVerifyError); + AuthStore.listen(EventTypes.AUTH_VERIFY_SUCCESS, this.handleVerifySuccess); + ClientStatusStore.listen(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); + UIStore.listen(EventTypes.UI_DEPENDENCIES_LOADED, this.handleUIDependenciesLoaded); + UIStore.listen(EventTypes.UI_DEPENDENCIES_CHANGE, this.handleUIDependenciesChange); AuthStore.verify(); } componentWillUnmount() { - AuthStore.unlisten( - EventTypes.AUTH_REGISTER_SUCCESS, - this.handleRegisterSuccess - ); - AuthStore.unlisten( - EventTypes.AUTH_LOGIN_ERROR, - this.handleLoginError - ); - AuthStore.unlisten( - EventTypes.AUTH_LOGIN_SUCCESS, - this.handleLoginSuccess - ); - AuthStore.unlisten( - EventTypes.AUTH_VERIFY_ERROR, - this.handleVerifyError - ); - AuthStore.unlisten( - EventTypes.AUTH_VERIFY_SUCCESS, - this.handleVerifySuccess - ); - ClientStatusStore.unlisten( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); - UIStore.unlisten( - EventTypes.UI_DEPENDENCIES_LOADED, - this.handleUIDependenciesLoaded - ); - UIStore.unlisten( - EventTypes.UI_DEPENDENCIES_CHANGE, - this.handleUIDependenciesChange - ); + AuthStore.unlisten(EventTypes.AUTH_REGISTER_SUCCESS, this.handleRegisterSuccess); + AuthStore.unlisten(EventTypes.AUTH_LOGIN_ERROR, this.handleLoginError); + AuthStore.unlisten(EventTypes.AUTH_LOGIN_SUCCESS, this.handleLoginSuccess); + AuthStore.unlisten(EventTypes.AUTH_VERIFY_ERROR, this.handleVerifyError); + AuthStore.unlisten(EventTypes.AUTH_VERIFY_SUCCESS, this.handleVerifySuccess); + ClientStatusStore.unlisten(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); + UIStore.unlisten(EventTypes.UI_DEPENDENCIES_LOADED, this.handleUIDependenciesLoaded); + UIStore.unlisten(EventTypes.UI_DEPENDENCIES_CHANGE, this.handleUIDependenciesChange); } handleClientStatusChange = () => { this.setState({ - isClientConnected: ClientStatusStore.getIsConnected() + isClientConnected: ClientStatusStore.getIsConnected(), }); - } + }; handleVerifySuccess(data) { if (data.initialUser) { @@ -173,26 +124,18 @@ class AuthEnforcer extends React.Component { const {message, satisfied} = dependencies[id]; const statusIcon = ICONS.satisfied; const classes = classnames('dependency-list__dependency', { - 'dependency-list__dependency--satisfied': satisfied + 'dependency-list__dependency--satisfied': satisfied, }); return (
  • - - {statusIcon} - - - {message} - + {statusIcon} + {message}
  • ); }); - return ( -
      - {listItems} -
    - ) + return
      {listItems}
    ; } handleUIDependenciesChange() { @@ -200,13 +143,12 @@ class AuthEnforcer extends React.Component { dependencies: { authentication: { message: ( - + ), - satisfied: this.state.authStatusDetermined + satisfied: this.state.authStatusDetermined, }, - ...UIStore.getDependencies() - } + ...UIStore.getDependencies(), + }, }); } @@ -226,8 +168,9 @@ class AuthEnforcer extends React.Component { } // Iterate over current dependencies looking for unsatisified dependencies. - const isDependencyActive = Object.keys(this.state.dependencies) - .some(dependencyKey => !this.state.dependencies[dependencyKey].satisfied); + const isDependencyActive = Object.keys(this.state.dependencies).some( + dependencyKey => !this.state.dependencies[dependencyKey].satisfied + ); // If any dependency is unsatisfied, show the loading indicator. if (isDependencyActive) { diff --git a/client/src/javascript/components/alerts/Alert.js b/client/src/javascript/components/alerts/Alert.js index a2329515..03747f91 100644 --- a/client/src/javascript/components/alerts/Alert.js +++ b/client/src/javascript/components/alerts/Alert.js @@ -10,19 +10,19 @@ import CircleExclamationIcon from '../icons/CircleExclamationIcon'; export default class Alert extends React.Component { static propTypes = { count: PropTypes.number, - id: PropTypes.string + id: PropTypes.string, }; static defaultProps = { count: 0, - type: 'success' + type: 'success', }; render() { let icon = ; let alertClasses = classnames('alert', { 'is-success': this.props.type === 'success', - 'is-error': this.props.type === 'error' + 'is-error': this.props.type === 'error', }); if (this.props.type === 'error') { @@ -38,7 +38,7 @@ export default class Alert extends React.Component { defaultMessage={Alerts[this.props.id]} values={{ count: this.props.count, - countElement: {this.props.count} + countElement: {this.props.count}, }} /> diff --git a/client/src/javascript/components/alerts/Alerts.js b/client/src/javascript/components/alerts/Alerts.js index ac81cd77..4de3bcb9 100644 --- a/client/src/javascript/components/alerts/Alerts.js +++ b/client/src/javascript/components/alerts/Alerts.js @@ -12,10 +12,10 @@ export default class Alerts extends React.Component { super(...arguments); this.state = { - alerts: [] + alerts: [], }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -50,8 +50,10 @@ export default class Alerts extends React.Component { } return ( - {alerts} diff --git a/client/src/javascript/components/auth/AuthForm.js b/client/src/javascript/components/auth/AuthForm.js index 7b8641d6..59236e8c 100644 --- a/client/src/javascript/components/auth/AuthForm.js +++ b/client/src/javascript/components/auth/AuthForm.js @@ -5,17 +5,7 @@ import AuthStore from '../../stores/AuthStore'; import EventTypes from '../../constants/EventTypes'; import RtorrentConnectionTypeSelection from '../general/RtorrentConnectionTypeSelection'; -import { - Button, - Form, - FormError, - FormRow, - Panel, - PanelContent, - PanelHeader, - PanelFooter, - Textbox -} from 'flood-ui-kit'; +import {Button, Form, FormError, FormRow, Panel, PanelContent, PanelHeader, PanelFooter, Textbox} from 'flood-ui-kit'; const METHODS_TO_BIND = ['handleAuthError', 'handleFormSubmit']; @@ -25,10 +15,10 @@ class AuthForm extends React.Component { this.state = { error: null, - isAuthStatusLoading: false + isAuthStatusLoading: false, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -51,13 +41,13 @@ class AuthForm extends React.Component { if (this.props.mode === 'login') { return this.props.intl.formatMessage({ id: 'auth.login', - defaultMessage: 'Login' + defaultMessage: 'Login', }); } return this.props.intl.formatMessage({ id: 'auth.create.an.account', - defaultMessage: 'Create an account' + defaultMessage: 'Create an account', }); } @@ -65,13 +55,13 @@ class AuthForm extends React.Component { if (this.props.mode === 'login') { return this.props.intl.formatMessage({ id: 'auth.login.intro', - defaultMessage: 'Log in to your account.' + defaultMessage: 'Log in to your account.', }); } return this.props.intl.formatMessage({ id: 'auth.create.an.account.intro', - defaultMessage: 'Welcome to Flood! Create a username and strong password.' + defaultMessage: 'Welcome to Flood! Create a username and strong password.', }); } @@ -87,7 +77,7 @@ class AuthForm extends React.Component { if (this.props.mode === 'login') { AuthStore.authenticate({ username: submission.formData.username, - password: submission.formData.password + password: submission.formData.password, }); } else { AuthStore.register({ @@ -95,7 +85,7 @@ class AuthForm extends React.Component { password: submission.formData.password, host: submission.formData.rtorrentHost, port: submission.formData.rtorrentPort, - socketPath: submission.formData.rtorrentSocketPath + socketPath: submission.formData.rtorrentSocketPath, }); } } @@ -108,13 +98,12 @@ class AuthForm extends React.Component { if (this.props.mode === 'login') { actionText = this.props.intl.formatMessage({ id: 'auth.log.in', - defaultMessage: 'Log In' + defaultMessage: 'Log In', }); - } else { actionText = this.props.intl.formatMessage({ id: 'auth.create.account', - defaultMessage: 'Create Account' + defaultMessage: 'Create Account', }); registerFields = ( @@ -127,9 +116,7 @@ class AuthForm extends React.Component { if (this.state.error) { errorRow = ( - - {this.state.error} - + {this.state.error} ); } @@ -137,7 +124,7 @@ class AuthForm extends React.Component { return (
    -
    this.formRef = ref}> + (this.formRef = ref)}>

    {this.getHeaderText()}

    diff --git a/client/src/javascript/components/general/Badge.js b/client/src/javascript/components/general/Badge.js index e9beb750..099a33fe 100644 --- a/client/src/javascript/components/general/Badge.js +++ b/client/src/javascript/components/general/Badge.js @@ -2,10 +2,6 @@ import React from 'react'; export default class Badge extends React.Component { render() { - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/general/ClientConnectionInterruption.js b/client/src/javascript/components/general/ClientConnectionInterruption.js index f316a8d1..1ac4245b 100644 --- a/client/src/javascript/components/general/ClientConnectionInterruption.js +++ b/client/src/javascript/components/general/ClientConnectionInterruption.js @@ -7,7 +7,7 @@ import { Panel, PanelContent, PanelHeader, - PanelFooter + PanelFooter, } from 'flood-ui-kit'; import {FormattedMessage} from 'react-intl'; import React from 'react'; @@ -23,54 +23,61 @@ export default class ClientConnectionInterruption extends React.Component { state = { hasTestedConnection: false, isConnectionVerified: false, - isTestingConnection: false + isTestingConnection: false, }; handleFormChange = () => { if (this.state.hasTestedConnection) { this.setState({ isConnectionVerified: false, - hasTestedConnection: false + hasTestedConnection: false, }); } }; handleFormSubmit = ({formData}) => { this.setState({ - isSavingSettings: true + isSavingSettings: true, }); - AuthActions.updateUser(AuthStore.getCurrentUsername(), formData).then(() => { - FloodActions.restartActivityStream(); - }).catch((error) => { - this.setState({ - isSavingSettings: false + AuthActions.updateUser(AuthStore.getCurrentUsername(), formData) + .then(() => { + FloodActions.restartActivityStream(); + }) + .catch(error => { + this.setState({ + isSavingSettings: false, + }); }); - }); - } + }; handleTestButtonClick = () => { if (this.state.isTestingConnection) return; const formData = this.formRef.getFormData(); - this.setState({ - isTestingConnection: true - }, () => { - ClientActions.testClientConnectionSettings(formData).then(() => { - this.setState({ - hasTestedConnection: true, - isConnectionVerified: true, - isTestingConnection: false - }); - }).catch(() => { - this.setState({ - hasTestedConnection: true, - isConnectionVerified: false, - isTestingConnection: false - }); - }); - }); - } + this.setState( + { + isTestingConnection: true, + }, + () => { + ClientActions.testClientConnectionSettings(formData) + .then(() => { + this.setState({ + hasTestedConnection: true, + isConnectionVerified: true, + isTestingConnection: false, + }); + }) + .catch(() => { + this.setState({ + hasTestedConnection: true, + isConnectionVerified: false, + isTestingConnection: false, + }); + }); + } + ); + }; renderConnectionTestResult() { const {hasTestedConnection, isConnectionVerified} = this.state; @@ -91,7 +98,10 @@ export default class ClientConnectionInterruption extends React.Component { return ( - + ); @@ -103,16 +113,18 @@ export default class ClientConnectionInterruption extends React.Component { return ( - this.formRef = ref}> + (this.formRef = ref)}>

    - +

    - +

    {this.renderFormError()} @@ -130,6 +142,6 @@ export default class ClientConnectionInterruption extends React.Component {
    - ) + ); } -} \ No newline at end of file +} diff --git a/client/src/javascript/components/general/CustomScrollbars.js b/client/src/javascript/components/general/CustomScrollbars.js index 4749500b..630a6ead 100644 --- a/client/src/javascript/components/general/CustomScrollbars.js +++ b/client/src/javascript/components/general/CustomScrollbars.js @@ -10,7 +10,7 @@ export default class CustomScrollbar extends React.Component { constructor() { super(); - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -21,9 +21,11 @@ export default class CustomScrollbar extends React.Component { } return ( -
    + onMouseUp={this.props.onThumbMouseUp} + /> ); } @@ -33,9 +35,7 @@ export default class CustomScrollbar extends React.Component { } return ( -
    +
    ); } @@ -59,13 +59,13 @@ export default class CustomScrollbar extends React.Component { ...otherProps } = this.props; let classes = classnames('scrollbars', className, { - 'is-inverted': inverted + 'is-inverted': inverted, }); return ( this.scrollbarRef = ref} + ref={ref => (this.scrollbarRef = ref)} renderView={this.renderView} renderThumbHorizontal={this.getHorizontalThumb} renderThumbVertical={this.getVerticalThumb} @@ -82,5 +82,5 @@ CustomScrollbar.defaultProps = { className: '', inverted: false, nativeScrollHandler: null, - scrollHandler: null + scrollHandler: null, }; diff --git a/client/src/javascript/components/general/Duration.js b/client/src/javascript/components/general/Duration.js index d3450d2c..f87bdf84 100644 --- a/client/src/javascript/components/general/Duration.js +++ b/client/src/javascript/components/general/Duration.js @@ -12,66 +12,93 @@ export default class Duration extends React.Component { let content = null; if (suffix) { - suffix = ( - - {suffix} - - ); + suffix = {suffix}; } if (duration === 'Infinity') { - content = ( - - ); + content = ; } else if (duration.years > 0) { content = [ - {duration.years} + {duration.years} + + + , - {duration.weeks} - + {duration.weeks} + + + + , ]; } else if (duration.weeks > 0) { content = [ - {duration.weeks} + {duration.weeks} + + + , - {duration.days} - + {duration.days} + + + + , ]; } else if (duration.days > 0) { content = [ - {duration.days} + {duration.days} + + + , - {duration.hours} - + {duration.hours} + + + + , ]; } else if (duration.hours > 0) { content = [ - {duration.hours} + {duration.hours} + + + , - {duration.minutes} - + {duration.minutes} + + + + , ]; } else if (duration.minutes > 0) { content = [ - {duration.minutes} + {duration.minutes} + + + , - {duration.seconds} - + {duration.seconds} + + + + , ]; } else { content = ( - {duration.seconds} + {duration.seconds} + + + ); } diff --git a/client/src/javascript/components/general/GlobalContextMenuMountPoint.js b/client/src/javascript/components/general/GlobalContextMenuMountPoint.js index 832e6e56..ccd5a570 100644 --- a/client/src/javascript/components/general/GlobalContextMenuMountPoint.js +++ b/client/src/javascript/components/general/GlobalContextMenuMountPoint.js @@ -12,32 +12,26 @@ class GlobalContextMenuMountPoint extends React.Component { onMenuClose: PropTypes.func, onMenuOpen: PropTypes.func, id: PropTypes.string.isRequired, - width: PropTypes.number + width: PropTypes.number, }; static defaultProps = { - width: 200 + width: 200, }; state = { clickPosition: {}, isOpen: false, items: [], - menuPosition: {} + menuPosition: {}, }; componentDidMount() { - UIStore.listen( - EventTypes.UI_CONTEXT_MENU_CHANGE, - this.handleContextMenuChange - ); + UIStore.listen(EventTypes.UI_CONTEXT_MENU_CHANGE, this.handleContextMenuChange); } componentWillUnmount() { - UIStore.unlisten( - EventTypes.UI_CONTEXT_MENU_CHANGE, - this.handleContextMenuChange - ); + UIStore.unlisten(EventTypes.UI_CONTEXT_MENU_CHANGE, this.handleContextMenuChange); } shouldComponentUpdate(nextProps, nextState) { @@ -51,8 +45,10 @@ class GlobalContextMenuMountPoint extends React.Component { let shouldUpdate = true; - if (this.state.clickPosition.x === nextState.clickPosition.x - && this.state.clickPosition.y === nextState.clickPosition.y) { + if ( + this.state.clickPosition.x === nextState.clickPosition.x && + this.state.clickPosition.y === nextState.clickPosition.y + ) { shouldUpdate = false; } @@ -86,35 +82,25 @@ class GlobalContextMenuMountPoint extends React.Component { let labelAction, labelSecondary, menuItemContent; const menuItemClasses = classnames('menu__item', { 'is-selectable': item.clickHandler, - 'menu__item--separator': item.type === 'separator' + 'menu__item--separator': item.type === 'separator', }); const primaryLabelClasses = classnames('menu__item__label--primary', { - 'has-action': item.labelAction + 'has-action': item.labelAction, }); if (item.labelSecondary) { - labelSecondary = ( - - {item.labelSecondary} - - ); + labelSecondary = {item.labelSecondary}; } if (item.labelAction) { - labelAction = ( - - {item.labelAction} - - ); + labelAction = {item.labelAction}; } if (item.type !== 'separator') { menuItemContent = ( - - {item.label} - + {item.label} {labelAction} {labelSecondary} @@ -123,11 +109,7 @@ class GlobalContextMenuMountPoint extends React.Component { } return ( -
  • +
  • {menuItemContent}
  • ); @@ -141,11 +123,11 @@ class GlobalContextMenuMountPoint extends React.Component { this.setState({ isOpen: true, clickPosition: activeContextMenu.clickPosition, - items: activeContextMenu.items + items: activeContextMenu.items, }); } else if (this.state.isOpen) { this.setState({ - isOpen: false + isOpen: false, }); } }; @@ -181,8 +163,7 @@ class GlobalContextMenuMountPoint extends React.Component { + in={this.state.isOpen}> {this.getMenuItems()} ); diff --git a/client/src/javascript/components/general/ListViewport.js b/client/src/javascript/components/general/ListViewport.js index 90968214..adf4f596 100644 --- a/client/src/javascript/components/general/ListViewport.js +++ b/client/src/javascript/components/general/ListViewport.js @@ -13,14 +13,14 @@ const methodsToBind = [ 'measureItemHeight', 'scrollToTop', 'setScrollPosition', - 'setViewportHeight' + 'setViewportHeight', ]; class ListViewport extends React.Component { static defaultProps = { bottomSpacerClass: 'list__spacer list__spacer--bottom', itemScrollOffset: 10, - topSpacerClass: 'list__spacer list__spacer--top' + topSpacerClass: 'list__spacer list__spacer--top', }; static propTypes = { @@ -30,7 +30,7 @@ class ListViewport extends React.Component { listClass: PropTypes.string, listLength: PropTypes.number.isRequired, scrollContainerClass: PropTypes.string, - topSpacerClass: PropTypes.string + topSpacerClass: PropTypes.string, }; constructor() { @@ -43,17 +43,17 @@ class ListViewport extends React.Component { itemHeight: null, listVerticalPadding: null, scrollTop: 0, - viewportHeight: null + viewportHeight: null, }; - methodsToBind.forEach((method) => { + methodsToBind.forEach(method => { this[method] = this[method].bind(this); }); this.setViewportHeight = _.debounce(this.setViewportHeight, 250); this.updateAfterScrolling = _.debounce(this.updateAfterScrolling, 500, { leading: true, - trailing: true + trailing: true, }); this.setScrollPosition = _.throttle(this.setScrollPosition, 100); } @@ -68,7 +68,7 @@ class ListViewport extends React.Component { if (state.itemHeight == null && nodeRefs.topSpacer != null) { this.setState({ - itemHeight: nodeRefs.topSpacer.nextSibling.offsetHeight + itemHeight: nodeRefs.topSpacer.nextSibling.offsetHeight, }); } @@ -78,7 +78,7 @@ class ListViewport extends React.Component { const paddingTop = Number(listStyle['padding-top'].replace('px', '')); this.setState({ - listVerticalPadding: paddingBottom + paddingTop + listVerticalPadding: paddingBottom + paddingTop, }); } } @@ -101,7 +101,7 @@ class ListViewport extends React.Component { if (this.state.itemHeight == null) { return { minItemIndex: 0, - maxItemIndex: Math.min(50, this.props.listLength) + maxItemIndex: Math.min(50, this.props.listLength), }; } @@ -109,19 +109,10 @@ class ListViewport extends React.Component { // of the viewport. We offset this to render a few more outide of the // container's dimensions, which looks nicer when the user scrolls. const {itemScrollOffset} = this.props; - const offsetBottom = scrollDelta > 0 - ? itemScrollOffset * 2 - : itemScrollOffset / 2; - const offsetTop = scrollDelta < 0 - ? itemScrollOffset * 2 - : itemScrollOffset / 2; + const offsetBottom = scrollDelta > 0 ? itemScrollOffset * 2 : itemScrollOffset / 2; + const offsetTop = scrollDelta < 0 ? itemScrollOffset * 2 : itemScrollOffset / 2; - let { - itemHeight, - listVerticalPadding, - scrollTop, - viewportHeight - } = this.state; + let {itemHeight, listVerticalPadding, scrollTop, viewportHeight} = this.state; if (listVerticalPadding) { viewportHeight = viewportHeight - listVerticalPadding; @@ -133,16 +124,11 @@ class ListViewport extends React.Component { // The minimum item index to render is the number of items above the // viewport's current scroll position, minus the offset. - const minItemIndex = Math.max( - 0, Math.floor(scrollTop / itemHeight) - offsetTop - ); + const minItemIndex = Math.max(0, Math.floor(scrollTop / itemHeight) - offsetTop); // The maximum item index to render is the minimum item rendered, plus the // number of items in view, plus double the offset. - let maxItemIndex = Math.min( - this.props.listLength, - minItemIndex + elementsInView + offsetBottom + offsetTop - ); + let maxItemIndex = Math.min(this.props.listLength, minItemIndex + elementsInView + offsetBottom + offsetTop); return {minItemIndex, maxItemIndex}; } @@ -163,12 +149,15 @@ class ListViewport extends React.Component { measureItemHeight() { this.lastScrollTop = 0; - this.setState({ - scrollTop: 0, - itemHeight: null - }, () => { - this.nodeRefs.outerScrollbar.scrollbarRef.scrollTop(0); - }); + this.setState( + { + scrollTop: 0, + itemHeight: null, + }, + () => { + this.nodeRefs.outerScrollbar.scrollbarRef.scrollTop(0); + } + ); } getListPadding(minItemIndex, maxItemIndex, itemCount) { @@ -218,7 +207,7 @@ class ListViewport extends React.Component { if (nodeRefs.outerScrollbar) { this.setState({ - viewportHeight: nodeRefs.outerScrollbar.scrollbarRef.getClientHeight() + viewportHeight: nodeRefs.outerScrollbar.scrollbarRef.getClientHeight(), }); } } @@ -229,12 +218,8 @@ class ListViewport extends React.Component { render() { const {lastScrollTop, nodeRefs, props, state} = this; - const {minItemIndex, maxItemIndex} = this.getViewportLimits( - state.scrollTop - lastScrollTop - ); - const listPadding = this.getListPadding( - minItemIndex, maxItemIndex, props.listLength - ); + const {minItemIndex, maxItemIndex} = this.getViewportLimits(state.scrollTop - lastScrollTop); + const listPadding = this.getListPadding(minItemIndex, maxItemIndex, props.listLength); const list = []; // For loops are fast, and performance matters here. @@ -243,13 +228,14 @@ class ListViewport extends React.Component { } const listContent = ( -
      nodeRefs.list = ref}> -
    • nodeRefs.topSpacer = ref} - style={{height: `${listPadding.top}px`}}>
    • +
        (nodeRefs.list = ref)}> +
      • (nodeRefs.topSpacer = ref)} + style={{height: `${listPadding.top}px`}} + /> {list} -
      • +
      ); @@ -260,11 +246,12 @@ class ListViewport extends React.Component { } return ( - this.nodeRefs.outerScrollbar = ref} + ref={ref => (this.nodeRefs.outerScrollbar = ref)} scrollHandler={this.handleScroll} style={scrollbarStyle}> {props.children} diff --git a/client/src/javascript/components/general/LoadingIndicator.js b/client/src/javascript/components/general/LoadingIndicator.js index 1d09448a..fe6f2d2a 100644 --- a/client/src/javascript/components/general/LoadingIndicator.js +++ b/client/src/javascript/components/general/LoadingIndicator.js @@ -4,7 +4,7 @@ import React from 'react'; export default class LoadingIndicator extends React.Component { render() { let classes = classnames('loading-indicator', { - 'is-inverse': this.props.inverse + 'is-inverse': this.props.inverse, }); return ( diff --git a/client/src/javascript/components/general/NavigationList.js b/client/src/javascript/components/general/NavigationList.js index c922e951..62b44a5a 100644 --- a/client/src/javascript/components/general/NavigationList.js +++ b/client/src/javascript/components/general/NavigationList.js @@ -10,20 +10,20 @@ class NavigationList extends React.Component { listClassName: PropTypes.string, onChange: PropTypes.func, selectedClassName: PropTypes.string, - uniqueClassName: PropTypes.string + uniqueClassName: PropTypes.string, }; static defaultProps = { itemClassName: 'navigation__item', listClassName: 'navigation', - selectedClassName: 'is-active' + selectedClassName: 'is-active', }; constructor() { super(); this.state = { - selectedItem: null + selectedItem: null, }; } @@ -38,12 +38,11 @@ class NavigationList extends React.Component { } let classes = classnames(this.props.itemClassName, { - [this.props.selectedClassName]: item.slug === selectedSlug + [this.props.selectedClassName]: item.slug === selectedSlug, }); return ( -
    • +
    • {item.label}
    • ); @@ -52,7 +51,7 @@ class NavigationList extends React.Component { handleItemClick(item) { this.setState({ - selectedItem: item.slug + selectedItem: item.slug, }); this.props.onChange(item); @@ -60,14 +59,10 @@ class NavigationList extends React.Component { render() { let classes = classnames(this.props.listClassName, { - [this.props.uniqueClassName]: this.props.uniqueClassName + [this.props.uniqueClassName]: this.props.uniqueClassName, }); - return ( -
        - {this.getNavigationItems(this.props.items)} -
      - ); + return
        {this.getNavigationItems(this.props.items)}
      ; } } diff --git a/client/src/javascript/components/general/Portal.js b/client/src/javascript/components/general/Portal.js index a9240156..0ee1c65b 100644 --- a/client/src/javascript/components/general/Portal.js +++ b/client/src/javascript/components/general/Portal.js @@ -8,11 +8,11 @@ import SettingsStore from '../../stores/SettingsStore'; class Portal extends React.Component { static propTypes = { - children: PropTypes.node + children: PropTypes.node, }; static defaultProps = { - children:
      + children:
      , }; componentDidMount() { @@ -34,11 +34,12 @@ class Portal extends React.Component { if (props.children) { const locale = SettingsStore.getFloodSettings('language'); - ReactDOM.render(( + ReactDOM.render( {props.children} - - ), this.nodeEl); + , + this.nodeEl + ); } } diff --git a/client/src/javascript/components/general/ProgressBar.js b/client/src/javascript/components/general/ProgressBar.js index 7261ec61..714398b8 100644 --- a/client/src/javascript/components/general/ProgressBar.js +++ b/client/src/javascript/components/general/ProgressBar.js @@ -11,9 +11,7 @@ export default class ProgressBar extends React.PureComponent { return (
      -
      - {this.props.icon} -
      +
      {this.props.icon}
      diff --git a/client/src/javascript/components/general/Ratio.js b/client/src/javascript/components/general/Ratio.js index 827487b2..cda88e0d 100644 --- a/client/src/javascript/components/general/Ratio.js +++ b/client/src/javascript/components/general/Ratio.js @@ -16,8 +16,6 @@ export default class Ratio extends React.Component { ratio = ratio.toFixed(precision); - return ( - - ); + return ; } } diff --git a/client/src/javascript/components/general/RtorrentConnectionTypeSelection.js b/client/src/javascript/components/general/RtorrentConnectionTypeSelection.js index 0b8ba7c5..76e5761d 100644 --- a/client/src/javascript/components/general/RtorrentConnectionTypeSelection.js +++ b/client/src/javascript/components/general/RtorrentConnectionTypeSelection.js @@ -5,15 +5,15 @@ import React, {Component} from 'react'; class RtorrentConnectionTypeSelection extends Component { static propTypes = { - onChange: PropTypes.func + onChange: PropTypes.func, }; static defaultProps = { - onChange: () => {} + onChange: () => {}, }; state = { - connectionType: 'tcp' + connectionType: 'tcp', }; handleTypeChange = (event, bar, baz) => { @@ -30,28 +30,18 @@ class RtorrentConnectionTypeSelection extends Component { - )} + label={} placeholder={this.props.intl.formatMessage({ id: 'auth.rtorrentHost', - defaultMessage: 'rTorrent Host' + defaultMessage: 'rTorrent Host', })} /> - )} + label={} placeholder={this.props.intl.formatMessage({ id: 'auth.rtorrentPort', - defaultMessage: 'rTorrent Port' + defaultMessage: 'rTorrent Port', })} /> @@ -62,15 +52,10 @@ class RtorrentConnectionTypeSelection extends Component { - )} + label={} placeholder={this.props.intl.formatMessage({ id: 'auth.rtorrentSocketPath', - defaultMessage: 'rTorrent Socket Path' + defaultMessage: 'rTorrent Socket Path', })} /> @@ -82,22 +67,27 @@ class RtorrentConnectionTypeSelection extends Component { - + - - + + - - + + diff --git a/client/src/javascript/components/general/Size.js b/client/src/javascript/components/general/Size.js index f85ef3a6..d6ae0712 100644 --- a/client/src/javascript/components/general/Size.js +++ b/client/src/javascript/components/general/Size.js @@ -19,12 +19,15 @@ class Size extends React.Component { let translatedUnit = intl.formatMessage({id: getTranslationString(computed.unit)}); if (isSpeed) { - translatedUnit = intl.formatMessage({ - id: 'unit.speed', - defaultMessage: '{baseUnit}/s' - }, { - baseUnit: translatedUnit - }); + translatedUnit = intl.formatMessage( + { + id: 'unit.speed', + defaultMessage: '{baseUnit}/s', + }, + { + baseUnit: translatedUnit, + } + ); } return ( @@ -38,7 +41,7 @@ class Size extends React.Component { Size.defaultProps = { isSpeed: false, - precision: 2 + precision: 2, }; export default injectIntl(Size); diff --git a/client/src/javascript/components/general/SortableList.js b/client/src/javascript/components/general/SortableList.js index 96299584..3b3482cc 100644 --- a/client/src/javascript/components/general/SortableList.js +++ b/client/src/javascript/components/general/SortableList.js @@ -16,10 +16,10 @@ class SortableList extends React.Component { this.sortableListRef = null; this.state = { listOffset: null, - items: props.items + items: props.items, }; - methodsToBind.forEach(method => this[method] = this[method].bind(this)); + methodsToBind.forEach(method => (this[method] = this[method].bind(this))); } componentWillReceiveProps(nextProps) { @@ -35,7 +35,7 @@ class SortableList extends React.Component { handleMouseDown(event) { if (this.sortableListRef != null) { this.setState({ - listOffset: this.sortableListRef.getBoundingClientRect() + listOffset: this.sortableListRef.getBoundingClientRect(), }); } @@ -65,14 +65,15 @@ class SortableList extends React.Component { handleDrop, handleMove, state: {items}, - props: {lockedIDs, renderItem} + props: {lockedIDs, renderItem}, } = this; return items.map((item, index) => { const {id, visible} = item; return ( - this.sortableListRef = ref}> - (this.sortableListRef = ref)}> + + renderItem={this.props.renderItem} + /> {this.getItemList()}
    ); diff --git a/client/src/javascript/components/general/SortableListItem.js b/client/src/javascript/components/general/SortableListItem.js index 78fefe5c..c0adde86 100644 --- a/client/src/javascript/components/general/SortableListItem.js +++ b/client/src/javascript/components/general/SortableListItem.js @@ -15,7 +15,7 @@ const itemSource = { canDrag({isLocked}) { return !isLocked; - } + }, }; const itemTarget = { @@ -35,8 +35,7 @@ const itemTarget = { } // Determine rectangle on screen - const hoverBoundingRect = ReactDOM.findDOMNode(component) - .getBoundingClientRect(); + const hoverBoundingRect = ReactDOM.findDOMNode(component).getBoundingClientRect(); // Determine mouse position const clientOffset = monitor.getClientOffset(); @@ -47,41 +46,32 @@ const itemTarget = { const isDraggingUp = dragIndex < hoverIndex; const isDraggingDown = dragIndex > hoverIndex; - const dragThreshhold = isDraggingDown - ? hoverBoundingRect.height * 0.85 - : hoverBoundingRect.height * 0.15; + const dragThreshhold = isDraggingDown ? hoverBoundingRect.height * 0.85 : hoverBoundingRect.height * 0.15; // Return early if we haven't dragged more than halfway past the next item. - if ((isDraggingUp && hoverClientY < dragThreshhold) - || (isDraggingDown && hoverClientY > dragThreshhold)) { + if ((isDraggingUp && hoverClientY < dragThreshhold) || (isDraggingDown && hoverClientY > dragThreshhold)) { return; } props.onMove(dragIndex, hoverIndex); monitor.getItem().index = hoverIndex; - } + }, }; class SortableListItem extends React.Component { static propTypes = { - id: PropTypes.string + id: PropTypes.string, }; componentDidMount() { // Replace the native drag preview with an empty image. this.props.connectDragPreview(getEmptyImage(), { - captureDraggingState: true + captureDraggingState: true, }); } render() { - const { - children, - isDragging, - isLocked, - connectDragSource, - connectDropTarget - } = this.props; + const {children, isDragging, isLocked, connectDragSource, connectDropTarget} = this.props; let lockedIcon = null; @@ -91,17 +81,15 @@ class SortableListItem extends React.Component { const classes = classnames('sortable-list__item', { 'sortable-list__item--is-dragging': isDragging, - 'sortable-list__item--is-locked': isLocked + 'sortable-list__item--is-locked': isLocked, }); return connectDragSource( connectDropTarget( - ( -
    - {lockedIcon} - {children} -
    - ) +
    + {lockedIcon} + {children} +
    ) ); } @@ -112,12 +100,12 @@ export default _.flow([ return { connectDragPreview: connect.dragPreview(), connectDragSource: connect.dragSource(), - isDragging: monitor.isDragging() + isDragging: monitor.isDragging(), }; }), DropTarget('globally-draggable-item', itemTarget, connect => { return { - connectDropTarget: connect.dropTarget() + connectDropTarget: connect.dropTarget(), }; - }) + }), ])(SortableListItem); diff --git a/client/src/javascript/components/general/SortableListItemDragLayer.js b/client/src/javascript/components/general/SortableListItemDragLayer.js index 7343d5b5..770b22f5 100644 --- a/client/src/javascript/components/general/SortableListItemDragLayer.js +++ b/client/src/javascript/components/general/SortableListItemDragLayer.js @@ -1,7 +1,7 @@ import {DragLayer} from 'react-dnd'; import {injectIntl} from 'react-intl'; import PropTypes from 'prop-types'; -import React, { Component } from 'react'; +import React, {Component} from 'react'; const layerStyles = { position: 'absolute', @@ -32,7 +32,7 @@ class SortableListItemDragLayer extends Component { differenceFromInitialOffset: PropTypes.object, isDragging: PropTypes.bool.isRequired, item: PropTypes.object, - itemType: PropTypes.string + itemType: PropTypes.string, }; render() { @@ -44,9 +44,7 @@ class SortableListItemDragLayer extends Component { return (
    -
    - {this.props.renderItem({...item, dragIndicator: true})} -
    +
    {this.props.renderItem({...item, dragIndicator: true})}
    ); } @@ -57,5 +55,5 @@ export default DragLayer(monitor => ({ differenceFromInitialOffset: monitor.getDifferenceFromInitialOffset(), isDragging: monitor.isDragging(), item: monitor.getItem(), - itemType: monitor.getItemType() + itemType: monitor.getItemType(), }))(injectIntl(SortableListItemDragLayer)); diff --git a/client/src/javascript/components/general/Tooltip.js b/client/src/javascript/components/general/Tooltip.js index 4e8e4bae..a157518d 100644 --- a/client/src/javascript/components/general/Tooltip.js +++ b/client/src/javascript/components/general/Tooltip.js @@ -14,7 +14,7 @@ const METHODS_TO_BIND = [ 'handleTooltipMouseEnter', 'handleTooltipMouseLeave', 'isOpen', - 'triggerClose' + 'triggerClose', ]; class Tooltip extends React.Component { @@ -27,20 +27,18 @@ class Tooltip extends React.Component { content: PropTypes.node.isRequired, elementTag: PropTypes.string, interactive: PropTypes.bool, - maxWidth: PropTypes.oneOfType([PropTypes.number, - PropTypes.string]), + maxWidth: PropTypes.oneOfType([PropTypes.number, PropTypes.string]), onMouseLeave: PropTypes.func, offset: PropTypes.number, onClose: PropTypes.func, onOpen: PropTypes.func, position: PropTypes.oneOf(['top', 'bottom', 'right', 'left']), - scrollContainer: PropTypes.oneOfType([PropTypes.object, - PropTypes.string]), + scrollContainer: PropTypes.oneOfType([PropTypes.object, PropTypes.string]), stayOpen: PropTypes.bool, suppress: PropTypes.bool, width: PropTypes.number, wrapperClassName: PropTypes.string, - wrapText: PropTypes.bool + wrapText: PropTypes.bool, }; static defaultProps = { @@ -56,13 +54,13 @@ class Tooltip extends React.Component { stayOpen: false, suppress: false, wrapperClassName: 'tooltip__wrapper', - wrapText: false + wrapText: false, }; constructor() { super(); - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -81,17 +79,14 @@ class Tooltip extends React.Component { return; } - let {anchor, position, coordinates} = this.getIdealLocation( - props.anchor, - props.position - ); + let {anchor, position, coordinates} = this.getIdealLocation(props.anchor, props.position); this.setState({ anchor, isOpen: true, position, coordinates, - wasTriggeredClose: false + wasTriggeredClose: false, }); this.addScrollListener(); @@ -139,14 +134,11 @@ class Tooltip extends React.Component { } getAnchor(isVertical, anchor, clearance, tooltipWidth, tooltipHeight) { - if (isVertical) { - return this.transformAnchor(anchor, clearance.left, clearance.right, - tooltipWidth, clearance.boundingRect.width); + return this.transformAnchor(anchor, clearance.left, clearance.right, tooltipWidth, clearance.boundingRect.width); } - return this.transformAnchor(anchor, clearance.top, clearance.bottom, - tooltipHeight, clearance.boundingRect.height); + return this.transformAnchor(anchor, clearance.top, clearance.bottom, tooltipHeight, clearance.boundingRect.height); } getCoordinates(position, clearance, tooltipWidth, tooltipHeight) { @@ -193,11 +185,7 @@ class Tooltip extends React.Component { if (position === 'top' && clearance.top < tooltipHeight) { position = 'bottom'; - } else if ( - position === 'bottom' - && clearance.bottom < tooltipHeight - && clearance.top > clearance.bottom - ) { + } else if (position === 'bottom' && clearance.bottom < tooltipHeight && clearance.top > clearance.bottom) { position = 'top'; } @@ -211,22 +199,17 @@ class Tooltip extends React.Component { let tooltipHeight = tooltipRect.height + ARROW_SIZE; let tooltipWidth = tooltipRect.width + ARROW_SIZE; - anchor = this.getAnchor(isVertical, anchor, clearance, tooltipWidth, - tooltipHeight); - position = this.getPosition(position, clearance, tooltipWidth, - tooltipHeight); + anchor = this.getAnchor(isVertical, anchor, clearance, tooltipWidth, tooltipHeight); + position = this.getPosition(position, clearance, tooltipWidth, tooltipHeight); - let coordinates = this.getCoordinates(position, clearance, tooltipWidth, - tooltipHeight); + let coordinates = this.getCoordinates(position, clearance, tooltipWidth, tooltipHeight); return {anchor, position, coordinates}; } getNodeClearance(domNode) { - let viewportHeight = Math.max(document.documentElement.clientHeight || 0, - window.innerHeight || 0); - let viewportWidth = Math.max(document.documentElement.clientWidth || 0, - window.innerWidth || 0); + let viewportHeight = Math.max(document.documentElement.clientHeight || 0, window.innerHeight || 0); + let viewportWidth = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0); let boundingRect = domNode.getBoundingClientRect(); return { @@ -234,7 +217,7 @@ class Tooltip extends React.Component { left: boundingRect.left, right: viewportWidth - boundingRect.right, top: boundingRect.top, - boundingRect + boundingRect, }; } @@ -257,8 +240,7 @@ class Tooltip extends React.Component { this.handleMouseEnter({forceOpen: true}); } - transformAnchor(anchor, clearanceStart, clearanceEnd, tooltipDimension, - triggerDimension) { + transformAnchor(anchor, clearanceStart, clearanceEnd, tooltipDimension, triggerDimension) { // Change the provided anchor based on the clearance available. if (anchor === 'start' && clearanceEnd < tooltipDimension) { return 'end'; @@ -295,19 +277,22 @@ class Tooltip extends React.Component { // Pass along any props that aren't specific to the Tooltip. let elementProps = _.omit(props, Object.keys(Tooltip.propTypes)); - let tooltipClasses = classnames(props.className, - `tooltip--anchor--${anchor}`, `tooltip--position--${position}`, - `tooltip--align--${align}`, { + let tooltipClasses = classnames( + props.className, + `tooltip--anchor--${anchor}`, + `tooltip--position--${position}`, + `tooltip--align--${align}`, + { 'is-interactive': props.interactive, 'is-open': state.isOpen, - 'tooltip--no-wrap': !props.wrapText + 'tooltip--no-wrap': !props.wrapText, } ); if (state.coordinates) { tooltipStyle = { left: state.coordinates.left, - top: state.coordinates.top + top: state.coordinates.top, }; } @@ -320,18 +305,21 @@ class Tooltip extends React.Component { } return ( - + {...elementProps} + ref="triggerNode"> {props.children} -
    -
    - {props.content} -
    +
    {props.content}
    diff --git a/client/src/javascript/components/general/WindowTitle.js b/client/src/javascript/components/general/WindowTitle.js index dea145ef..cd2c406f 100644 --- a/client/src/javascript/components/general/WindowTitle.js +++ b/client/src/javascript/components/general/WindowTitle.js @@ -8,7 +8,6 @@ import TransferDataStore from '../../stores/TransferDataStore'; const METHODS_TO_BIND = ['handleTransferChange']; - class WindowTitle extends React.Component { constructor() { super(); @@ -17,23 +16,17 @@ class WindowTitle extends React.Component { title: 'Flood', }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TransferDataStore.listen( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.handleTransferChange - ); + TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.handleTransferChange); } componentWillUnmount() { - TransferDataStore.unlisten( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.handleTransferChange - ); + TransferDataStore.unlisten(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.handleTransferChange); } handleTransferChange() { @@ -47,30 +40,39 @@ class WindowTitle extends React.Component { const formattedDownSpeed = intl.formatNumber(down.value); const formattedUpSpeed = intl.formatNumber(up.value); - const translatedDownUnit = intl.formatMessage({ - id: 'unit.speed', - defaultMessage: '{baseUnit}/s' - }, { - baseUnit: intl.formatMessage({id: getTranslationString(down.unit)}) - }); - const translatedUpUnit = intl.formatMessage({ - id: 'unit.speed', - defaultMessage: '{baseUnit}/s' - }, { - baseUnit: intl.formatMessage({id: getTranslationString(up.unit)}) - }); + const translatedDownUnit = intl.formatMessage( + { + id: 'unit.speed', + defaultMessage: '{baseUnit}/s', + }, + { + baseUnit: intl.formatMessage({id: getTranslationString(down.unit)}), + } + ); + const translatedUpUnit = intl.formatMessage( + { + id: 'unit.speed', + defaultMessage: '{baseUnit}/s', + }, + { + baseUnit: intl.formatMessage({id: getTranslationString(up.unit)}), + } + ); - const formattedTitle = intl.formatMessage({ - id: 'window.title', - // \u2193 and \u2191 are down and up arrows, respectively - defaultMessage: '\u2193 {down} \u2191 {up} - Flood', - }, { - down: `${formattedDownSpeed} ${translatedDownUnit}`, - up: `${formattedUpSpeed} ${translatedUpUnit}`, - }); + const formattedTitle = intl.formatMessage( + { + id: 'window.title', + // \u2193 and \u2191 are down and up arrows, respectively + defaultMessage: '\u2193 {down} \u2191 {up} - Flood', + }, + { + down: `${formattedDownSpeed} ${translatedDownUnit}`, + up: `${formattedUpSpeed} ${translatedUpUnit}`, + } + ); this.setState({ - title: formattedTitle + title: formattedTitle, }); } @@ -78,13 +80,8 @@ class WindowTitle extends React.Component { const {children} = this.props; const {title} = this.state; - return ( - - {children} - - ); + return {children}; } } - export default injectIntl(WindowTitle); diff --git a/client/src/javascript/components/general/filesystem/DirectoryFileList.js b/client/src/javascript/components/general/filesystem/DirectoryFileList.js index 4e7e0356..0abfcc3d 100644 --- a/client/src/javascript/components/general/filesystem/DirectoryFileList.js +++ b/client/src/javascript/components/general/filesystem/DirectoryFileList.js @@ -15,23 +15,23 @@ class DirectoryFiles extends React.Component { static propTypes = { isParentSelected: PropTypes.bool, path: PropTypes.array, - selectedItems: PropTypes.object + selectedItems: PropTypes.object, }; static defaultProps = { isParentSelected: false, path: [], - selectedItems: {} + selectedItems: {}, }; constructor() { super(); this.state = { - files: null + files: null, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -47,16 +47,13 @@ class DirectoryFiles extends React.Component { return (
    -
    - +
    -
    {ICONS.file}
    @@ -73,7 +70,7 @@ class DirectoryFiles extends React.Component { isParentSelected: this.props.isParentSelected, isSelected, path: this.getCurrentPath(file), - type: 'file' + type: 'file', }); } @@ -91,31 +88,31 @@ class DirectoryFiles extends React.Component { let files = branch.map((file, index) => { let isSelected = this.props.selectedItems[file.filename] && this.props.selectedItems[file.filename].isSelected; - let classes = classnames('directory-tree__node file', - 'directory-tree__node--file directory-tree__node--selectable', { - 'directory-tree__node--selected': isSelected - }); + let classes = classnames( + 'directory-tree__node file', + 'directory-tree__node--file directory-tree__node--selectable', + { + 'directory-tree__node--selected': isSelected, + } + ); return ( -
    +
    {this.getIcon(file, isSelected)} -
    - {file.filename} -
    +
    {file.filename}
    -
    - {file.percentComplete}% -
    -
    {file.percentComplete}%
    +
    - {files} -
    - ); + return
    {files}
    ; } } diff --git a/client/src/javascript/components/general/filesystem/DirectoryTree.js b/client/src/javascript/components/general/filesystem/DirectoryTree.js index 2a543dc9..ea617727 100644 --- a/client/src/javascript/components/general/filesystem/DirectoryTree.js +++ b/client/src/javascript/components/general/filesystem/DirectoryTree.js @@ -4,21 +4,19 @@ import React from 'react'; import DirectoryFileList from './DirectoryFileList'; import DirectoryTreeNode from './DirectoryTreeNode'; -const METHODS_TO_BIND = [ - 'getDirectoryTreeDomNodes' -]; +const METHODS_TO_BIND = ['getDirectoryTreeDomNodes']; class DirectoryTree extends React.Component { static propTypes = { isParentSelected: PropTypes.bool, path: PropTypes.array, - selectedItems: PropTypes.object + selectedItems: PropTypes.object, }; static defaultProps = { isParentSelected: false, path: [], - selectedItems: {} + selectedItems: {}, }; constructor() { @@ -26,10 +24,10 @@ class DirectoryTree extends React.Component { this.state = { selectedDirectories: [], - selectedNodes: [] + selectedNodes: [], }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -40,7 +38,8 @@ class DirectoryTree extends React.Component { let fileList = null; depth++; - directories = Object.keys(directories).sort(this.sortDirectories) + directories = Object.keys(directories) + .sort(this.sortDirectories) .map((directoryName, index) => { let subSelectedItems = {}; @@ -97,9 +96,7 @@ class DirectoryTree extends React.Component { render() { return ( -
    - {this.getDirectoryTreeDomNodes(this.props.tree, this.props.depth)} -
    +
    {this.getDirectoryTreeDomNodes(this.props.tree, this.props.depth)}
    ); } } diff --git a/client/src/javascript/components/general/filesystem/DirectoryTreeNode.js b/client/src/javascript/components/general/filesystem/DirectoryTreeNode.js index da74e79f..c0627482 100644 --- a/client/src/javascript/components/general/filesystem/DirectoryTreeNode.js +++ b/client/src/javascript/components/general/filesystem/DirectoryTreeNode.js @@ -13,23 +13,23 @@ class DirectoryTreeNode extends React.Component { static propTypes = { isParentSelected: PropTypes.bool, path: PropTypes.array, - selectedItems: PropTypes.object + selectedItems: PropTypes.object, }; static defaultProps = { isParentSelected: false, path: [], - selectedItems: {} + selectedItems: {}, }; constructor() { super(); this.state = { - expanded: false + expanded: false, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -49,7 +49,8 @@ class DirectoryTreeNode extends React.Component { return (
    -
    -
    {icon}
    @@ -70,14 +72,17 @@ class DirectoryTreeNode extends React.Component { if (this.state.expanded) { return (
    - + selectedItems={this.props.selectedItems} + />
    ); } @@ -87,7 +92,7 @@ class DirectoryTreeNode extends React.Component { handleDirectoryClick(event) { this.setState({ - expanded: !this.state.expanded + expanded: !this.state.expanded, }); } @@ -99,30 +104,28 @@ class DirectoryTreeNode extends React.Component { isParentSelected: this.props.isParentSelected, isSelected: this.props.isSelected, path: this.getCurrentPath(), - type: 'directory' + type: 'directory', }); } render() { - let branchClasses = classnames('directory-tree__branch', - `directory-tree__branch--depth-${this.props.depth}`, { - 'directory-tree__node--selected': this.props.isSelected, - }); - let directoryClasses = classnames('directory-tree__node', - 'directory-tree__node--selectable directory-tree__node--directory', { - 'is-expanded': this.state.expanded - }); + let branchClasses = classnames('directory-tree__branch', `directory-tree__branch--depth-${this.props.depth}`, { + 'directory-tree__node--selected': this.props.isSelected, + }); + let directoryClasses = classnames( + 'directory-tree__node', + 'directory-tree__node--selectable directory-tree__node--directory', + { + 'is-expanded': this.state.expanded, + } + ); return (
    -
    +
    {this.getIcon()} -
    - {this.props.directoryName} -
    +
    {this.props.directoryName}
    {this.getSubTree()} diff --git a/client/src/javascript/components/general/filesystem/FilesystemBrowser.js b/client/src/javascript/components/general/filesystem/FilesystemBrowser.js index c95595a9..ab784b76 100644 --- a/client/src/javascript/components/general/filesystem/FilesystemBrowser.js +++ b/client/src/javascript/components/general/filesystem/FilesystemBrowser.js @@ -11,20 +11,20 @@ import UIStore from '../../../stores/UIStore'; const MESSAGES = defineMessages({ EACCES: { id: 'filesystem.error.eacces', - defaultMessage: 'Flood does not have permission to read this directory.' + defaultMessage: 'Flood does not have permission to read this directory.', }, ENOENT: { id: 'filesystem.error.enoent', - defaultMessage: 'This path does not exist. It will be created.' + defaultMessage: 'This path does not exist. It will be created.', }, emptyDirectory: { id: 'filesystem.empty.directory', - defaultMessage: 'Empty directory.' + defaultMessage: 'Empty directory.', }, fetching: { id: 'filesystem.fetching', - defaultMessage: 'Fetching directory structure...' - } + defaultMessage: 'Fetching directory structure...', + }, }); class FilesystemBrowser extends React.PureComponent { @@ -33,19 +33,13 @@ class FilesystemBrowser extends React.PureComponent { this.state = { directory: props.directory, - separator: '/' + separator: '/', }; } componentDidMount() { - UIStore.listen( - EventTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, - this.handleDirectoryListFetchError - ); - UIStore.listen( - EventTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, - this.handleDirectoryListFetchSuccess - ); + UIStore.listen(EventTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, this.handleDirectoryListFetchError); + UIStore.listen(EventTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, this.handleDirectoryListFetchSuccess); UIStore.fetchDirectoryList({path: this.state.directory}); } @@ -57,14 +51,8 @@ class FilesystemBrowser extends React.PureComponent { } componentWillUnmount() { - UIStore.unlisten( - EventTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, - this.handleDirectoryListFetchError - ); - UIStore.unlisten( - EventTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, - this.handleDirectoryListFetchSuccess - ); + UIStore.unlisten(EventTypes.FLOOD_FETCH_DIRECTORY_LIST_ERROR, this.handleDirectoryListFetchError); + UIStore.unlisten(EventTypes.FLOOD_FETCH_DIRECTORY_LIST_SUCCESS, this.handleDirectoryListFetchSuccess); } getNewDestination(nextDirectorySegment) { @@ -77,12 +65,12 @@ class FilesystemBrowser extends React.PureComponent { return `${directory}${separator}${nextDirectorySegment}`; } - handleDirectoryClick = (directory) => { + handleDirectoryClick = directory => { const nextDirectory = this.getNewDestination(directory); this.setState({ directory: nextDirectory, - isFetching: true + isFetching: true, }); if (this.props.onDirectorySelection) { @@ -90,20 +78,20 @@ class FilesystemBrowser extends React.PureComponent { } }; - handleDirectoryListFetchError = (error) => { + handleDirectoryListFetchError = error => { this.setState({ error, - isFetching: false + isFetching: false, }); }; - handleDirectoryListFetchSuccess = (response) => { + handleDirectoryListFetchSuccess = response => { // response includes hasParent, separator, and an array of directories. this.setState({ ...response, directory: response.path, error: null, - isFetching: false + isFetching: false, }); }; @@ -121,7 +109,7 @@ class FilesystemBrowser extends React.PureComponent { this.setState({ directory, - isFetching: true + isFetching: true, }); if (this.props.onDirectorySelection) { @@ -130,12 +118,7 @@ class FilesystemBrowser extends React.PureComponent { }; render() { - const { - directories, - error, - files = [], - hasParent - } = this.state; + const {directories, error, files = [], hasParent} = this.state; let errorMessage = null; let listItems = null; let parentDirectory = null; @@ -146,9 +129,7 @@ class FilesystemBrowser extends React.PureComponent { shouldShowDirectoryList = false; errorMessage = (
    - - {this.props.intl.formatMessage(MESSAGES.fetching)} - + {this.props.intl.formatMessage(MESSAGES.fetching)}
    ); } @@ -162,9 +143,7 @@ class FilesystemBrowser extends React.PureComponent { errorMessage = (
    - - {this.props.intl.formatMessage(MESSAGES[error.data.code])} - + {this.props.intl.formatMessage(MESSAGES[error.data.code])}
    ); } @@ -173,12 +152,11 @@ class FilesystemBrowser extends React.PureComponent { parentDirectory = (
  • + onClick={this.handleParentDirectoryClick}> {this.props.intl.formatMessage({ id: 'filesystem.parent.directory', - defaultMessage: 'Parent Directory' + defaultMessage: 'Parent Directory', })}
  • ); @@ -187,7 +165,8 @@ class FilesystemBrowser extends React.PureComponent { if (shouldShowDirectoryList) { const directoryList = directories.map((directory, index) => { return ( -
  • this.handleDirectoryClick(directory)}> @@ -199,10 +178,7 @@ class FilesystemBrowser extends React.PureComponent { const filesList = files.map((file, index) => { return ( -
  • +
  • {file}
  • @@ -215,19 +191,13 @@ class FilesystemBrowser extends React.PureComponent { if ((!listItems || listItems.length === 0) && !errorMessage) { errorMessage = (
    - - {this.props.intl.formatMessage(MESSAGES.emptyDirectory)} - + {this.props.intl.formatMessage(MESSAGES.emptyDirectory)}
    ); } return ( - +
    {parentDirectory} {errorMessage} diff --git a/client/src/javascript/components/general/filesystem/PriorityMeter.js b/client/src/javascript/components/general/filesystem/PriorityMeter.js index c1cd4cb6..87db64fc 100644 --- a/client/src/javascript/components/general/filesystem/PriorityMeter.js +++ b/client/src/javascript/components/general/filesystem/PriorityMeter.js @@ -11,11 +11,11 @@ class PriorityMeter extends React.Component { this.state = { optimisticData: { - level: null - } + level: null, + }, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -37,22 +37,22 @@ class PriorityMeter extends React.Component { case 'DONT_DOWNLOAD': return this.props.intl.formatMessage({ id: 'priority.dont.download', - defaultMessage: 'Don\'t Download' + defaultMessage: "Don't Download", }); case 'HIGH': return this.props.intl.formatMessage({ id: 'priority.high', - defaultMessage: 'High' + defaultMessage: 'High', }); case 'LOW': return this.props.intl.formatMessage({ id: 'priority.low', - defaultMessage: 'Low' + defaultMessage: 'Low', }); case 'NORMAL': return this.props.intl.formatMessage({ id: 'priority.normal', - defaultMessage: 'Normal' + defaultMessage: 'Normal', }); default: return ''; @@ -82,18 +82,18 @@ class PriorityMeter extends React.Component { let label = null; if (this.props.showLabel) { - label = ( - - {this.getPriorityLabel()} - - ); + label = {this.getPriorityLabel()}; } return (
    -
    +
    {label}
    ); diff --git a/client/src/javascript/components/general/filesystem/TorrentDestination.js b/client/src/javascript/components/general/filesystem/TorrentDestination.js index 9766fe4b..a4c996e0 100644 --- a/client/src/javascript/components/general/filesystem/TorrentDestination.js +++ b/client/src/javascript/components/general/filesystem/TorrentDestination.js @@ -16,10 +16,11 @@ class NewTorrentDestination extends React.Component { constructor(props) { super(props); - const destination = props.suggested - || SettingsStore.getFloodSettings('torrentDestination') - || SettingsStore.getClientSettings('directoryDefault') - || ''; + const destination = + props.suggested || + SettingsStore.getFloodSettings('torrentDestination') || + SettingsStore.getClientSettings('directoryDefault') || + ''; this.state = { destination, @@ -28,7 +29,7 @@ class NewTorrentDestination extends React.Component { directories: null, files: null, isFetching: false, - isDirectoryListOpen: false + isDirectoryListOpen: false, }; this.handleWindowResize = _.debounce(this.handleWindowResize, 100); @@ -42,13 +43,13 @@ class NewTorrentDestination extends React.Component { if (!this.state.isDirectoryListOpen && nextState.isDirectoryListOpen) { this.addDestinationOpenEventListeners(); } else if (this.state.isDirectoryListOpen && !nextState.isDirectoryListOpen) { - this.removeDestinationOpenEventListeners() + this.removeDestinationOpenEventListeners(); } } componentWillUnmount() { UIStore.unlisten(EventTypes.UI_MODAL_DISMISSED, this.handleModalDismiss); - this.removeDestinationOpenEventListeners() + this.removeDestinationOpenEventListeners(); } addDestinationOpenEventListeners() { @@ -70,11 +71,11 @@ class NewTorrentDestination extends React.Component { return this.state.destination; } - handleBasePathCheckBoxCheck = (value) => { + handleBasePathCheckBoxCheck = value => { this.setState({isBasePath: value}); }; - handleDestinationChange = (event) => { + handleDestinationChange = event => { const destination = event.target.value; if (this.props.onChange) { @@ -84,12 +85,12 @@ class NewTorrentDestination extends React.Component { this.setState({destination}); }; - handleDirectoryListButtonClick = (event) => { + handleDirectoryListButtonClick = event => { const isOpening = !this.state.isDirectoryListOpen; this.setState({ isDirectoryListOpen: isOpening, - isFetching: isOpening + isFetching: isOpening, }); }; @@ -120,7 +121,7 @@ class NewTorrentDestination extends React.Component { global.removeEventListener('resize', this.handleWindowResize); } - setTextboxRef = (ref) => { + setTextboxRef = ref => { if (this.state.textboxRef !== ref) { this.setState({textboxRef: ref}); } @@ -128,7 +129,7 @@ class NewTorrentDestination extends React.Component { toggleOpenState = () => { this.setState({ - isDirectoryListOpen: !this.state.isDirectoryListOpen + isDirectoryListOpen: !this.state.isDirectoryListOpen, }); }; @@ -145,10 +146,9 @@ class NewTorrentDestination extends React.Component { onClick={event => event.nativeEvent.stopImmediatePropagation()} placeholder={this.props.intl.formatMessage({ id: 'torrents.add.destination.placeholder', - defaultMessage: 'Destination' + defaultMessage: 'Destination', })} - setRef={this.setTextboxRef} - > + setRef={this.setTextboxRef}> @@ -158,18 +158,17 @@ class NewTorrentDestination extends React.Component { onClick={event => event.nativeEvent.stopImmediatePropagation()} overlayProps={{isInteractive: false}} padding={false} - ref={ref => this.contextMenuInstanceRef = ref} - setRef={ref => this.contextMenuNodeRef = ref} + ref={ref => (this.contextMenuInstanceRef = ref)} + setRef={ref => (this.contextMenuNodeRef = ref)} scrolling={false} - triggerRef={this.state.textboxRef} - > + triggerRef={this.state.textboxRef}> @@ -179,10 +178,7 @@ class NewTorrentDestination extends React.Component { - + diff --git a/client/src/javascript/components/general/form-elements/Dropdown.js b/client/src/javascript/components/general/form-elements/Dropdown.js index 5654cf0b..b1fa33d4 100644 --- a/client/src/javascript/components/general/form-elements/Dropdown.js +++ b/client/src/javascript/components/general/form-elements/Dropdown.js @@ -17,7 +17,7 @@ const METHODS_TO_BIND = [ 'handleActiveDropdownChange', 'handleDropdownClick', 'handleItemSelect', - 'handleKeyPress' + 'handleKeyPress', ]; class Dropdown extends React.Component { @@ -29,7 +29,7 @@ class Dropdown extends React.Component { menuItems: PropTypes.arrayOf(PropTypes.arrayOf(PropTypes.object)).isRequired, noWrap: PropTypes.bool, onOpen: PropTypes.func, - width: PropTypes.oneOf(['small', 'medium', 'large']) + width: PropTypes.oneOf(['small', 'medium', 'large']), }; static defaultProps = { @@ -38,7 +38,7 @@ class Dropdown extends React.Component { dropdownWrapperClass: 'dropdown', dropdownButtonClass: 'dropdown__trigger', matchButtonWidth: false, - noWrap: false + noWrap: false, }; constructor() { @@ -47,10 +47,10 @@ class Dropdown extends React.Component { this.id = _.uniqueId('dropdown_'); this.state = { - isOpen: false + isOpen: false, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -60,8 +60,7 @@ class Dropdown extends React.Component { closeDropdown() { global.removeEventListener('keydown', this.handleKeyPress); global.removeEventListener('click', this.closeDropdown); - UIStore.unlisten(EventTypes.UI_DROPDOWN_MENU_CHANGE, - this.handleActiveDropdownChange); + UIStore.unlisten(EventTypes.UI_DROPDOWN_MENU_CHANGE, this.handleActiveDropdownChange); this.setState({isOpen: false}); } @@ -69,8 +68,7 @@ class Dropdown extends React.Component { openDropdown() { global.addEventListener('keydown', this.handleKeyPress); global.addEventListener('click', this.closeDropdown); - UIStore.listen(EventTypes.UI_DROPDOWN_MENU_CHANGE, - this.handleActiveDropdownChange); + UIStore.listen(EventTypes.UI_DROPDOWN_MENU_CHANGE, this.handleActiveDropdownChange); this.setState({isOpen: true}); @@ -116,8 +114,7 @@ class Dropdown extends React.Component { } return ( -
    +
    {label}
    ); @@ -128,7 +125,7 @@ class Dropdown extends React.Component { let content = [
    {this.getDropdownButton({header: true, trigger: false})} -
    +
    , ]; let dropdownLists = items.map((itemList, index) => { return ( @@ -144,18 +141,14 @@ class Dropdown extends React.Component { ); - return ( -
    - {content} -
    - ); + return
    {content}
    ; } getDropdownMenuItems(listItems) { return listItems.map((property, index) => { let classes = classnames('dropdown__item menu__item', property.className, { 'is-selectable': property.selectable !== false, - 'is-selected': property.selected + 'is-selected': property.selected, }); let clickHandler = null; @@ -164,9 +157,7 @@ class Dropdown extends React.Component { } return ( -
  • +
  • {property.displayName}
  • ); @@ -174,16 +165,16 @@ class Dropdown extends React.Component { } render() { - let dropdownWrapperClass = classnames(this.props.dropdownWrapperClass, + let dropdownWrapperClass = classnames( + this.props.dropdownWrapperClass, `${this.props.baseClassName}--direction-${this.props.direction}`, { - [`${this.props.baseClassName}--match-button-width`]: - this.props.matchButtonWidth, - [`${this.props.baseClassName}--width-${this.props.width}`]: - this.props.width != null, + [`${this.props.baseClassName}--match-button-width`]: this.props.matchButtonWidth, + [`${this.props.baseClassName}--width-${this.props.width}`]: this.props.width != null, [`${this.props.baseClassName}--no-wrap`]: this.props.nowrap, - 'is-expanded': this.state.isOpen - }); + 'is-expanded': this.state.isOpen, + } + ); let menu = null; @@ -194,10 +185,7 @@ class Dropdown extends React.Component { return (
    {this.getDropdownButton({header: false, trigger: true})} - + {menu}
    diff --git a/client/src/javascript/components/general/form-elements/TextboxRepeater.js b/client/src/javascript/components/general/form-elements/TextboxRepeater.js index 20fbb481..d63f0cf4 100644 --- a/client/src/javascript/components/general/form-elements/TextboxRepeater.js +++ b/client/src/javascript/components/general/form-elements/TextboxRepeater.js @@ -6,7 +6,7 @@ import RemoveMini from '../../icons/RemoveMini'; export default class TextboxRepeater extends React.PureComponent { state = { - textboxes: [{id: 0, value: ''}] + textboxes: [{id: 0, value: ''}], }; _idCounter = 0; @@ -35,8 +35,7 @@ export default class TextboxRepeater extends React.PureComponent { defaultValue={textbox.value} label={index === 0 && this.props.label} placeholder={this.props.placeholder} - wrapperClassName="textbox-repeater" - > + wrapperClassName="textbox-repeater"> @@ -47,23 +46,19 @@ export default class TextboxRepeater extends React.PureComponent { }); }; - handleTextboxAdd = (index) => { + handleTextboxAdd = index => { const textboxes = Object.assign([], this.state.textboxes); textboxes.splice(index + 1, 0, {id: this.getID(), value: ''}); this.setState({textboxes}); }; - handleTextboxRemove = (index) => { + handleTextboxRemove = index => { const textboxes = Object.assign([], this.state.textboxes); textboxes.splice(index, 1); this.setState({textboxes}); }; render() { - return ( - - {this.getTextboxes()} - - ); + return {this.getTextboxes()}; } } diff --git a/client/src/javascript/components/icons/Active.js b/client/src/javascript/components/icons/Active.js index e456c137..dbcb568a 100644 --- a/client/src/javascript/components/icons/Active.js +++ b/client/src/javascript/components/icons/Active.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Active extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/Add.js b/client/src/javascript/components/icons/Add.js index b0b5ff74..41e6e4ac 100644 --- a/client/src/javascript/components/icons/Add.js +++ b/client/src/javascript/components/icons/Add.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class AddMini extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/AddMini.js b/client/src/javascript/components/icons/AddMini.js index 93a1914e..171cfd05 100644 --- a/client/src/javascript/components/icons/AddMini.js +++ b/client/src/javascript/components/icons/AddMini.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class AddMini extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/All.js b/client/src/javascript/components/icons/All.js index 320b2e00..f77164bb 100644 --- a/client/src/javascript/components/icons/All.js +++ b/client/src/javascript/components/icons/All.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class All extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/ArrowIcon.js b/client/src/javascript/components/icons/ArrowIcon.js index 58f7ac66..5e40803d 100644 --- a/client/src/javascript/components/icons/ArrowIcon.js +++ b/client/src/javascript/components/icons/ArrowIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class ArrowIcon extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/BaseIcon.js b/client/src/javascript/components/icons/BaseIcon.js index 2ea483a4..b762cda9 100644 --- a/client/src/javascript/components/icons/BaseIcon.js +++ b/client/src/javascript/components/icons/BaseIcon.js @@ -5,12 +5,12 @@ export default class BaseIcon extends React.Component { static propTypes = { className: PropTypes.string, size: PropTypes.string, - viewBox: PropTypes.string + viewBox: PropTypes.string, }; static defaultProps = { className: '', - viewBox: '0 0 60 60' + viewBox: '0 0 60 60', }; getViewBox() { diff --git a/client/src/javascript/components/icons/CalendarCreatedIcon.js b/client/src/javascript/components/icons/CalendarCreatedIcon.js index 6de0bcc6..5f880c4c 100644 --- a/client/src/javascript/components/icons/CalendarCreatedIcon.js +++ b/client/src/javascript/components/icons/CalendarCreatedIcon.js @@ -5,7 +5,8 @@ import BaseIcon from './BaseIcon'; export default class CalendarCreatedIcon extends BaseIcon { render() { return ( - diff --git a/client/src/javascript/components/icons/CalendarIcon.js b/client/src/javascript/components/icons/CalendarIcon.js index af113217..c00a6a4a 100644 --- a/client/src/javascript/components/icons/CalendarIcon.js +++ b/client/src/javascript/components/icons/CalendarIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class CalendarIcon extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/Checkmark.js b/client/src/javascript/components/icons/Checkmark.js index 6a857516..37762e18 100644 --- a/client/src/javascript/components/icons/Checkmark.js +++ b/client/src/javascript/components/icons/Checkmark.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Checkmark extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/ChevronLeftIcon.js b/client/src/javascript/components/icons/ChevronLeftIcon.js index 7ccae469..778b12ba 100644 --- a/client/src/javascript/components/icons/ChevronLeftIcon.js +++ b/client/src/javascript/components/icons/ChevronLeftIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class ChevronLeftIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/ChevronRightIcon.js b/client/src/javascript/components/icons/ChevronRightIcon.js index 016e25ef..7461c659 100644 --- a/client/src/javascript/components/icons/ChevronRightIcon.js +++ b/client/src/javascript/components/icons/ChevronRightIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class ChevronRightIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/CircleCheckmarkIcon.js b/client/src/javascript/components/icons/CircleCheckmarkIcon.js index c42cb8eb..9e9d62ed 100644 --- a/client/src/javascript/components/icons/CircleCheckmarkIcon.js +++ b/client/src/javascript/components/icons/CircleCheckmarkIcon.js @@ -5,11 +5,13 @@ import BaseIcon from './BaseIcon'; export default class CircleCheckmarkIcon extends BaseIcon { render() { return ( - - - - + + + + ); } diff --git a/client/src/javascript/components/icons/CircleExclamationIcon.js b/client/src/javascript/components/icons/CircleExclamationIcon.js index d464ef54..2f5a262f 100644 --- a/client/src/javascript/components/icons/CircleExclamationIcon.js +++ b/client/src/javascript/components/icons/CircleExclamationIcon.js @@ -5,11 +5,13 @@ import BaseIcon from './BaseIcon'; export default class CircleExclamationIcon extends BaseIcon { render() { return ( - - - - + + + + ); } diff --git a/client/src/javascript/components/icons/CircleIcon.js b/client/src/javascript/components/icons/CircleIcon.js index 8359deaf..6466efc8 100644 --- a/client/src/javascript/components/icons/CircleIcon.js +++ b/client/src/javascript/components/icons/CircleIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class Circle extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/ClipboardIcon.js b/client/src/javascript/components/icons/ClipboardIcon.js index c01c7b6e..0e226903 100644 --- a/client/src/javascript/components/icons/ClipboardIcon.js +++ b/client/src/javascript/components/icons/ClipboardIcon.js @@ -5,13 +5,12 @@ import BaseIcon from './BaseIcon'; export default class ClipboardIcon extends BaseIcon { render() { return ( - - - - - - + + + + + + ); } diff --git a/client/src/javascript/components/icons/ClockIcon.js b/client/src/javascript/components/icons/ClockIcon.js index 72c25b7c..19bfac22 100644 --- a/client/src/javascript/components/icons/ClockIcon.js +++ b/client/src/javascript/components/icons/ClockIcon.js @@ -5,10 +5,9 @@ import BaseIcon from './BaseIcon'; export default class ClockIcon extends BaseIcon { render() { return ( - - - + + + ); } diff --git a/client/src/javascript/components/icons/Close.js b/client/src/javascript/components/icons/Close.js index 12df69cb..6c330b24 100644 --- a/client/src/javascript/components/icons/Close.js +++ b/client/src/javascript/components/icons/Close.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Close extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/CommentIcon.js b/client/src/javascript/components/icons/CommentIcon.js index e419bdec..2004234c 100644 --- a/client/src/javascript/components/icons/CommentIcon.js +++ b/client/src/javascript/components/icons/CommentIcon.js @@ -5,7 +5,8 @@ import BaseIcon from './BaseIcon'; export default class CommentIcon extends BaseIcon { render() { return ( - diff --git a/client/src/javascript/components/icons/Completed.js b/client/src/javascript/components/icons/Completed.js index 46911a62..99816e6f 100644 --- a/client/src/javascript/components/icons/Completed.js +++ b/client/src/javascript/components/icons/Completed.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Completed extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/DetailNotAvailableIcon.js b/client/src/javascript/components/icons/DetailNotAvailableIcon.js index 01d5157b..58a2a991 100644 --- a/client/src/javascript/components/icons/DetailNotAvailableIcon.js +++ b/client/src/javascript/components/icons/DetailNotAvailableIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class DetailNotAvailableIcon extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/Disk.js b/client/src/javascript/components/icons/Disk.js index f67785eb..3692e509 100644 --- a/client/src/javascript/components/icons/Disk.js +++ b/client/src/javascript/components/icons/Disk.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Disk extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/DiskIcon.js b/client/src/javascript/components/icons/DiskIcon.js index 7e19d420..3aec041e 100644 --- a/client/src/javascript/components/icons/DiskIcon.js +++ b/client/src/javascript/components/icons/DiskIcon.js @@ -5,19 +5,20 @@ import BaseIcon from './BaseIcon'; export default class DiskIcon extends BaseIcon { render() { return ( - - - - - - - - - - - + + + + + + + + + + + ); } diff --git a/client/src/javascript/components/icons/DotsMini.js b/client/src/javascript/components/icons/DotsMini.js index 7be8947a..300a1bec 100644 --- a/client/src/javascript/components/icons/DotsMini.js +++ b/client/src/javascript/components/icons/DotsMini.js @@ -5,11 +5,10 @@ import BaseIcon from './BaseIcon'; export default class DotsMini extends BaseIcon { render() { return ( - - - - + + + + ); } diff --git a/client/src/javascript/components/icons/Download.js b/client/src/javascript/components/icons/Download.js index 20796338..ef641ac8 100644 --- a/client/src/javascript/components/icons/Download.js +++ b/client/src/javascript/components/icons/Download.js @@ -5,10 +5,9 @@ import BaseIcon from './BaseIcon'; export default class Download extends BaseIcon { render() { return ( - - - + + + ); } diff --git a/client/src/javascript/components/icons/DownloadSmall.js b/client/src/javascript/components/icons/DownloadSmall.js index 9d7c63bc..f2bf889b 100644 --- a/client/src/javascript/components/icons/DownloadSmall.js +++ b/client/src/javascript/components/icons/DownloadSmall.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class DownloadSmall extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/DownloadThickIcon.js b/client/src/javascript/components/icons/DownloadThickIcon.js index fa70551d..f2115ffc 100644 --- a/client/src/javascript/components/icons/DownloadThickIcon.js +++ b/client/src/javascript/components/icons/DownloadThickIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class DownloadThickIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/ETA.js b/client/src/javascript/components/icons/ETA.js index db5f9281..92490c9e 100644 --- a/client/src/javascript/components/icons/ETA.js +++ b/client/src/javascript/components/icons/ETA.js @@ -5,10 +5,15 @@ import BaseIcon from './BaseIcon'; export default class ETA extends BaseIcon { render() { return ( - - - + + + ); } diff --git a/client/src/javascript/components/icons/ErrorIcon.js b/client/src/javascript/components/icons/ErrorIcon.js index 1131e0dd..f7be7a63 100644 --- a/client/src/javascript/components/icons/ErrorIcon.js +++ b/client/src/javascript/components/icons/ErrorIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Error extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/FeedIcon.js b/client/src/javascript/components/icons/FeedIcon.js index 43748cde..c0f06a55 100644 --- a/client/src/javascript/components/icons/FeedIcon.js +++ b/client/src/javascript/components/icons/FeedIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class FeedIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/File.js b/client/src/javascript/components/icons/File.js index ce8e789c..a3c88567 100644 --- a/client/src/javascript/components/icons/File.js +++ b/client/src/javascript/components/icons/File.js @@ -5,10 +5,9 @@ import BaseIcon from './BaseIcon'; export default class File extends BaseIcon { render() { return ( - + - + ); diff --git a/client/src/javascript/components/icons/Files.js b/client/src/javascript/components/icons/Files.js index 5f668caf..b5235962 100644 --- a/client/src/javascript/components/icons/Files.js +++ b/client/src/javascript/components/icons/Files.js @@ -5,11 +5,19 @@ import BaseIcon from './BaseIcon'; export default class Files extends BaseIcon { render() { return ( - - - - + + + + ); } diff --git a/client/src/javascript/components/icons/FolderClosedOutlined.js b/client/src/javascript/components/icons/FolderClosedOutlined.js index 63fa22eb..04258db1 100644 --- a/client/src/javascript/components/icons/FolderClosedOutlined.js +++ b/client/src/javascript/components/icons/FolderClosedOutlined.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class FolderClosedOutline extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/FolderClosedSolid.js b/client/src/javascript/components/icons/FolderClosedSolid.js index 1ca1a75a..33a8636d 100644 --- a/client/src/javascript/components/icons/FolderClosedSolid.js +++ b/client/src/javascript/components/icons/FolderClosedSolid.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class FolderClosedOutline extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/FolderOpenOutlined.js b/client/src/javascript/components/icons/FolderOpenOutlined.js index a611812a..8738478c 100644 --- a/client/src/javascript/components/icons/FolderOpenOutlined.js +++ b/client/src/javascript/components/icons/FolderOpenOutlined.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class FolderOpenOutlined extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/FolderOpenSolid.js b/client/src/javascript/components/icons/FolderOpenSolid.js index b72008d1..7c3dbcdb 100644 --- a/client/src/javascript/components/icons/FolderOpenSolid.js +++ b/client/src/javascript/components/icons/FolderOpenSolid.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class FolderOpenSolid extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/HashIcon.js b/client/src/javascript/components/icons/HashIcon.js index 94b80c96..baf72ad5 100644 --- a/client/src/javascript/components/icons/HashIcon.js +++ b/client/src/javascript/components/icons/HashIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class HashIcon extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/Inactive.js b/client/src/javascript/components/icons/Inactive.js index 65c376ab..88af526c 100644 --- a/client/src/javascript/components/icons/Inactive.js +++ b/client/src/javascript/components/icons/Inactive.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Inactive extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/InfinityIcon.js b/client/src/javascript/components/icons/InfinityIcon.js index b94f3f26..f5f84d6d 100644 --- a/client/src/javascript/components/icons/InfinityIcon.js +++ b/client/src/javascript/components/icons/InfinityIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class InfinityIcon extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/InformationIcon.js b/client/src/javascript/components/icons/InformationIcon.js index 8c4928df..809ed698 100644 --- a/client/src/javascript/components/icons/InformationIcon.js +++ b/client/src/javascript/components/icons/InformationIcon.js @@ -5,11 +5,16 @@ import BaseIcon from './BaseIcon'; export default class InformationIcon extends BaseIcon { render() { return ( - - - - + + + + ); } diff --git a/client/src/javascript/components/icons/Limits.js b/client/src/javascript/components/icons/Limits.js index 8fa237ad..1236faef 100644 --- a/client/src/javascript/components/icons/Limits.js +++ b/client/src/javascript/components/icons/Limits.js @@ -5,15 +5,26 @@ import BaseIcon from './BaseIcon'; export default class Limits extends BaseIcon { render() { return ( - - - - - - - - + + + + + + + + ); } diff --git a/client/src/javascript/components/icons/LoadingIndicatorDots.js b/client/src/javascript/components/icons/LoadingIndicatorDots.js index 82db6c09..5bd3b925 100644 --- a/client/src/javascript/components/icons/LoadingIndicatorDots.js +++ b/client/src/javascript/components/icons/LoadingIndicatorDots.js @@ -5,11 +5,21 @@ import BaseIcon from './BaseIcon'; export default class LoadingIndicatorDots extends BaseIcon { render() { return ( - - - - + + + ); } diff --git a/client/src/javascript/components/icons/LockIcon.js b/client/src/javascript/components/icons/LockIcon.js index ce3d8bec..d3ce8f68 100644 --- a/client/src/javascript/components/icons/LockIcon.js +++ b/client/src/javascript/components/icons/LockIcon.js @@ -5,10 +5,11 @@ import BaseIcon from './BaseIcon'; export default class LockIcon extends BaseIcon { render() { return ( - - + + ); diff --git a/client/src/javascript/components/icons/Logout.js b/client/src/javascript/components/icons/Logout.js index 9fd88d8f..6f21dfae 100644 --- a/client/src/javascript/components/icons/Logout.js +++ b/client/src/javascript/components/icons/Logout.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class Logout extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/NotificationIcon.js b/client/src/javascript/components/icons/NotificationIcon.js index 91fb4a55..a5db7da9 100644 --- a/client/src/javascript/components/icons/NotificationIcon.js +++ b/client/src/javascript/components/icons/NotificationIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class NotificationIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/PeersIcon.js b/client/src/javascript/components/icons/PeersIcon.js index c99c1f8a..ce1e694d 100644 --- a/client/src/javascript/components/icons/PeersIcon.js +++ b/client/src/javascript/components/icons/PeersIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class PeersIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/RadarIcon.js b/client/src/javascript/components/icons/RadarIcon.js index 5ca7b152..200181e9 100644 --- a/client/src/javascript/components/icons/RadarIcon.js +++ b/client/src/javascript/components/icons/RadarIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class RadarIcon extends BaseIcon { render() { return ( - + diff --git a/client/src/javascript/components/icons/RadioDot.js b/client/src/javascript/components/icons/RadioDot.js index 7533128b..0ca183d9 100644 --- a/client/src/javascript/components/icons/RadioDot.js +++ b/client/src/javascript/components/icons/RadioDot.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class RadioDot extends BaseIcon { render() { return ( - + ); diff --git a/client/src/javascript/components/icons/Ratio.js b/client/src/javascript/components/icons/Ratio.js index cf498ca7..a3e4e045 100644 --- a/client/src/javascript/components/icons/Ratio.js +++ b/client/src/javascript/components/icons/Ratio.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Ratio extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/RatioIcon.js b/client/src/javascript/components/icons/RatioIcon.js index 20569e0e..cd56779b 100644 --- a/client/src/javascript/components/icons/RatioIcon.js +++ b/client/src/javascript/components/icons/RatioIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class RatioIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/Remove.js b/client/src/javascript/components/icons/Remove.js index 94857962..85a7b01f 100644 --- a/client/src/javascript/components/icons/Remove.js +++ b/client/src/javascript/components/icons/Remove.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class AddMini extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/RemoveMini.js b/client/src/javascript/components/icons/RemoveMini.js index 562d6286..a9b91582 100644 --- a/client/src/javascript/components/icons/RemoveMini.js +++ b/client/src/javascript/components/icons/RemoveMini.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class RemoveMini extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/Search.js b/client/src/javascript/components/icons/Search.js index 6dc858f4..dcf97c9e 100644 --- a/client/src/javascript/components/icons/Search.js +++ b/client/src/javascript/components/icons/Search.js @@ -5,10 +5,15 @@ import BaseIcon from './BaseIcon'; export default class Search extends BaseIcon { render() { return ( - - - + + + ); } diff --git a/client/src/javascript/components/icons/SeedsIcon.js b/client/src/javascript/components/icons/SeedsIcon.js index a636ac0e..c3d1d7fb 100644 --- a/client/src/javascript/components/icons/SeedsIcon.js +++ b/client/src/javascript/components/icons/SeedsIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class SeedsIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/SettingsIcon.js b/client/src/javascript/components/icons/SettingsIcon.js index d5a12dc2..35299f18 100644 --- a/client/src/javascript/components/icons/SettingsIcon.js +++ b/client/src/javascript/components/icons/SettingsIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class SettingsIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/SpinnerIcon.js b/client/src/javascript/components/icons/SpinnerIcon.js index e562f397..9830bbb8 100644 --- a/client/src/javascript/components/icons/SpinnerIcon.js +++ b/client/src/javascript/components/icons/SpinnerIcon.js @@ -18,14 +18,21 @@ export default class SpinnerIcon extends BaseIcon { let maskID = `icon--spinner__mask-id--${this.id}`; return ( - + - + - + ); } diff --git a/client/src/javascript/components/icons/StartIcon.js b/client/src/javascript/components/icons/StartIcon.js index 82d49ef7..3d33bb1c 100644 --- a/client/src/javascript/components/icons/StartIcon.js +++ b/client/src/javascript/components/icons/StartIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Start extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/StopIcon.js b/client/src/javascript/components/icons/StopIcon.js index 347e1a2c..365cd3ec 100644 --- a/client/src/javascript/components/icons/StopIcon.js +++ b/client/src/javascript/components/icons/StopIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class Stop extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/icons/TrackerMessageIcon.js b/client/src/javascript/components/icons/TrackerMessageIcon.js index 86c50e00..42835543 100644 --- a/client/src/javascript/components/icons/TrackerMessageIcon.js +++ b/client/src/javascript/components/icons/TrackerMessageIcon.js @@ -5,8 +5,7 @@ import BaseIcon from './BaseIcon'; export default class TrackerMessageIcon extends BaseIcon { render() { return ( - + diff --git a/client/src/javascript/components/icons/Upload.js b/client/src/javascript/components/icons/Upload.js index 62c8832c..d8b45275 100644 --- a/client/src/javascript/components/icons/Upload.js +++ b/client/src/javascript/components/icons/Upload.js @@ -5,10 +5,9 @@ import BaseIcon from './BaseIcon'; export default class Upload extends BaseIcon { render() { return ( - - - + + + ); } diff --git a/client/src/javascript/components/icons/UploadThickIcon.js b/client/src/javascript/components/icons/UploadThickIcon.js index 606c6710..f3502fb4 100644 --- a/client/src/javascript/components/icons/UploadThickIcon.js +++ b/client/src/javascript/components/icons/UploadThickIcon.js @@ -5,9 +5,8 @@ import BaseIcon from './BaseIcon'; export default class UploadThickIcon extends BaseIcon { render() { return ( - - + + ); } diff --git a/client/src/javascript/components/layout/ApplicationContent.js b/client/src/javascript/components/layout/ApplicationContent.js index df72f699..325c10c9 100644 --- a/client/src/javascript/components/layout/ApplicationContent.js +++ b/client/src/javascript/components/layout/ApplicationContent.js @@ -3,15 +3,11 @@ import React from 'react'; class ApplicationContent extends React.Component { static propTypes = { - children: PropTypes.node + children: PropTypes.node, }; render() { - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/layout/ApplicationPanel.js b/client/src/javascript/components/layout/ApplicationPanel.js index 31a9ca4c..c46acdc6 100644 --- a/client/src/javascript/components/layout/ApplicationPanel.js +++ b/client/src/javascript/components/layout/ApplicationPanel.js @@ -6,24 +6,20 @@ class ApplicationContent extends React.Component { static propTypes = { children: PropTypes.node, className: PropTypes.string, - modifier: PropTypes.string + modifier: PropTypes.string, }; static defaultProps = { - baseClassName: 'application__panel' + baseClassName: 'application__panel', }; render() { let classes = classnames(this.props.baseClassName, { [`${this.props.baseClassName}--${this.props.modifier}`]: this.props.baseClassName, - [this.props.className]: this.props.className + [this.props.className]: this.props.className, }); - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/layout/ApplicationView.js b/client/src/javascript/components/layout/ApplicationView.js index a93cbe61..5d25aaab 100644 --- a/client/src/javascript/components/layout/ApplicationView.js +++ b/client/src/javascript/components/layout/ApplicationView.js @@ -5,19 +5,15 @@ import React from 'react'; class ApplicationView extends React.Component { static propTypes = { children: PropTypes.node, - modifier: PropTypes.string + modifier: PropTypes.string, }; render() { let classes = classnames('application__view', { - [`application__view--${this.props.modifier}`]: this.props.modifier != null + [`application__view--${this.props.modifier}`]: this.props.modifier != null, }); - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/modals/Modal.js b/client/src/javascript/components/modals/Modal.js index f672a70e..8890489b 100644 --- a/client/src/javascript/components/modals/Modal.js +++ b/client/src/javascript/components/modals/Modal.js @@ -12,10 +12,10 @@ export default class Modal extends React.Component { this.domRefs = {}; this.state = { - activeTabId: null + activeTabId: null, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -41,18 +41,23 @@ export default class Modal extends React.Component { } render() { - const contentWrapperClasses = classnames('modal__content__wrapper', - `modal--align-${this.props.alignment}`, `modal--size-${this.props.size}`, { - 'modal--horizontal': this.props.orientation === 'horizontal', - 'modal--vertical': this.props.orientation === 'vertical', - 'modal--tabs-in-header': !this.props.tabsInBody, - 'modal--tabs-in-body': this.props.tabsInBody, - 'inverse': this.props.inverse - }, this.props.className); + const contentWrapperClasses = classnames( + 'modal__content__wrapper', + `modal--align-${this.props.alignment}`, + `modal--size-${this.props.size}`, + { + 'modal--horizontal': this.props.orientation === 'horizontal', + 'modal--vertical': this.props.orientation === 'vertical', + 'modal--tabs-in-header': !this.props.tabsInBody, + 'modal--tabs-in-body': this.props.tabsInBody, + inverse: this.props.inverse, + }, + this.props.className + ); let modalBody = this.props.content; let modalHeader = this.props.heading; let headerClasses = classnames('modal__header', { - 'has-tabs': this.props.tabs + 'has-tabs': this.props.tabs, }); let bodyTabs; @@ -62,8 +67,7 @@ export default class Modal extends React.Component { if (this.props.tabs) { let activeTabId = this.getActiveTabId(); let activeTab = this.props.tabs[activeTabId]; - let contentClasses = classnames('modal__content', - activeTab.modalContentClasses); + let contentClasses = classnames('modal__content', activeTab.modalContentClasses); let ModalContentComponent = activeTab.content; let modalContentData = activeTab.props; @@ -87,15 +91,14 @@ export default class Modal extends React.Component { bodyTabs,
    -
    +
    , ]; } if (this.props.actions) { footer = (
    - +
    ); } @@ -106,8 +109,7 @@ export default class Modal extends React.Component { {modalHeader} {headerTabs}
    -
    this.setRef('modal-body', ref)}> +
    this.setRef('modal-body', ref)}> {modalBody} {footer}
    @@ -122,5 +124,5 @@ Modal.defaultProps = { inverse: true, size: 'medium', orientation: 'horizontal', - tabsInBody: false + tabsInBody: false, }; diff --git a/client/src/javascript/components/modals/ModalActions.js b/client/src/javascript/components/modals/ModalActions.js index 3eb7caa9..703e81cf 100644 --- a/client/src/javascript/components/modals/ModalActions.js +++ b/client/src/javascript/components/modals/ModalActions.js @@ -8,17 +8,12 @@ export default class ModalActions extends React.Component { getModalButtons(actions) { let buttons = actions.map((action, index) => { let classes = classnames('button', { - [action.supplementalClassName]: action.supplementalClassName + [action.supplementalClassName]: action.supplementalClassName, }); if (action.type === 'checkbox') { return ( - + {action.content} ); @@ -31,22 +26,17 @@ export default class ModalActions extends React.Component { onClick={this.getClickHandler(action)} priority={action.type} key={index} - type={action.submit ? 'submit' : 'button'} - > + type={action.submit ? 'submit' : 'button'}> {action.content} ); }); - return ( -
    - {buttons} -
    - ); + return
    {buttons}
    ; } getClickHandler(action) { - return (event) => { + return event => { if (action.clickHandler) { action.clickHandler(event); } @@ -58,14 +48,10 @@ export default class ModalActions extends React.Component { } render() { - return ( -
    - {this.getModalButtons(this.props.actions)} -
    - ); + return
    {this.getModalButtons(this.props.actions)}
    ; } } ModalActions.defaultProps = { - alignment: 'left' + alignment: 'left', }; diff --git a/client/src/javascript/components/modals/ModalTabs.js b/client/src/javascript/components/modals/ModalTabs.js index 11d27d9d..b31c46a8 100644 --- a/client/src/javascript/components/modals/ModalTabs.js +++ b/client/src/javascript/components/modals/ModalTabs.js @@ -15,24 +15,19 @@ export default class ModalTabs extends React.Component { currentTab.id = tabId; let classes = classnames('modal__tab', { - 'is-active': tabId === this.props.activeTabId + 'is-active': tabId === this.props.activeTabId, }); return ( -
  • +
  • {currentTab.label}
  • ); }); - return ( -
      - {tabs} -
    - ); + return
      {tabs}
    ; } } ModalTabs.defaultProps = { - tabs: [] + tabs: [], }; diff --git a/client/src/javascript/components/modals/Modals.js b/client/src/javascript/components/modals/Modals.js index 4b5859fa..3ab961cb 100644 --- a/client/src/javascript/components/modals/Modals.js +++ b/client/src/javascript/components/modals/Modals.js @@ -14,11 +14,7 @@ import TorrentDetailsModal from './torrent-details-modal/TorrentDetailsModal'; import UIActions from '../../actions/UIActions'; import UIStore from '../../stores/UIStore'; -const METHODS_TO_BIND = [ - 'handleKeyPress', - 'handleOverlayClick', - 'onModalChange' -]; +const METHODS_TO_BIND = ['handleKeyPress', 'handleOverlayClick', 'onModalChange']; export default class Modals extends React.Component { constructor() { @@ -32,14 +28,14 @@ export default class Modals extends React.Component { 'remove-torrents': RemoveTorrentsModal, 'set-taxonomy': SetTagsModal, settings: SettingsModal, - 'torrent-details': TorrentDetailsModal + 'torrent-details': TorrentDetailsModal, }; this.state = { - activeModal: null + activeModal: null, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -63,10 +59,7 @@ export default class Modals extends React.Component { getModal() { let ActiveModal = this.modals[this.state.activeModal.id]; - return ( - - ); + return ; } handleKeyPress(event) { @@ -100,10 +93,7 @@ export default class Modals extends React.Component { } return ( - + {modal} ); diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsActions.js b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsActions.js index deebec42..417c34ec 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsActions.js +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsActions.js @@ -12,39 +12,37 @@ class AddTorrentsActions extends PureComponent { clickHandler: this.handleStartTorrentsToggle, content: this.props.intl.formatMessage({ id: 'torrents.add.start.label', - defaultMessage: 'Start Torrent' + defaultMessage: 'Start Torrent', }), id: 'start', triggerDismiss: false, - type: 'checkbox' + type: 'checkbox', }, { clickHandler: null, content: this.props.intl.formatMessage({ id: 'button.cancel', - defaultMessage: 'Cancel' + defaultMessage: 'Cancel', }), triggerDismiss: true, - type: 'tertiary' + type: 'tertiary', }, { clickHandler: this.props.onAddTorrentsClick, content: this.props.intl.formatMessage({ id: 'torrents.add.button.add', - defaultMessage: 'Add Torrent' + defaultMessage: 'Add Torrent', }), isLoading: this.props.isAddingTorrents, submit: true, triggerDismiss: false, - type: 'primary' - } + type: 'primary', + }, ]; } render() { - return ( - - ); + return ; } } diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.js b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.js index 5c6050d4..8f331392 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.js +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsByFile.js @@ -20,7 +20,7 @@ class AddTorrentsByFile extends React.Component { isAddingTorrents: false, files: [], tags: '', - startTorrents: SettingsStore.getFloodSettings('startTorrentsOnLoad') + startTorrents: SettingsStore.getFloodSettings('startTorrentsOnLoad'), }; getFileDropzone() { @@ -29,21 +29,14 @@ class AddTorrentsByFile extends React.Component { if (this.state.files.length > 0) { const files = this.state.files.map((file, index) => { return ( -
  • +
  • - - {file.name} - + {file.name} this.handleFileRemove(index)} - > + onClick={() => this.handleFileRemove(index)}>
  • @@ -51,10 +44,7 @@ class AddTorrentsByFile extends React.Component { }); fileContent = ( -
      +
        {files}
      ); @@ -63,10 +53,7 @@ class AddTorrentsByFile extends React.Component { return ( {fileContent} + disablePreview>
      - - {' '} + {' '} - - . + + + .
      @@ -105,7 +85,7 @@ class AddTorrentsByFile extends React.Component { } this.setState(state => { - return { errors: nextErrorsState, files: state.files.concat(files) }; + return {errors: nextErrorsState, files: state.files.concat(files)}; }); }; @@ -148,22 +128,20 @@ class AddTorrentsByFile extends React.Component { render() { return ( -
      this._formRef = ref}> - - {this.getFileDropzone()} - + (this._formRef = ref)}> + {this.getFileDropzone()} { - if (/^urls/.test(formItemKey)) { - accumulator.push(this._formData[formItemKey]); - } + return Object.keys(this._formData).reduce((accumulator, formItemKey) => { + if (/^urls/.test(formItemKey)) { + accumulator.push(this._formData[formItemKey]); + } - return accumulator; - }, - [] - ); + return accumulator; + }, []); } handleAddTorrents = () => { @@ -43,12 +40,12 @@ class AddTorrentsByURL extends React.Component { destination: formData.destination, isBasePath: formData.useBasePath, start: formData.start, - tags: formData.tags.split(',') + tags: formData.tags.split(','), }); SettingsStore.updateOptimisticallyOnly({ id: 'startTorrentsOnLoad', - data: formData.start + data: formData.start, }); }; @@ -58,23 +55,23 @@ class AddTorrentsByURL extends React.Component { render() { return ( - this._formRef = ref}> + (this._formRef = ref)}> @@ -83,7 +80,7 @@ class AddTorrentsByURL extends React.Component { defaultValue={this.state.tags} label={this.props.intl.formatMessage({ id: 'torrents.add.tags', - defaultMessage: 'Tags' + defaultMessage: 'Tags', })} /> diff --git a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.js b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.js index 7b51e31c..338ead1c 100644 --- a/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.js +++ b/client/src/javascript/components/modals/add-torrents-modal/AddTorrentsModal.js @@ -17,23 +17,23 @@ class AddTorrents extends React.Component { content: AddTorrentsByURL, label: this.props.intl.formatMessage({ id: 'torrents.add.tab.url.title', - defaultMessage: 'By URL' - }) + defaultMessage: 'By URL', + }), }, 'by-file': { content: AddTorrentsByFile, label: this.props.intl.formatMessage({ id: 'torrents.add.tab.file.title', - defaultMessage: 'By File' - }) - } + defaultMessage: 'By File', + }), + }, }; return ( - {this.props.options.content} -
    - ); + return
    {this.props.options.content}
    ; } render() { diff --git a/client/src/javascript/components/modals/feeds-modal/DownloadRulesTab.js b/client/src/javascript/components/modals/feeds-modal/DownloadRulesTab.js index 38cdef29..b0b1dacc 100644 --- a/client/src/javascript/components/modals/feeds-modal/DownloadRulesTab.js +++ b/client/src/javascript/components/modals/feeds-modal/DownloadRulesTab.js @@ -1,5 +1,16 @@ import _ from 'lodash'; -import {Button, Checkbox, Form, FormError, FormRow, FormRowGroup, FormRowItem, Select, SelectItem, Textbox} from 'flood-ui-kit'; +import { + Button, + Checkbox, + Form, + FormError, + FormRow, + FormRowGroup, + FormRowItem, + Select, + SelectItem, + Textbox, +} from 'flood-ui-kit'; import {defineMessages, FormattedMessage, injectIntl} from 'react-intl'; import React from 'react'; @@ -13,116 +24,100 @@ import Validator from '../../../util/Validator'; const MESSAGES = defineMessages({ mustSpecifyDestination: { id: 'feeds.validation.must.specify.destination', - defaultMessage: 'You must specify a destination.' + defaultMessage: 'You must specify a destination.', }, mustSelectFeed: { id: 'feeds.validation.must.select.feed', - defaultMessage: 'You must select a feed.' + defaultMessage: 'You must select a feed.', }, mustSpecifyLabel: { id: 'feeds.validation.must.specify.label', - defaultMessage: 'You must specify a label.' + defaultMessage: 'You must specify a label.', }, invalidRegularExpression: { id: 'feeds.validation.invalid.regular.expression', - defaultMessage: 'Invalid regular expression.' + defaultMessage: 'Invalid regular expression.', }, url: { id: 'feeds.url', - defaultMessage: 'URL' + defaultMessage: 'URL', }, label: { id: 'feeds.label', - defaultMessage: 'Label' + defaultMessage: 'Label', }, regEx: { id: 'feeds.regEx', - defaultMessage: 'RegEx' + defaultMessage: 'RegEx', }, tags: { id: 'feeds.tags', - defaultMessage: 'Tags' - } + defaultMessage: 'Tags', + }, }); class DownloadRulesTab extends React.Component { validatedFields = { destination: { isValid: Validator.isNotEmpty, - error: this.props.intl.formatMessage(MESSAGES.mustSpecifyDestination) + error: this.props.intl.formatMessage(MESSAGES.mustSpecifyDestination), }, feedID: { isValid: Validator.isNotEmpty, - error: this.props.intl.formatMessage(MESSAGES.mustSelectFeed) + error: this.props.intl.formatMessage(MESSAGES.mustSelectFeed), }, label: { isValid: Validator.isNotEmpty, - error: this.props.intl.formatMessage(MESSAGES.mustSpecifyLabel) + error: this.props.intl.formatMessage(MESSAGES.mustSpecifyLabel), }, match: { - isValid: (value) => { + isValid: value => { return Validator.isNotEmpty(value) && Validator.isRegExValid(value); }, - error: this.props.intl.formatMessage(MESSAGES.invalidRegularExpression) + error: this.props.intl.formatMessage(MESSAGES.invalidRegularExpression), }, exclude: { - isValid: (value) => { + isValid: value => { if (Validator.isNotEmpty(value)) { return Validator.isRegExValid(value); } return true; }, - error: this.props.intl.formatMessage(MESSAGES.invalidRegularExpression) - } + error: this.props.intl.formatMessage(MESSAGES.invalidRegularExpression), + }, }; state = { errors: {}, feeds: FeedMonitorStore.getFeeds(), - rules: FeedMonitorStore.getRules() + rules: FeedMonitorStore.getRules(), }; componentDidMount() { - FeedMonitorStore.listen( - EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, - this.handleFeedMonitorsFetchSuccess - ); + FeedMonitorStore.listen(EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, this.handleFeedMonitorsFetchSuccess); } componentWillUnmount() { - FeedMonitorStore.unlisten( - EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, - this.handleFeedMonitorsFetchSuccess - ); + FeedMonitorStore.unlisten(EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, this.handleFeedMonitorsFetchSuccess); } - checkFieldValidity = _.throttle( - (fieldName, fieldValue) => { - const {errors} = this.state; + checkFieldValidity = _.throttle((fieldName, fieldValue) => { + const {errors} = this.state; - if ( - this.state.errors[fieldName] - && this.validatedFields[fieldName].isValid(fieldValue) - ) { - delete errors[fieldName]; - this.setState({errors}); - } - }, - 150 - ); + if (this.state.errors[fieldName] && this.validatedFields[fieldName].isValid(fieldValue)) { + delete errors[fieldName]; + this.setState({errors}); + } + }, 150); getAmendedFormData() { const formData = this.formRef.getFormData(); - return Object.assign( - {}, - formData, - { - field: 'title', - tags: formData.tags.split(',') - } - ); + return Object.assign({}, formData, { + field: 'title', + tags: formData.tags.split(','), + }); } getAvailableFeedsOptions() { @@ -130,45 +125,38 @@ class DownloadRulesTab extends React.Component { return [ - + - + , ]; } - return this.state.feeds.reduce((feedOptions, feed) => { - return feedOptions.concat( - - {feed.label} - - ); - }, [ - - - - - - ]); + return this.state.feeds.reduce( + (feedOptions, feed) => { + return feedOptions.concat( + + {feed.label} + + ); + }, + [ + + + + + , + ] + ); } getRuleFields() { - const errors = Object.keys(this.state.errors).map( - (errorID, index) => { - return ( - - - {this.state.errors[errorID]} - - - ); - } - ); + const errors = Object.keys(this.state.errors).map((errorID, index) => { + return ( + + {this.state.errors[errorID]} + + ); + }); return ( @@ -178,7 +166,7 @@ class DownloadRulesTab extends React.Component { id="label" label={this.props.intl.formatMessage({ id: 'feeds.label', - defaultMessage: 'Label' + defaultMessage: 'Label', })} /> @@ -197,7 +184,7 @@ class DownloadRulesTab extends React.Component { id="match" label={this.props.intl.formatMessage({ id: 'feeds.match.pattern', - defaultMessage: 'Match Pattern' + defaultMessage: 'Match Pattern', })} placeholder={this.props.intl.formatMessage(MESSAGES.regEx)} /> @@ -205,7 +192,7 @@ class DownloadRulesTab extends React.Component { id="exclude" label={this.props.intl.formatMessage({ id: 'feeds.exclude.pattern', - defaultMessage: 'Exclude Pattern' + defaultMessage: 'Exclude Pattern', })} placeholder={this.props.intl.formatMessage(MESSAGES.regEx)} /> @@ -213,7 +200,7 @@ class DownloadRulesTab extends React.Component { id="tags" label={this.props.intl.formatMessage({ id: 'feeds.apply.tags', - defaultMessage: 'Apply Tags' + defaultMessage: 'Apply Tags', })} placeholder={this.props.intl.formatMessage(MESSAGES.tags)} /> @@ -222,22 +209,16 @@ class DownloadRulesTab extends React.Component { id="destination" label={this.props.intl.formatMessage({ id: 'feeds.torrent.destination', - defaultMessage: 'Torrent Destination' + defaultMessage: 'Torrent Destination', })} /> - + @@ -249,10 +230,7 @@ class DownloadRulesTab extends React.Component { return (
    • - +
    ); @@ -265,29 +243,26 @@ class DownloadRulesTab extends React.Component { if (rule.exclude) { excludeNode = ( -
  • - {rule.exclude} + {rule.exclude}
  • ); } if (rule.tags && rule.tags.length > 0) { const tagNodes = rule.tags.map((tag, index) => { - return {tag}; + return ( + + {tag} + + ); }); tags = ( -
  • - {tagNodes} +
  • + {tagNodes}
  • ); } @@ -296,25 +271,28 @@ class DownloadRulesTab extends React.Component {
    • -
    • {rule.label}
    • -
    • - + {# matches}}" + values={{count: matchedCount}} + />
      -
    • - {rule.match} + {rule.match}
    • {excludeNode} {tags} @@ -322,25 +300,20 @@ class DownloadRulesTab extends React.Component {
    this.handleRemoveRuleClick(rule)} - > + onClick={() => this.handleRemoveRuleClick(rule)}>
  • ); }); - return ( -
      - {rulesList} -
    - ); + return
      {rulesList}
    ; } handleFeedMonitorsFetchSuccess = () => { this.setState({ feeds: FeedMonitorStore.getFeeds(), - rules: FeedMonitorStore.getRules() + rules: FeedMonitorStore.getRules(), }); }; @@ -367,18 +340,15 @@ class DownloadRulesTab extends React.Component { validateForm() { const formData = this.getAmendedFormData(); - const errors = Object.keys(this.validatedFields).reduce( - (accumulator, fieldName) => { - const fieldValue = formData[fieldName]; + const errors = Object.keys(this.validatedFields).reduce((accumulator, fieldName) => { + const fieldValue = formData[fieldName]; - if (!this.validatedFields[fieldName].isValid(fieldValue)) { - accumulator[fieldName] = this.validatedFields[fieldName].error; - } + if (!this.validatedFields[fieldName].isValid(fieldValue)) { + accumulator[fieldName] = this.validatedFields[fieldName].error; + } - return accumulator; - }, - {} - ); + return accumulator; + }, {}); return {errors, isValid: !Object.keys(errors).length}; } @@ -389,24 +359,15 @@ class DownloadRulesTab extends React.Component { className="inverse" onChange={this.handleFormChange} onSubmit={this.handleFormSubmit} - ref={ref => this.formRef = ref} - > + ref={ref => (this.formRef = ref)}> - + - - {this.getRulesList()} - + {this.getRulesList()} - + {this.getRuleFields()} diff --git a/client/src/javascript/components/modals/feeds-modal/FeedsModal.js b/client/src/javascript/components/modals/feeds-modal/FeedsModal.js index fa3bf052..085c2fd2 100644 --- a/client/src/javascript/components/modals/feeds-modal/FeedsModal.js +++ b/client/src/javascript/components/modals/feeds-modal/FeedsModal.js @@ -17,16 +17,16 @@ class FeedsModal extends React.Component { content: FeedsTab, label: this.props.intl.formatMessage({ id: 'feeds.tabs.feeds', - defaultMessage: 'Feeds' - }) + defaultMessage: 'Feeds', + }), }, downloadRules: { content: DownloadRulesTab, label: this.props.intl.formatMessage({ id: 'feeds.tabs.download.rules', - defaultMessage: 'Download Rules' - }) - } + defaultMessage: 'Download Rules', + }), + }, }; return ( @@ -34,7 +34,7 @@ class FeedsModal extends React.Component { dismiss={this.props.dismiss} heading={this.props.intl.formatMessage({ id: 'feeds.tabs.heading', - defaultMessage: 'Torrent Feeds' + defaultMessage: 'Torrent Feeds', })} orientation="horizontal" size="large" diff --git a/client/src/javascript/components/modals/feeds-modal/FeedsTab.js b/client/src/javascript/components/modals/feeds-modal/FeedsTab.js index 0c4ff8f6..96e22fbf 100644 --- a/client/src/javascript/components/modals/feeds-modal/FeedsTab.js +++ b/client/src/javascript/components/modals/feeds-modal/FeedsTab.js @@ -13,28 +13,28 @@ import Validator from '../../../util/Validator'; const MESSAGES = defineMessages({ mustSpecifyURL: { id: 'feeds.validation.must.specify.valid.feed.url', - defaultMessage: 'You must specify a valid feed URL.' + defaultMessage: 'You must specify a valid feed URL.', }, mustSpecifyLabel: { id: 'feeds.validation.must.specify.label', - defaultMessage: 'You must specify a label.' + defaultMessage: 'You must specify a label.', }, min: { id: 'feeds.time.min', - defaultMessage: '{durationValue} min' + defaultMessage: '{durationValue} min', }, hr: { id: 'feeds.time.hr', - defaultMessage: '{durationValue} hr' + defaultMessage: '{durationValue} hr', }, url: { id: 'feeds.url', - defaultMessage: 'URL' + defaultMessage: 'URL', }, label: { id: 'feeds.label', - defaultMessage: 'Label' - } + defaultMessage: 'Label', + }, }); class FeedsTab extends React.Component { @@ -42,12 +42,12 @@ class FeedsTab extends React.Component { validatedFields = { url: { isValid: Validator.isURLValid, - error: this.props.intl.formatMessage(MESSAGES.mustSpecifyURL) + error: this.props.intl.formatMessage(MESSAGES.mustSpecifyURL), }, label: { isValid: Validator.isNotEmpty, - error: this.props.intl.formatMessage(MESSAGES.mustSpecifyLabel) - } + error: this.props.intl.formatMessage(MESSAGES.mustSpecifyLabel), + }, }; state = { @@ -55,53 +55,41 @@ class FeedsTab extends React.Component { intervals: [ { displayName: this.props.intl.formatMessage(MESSAGES.min, {durationValue: 5}), - value: 5 + value: 5, }, { displayName: this.props.intl.formatMessage(MESSAGES.min, {durationValue: 15}), - value: 15 + value: 15, }, { displayName: this.props.intl.formatMessage(MESSAGES.min, {durationValue: 30}), - value: 30 + value: 30, }, { displayName: this.props.intl.formatMessage(MESSAGES.hr, {durationValue: 5}), - value: 60 - } + value: 60, + }, ], feeds: FeedMonitorStore.getFeeds(), - rules: FeedMonitorStore.getRules() + rules: FeedMonitorStore.getRules(), }; componentDidMount() { - FeedMonitorStore.listen( - EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, - this.handleFeedMonitorsFetchSuccess - ); + FeedMonitorStore.listen(EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, this.handleFeedMonitorsFetchSuccess); } componentWillUnmount() { - FeedMonitorStore.unlisten( - EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, - this.handleFeedMonitorsFetchSuccess - ); + FeedMonitorStore.unlisten(EventTypes.SETTINGS_FEED_MONITORS_FETCH_SUCCESS, this.handleFeedMonitorsFetchSuccess); } - checkFieldValidity = _.throttle( - (fieldName, fieldValue) => { - const {errors} = this.state; + checkFieldValidity = _.throttle((fieldName, fieldValue) => { + const {errors} = this.state; - if ( - this.state.errors[fieldName] - && this.validatedFields[fieldName].isValid(fieldValue) - ) { - delete errors[fieldName]; - this.setState({errors}); - } - }, - 150 - ); + if (this.state.errors[fieldName] && this.validatedFields[fieldName].isValid(fieldValue)) { + delete errors[fieldName]; + this.setState({errors}); + } + }, 150); getIntervalSelectOptions() { return this.state.intervals.map((interval, index) => { @@ -122,32 +110,28 @@ class FeedsTab extends React.Component { label={this.props.intl.formatMessage(MESSAGES.label)} placeholder={this.props.intl.formatMessage(MESSAGES.label)} /> - + @@ -159,10 +143,7 @@ class FeedsTab extends React.Component { return (
    • - +
    ); @@ -175,49 +156,53 @@ class FeedsTab extends React.Component {
    • -
    • {feed.label}
    • -
    • - + {# matches}}" + values={{count: matchedCount}} + />
    this.handleRemoveFeedClick(feed)} - > + onClick={() => this.handleRemoveFeedClick(feed)}>
  • ); }); - return ( -
      - {feedsList} -
    - ); + return
      {feedsList}
    ; } getSelectedDropdownItem(itemSet) { - return this.state[itemSet].find((item) => { + return this.state[itemSet].find(item => { return item.selected; }); } @@ -236,7 +221,7 @@ class FeedsTab extends React.Component { handleFeedMonitorsFetchSuccess = () => { this.setState({ feeds: FeedMonitorStore.getFeeds(), - rules: FeedMonitorStore.getRules() + rules: FeedMonitorStore.getRules(), }); }; @@ -244,7 +229,7 @@ class FeedsTab extends React.Component { this.checkFieldValidity(event.target.name, formData[event.target.name]); }; - handleRemoveFeedClick = (feed) => { + handleRemoveFeedClick = feed => { FeedMonitorStore.removeFeed(feed._id); }; @@ -264,39 +249,28 @@ class FeedsTab extends React.Component { } render() { - const errors = Object.keys(this.state.errors).map( - (errorID, index) => { - return ( - - - {this.state.errors[errorID]} - - - ); - } - ); + const errors = Object.keys(this.state.errors).map((errorID, index) => { + return ( + + {this.state.errors[errorID]} + + ); + }); return (
    this.formRef = ref} - > + ref={ref => (this.formRef = ref)}> - + - - {this.getFeedsList()} - + {this.getFeedsList()} - + {errors} {this.getAddFeedForm()} diff --git a/client/src/javascript/components/modals/move-torrents-modal/MoveTorrentsModal.js b/client/src/javascript/components/modals/move-torrents-modal/MoveTorrentsModal.js index bf05349f..2a519951 100644 --- a/client/src/javascript/components/modals/move-torrents-modal/MoveTorrentsModal.js +++ b/client/src/javascript/components/modals/move-torrents-modal/MoveTorrentsModal.js @@ -15,7 +15,7 @@ class MoveTorrents extends React.Component { isExpanded: false, isSettingDownloadPath: false, moveTorrents: false, - originalSource: null + originalSource: null, }; componentWillMount() { @@ -46,28 +46,28 @@ class MoveTorrents extends React.Component { checked: false, content: this.props.intl.formatMessage({ id: 'torrents.move.data.label', - defaultMessage: 'Move data' + defaultMessage: 'Move data', }), id: 'moveFiles', - type: 'checkbox' + type: 'checkbox', }, { content: this.props.intl.formatMessage({ id: 'button.cancel', - defaultMessage: 'Cancel' + defaultMessage: 'Cancel', }), triggerDismiss: true, - type: 'tertiary' + type: 'tertiary', }, { content: this.props.intl.formatMessage({ id: 'torrents.move.button.set.location', - defaultMessage: 'Set Location' + defaultMessage: 'Set Location', }), isLoading: this.state.isSettingDownloadPath, submit: true, - type: 'primary' - } + type: 'primary', + }, ]; } @@ -75,10 +75,7 @@ class MoveTorrents extends React.Component { return (
    - +
    @@ -96,7 +93,7 @@ class MoveTorrents extends React.Component { isBasePath: formData.useBasePath, filenames, moveFiles: formData.moveFiles, - sources + sources, }); } }; @@ -104,7 +101,10 @@ class MoveTorrents extends React.Component { removeTrailingFilename(path, filename) { let directoryPath = path.substring(0, path.length - filename.length); - if (directoryPath.charAt(directoryPath.length - 1) === '/' || directoryPath.charAt(directoryPath.length - 1) === '\\') { + if ( + directoryPath.charAt(directoryPath.length - 1) === '/' || + directoryPath.charAt(directoryPath.length - 1) === '\\' + ) { directoryPath = directoryPath.substring(0, directoryPath.length - 1); } @@ -118,8 +118,9 @@ class MoveTorrents extends React.Component { dismiss={this.props.dismiss} heading={this.props.intl.formatMessage({ id: 'torrents.move.heading', - defaultMessage: 'Set Torrent Location' - })} /> + defaultMessage: 'Set Torrent Location', + })} + /> ); } } diff --git a/client/src/javascript/components/modals/remove-torrents-modal/RemoveTorrentsModal.js b/client/src/javascript/components/modals/remove-torrents-modal/RemoveTorrentsModal.js index 6fedb0d7..5e240c98 100644 --- a/client/src/javascript/components/modals/remove-torrents-modal/RemoveTorrentsModal.js +++ b/client/src/javascript/components/modals/remove-torrents-modal/RemoveTorrentsModal.js @@ -15,8 +15,8 @@ class RemoveTorrentsModal extends React.Component { clickHandler: null, content: 'OK', triggerDismiss: true, - type: 'primary' - } + type: 'primary', + }, ]; } @@ -25,20 +25,20 @@ class RemoveTorrentsModal extends React.Component { clickHandler: this.handleRemoveTorrentDecline, content: this.props.intl.formatMessage({ id: 'button.no', - defaultMessage: 'No' + defaultMessage: 'No', }), triggerDismiss: true, - type: 'tertiary' + type: 'tertiary', }, { clickHandler: this.handleRemovalConfirmation, content: this.props.intl.formatMessage({ id: 'button.yes', - defaultMessage: 'Yes' + defaultMessage: 'Yes', }), triggerDismiss: true, - type: 'primary' - } + type: 'primary', + }, ]; } @@ -78,10 +78,8 @@ class RemoveTorrentsModal extends React.Component { return (
    -
    this.formRef = ref}> - - {modalContent} - + (this.formRef = ref)}> + {modalContent} {deleteDataContent}
    @@ -98,15 +96,17 @@ class RemoveTorrentsModal extends React.Component { let selectedTorrents = TorrentStore.getSelectedTorrents(); let modalHeading = this.props.intl.formatMessage({ id: 'torrents.remove', - defaultMessage: 'Remove Torrents' + defaultMessage: 'Remove Torrents', }); return ( - + heading={modalHeading} + /> ); } } diff --git a/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.js b/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.js index a40a21ba..9a4ad8b0 100644 --- a/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.js +++ b/client/src/javascript/components/modals/set-tags-modal/SetTagsModal.js @@ -11,23 +11,20 @@ class SetTagsModal extends React.Component { state = { isSettingTags: false, - tags: '' + tags: '', }; handleSetTagsClick = () => { const formData = this.formRef.getFormData(); const tags = formData.tags ? formData.tags.split(',') : []; - this.setState( - {isSettingTags: true}, - () => TorrentActions.setTaxonomy(TorrentStore.getSelectedTorrents(), tags) - ); + this.setState({isSettingTags: true}, () => TorrentActions.setTaxonomy(TorrentStore.getSelectedTorrents(), tags)); }; getActions() { let primaryButtonText = this.props.intl.formatMessage({ id: 'torrents.set.tags.button.set', - defaultMessage: 'Set Tags' + defaultMessage: 'Set Tags', }); return [ @@ -35,18 +32,18 @@ class SetTagsModal extends React.Component { clickHandler: null, content: this.props.intl.formatMessage({ id: 'button.cancel', - defaultMessage: 'Cancel' + defaultMessage: 'Cancel', }), triggerDismiss: true, - type: 'tertiary' + type: 'tertiary', }, { clickHandler: this.handleSetTagsClick, content: primaryButtonText, isLoading: this.state.isSettingTags, triggerDismiss: false, - type: 'primary' - } + type: 'primary', + }, ]; } @@ -55,14 +52,14 @@ class SetTagsModal extends React.Component { return (
    -
    this.formRef = ref}> + (this.formRef = ref)}> @@ -73,13 +70,15 @@ class SetTagsModal extends React.Component { render() { return ( - + defaultMessage: 'Set Tags', + })} + /> ); } } diff --git a/client/src/javascript/components/modals/settings-modal/AuthTab.js b/client/src/javascript/components/modals/settings-modal/AuthTab.js index e1177887..91aae9e4 100644 --- a/client/src/javascript/components/modals/settings-modal/AuthTab.js +++ b/client/src/javascript/components/modals/settings-modal/AuthTab.js @@ -16,7 +16,7 @@ class AuthTab extends SettingsTab { addUserError: null, hasFetchedUserList: false, isAddingUser: false, - users: [] + users: [], }; formData = {}; @@ -27,43 +27,19 @@ class AuthTab extends SettingsTab { } componentDidMount() { - AuthStore.listen( - EventTypes.AUTH_LIST_USERS_SUCCESS, - this.handleUserListChange - ); - AuthStore.listen( - EventTypes.AUTH_CREATE_USER_ERROR, - this.handleUserAddError - ); - AuthStore.listen( - EventTypes.AUTH_CREATE_USER_SUCCESS, - this.handleUserAddSuccess - ); - AuthStore.listen( - EventTypes.AUTH_DELETE_USER_SUCCESS, - this.handleUserDeleteSuccess - ); + AuthStore.listen(EventTypes.AUTH_LIST_USERS_SUCCESS, this.handleUserListChange); + AuthStore.listen(EventTypes.AUTH_CREATE_USER_ERROR, this.handleUserAddError); + AuthStore.listen(EventTypes.AUTH_CREATE_USER_SUCCESS, this.handleUserAddSuccess); + AuthStore.listen(EventTypes.AUTH_DELETE_USER_SUCCESS, this.handleUserDeleteSuccess); AuthStore.fetchUserList(); } componentWillUnmount() { - AuthStore.unlisten( - EventTypes.AUTH_LIST_USERS_SUCCESS, - this.handleUserListChange - ); - AuthStore.unlisten( - EventTypes.AUTH_CREATE_USER_ERROR, - this.handleUserAddError - ); - AuthStore.unlisten( - EventTypes.AUTH_CREATE_USER_SUCCESS, - this.handleUserAddSuccess - ); - AuthStore.unlisten( - EventTypes.AUTH_DELETE_USER_SUCCESS, - this.handleUserDeleteSuccess - ); + AuthStore.unlisten(EventTypes.AUTH_LIST_USERS_SUCCESS, this.handleUserListChange); + AuthStore.unlisten(EventTypes.AUTH_CREATE_USER_ERROR, this.handleUserAddError); + AuthStore.unlisten(EventTypes.AUTH_CREATE_USER_SUCCESS, this.handleUserAddSuccess); + AuthStore.unlisten(EventTypes.AUTH_DELETE_USER_SUCCESS, this.handleUserDeleteSuccess); } getUserList() { @@ -82,32 +58,26 @@ class AuthTab extends SettingsTab { removeIcon = ( + onClick={this.handleDeleteUserClick.bind(this, user.username)}> ); } else { badge = ( - + ); } const classes = classnames('interactive-list__item', { - 'interactive-list__item--disabled': isCurrentUser + 'interactive-list__item--disabled': isCurrentUser, }); return (
  • -
    - {user.username} -
    +
    {user.username}
    {badge}
    {removeIcon} @@ -124,13 +94,13 @@ class AuthTab extends SettingsTab { this.formData = formData; }; - handleFormSubmit = (formData) => { + handleFormSubmit = formData => { if (this.formData.username === '') { this.setState({ addUserError: this.props.intl.formatMessage({ id: 'auth.error.username.empty', - defaultMessage: 'Username cannot be empty.' - }) + defaultMessage: 'Username cannot be empty.', + }), }); } else { this.setState({isAddingUser: true}); @@ -139,7 +109,7 @@ class AuthTab extends SettingsTab { password: this.formData.password, host: this.formData.rtorrentHost, port: this.formData.rtorrentPort, - socketPath: this.formData.rtorrentSocketPath + socketPath: this.formData.rtorrentSocketPath, }); } }; @@ -148,7 +118,7 @@ class AuthTab extends SettingsTab { this.setState({hasFetchedUserList: true, users: AuthStore.getUsers()}); }; - handleUserAddError = (error) => { + handleUserAddError = error => { this.setState({addUserError: error, isAddingUser: false}); }; @@ -167,7 +137,7 @@ class AuthTab extends SettingsTab { render() { const isLoading = !this.state.hasFetchedUserList && this.state.users.length === 0; const interactiveListClasses = classnames('interactive-list', { - 'interactive-list--loading': isLoading + 'interactive-list--loading': isLoading, }); let errorElement = null; let loadingIndicator = null; @@ -175,9 +145,7 @@ class AuthTab extends SettingsTab { if (this.state.addUserError) { errorElement = ( - - {this.state.addUserError} - + {this.state.addUserError} ); } @@ -191,16 +159,9 @@ class AuthTab extends SettingsTab { } return ( - this.formRef = ref} - > + (this.formRef = ref)}> - + @@ -208,8 +169,7 @@ class AuthTab extends SettingsTab { + transitionLeaveTimeout={250}> {loadingIndicator} {this.getUserList()} @@ -217,47 +177,31 @@ class AuthTab extends SettingsTab { - + {errorElement} - )} + label={} placeholder={this.props.intl.formatMessage({ id: 'auth.username', - defaultMessage: 'Username' + defaultMessage: 'Username', })} /> - )} + label={} placeholder={this.props.intl.formatMessage({ id: 'auth.password', - defaultMessage: 'Password' + defaultMessage: 'Password', })} /> diff --git a/client/src/javascript/components/modals/settings-modal/BandwidthTab.js b/client/src/javascript/components/modals/settings-modal/BandwidthTab.js index 2690782e..74b8c1fb 100644 --- a/client/src/javascript/components/modals/settings-modal/BandwidthTab.js +++ b/client/src/javascript/components/modals/settings-modal/BandwidthTab.js @@ -9,20 +9,19 @@ export default class BandwidthTab extends SettingsTab { state = {}; handleFormChange = ({event, formData}) => { - if (event.target.name === 'dropdownPresetDownload' - || event.target.name === 'dropdownPresetUpload') { + if (event.target.name === 'dropdownPresetDownload' || event.target.name === 'dropdownPresetUpload') { this.props.onSettingsChange({ speedLimits: { download: this.processSpeedsForSave(formData.dropdownPresetDownload), - upload: this.processSpeedsForSave(formData.dropdownPresetUpload) - } + upload: this.processSpeedsForSave(formData.dropdownPresetUpload), + }, }); return; } this.handleClientSettingFieldChange(event.target.name, event); - } + }; getDownloadValue() { if (this.props.settings.speedLimits != null) { @@ -53,131 +52,125 @@ export default class BandwidthTab extends SettingsTab { return []; } - return speeds.replace(/\s/g, '').split(',').map(speed => Number(speed) * 1024); + return speeds + .replace(/\s/g, '') + .split(',') + .map(speed => Number(speed) * 1024); } render() { return (
    - + - )} + } id="dropdownPresetDownload" /> - )} + } id="dropdownPresetUpload" /> - )} + } id="throttleGlobalDownMax" /> - )} + } id="throttleGlobalUpMax" /> - + - )} + label={ + + } id="throttleMaxUploads" /> - )} + } id="throttleMaxUploadsDiv" /> - )} + } id="throttleMaxUploadsGlobal" /> - )} + } id="throttleMaxDownloads" /> - )} + } id="throttleMaxDownloadsDiv" /> - )} + } id="throttleMaxDownloadsGlobal" /> diff --git a/client/src/javascript/components/modals/settings-modal/ConnectivityTab.js b/client/src/javascript/components/modals/settings-modal/ConnectivityTab.js index 9d322d51..125524bb 100644 --- a/client/src/javascript/components/modals/settings-modal/ConnectivityTab.js +++ b/client/src/javascript/components/modals/settings-modal/ConnectivityTab.js @@ -26,7 +26,7 @@ export default class ConnectivityTab extends SettingsTab { id: 'dht', data: [dhtEnabledString], overrideID: 'dhtStats', - overrideData: {dht: dhtEnabledString} + overrideData: {dht: dhtEnabledString}, }); } else { this.handleClientSettingFieldChange(event.target.name, event); @@ -37,21 +37,15 @@ export default class ConnectivityTab extends SettingsTab { return ( - + - )} + label={ + + } width="one-quarter" /> - + matchTextboxHeight> + - + matchTextboxHeight> + - )} + label={ + + } /> - )} + } /> - + - )} + label={} width="one-quarter" /> - - + + - + matchTextboxHeight> + - + - )} + label={} /> - )} + label={} /> - )} + } /> - )} + } /> - )} + label={} width="one-half" /> diff --git a/client/src/javascript/components/modals/settings-modal/ResourcesTab.js b/client/src/javascript/components/modals/settings-modal/ResourcesTab.js index 7b10000e..1151fdb8 100644 --- a/client/src/javascript/components/modals/settings-modal/ResourcesTab.js +++ b/client/src/javascript/components/modals/settings-modal/ResourcesTab.js @@ -16,33 +16,25 @@ export default class ResourcesTab extends SettingsTab { return ( - + - )} + } /> - )} + label={} width="one-half" /> + matchTextboxHeight> - + - (MB) + {' '} + (MB)
  • - )} + } width="one-half" /> diff --git a/client/src/javascript/components/modals/settings-modal/SettingsModal.js b/client/src/javascript/components/modals/settings-modal/SettingsModal.js index 12d1c23e..c342bab4 100644 --- a/client/src/javascript/components/modals/settings-modal/SettingsModal.js +++ b/client/src/javascript/components/modals/settings-modal/SettingsModal.js @@ -17,7 +17,7 @@ const METHODS_TO_BIND = [ 'handleModalRefSet', 'handleSaveSettingsClick', 'handleSaveSettingsError', - 'handleSettingsStoreChange' + 'handleSettingsStoreChange', ]; class SettingsModal extends React.Component { @@ -30,26 +30,22 @@ class SettingsModal extends React.Component { changedClientSettings: {}, changedFloodSettings: {}, clientSettings: SettingsStore.getClientSettings(), - floodSettings: SettingsStore.getFloodSettings() + floodSettings: SettingsStore.getFloodSettings(), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - SettingsStore.listen(EventTypes.SETTINGS_CHANGE, - this.handleSettingsStoreChange); - SettingsStore.listen(EventTypes.SETTINGS_SAVE_REQUEST_ERROR, - this.handleSaveSettingsError); + SettingsStore.listen(EventTypes.SETTINGS_CHANGE, this.handleSettingsStoreChange); + SettingsStore.listen(EventTypes.SETTINGS_SAVE_REQUEST_ERROR, this.handleSaveSettingsError); } componentWillUnmount() { - SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, - this.handleSettingsStoreChange); - SettingsStore.unlisten(EventTypes.SETTINGS_SAVE_REQUEST_ERROR, - this.handleSaveSettingsError); + SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, this.handleSettingsStoreChange); + SettingsStore.unlisten(EventTypes.SETTINGS_SAVE_REQUEST_ERROR, this.handleSaveSettingsError); } getActions() { @@ -58,40 +54,41 @@ class SettingsModal extends React.Component { clickHandler: null, content: this.props.intl.formatMessage({ id: 'button.cancel', - defaultMessage: 'Cancel' + defaultMessage: 'Cancel', }), triggerDismiss: true, - type: 'tertiary' + type: 'tertiary', }, { clickHandler: this.handleSaveSettingsClick, isLoading: this.state.isSavingSettings, content: this.props.intl.formatMessage({ id: 'button.save', - defaultMessage: 'Save Settings' + defaultMessage: 'Save Settings', }), triggerDismiss: false, - type: 'primary' - } + type: 'primary', + }, ]; } handleCustomsSettingChange(data) { this.setState({ - changedClientSettings: this.mergeObjects(this.state.changedClientSettings, - {[data.id]: {...data, overrideLocalSetting: true}}) + changedClientSettings: this.mergeObjects(this.state.changedClientSettings, { + [data.id]: {...data, overrideLocalSetting: true}, + }), }); } handleSaveSettingsClick() { - let floodSettings = Object.keys(this.state.changedFloodSettings).map((settingsKey) => { + let floodSettings = Object.keys(this.state.changedFloodSettings).map(settingsKey => { return { id: settingsKey, - data: this.state.changedFloodSettings[settingsKey] + data: this.state.changedFloodSettings[settingsKey], }; }); - let clientSettings = Object.keys(this.state.changedClientSettings).map((settingsKey) => { + let clientSettings = Object.keys(this.state.changedClientSettings).map(settingsKey => { let data = this.state.changedClientSettings[settingsKey]; if (data.overrideLocalSetting) { @@ -105,12 +102,12 @@ class SettingsModal extends React.Component { SettingsStore.saveFloodSettings(floodSettings, { dismissModal: true, - alert: true + alert: true, }); SettingsStore.saveClientSettings(clientSettings, { dismissModal: true, - alert: true + alert: true, }); } @@ -125,7 +122,7 @@ class SettingsModal extends React.Component { handleSettingsStoreChange() { this.setState({ clientSettings: SettingsStore.getClientSettings(), - floodSettings: SettingsStore.getFloodSettings() + floodSettings: SettingsStore.getFloodSettings(), }); } @@ -150,13 +147,18 @@ class SettingsModal extends React.Component { } mergeObjects(objA, objB) { - Object.keys(objB).forEach((key) => { + Object.keys(objB).forEach(key => { if (!objB.hasOwnProperty(key) || objB[key] == null) { return; } // If it's an object, then recursive merge. - if (!Array.isArray(objB[key]) && !Array.isArray(objB[key]) && typeof objA[key] === 'object' && typeof objB[key] === 'object') { + if ( + !Array.isArray(objB[key]) && + !Array.isArray(objB[key]) && + typeof objA[key] === 'object' && + typeof objB[key] === 'object' + ) { objA[key] = this.mergeObjects(objA[key], objB[key]); } else { objA[key] = objB[key]; @@ -173,67 +175,69 @@ class SettingsModal extends React.Component { props: { onClientSettingsChange: this.handleClientSettingsChange, onSettingsChange: this.handleFloodSettingsChange, - settings: this.mergeObjects(this.state.floodSettings, this.state.clientSettings) + settings: this.mergeObjects(this.state.floodSettings, this.state.clientSettings), }, label: this.props.intl.formatMessage({ id: 'settings.tabs.bandwidth', - defaultMessage: 'Bandwidth' - }) + defaultMessage: 'Bandwidth', + }), }, connectivity: { content: ConnectivityTab, props: { onCustomSettingsChange: this.handleCustomsSettingChange, onClientSettingsChange: this.handleClientSettingsChange, - settings: this.state.clientSettings + settings: this.state.clientSettings, }, label: this.props.intl.formatMessage({ id: 'settings.tabs.connectivity', - defaultMessage: 'Connectivity' - }) + defaultMessage: 'Connectivity', + }), }, resources: { content: ResourcesTab, props: { onClientSettingsChange: this.handleClientSettingsChange, - settings: this.state.clientSettings + settings: this.state.clientSettings, }, label: this.props.intl.formatMessage({ id: 'settings.tabs.resources', - defaultMessage: 'Resources' - }) + defaultMessage: 'Resources', + }), }, authentication: { content: AuthTab, label: this.props.intl.formatMessage({ id: 'settings.tabs.authentication', - defaultMessage: 'Authentication' - }) + defaultMessage: 'Authentication', + }), }, ui: { content: UITab, label: this.props.intl.formatMessage({ id: 'settings.tabs.userinterface', - defaultMessage: 'User Interface' + defaultMessage: 'User Interface', }), props: { onSettingsChange: this.handleFloodSettingsChange, - scrollContainer: this.modalBodyRef - } - } + scrollContainer: this.modalBodyRef, + }, + }, }; return ( - + tabs={tabs} + /> ); } } diff --git a/client/src/javascript/components/modals/settings-modal/UITab.js b/client/src/javascript/components/modals/settings-modal/UITab.js index e224103c..d4c2ee10 100644 --- a/client/src/javascript/components/modals/settings-modal/UITab.js +++ b/client/src/javascript/components/modals/settings-modal/UITab.js @@ -16,11 +16,11 @@ class UITab extends SettingsTab { state = { torrentDetails: SettingsStore.getFloodSettings('torrentDetails'), torrentListViewSize: SettingsStore.getFloodSettings('torrentListViewSize'), - selectedLanguage: SettingsStore.getFloodSettings('language') + selectedLanguage: SettingsStore.getFloodSettings('language'), }; getLanguageSelectOptions() { - return Object.keys(Languages).map((languageID) => { + return Object.keys(Languages).map(languageID => { const selectedLanguageDefinition = Languages[languageID]; return ( @@ -76,7 +76,7 @@ class UITab extends SettingsTab { } }; - handleTorrentDetailsMove = (items) => { + handleTorrentDetailsMove = items => { this.setState({torrentDetails: items}); this.props.onSettingsChange({torrentDetails: items}); }; @@ -92,8 +92,7 @@ class UITab extends SettingsTab { this.handleDetailCheckboxValueChange(id, event.target.checked)} - modifier="dark" - > + modifier="dark"> Enabled @@ -101,20 +100,23 @@ class UITab extends SettingsTab { } if ( - id === 'tags' - && this.state.torrentListViewSize === 'expanded' - && index < this.state.torrentDetails.length - 1 + id === 'tags' && + this.state.torrentListViewSize === 'expanded' && + index < this.state.torrentDetails.length - 1 ) { const tooltipContent = ( - + ); warning = ( - this.tooltipRef = ref} + ref={ref => (this.tooltipRef = ref)} scrollContainer={this.props.scrollContainer} width={200} wrapperClassName="sortable-list__content sortable-list__content--secondary tooltip__wrapper" @@ -128,19 +130,14 @@ class UITab extends SettingsTab {
    {warning} - + {checkbox}
    ); if (item.dragIndicator) { - return ( -
    - {content} -
    - ); + return
    {content}
    ; } return content; @@ -153,8 +150,8 @@ class UITab extends SettingsTab { if (this.state.torrentListViewSize === 'expanded') { let nextUnlockedIndex = lockedIDs.length; - torrentDetailItems = torrentDetailItems.reduce( - (accumulator, detail, index) => { + torrentDetailItems = torrentDetailItems + .reduce((accumulator, detail, index) => { let lockedIDIndex = lockedIDs.indexOf(detail.id); if (lockedIDIndex > -1) { @@ -164,59 +161,44 @@ class UITab extends SettingsTab { } return accumulator; - }, []).filter(item => item != null); + }, []) + .filter(item => item != null); } return ( - + - + - + width="auto"> + - + width="auto"> + - + { - let lockedIDIndex = lockedIDs.indexOf(detail.id); + torrentDetailItems = torrentDetailItems.reduce((accumulator, detail, index) => { + let lockedIDIndex = lockedIDs.indexOf(detail.id); - if (lockedIDIndex > -1) { - accumulator[lockedIDIndex] = detail; - } else { - accumulator[nextUnlockedIndex++] = detail; - } + if (lockedIDIndex > -1) { + accumulator[lockedIDIndex] = detail; + } else { + accumulator[nextUnlockedIndex++] = detail; + } - return accumulator; - }, []); + return accumulator; + }, []); } return ( diff --git a/client/src/javascript/components/modals/torrent-details-modal/NavigationList.js b/client/src/javascript/components/modals/torrent-details-modal/NavigationList.js index aacb0d16..61e60871 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/NavigationList.js +++ b/client/src/javascript/components/modals/torrent-details-modal/NavigationList.js @@ -9,31 +9,30 @@ class NavigationList extends React.Component { items: PropTypes.array, listClassName: PropTypes.string, onChange: PropTypes.func, - selectedClassName: PropTypes.string + selectedClassName: PropTypes.string, }; static defaultProps = { itemClassName: 'navigation__item', - listClassName: 'navigation' + listClassName: 'navigation', }; constructor() { super(); this.state = { - selectedItem: null + selectedItem: null, }; } getNavigationItems(items) { return items.map((item, index) => { let classes = classnames(this.props.itemClassName, { - [this.props.selectedClassName]: item.slug === this.state.selectedItem + [this.props.selectedClassName]: item.slug === this.state.selectedItem, }); return ( -
  • +
  • {item.label}
  • ); @@ -42,18 +41,14 @@ class NavigationList extends React.Component { handleItemClick(item) { this.setState({ - selectedItem: item.slug + selectedItem: item.slug, }); this.props.onChange(item); } render() { - return ( -
      - {this.getNavigationItems(this.props.items)} -
    - ); + return
      {this.getNavigationItems(this.props.items)}
    ; } } diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.js index f3979fe9..23b04315 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentDetailsModal.js @@ -13,10 +13,7 @@ import TorrentTrackers from './TorrentTrackers'; import UIActions from '../../../actions/UIActions'; import UIStore from '../../../stores/UIStore'; -const METHODS_TO_BIND = [ - 'onTorrentDetailsChange', - 'onReceiveTorrentsSuccess' -]; +const METHODS_TO_BIND = ['onTorrentDetailsChange', 'onReceiveTorrentsSuccess']; class TorrentDetailsModal extends React.Component { constructor() { @@ -24,10 +21,10 @@ class TorrentDetailsModal extends React.Component { this.state = { torrent: null, - torrentDetails: null + torrentDetails: null, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -35,37 +32,31 @@ class TorrentDetailsModal extends React.Component { componentWillMount() { this.setState({ torrent: TorrentStore.getTorrent(UIStore.getTorrentDetailsHash()), - torrentDetails: TorrentStore.getTorrentDetails( - UIStore.getTorrentDetailsHash()) + torrentDetails: TorrentStore.getTorrentDetails(UIStore.getTorrentDetailsHash()), }); } componentDidMount() { - TorrentStore.listen(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, - this.onTorrentDetailsChange); - TorrentStore.listen(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, - this.onReceiveTorrentsSuccess); + TorrentStore.listen(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, this.onTorrentDetailsChange); + TorrentStore.listen(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, this.onReceiveTorrentsSuccess); TorrentStore.fetchTorrentDetails(); } componentWillUnmount() { - TorrentStore.unlisten(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, - this.onTorrentDetailsChange); - TorrentStore.unlisten(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, - this.onReceiveTorrentsSuccess); + TorrentStore.unlisten(EventTypes.CLIENT_TORRENT_DETAILS_CHANGE, this.onTorrentDetailsChange); + TorrentStore.unlisten(EventTypes.CLIENT_TORRENTS_REQUEST_SUCCESS, this.onReceiveTorrentsSuccess); TorrentStore.stopPollingTorrentDetails(); } onReceiveTorrentsSuccess() { this.setState({ - torrent: TorrentStore.getTorrent(UIStore.getTorrentDetailsHash()) + torrent: TorrentStore.getTorrent(UIStore.getTorrentDetailsHash()), }); } onTorrentDetailsChange() { this.setState({ - torrentDetails: TorrentStore.getTorrentDetails( - UIStore.getTorrentDetailsHash()) + torrentDetails: TorrentStore.getTorrentDetails(UIStore.getTorrentDetailsHash()), }); } @@ -74,17 +65,14 @@ class TorrentDetailsModal extends React.Component { } getModalHeading() { - return ( - - ); + return ; } render() { let props = { ...this.props.options, torrent: this.state.torrent, - ...this.state.torrentDetails + ...this.state.torrentDetails, }; let tabs = { @@ -92,43 +80,43 @@ class TorrentDetailsModal extends React.Component { content: TorrentGeneralInfo, label: this.props.intl.formatMessage({ id: 'torrents.details.details', - defaultMessage: 'Details' + defaultMessage: 'Details', }), - props + props, }, 'torrent-files': { content: TorrentFiles, label: this.props.intl.formatMessage({ id: 'torrents.details.files', - defaultMessage: 'Files' + defaultMessage: 'Files', }), modalContentClasses: 'modal__content--nested-scroll', - props + props, }, 'torrent-peers': { content: TorrentPeers, label: this.props.intl.formatMessage({ id: 'torrents.details.peers', - defaultMessage: 'Peers' + defaultMessage: 'Peers', }), - props + props, }, 'torrent-trackers': { content: TorrentTrackers, label: this.props.intl.formatMessage({ id: 'torrents.details.trackers', - defaultMessage: 'Trackers' + defaultMessage: 'Trackers', }), - props + props, }, 'torrent-mediainfo': { content: TorrentMediainfo, label: this.props.intl.formatMessage({ id: 'torrents.details.mediainfo', - defaultMessage: 'Mediainfo' + defaultMessage: 'Mediainfo', }), - props - } + props, + }, }; return ( diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.js index 48239fee..0a3dc74c 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentFiles.js @@ -10,11 +10,7 @@ import DirectoryTree from '../../general/filesystem/DirectoryTree'; import TorrentStore from '../../../stores/TorrentStore'; const TORRENT_PROPS_TO_CHECK = ['bytesDone']; -const METHODS_TO_BIND = [ - 'handleItemSelect', - 'handlePriorityChange', - 'handleSelectAllClick' -]; +const METHODS_TO_BIND = ['handleItemSelect', 'handlePriorityChange', 'handleSelectAllClick']; class TorrentFiles extends React.Component { constructor() { @@ -27,10 +23,10 @@ class TorrentFiles extends React.Component { allSelected: false, lastSelectedPath: '', selectedItems: {}, - selectedFiles: [] + selectedFiles: [], }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -44,7 +40,7 @@ class TorrentFiles extends React.Component { // If we know that the user changed a file's priority, we deeply check the // file tree to render when the priority change is detected. if (this.hasPriorityChanged) { - let shouldUpdate = !(_.isEqual(nextProps.fileTree, this.props.fileTree)); + let shouldUpdate = !_.isEqual(nextProps.fileTree, this.props.fileTree); // Reset the flag so we don't deeply check the next file tree. if (shouldUpdate) { @@ -55,14 +51,13 @@ class TorrentFiles extends React.Component { } // Update when the previous props weren't defined and the next are. - if ((!this.props.torrent && nextProps.torrent) - || (!this.props.fileTree && nextProps.fileTree)) { + if ((!this.props.torrent && nextProps.torrent) || (!this.props.fileTree && nextProps.fileTree)) { return true; } // Check specific properties to re-render when the torrent is active. if (nextProps.torrent) { - return TORRENT_PROPS_TO_CHECK.some((property) => { + return TORRENT_PROPS_TO_CHECK.some(property => { return this.props.torrent[property] !== nextProps.torrent[property]; }); } @@ -72,7 +67,9 @@ class TorrentFiles extends React.Component { getSelectedFiles(selectionTree, selectedFiles = []) { if (selectionTree.files) { - selectedFiles = [...selectedFiles, ...Object.keys(selectionTree.files).reduce((previousValue, filename) => { + selectedFiles = [ + ...selectedFiles, + ...Object.keys(selectionTree.files).reduce((previousValue, filename) => { let file = selectionTree.files[filename]; if (file.isSelected) { @@ -80,11 +77,12 @@ class TorrentFiles extends React.Component { } return previousValue; - }, [])]; + }, []), + ]; } if (selectionTree.directories) { - Object.keys(selectionTree.directories).forEach((directory) => { + Object.keys(selectionTree.directories).forEach(directory => { selectedFiles = [...selectedFiles, ...this.getSelectedFiles(selectionTree.directories[directory])]; }); } @@ -106,18 +104,13 @@ class TorrentFiles extends React.Component { handleFormChange = ({event, formData}) => { if (event.target.name === 'file-priority') { this.handlePriorityChange(); - TorrentStore.setFilePriority( - this.props.hash, - this.state.selectedFiles, - event.target.value - ); + TorrentStore.setFilePriority(this.props.hash, this.state.selectedFiles, event.target.value); } }; handleItemSelect(selectedItem) { this.hasSelectionChanged = true; - let selectedItems = this.mergeSelection(selectedItem, - this.state.selectedItems, 0, this.props.fileTree); + let selectedItems = this.mergeSelection(selectedItem, this.state.selectedItems, 0, this.props.fileTree); let selectedFiles = this.getSelectedFiles(selectedItems); this.setState({selectedItems, allSelected: false, selectedFiles}); } @@ -128,11 +121,13 @@ class TorrentFiles extends React.Component { handleSelectAllClick() { this.hasSelectionChanged = true; - let selectedItems = this.selectAll(this.state.selectedItems, - this.props.fileTree, this.state.allSelected); + let selectedItems = this.selectAll(this.state.selectedItems, this.props.fileTree, this.state.allSelected); let selectedFiles = this.getSelectedFiles(selectedItems); - this.setState({selectedItems, allSelected: !this.state.allSelected, - selectedFiles}); + this.setState({ + selectedItems, + allSelected: !this.state.allSelected, + selectedFiles, + }); } isLoaded() { @@ -166,9 +161,12 @@ class TorrentFiles extends React.Component { delete tree.isSelected; } - tree.directories[pathSegment] = this.mergeSelection(item, - tree.directories[pathSegment], depth, - fileTree.directories[pathSegment]); + tree.directories[pathSegment] = this.mergeSelection( + item, + tree.directories[pathSegment], + depth, + fileTree.directories[pathSegment] + ); } else { if (item.isSelected) { delete tree.isSelected; @@ -178,8 +176,7 @@ class TorrentFiles extends React.Component { // If a directory was checked, recursively check all its children. if (item.type === 'directory') { - value = this.selectAll(tree[selectionSubTree][pathSegment], - fileTree[selectionSubTree][pathSegment]); + value = this.selectAll(tree[selectionSubTree][pathSegment], fileTree[selectionSubTree][pathSegment]); } else { value = {...item, isSelected: true}; } @@ -193,7 +190,7 @@ class TorrentFiles extends React.Component { selectAll(selectionTree = {}, fileTree = {}, deselect = false) { if (fileTree.files) { - fileTree.files.forEach((file) => { + fileTree.files.forEach(file => { if (!selectionTree.files) { selectionTree.files = {}; } @@ -207,7 +204,7 @@ class TorrentFiles extends React.Component { } if (fileTree.directories) { - Object.keys(fileTree.directories).forEach((directory) => { + Object.keys(fileTree.directories).forEach(directory => { if (!selectionTree.directories) { selectionTree.directories = {}; } @@ -218,7 +215,8 @@ class TorrentFiles extends React.Component { selectionTree.directories[directory] = this.selectAll( selectionTree.directories[directory], - fileTree.directories[directory], deselect + fileTree.directories[directory], + deselect ); }); } @@ -235,55 +233,54 @@ class TorrentFiles extends React.Component { if (this.isLoaded()) { directoryHeadingIconContent = (
    -
    - +
    -
    ); fileDetailContent = ( - + selectedItems={this.state.selectedItems} + tree={fileTree} + /> ); } else { directoryHeadingIconContent = ; - fileDetailContent = ( -
    - Loading file detail... -
    - ); + fileDetailContent =
    Loading file detail...
    ; } - let directoryHeadingClasses = classnames('directory-tree__node', - 'directory-tree__parent-directory torrent-details__section__heading', { - 'directory-tree__node--selected': this.state.allSelected - }); + let directoryHeadingClasses = classnames( + 'directory-tree__node', + 'directory-tree__parent-directory torrent-details__section__heading', + { + 'directory-tree__node--selected': this.state.allSelected, + } + ); let directoryHeading = (
    {directoryHeadingIconContent} -
    - {torrent.directory} -
    +
    {torrent.directory}
    ); let wrapperClasses = classnames('inverse directory-tree__wrapper', { - 'directory-tree__wrapper--toolbar-visible': this.state.selectedFiles.length > 0 + 'directory-tree__wrapper--toolbar-visible': this.state.selectedFiles.length > 0, }); return ( @@ -291,13 +288,19 @@ class TorrentFiles extends React.Component {
    - {this.state.selectedFiles.length} - }}/> + countElement: ( + + {this.state.selectedFiles.length} + + ), + }} + /> diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentGeneralInfo.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentGeneralInfo.js index 652f00e6..b482718e 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentGeneralInfo.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentGeneralInfo.js @@ -7,7 +7,9 @@ class TorrentGeneralInfo extends React.Component { getTags(tags) { return tags.map((tag, index) => { return ( - {tag} + + {tag} + ); }); } @@ -27,8 +29,7 @@ class TorrentGeneralInfo extends React.Component { const VALUE_NOT_AVAILABLE = ( - + ); @@ -38,84 +39,63 @@ class TorrentGeneralInfo extends React.Component { - + - + {dateAdded ? this.props.intl.formatDate(dateAdded, { - year: 'numeric', - month: 'long', - day: '2-digit'}) + ' ' + + year: 'numeric', + month: 'long', + day: '2-digit', + }) + + ' ' + this.props.intl.formatTime(dateAdded) : VALUE_NOT_AVAILABLE} - - - - {torrent.basePath} + + {torrent.basePath} - + {torrent.ignoreScheduler === '1' ? this.props.intl.formatMessage({ - id: 'torrents.details.general.scheduler.ignored', - defaultMessage: 'Ignored'}) + id: 'torrents.details.general.scheduler.ignored', + defaultMessage: 'Ignored', + }) : this.props.intl.formatMessage({ - id: 'torrents.details.general.scheduler.obeyed', - defaultMessage: 'Obeyed'})} + id: 'torrents.details.general.scheduler.obeyed', + defaultMessage: 'Obeyed', + })} - + - {(torrent.tags.length - ? this.getTags(torrent.tags) - : VALUE_NOT_AVAILABLE)} + {torrent.tags.length ? this.getTags(torrent.tags) : VALUE_NOT_AVAILABLE} - + - + @@ -124,10 +104,7 @@ class TorrentGeneralInfo extends React.Component { - + , - total: + total: , }} /> - + , - total: + total: , }} /> - + - - - - {torrent.comment || VALUE_NOT_AVAILABLE} + + {torrent.comment || VALUE_NOT_AVAILABLE} - + {creation ? this.props.intl.formatDate(creation, { - year: 'numeric', - month: 'long', - day: '2-digit'}) + ' ' + + year: 'numeric', + month: 'long', + day: '2-digit', + }) + + ' ' + this.props.intl.formatTime(creation) : VALUE_NOT_AVAILABLE} - - - - {torrent.hash} + + {torrent.hash} - + @@ -220,38 +177,31 @@ class TorrentGeneralInfo extends React.Component { - + {torrent.isPrivate === '0' ? this.props.intl.formatMessage({ - id: 'torrents.details.general.type.public', - defaultMessage: 'Public'}) + id: 'torrents.details.general.type.public', + defaultMessage: 'Public', + }) : this.props.intl.formatMessage({ - id: 'torrents.details.general.type.private', - defaultMessage: 'Private'})} + id: 'torrents.details.general.type.private', + defaultMessage: 'Private', + })} - + - + - {(torrent.message ? torrent.message : VALUE_NOT_AVAILABLE)} + {torrent.message ? torrent.message : VALUE_NOT_AVAILABLE} diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentHeading.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentHeading.js index 0eba3906..99fd5cbd 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentHeading.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentHeading.js @@ -19,21 +19,17 @@ import {torrentStatusClasses} from '../../../util/torrentStatusClasses'; import {torrentStatusIcons} from '../../../util/torrentStatusIcons'; import UploadThickIcon from '../../icons/UploadThickIcon'; -const METHODS_TO_BIND = [ - 'getCurrentStatus', - 'handleStart', - 'handleStop' -]; +const METHODS_TO_BIND = ['getCurrentStatus', 'handleStart', 'handleStop']; export default class TorrentHeading extends React.Component { constructor() { super(); this.state = { - optimisticData: {currentStatus: null} + optimisticData: {currentStatus: null}, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -53,37 +49,35 @@ export default class TorrentHeading extends React.Component { } getTorrentActions(torrent) { - let currentStatus = this.state.optimisticData.currentStatus - || this.getCurrentStatus(torrent.status); + let currentStatus = this.state.optimisticData.currentStatus || this.getCurrentStatus(torrent.status); let statusIcons = { - 'start': , - 'stop': + start: , + stop: , }; let torrentActions = ['start', 'stop']; let torrentActionElements = [ -
  • - -
  • +
  • + +
  • , ]; torrentActions.forEach((torrentAction, index) => { let capitalizedAction = stringUtil.capitalize(torrentAction); - let classes = classnames('torrent-details__sub-heading__tertiary', - 'torrent-details__action', { - 'is-active': torrentAction === currentStatus - }); + let classes = classnames('torrent-details__sub-heading__tertiary', 'torrent-details__action', { + 'is-active': torrentAction === currentStatus, + }); torrentActionElements.push( -
  • +
  • {statusIcons[torrentAction]} - +
  • ); }); @@ -137,9 +131,7 @@ export default class TorrentHeading extends React.Component { -
      - {this.getTorrentActions(torrent)} -
    +
      {this.getTorrentActions(torrent)}
    diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js index 191b0d16..67dfcce3 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentMediainfo.js @@ -11,31 +11,32 @@ import TorrentStore from '../../../stores/TorrentStore'; const MESSAGES = defineMessages({ copy: { id: 'general.clipboard.copy', - defaultMessage: 'Copy' + defaultMessage: 'Copy', }, copied: { id: 'general.clipboard.copied', - defaultMessage: 'Copied' + defaultMessage: 'Copied', }, execError: { id: 'mediainfo.execError', - defaultMessage: 'An error occurred while running mediainfo on the server. Check that mediainfo is installed and available in the PATH to Flood.' + defaultMessage: + 'An error occurred while running mediainfo on the server. Check that mediainfo is installed and available in the PATH to Flood.', }, fetching: { id: 'mediainfo.fetching', - defaultMessage: 'Fetching...' + defaultMessage: 'Fetching...', }, heading: { id: 'mediainfo.heading', - defaultMessage: 'Mediainfo Output' - } + defaultMessage: 'Mediainfo Output', + }, }); const METHODS_TO_BIND = [ 'handleCopyButtonMouseLeave', 'handleCopySuccess', 'handleFetchMediainfoError', - 'handleFetchMediainfoSuccess' + 'handleFetchMediainfoSuccess', ]; class TorrentMediainfo extends React.Component { @@ -47,23 +48,17 @@ class TorrentMediainfo extends React.Component { copiedToClipboard: false, isFetchingMediainfo: true, mediainfo: null, - fetchMediainfoError: null + fetchMediainfoError: null, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TorrentStore.listen( - EventTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, - this.handleFetchMediainfoSuccess - ); - TorrentStore.listen( - EventTypes.FLOOD_FETCH_MEDIAINFO_ERROR, - this.handleFetchMediainfoError - ); + TorrentStore.listen(EventTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, this.handleFetchMediainfoSuccess); + TorrentStore.listen(EventTypes.FLOOD_FETCH_MEDIAINFO_ERROR, this.handleFetchMediainfoError); TorrentStore.fetchMediainfo(this.props.hash); } @@ -72,7 +67,7 @@ class TorrentMediainfo extends React.Component { this.clipboard = new Clipboard(this.copyButtonRef, { text: () => { return this.state.mediainfo; - } + }, }); this.clipboard.on('success', this.handleCopySuccess); @@ -80,34 +75,28 @@ class TorrentMediainfo extends React.Component { } componentWillUnmount() { - TorrentStore.unlisten( - EventTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, - this.handleFetchMediainfoSuccess - ); - TorrentStore.unlisten( - EventTypes.FLOOD_FETCH_MEDIAINFO_ERROR, - this.handleFetchMediainfoError - ); + TorrentStore.unlisten(EventTypes.FLOOD_FETCH_MEDIAINFO_SUCCESS, this.handleFetchMediainfoSuccess); + TorrentStore.unlisten(EventTypes.FLOOD_FETCH_MEDIAINFO_ERROR, this.handleFetchMediainfoError); } handleCopyButtonMouseLeave() { global.setTimeout(() => { this.setState({ - copiedToClipboard: false + copiedToClipboard: false, }); }, 500); } handleCopySuccess() { this.setState({ - copiedToClipboard: true + copiedToClipboard: true, }); } handleFetchMediainfoError(error) { this.setState({ isFetchingMediainfo: false, - fetchMediainfoError: error + fetchMediainfoError: error, }); } @@ -115,7 +104,7 @@ class TorrentMediainfo extends React.Component { this.setState({ mediainfo: TorrentStore.getMediainfo(this.props.hash), isFetchingMediainfo: false, - fetchMediainfoError: null + fetchMediainfoError: null, }); } @@ -123,8 +112,7 @@ class TorrentMediainfo extends React.Component { if (this.state.isFetchingMediainfo) { return (
    - +
    ); } @@ -135,12 +123,9 @@ class TorrentMediainfo extends React.Component { return (

    - +

    -
    -            {JSON.stringify(errorData.error, null, 2)}
    -          
    +
    {JSON.stringify(errorData.error, null, 2)}
    ); } @@ -156,24 +141,19 @@ class TorrentMediainfo extends React.Component {
    - +
    - -
    -
    -          {this.state.mediainfo}
    -        
    +
    {this.state.mediainfo}
    ); } diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentPeers.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentPeers.js index 2624bf2c..085ba1b3 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentPeers.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentPeers.js @@ -12,7 +12,7 @@ export default class TorrentPeers extends React.Component { super(); this.state = { - erroredCountryImages: [] + erroredCountryImages: [], }; } @@ -45,16 +45,15 @@ export default class TorrentPeers extends React.Component { alt={countryCode} className="peers-list__flag__image" onError={this.getImageErrorHandlerFn(countryCode)} - src={flagImageSrc} /> + src={flagImageSrc} + /> ); } peerCountry = ( {image} - - {countryCode} - + {countryCode} ); } @@ -71,15 +70,9 @@ export default class TorrentPeers extends React.Component { - - {peer.completedPercent}% - - - {peer.clientVersion} - - - {encryptedIcon} - + {peer.completedPercent}% + {peer.clientVersion} + {encryptedIcon} ); }); @@ -90,34 +83,17 @@ export default class TorrentPeers extends React.Component { - - - {peers.length} - - - - DL - - - UL - - - % - - - Client - - - Enc + + {peers.length} + DL + UL + % + Client + Enc - - {peerList} - + {peerList}
    ); diff --git a/client/src/javascript/components/modals/torrent-details-modal/TorrentTrackers.js b/client/src/javascript/components/modals/torrent-details-modal/TorrentTrackers.js index a8ba8a55..91ebd0ca 100644 --- a/client/src/javascript/components/modals/torrent-details-modal/TorrentTrackers.js +++ b/client/src/javascript/components/modals/torrent-details-modal/TorrentTrackers.js @@ -13,12 +13,8 @@ export default class TorrentTrackrs extends React.Component { let trackerDetails = trackers.map((tracker, index) => { return ( - - {tracker.url} - - - {trackerTypes[tracker.type - 1]} - + {tracker.url} + {trackerTypes[tracker.type - 1]} ); }); @@ -30,25 +26,15 @@ export default class TorrentTrackrs extends React.Component { - - - {trackerCount} - + + {trackerCount} - + - - {trackerDetails} - + {trackerDetails}
    ); diff --git a/client/src/javascript/components/sidebar/FeedsButton.js b/client/src/javascript/components/sidebar/FeedsButton.js index d9af0853..3f5c7d68 100644 --- a/client/src/javascript/components/sidebar/FeedsButton.js +++ b/client/src/javascript/components/sidebar/FeedsButton.js @@ -8,8 +8,8 @@ import UIActions from '../../actions/UIActions'; const MESSAGES = defineMessages({ feeds: { id: 'sidebar.button.feeds', - defaultMessage: 'Feeds' - } + defaultMessage: 'Feeds', + }, }); const METHODS_TO_BIND = ['handleFeedsButtonClick']; @@ -20,7 +20,7 @@ class FeedsButton extends React.Component { this.tooltipRef = null; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -40,7 +40,7 @@ class FeedsButton extends React.Component { this.tooltipRef = ref} + ref={ref => (this.tooltipRef = ref)} position="bottom" wrapperClassName="sidebar__action sidebar__icon-button sidebar__icon-button--interactive tooltip__wrapper"> diff --git a/client/src/javascript/components/sidebar/LogoutButton.js b/client/src/javascript/components/sidebar/LogoutButton.js index f40137c0..1363c5d9 100644 --- a/client/src/javascript/components/sidebar/LogoutButton.js +++ b/client/src/javascript/components/sidebar/LogoutButton.js @@ -8,8 +8,8 @@ import Tooltip from '../general/Tooltip'; const MESSAGES = defineMessages({ logOut: { id: 'sidebar.button.log.out', - defaultMessage: 'Log Out' - } + defaultMessage: 'Log Out', + }, }); class LogoutButton extends React.Component { diff --git a/client/src/javascript/components/sidebar/NotificationsButton.js b/client/src/javascript/components/sidebar/NotificationsButton.js index f2552467..2ab9eff9 100644 --- a/client/src/javascript/components/sidebar/NotificationsButton.js +++ b/client/src/javascript/components/sidebar/NotificationsButton.js @@ -19,48 +19,48 @@ const INTIAL_COUNT_STATE = {total: 0, unread: 0, read: 0}; const MESSAGES = defineMessages({ notifications: { id: 'sidebar.button.notifications', - defaultMessage: 'Notifications' + defaultMessage: 'Notifications', }, 'notification.torrent.finished.heading': { id: 'notification.torrent.finished.heading', - defaultMessage: 'Finished Downloading' + defaultMessage: 'Finished Downloading', }, 'notification.torrent.finished.body': { id: 'notification.torrent.finished.body', - defaultMessage: '{name}' + defaultMessage: '{name}', }, 'notification.torrent.errored.heading': { id: 'notification.torrent.errored.heading', - defaultMessage: 'Error Reported' + defaultMessage: 'Error Reported', }, 'notification.torrent.errored.body': { id: 'notification.torrent.errored.body', - defaultMessage: '{name}' + defaultMessage: '{name}', }, 'notification.feed.downloaded.torrent.heading': { id: 'notification.feed.downloaded.torrent.heading', - defaultMessage: 'Matched Feed Rule' + defaultMessage: 'Matched Feed Rule', }, clearAll: { id: 'notification.clear.all', - defaultMessage: 'Clear All' + defaultMessage: 'Clear All', }, showing: { id: 'notification.showing', - defaultMessage: 'Showing' + defaultMessage: 'Showing', }, at: { id: 'general.at', - defaultMessage: 'at' + defaultMessage: 'at', }, to: { id: 'general.to', - defaultMessage: 'to' + defaultMessage: 'to', }, of: { id: 'general.of', - defaultMessage: 'of' - } + defaultMessage: 'of', + }, }); const METHODS_TO_BIND = [ @@ -72,7 +72,7 @@ const METHODS_TO_BIND = [ 'handleNotificationCountChange', 'handleNewerNotificationsClick', 'handleOlderNotificationsClick', - 'handleTooltipOpen' + 'handleTooltipOpen', ]; const NOTIFICATIONS_PER_PAGE = 10; @@ -84,60 +84,35 @@ class NotificationsButton extends React.Component { this.state = { paginationStart: 0, count: INTIAL_COUNT_STATE, - notifications: [] + notifications: [], }; this.tooltipRef = null; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); UIStore.registerDependency({ id: 'notifications', - message: ( - - ) + message: , }); } componentDidMount() { - NotificationStore.listen( - EventTypes.NOTIFICATIONS_FETCH_SUCCESS, - this.handleNotificationFetchSuccess - ); - NotificationStore.listen( - EventTypes.NOTIFICATIONS_FETCH_ERROR, - this.handleNotificationFetchError - ); - NotificationStore.listen( - EventTypes.NOTIFICATIONS_COUNT_CHANGE, - this.handleNotificationCountChange - ); + NotificationStore.listen(EventTypes.NOTIFICATIONS_FETCH_SUCCESS, this.handleNotificationFetchSuccess); + NotificationStore.listen(EventTypes.NOTIFICATIONS_FETCH_ERROR, this.handleNotificationFetchError); + NotificationStore.listen(EventTypes.NOTIFICATIONS_COUNT_CHANGE, this.handleNotificationCountChange); } componentWillUnmount() { - NotificationStore.unlisten( - EventTypes.NOTIFICATIONS_FETCH_SUCCESS, - this.handleNotificationFetchSuccess - ); - NotificationStore.unlisten( - EventTypes.NOTIFICATIONS_FETCH_ERROR, - this.handleNotificationFetchError - ); - NotificationStore.unlisten( - EventTypes.NOTIFICATIONS_COUNT_CHANGE, - this.handleNotificationCountChange - ); + NotificationStore.unlisten(EventTypes.NOTIFICATIONS_FETCH_SUCCESS, this.handleNotificationFetchSuccess); + NotificationStore.unlisten(EventTypes.NOTIFICATIONS_FETCH_ERROR, this.handleNotificationFetchError); + NotificationStore.unlisten(EventTypes.NOTIFICATIONS_COUNT_CHANGE, this.handleNotificationCountChange); } getBadge() { if (this.state.count.total > 0) { - return ( - - {this.state.count.total} - - ); + return {this.state.count.total}; } return null; @@ -145,15 +120,12 @@ class NotificationsButton extends React.Component { getBottomToolbar() { if (this.state.count.total > 0) { - let newerButtonClass = classnames('toolbar__item toolbar__item--button', - 'tooltip__content--padding-surrogate', - {'is-disabled': this.state.paginationStart === 0}); - let olderButtonClass = classnames('toolbar__item toolbar__item--button', - 'tooltip__content--padding-surrogate', - { - 'is-disabled': this.state.paginationStart + NOTIFICATIONS_PER_PAGE - >= this.state.count.total - }); + let newerButtonClass = classnames('toolbar__item toolbar__item--button', 'tooltip__content--padding-surrogate', { + 'is-disabled': this.state.paginationStart === 0, + }); + let olderButtonClass = classnames('toolbar__item toolbar__item--button', 'tooltip__content--padding-surrogate', { + 'is-disabled': this.state.paginationStart + NOTIFICATIONS_PER_PAGE >= this.state.count.total, + }); let olderFrom = this.state.paginationStart + NOTIFICATIONS_PER_PAGE + 1; let olderTo = this.state.paginationStart + NOTIFICATIONS_PER_PAGE * 2; @@ -169,19 +141,19 @@ class NotificationsButton extends React.Component { } return ( -
      -
    • +
    • {newerFrom + 1} – {newerTo}
    • -
    • {this.props.intl.formatMessage(MESSAGES.clearAll)}
    • -
    • +
    • {olderFrom} – {olderTo}
    @@ -192,48 +164,44 @@ class NotificationsButton extends React.Component { } getNotification(notification, index) { - let date = this.props.intl.formatDate(notification.ts, - {year: 'numeric', month: 'long', day: '2-digit'}); + let date = this.props.intl.formatDate(notification.ts, {year: 'numeric', month: 'long', day: '2-digit'}); let time = this.props.intl.formatTime(notification.ts); let notificationBody = null; if (notification.id === 'notification.feed.downloaded.torrent') { notificationBody = ( - - {notification.data.ruleLabel}{' / '} + {notification.data.ruleLabel} + {' / '} {notification.data.feedLabel} ), - title: notification.data.title - }} /> + title: notification.data.title, + }} + /> ); } else { - notificationBody = this.props.intl.formatMessage( - MESSAGES[`${notification.id}.body`], notification.data - ); + notificationBody = this.props.intl.formatMessage(MESSAGES[`${notification.id}.body`], notification.data); } return (
  • - {this.props.intl.formatMessage( - MESSAGES[`${notification.id}.heading`] - )} + {this.props.intl.formatMessage(MESSAGES[`${notification.id}.heading`])} {` — `} {date} {this.props.intl.formatMessage(MESSAGES.at)} {time}
    -
    - {notificationBody} -
    +
    {notificationBody}
  • ); } @@ -273,7 +241,8 @@ class NotificationsButton extends React.Component { getTooltipContent() { if (this.state.count.total === 0) { return ( -
    {this.props.intl.formatMessage(MESSAGES.notifications)}
    @@ -282,24 +251,15 @@ class NotificationsButton extends React.Component { const {isLoading, notifications = []} = this.state; - const notificationsWrapperClasses = classnames( - 'notifications', - { - 'notifications--is-loading': isLoading - } - ); + const notificationsWrapperClasses = classnames('notifications', { + 'notifications--is-loading': isLoading, + }); return (
    {this.getTopToolbar()} -
    - {loadingIndicatorIcon} -
    - +
    {loadingIndicatorIcon}
    +
      {notifications.map(this.getNotification)}
    @@ -311,12 +271,12 @@ class NotificationsButton extends React.Component { handleClearNotificationsClick() { this.setState({ - paginationStart: 0 + paginationStart: 0, }); NotificationStore.clearAll({ id: 'notification-tooltip', - limit: NOTIFICATIONS_PER_PAGE + limit: NOTIFICATIONS_PER_PAGE, }); if (this.tooltipRef != null) { @@ -334,7 +294,7 @@ class NotificationsButton extends React.Component { NotificationStore.fetchNotifications({ id: 'notification-tooltip', limit: NOTIFICATIONS_PER_PAGE, - start: this.state.paginationStart + start: this.state.paginationStart, }); } } @@ -348,7 +308,7 @@ class NotificationsButton extends React.Component { let notificationState = { ...NotificationStore.getNotifications('notification-tooltip'), - isLoading: false + isLoading: false, }; this.setState(notificationState); @@ -358,13 +318,13 @@ class NotificationsButton extends React.Component { if (this.state.paginationStart - NOTIFICATIONS_PER_PAGE >= 0) { this.setState({ isLoading: true, - paginationStart: this.state.paginationStart - NOTIFICATIONS_PER_PAGE + paginationStart: this.state.paginationStart - NOTIFICATIONS_PER_PAGE, }); NotificationStore.fetchNotifications({ id: 'notification-tooltip', limit: NOTIFICATIONS_PER_PAGE, - start: this.state.paginationStart - NOTIFICATIONS_PER_PAGE + start: this.state.paginationStart - NOTIFICATIONS_PER_PAGE, }); } } @@ -373,13 +333,13 @@ class NotificationsButton extends React.Component { if (this.state.count.total > this.state.paginationStart + NOTIFICATIONS_PER_PAGE) { this.setState({ isLoading: true, - paginationStart: this.state.paginationStart + NOTIFICATIONS_PER_PAGE + paginationStart: this.state.paginationStart + NOTIFICATIONS_PER_PAGE, }); NotificationStore.fetchNotifications({ id: 'notification-tooltip', limit: NOTIFICATIONS_PER_PAGE, - start: this.state.paginationStart + NOTIFICATIONS_PER_PAGE + start: this.state.paginationStart + NOTIFICATIONS_PER_PAGE, }); } } @@ -390,7 +350,7 @@ class NotificationsButton extends React.Component { NotificationStore.fetchNotifications({ id: 'notification-tooltip', limit: NOTIFICATIONS_PER_PAGE, - start: this.state.paginationStart + start: this.state.paginationStart, }); } @@ -402,7 +362,7 @@ class NotificationsButton extends React.Component { interactive={this.state.count.total !== 0} onClose={this.handleTooltipClose} onOpen={this.handleTooltipOpen} - ref={ref => this.tooltipRef = ref} + ref={ref => (this.tooltipRef = ref)} width={this.state.count.total === 0 ? null : 340} position="bottom" wrapperClassName="sidebar__action sidebar__icon-button diff --git a/client/src/javascript/components/sidebar/SearchTorrents.js b/client/src/javascript/components/sidebar/SearchTorrents.js index 973ebe2a..607d60ca 100644 --- a/client/src/javascript/components/sidebar/SearchTorrents.js +++ b/client/src/javascript/components/sidebar/SearchTorrents.js @@ -1,6 +1,6 @@ import {injectIntl} from 'react-intl'; import classnames from 'classnames'; -import React from'react'; +import React from 'react'; import Close from '../icons/Close'; import EventTypes from '../../constants/EventTypes'; @@ -8,33 +8,27 @@ import Search from '../icons/Search'; import TorrentFilterStore from '../../stores/TorrentFilterStore'; import UIActions from '../../actions/UIActions'; -const METHODS_TO_BIND = [ - 'handleExternalSearchChange', - 'handleSearchChange', - 'resetSearch' -]; +const METHODS_TO_BIND = ['handleExternalSearchChange', 'handleSearchChange', 'resetSearch']; class SearchBox extends React.Component { constructor() { super(); this.state = { - searchValue: '' + searchValue: '', }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_SEARCH_CHANGE, - this.handleExternalSearchChange); + TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_SEARCH_CHANGE, this.handleExternalSearchChange); } componentWillUnmount() { - TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_SEARCH_CHANGE, - this.handleExternalSearchChange); + TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_SEARCH_CHANGE, this.handleExternalSearchChange); } handleExternalSearchChange() { @@ -59,9 +53,9 @@ class SearchBox extends React.Component { render() { let clearSearchButton = null; let classes = classnames({ - 'sidebar__item': true, - 'search': true, - 'is-in-use': this.isSearchActive() + sidebar__item: true, + search: true, + 'is-in-use': this.isSearchActive(), }); if (this.isSearchActive()) { @@ -76,14 +70,16 @@ class SearchBox extends React.Component {
    {clearSearchButton} - + value={this.state.searchValue} + />
    ); } diff --git a/client/src/javascript/components/sidebar/SettingsButton.js b/client/src/javascript/components/sidebar/SettingsButton.js index fecfd14d..2d18fe4d 100644 --- a/client/src/javascript/components/sidebar/SettingsButton.js +++ b/client/src/javascript/components/sidebar/SettingsButton.js @@ -8,8 +8,8 @@ import UIActions from '../../actions/UIActions'; const MESSAGES = defineMessages({ settings: { id: 'sidebar.button.settings', - defaultMessage: 'Settings' - } + defaultMessage: 'Settings', + }, }); const METHODS_TO_BIND = ['handleSettingsButtonClick']; @@ -19,7 +19,7 @@ class SettingsButton extends React.Component { this.tooltipRef = null; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -39,7 +39,7 @@ class SettingsButton extends React.Component { this.tooltipRef = ref} + ref={ref => (this.tooltipRef = ref)} position="bottom" wrapperClassName="sidebar__action sidebar__icon-button sidebar__icon-button--interactive tooltip__wrapper"> diff --git a/client/src/javascript/components/sidebar/Sidebar.js b/client/src/javascript/components/sidebar/Sidebar.js index b9437f15..b35df252 100644 --- a/client/src/javascript/components/sidebar/Sidebar.js +++ b/client/src/javascript/components/sidebar/Sidebar.js @@ -23,21 +23,16 @@ class Sidebar extends React.Component { UIStore.registerDependency({ id: 'torrent-taxonomy', - message: ( - - ), + message: , }); } componentDidMount() { - TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyRequestSuccess); + TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyRequestSuccess); } componentWillUnmount() { - TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyRequestSuccess); + TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyRequestSuccess); } onTorrentTaxonomyRequestSuccess() { diff --git a/client/src/javascript/components/sidebar/SidebarActions.js b/client/src/javascript/components/sidebar/SidebarActions.js index 09a2edd5..c43319f2 100644 --- a/client/src/javascript/components/sidebar/SidebarActions.js +++ b/client/src/javascript/components/sidebar/SidebarActions.js @@ -2,11 +2,7 @@ import React from 'react'; class SidebarActions extends React.Component { render() { - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/sidebar/SidebarFilter.js b/client/src/javascript/components/sidebar/SidebarFilter.js index 25444720..43ba5821 100644 --- a/client/src/javascript/components/sidebar/SidebarFilter.js +++ b/client/src/javascript/components/sidebar/SidebarFilter.js @@ -4,15 +4,13 @@ import React from 'react'; import Badge from '../general/Badge'; -const METHODS_TO_BIND = [ - 'handleClick' -]; +const METHODS_TO_BIND = ['handleClick']; class SidebarFilter extends React.Component { constructor() { super(); - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -23,19 +21,19 @@ class SidebarFilter extends React.Component { render() { let classNames = classnames('sidebar-filter__item', { - 'is-active': this.props.isActive + 'is-active': this.props.isActive, }); let name = this.props.name; if (this.props.name === 'all') { name = this.props.intl.formatMessage({ id: 'filter.all', - defaultMessage: 'All' + defaultMessage: 'All', }); } else if (this.props.name === 'untagged') { name = this.props.intl.formatMessage({ id: 'filter.untagged', - defaultMessage: 'Untagged' + defaultMessage: 'Untagged', }); } @@ -43,9 +41,7 @@ class SidebarFilter extends React.Component {
  • {this.props.icon} {name} - - {this.props.count} - + {this.props.count}
  • ); } diff --git a/client/src/javascript/components/sidebar/SidebarItem.js b/client/src/javascript/components/sidebar/SidebarItem.js index 3debfa6a..38ddda28 100644 --- a/client/src/javascript/components/sidebar/SidebarItem.js +++ b/client/src/javascript/components/sidebar/SidebarItem.js @@ -6,23 +6,19 @@ class SidebarItem extends React.Component { static propTypes = { baseClassName: PropTypes.string, children: PropTypes.node, - modifier: PropTypes.string + modifier: PropTypes.string, }; static defaultProps = { - baseClassName: 'sidebar__item' + baseClassName: 'sidebar__item', }; render() { let classes = classnames(this.props.baseClassName, { - [`${this.props.baseClassName}--${this.props.modifier}`]: this.props.modifier + [`${this.props.baseClassName}--${this.props.modifier}`]: this.props.modifier, }); - return ( -
    - {this.props.children} -
    - ); + return
    {this.props.children}
    ; } } diff --git a/client/src/javascript/components/sidebar/SpeedLimitDropdown.js b/client/src/javascript/components/sidebar/SpeedLimitDropdown.js index 6febe774..19f55783 100644 --- a/client/src/javascript/components/sidebar/SpeedLimitDropdown.js +++ b/client/src/javascript/components/sidebar/SpeedLimitDropdown.js @@ -14,18 +14,14 @@ import TransferDataStore from '../../stores/TransferDataStore'; const MESSAGES = defineMessages({ speedLimits: { defaultMessage: 'Speed Limits', - id: 'sidebar.button.speedlimits' + id: 'sidebar.button.speedlimits', }, unlimited: { defaultMessage: 'Unlimited', - id: 'speed.unlimited' - } + id: 'speed.unlimited', + }, }); -const METHODS_TO_BIND = [ - 'handleDropdownOpen', - 'handleSettingsFetchRequestSuccess', - 'onTransferSummaryChange' -]; +const METHODS_TO_BIND = ['handleDropdownOpen', 'handleSettingsFetchRequestSuccess', 'onTransferSummaryChange']; class SpeedLimitDropdown extends React.Component { constructor() { @@ -35,57 +31,46 @@ class SpeedLimitDropdown extends React.Component { speedLimits: SettingsStore.getFloodSettings('speedLimits'), currentThrottles: { download: null, - upload: null - } + upload: null, + }, }; this.tooltip = null; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - SettingsStore.listen( - EventTypes.SETTINGS_CHANGE, - this.handleSettingsFetchRequestSuccess - ); - TransferDataStore.listen( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.onTransferSummaryChange - ); + SettingsStore.listen(EventTypes.SETTINGS_CHANGE, this.handleSettingsFetchRequestSuccess); + TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.onTransferSummaryChange); } componentWillUnmount() { - SettingsStore.unlisten( - EventTypes.SETTINGS_CHANGE, - this.handleSettingsFetchRequestSuccess - ); - TransferDataStore.unlisten( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.onTransferSummaryChange - ); + SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, this.handleSettingsFetchRequestSuccess); + TransferDataStore.unlisten(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.onTransferSummaryChange); } onTransferSummaryChange() { const transferSummary = TransferDataStore.getTransferSummary(); if ( - this.state.currentThrottles.upload !== transferSummary.upThrottle - || this.state.currentThrottles.download !== transferSummary.downThrottle + this.state.currentThrottles.upload !== transferSummary.upThrottle || + this.state.currentThrottles.download !== transferSummary.downThrottle ) { this.setState({ currentThrottles: { upload: transferSummary.upThrottle, - download: transferSummary.downThrottle - } + download: transferSummary.downThrottle, + }, }); } } getDropdownHeader() { return ( - @@ -101,7 +86,9 @@ class SpeedLimitDropdown extends React.Component { {this.tooltip = node;}} + ref={node => { + this.tooltip = node; + }} wrapperClassName="sidebar__icon-button tooltip__wrapper"> @@ -112,9 +99,7 @@ class SpeedLimitDropdown extends React.Component { if (bytes === 0) { return this.props.intl.formatMessage(MESSAGES.unlimited); } else { - return ( - - ); + return ; } } @@ -123,14 +108,14 @@ class SpeedLimitDropdown extends React.Component { className: `dropdown__label dropdown__label--${property}`, displayName: `${property.charAt(0).toUpperCase()}${property.slice(1)}`, selectable: false, - value: null + value: null, }; let insertCurrentThrottle = true; let currentThrottle = this.state.currentThrottles; let speeds = this.state.speedLimits[property]; - let items = speeds.map((bytes) => { + let items = speeds.map(bytes => { let selected = false; bytes = Number(bytes); @@ -146,7 +131,7 @@ class SpeedLimitDropdown extends React.Component { property, selected, selectable: true, - value: bytes + value: bytes, }; }); @@ -162,7 +147,7 @@ class SpeedLimitDropdown extends React.Component { property: property, selected: true, selectable: true, - value: currentThrottle[property] + value: currentThrottle[property], }); } @@ -199,7 +184,8 @@ class SpeedLimitDropdown extends React.Component { header={this.getDropdownHeader()} menuItems={this.getDropdownMenus()} onOpen={this.handleDropdownOpen} - trigger={this.getDropdownTrigger()} /> + trigger={this.getDropdownTrigger()} + /> ); } } diff --git a/client/src/javascript/components/sidebar/StatusFilters.js b/client/src/javascript/components/sidebar/StatusFilters.js index 7429d4ba..2eacad4c 100644 --- a/client/src/javascript/components/sidebar/StatusFilters.js +++ b/client/src/javascript/components/sidebar/StatusFilters.js @@ -13,12 +13,7 @@ import StopIcon from '../icons/StopIcon'; import TorrentFilterStore from '../../stores/TorrentFilterStore'; import UIActions from '../../actions/UIActions'; -const METHODS_TO_BIND = [ - 'getFilters', - 'handleClick', - 'onStatusFilterChange', - 'onTorrentTaxonomyChange' -]; +const METHODS_TO_BIND = ['getFilters', 'handleClick', 'onStatusFilterChange', 'onTorrentTaxonomyChange']; class StatusFilters extends React.Component { constructor() { @@ -27,26 +22,22 @@ class StatusFilters extends React.Component { this.state = { statusCount: {}, statusFilter: TorrentFilterStore.getStatusFilter(), - trackerFilter: TorrentFilterStore.getTrackerFilter() + trackerFilter: TorrentFilterStore.getTrackerFilter(), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, - this.onStatusFilterChange); + TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange); } componentWillUnmount() { - TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, - this.onStatusFilterChange); + TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_STATUS_CHANGE, this.onStatusFilterChange); } handleClick(filter) { @@ -58,70 +49,72 @@ class StatusFilters extends React.Component { { label: this.props.intl.formatMessage({ id: 'filter.all', - defaultMessage: 'All' + defaultMessage: 'All', }), slug: 'all', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.downloading', - defaultMessage: 'Downloading' + defaultMessage: 'Downloading', }), slug: 'downloading', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.completed', - defaultMessage: 'Complete' + defaultMessage: 'Complete', }), slug: 'complete', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.stopped', - defaultMessage: 'Stopped' + defaultMessage: 'Stopped', }), slug: 'stopped', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.active', - defaultMessage: 'All' + defaultMessage: 'All', }), slug: 'active', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.inactive', - defaultMessage: 'Inactive' + defaultMessage: 'Inactive', }), slug: 'inactive', - icon: + icon: , }, { label: this.props.intl.formatMessage({ id: 'filter.status.error', - defaultMessage: 'Error' + defaultMessage: 'Error', }), slug: 'error', - icon: - } + icon: , + }, ]; - let filterElements = filters.map((filter) => { + let filterElements = filters.map(filter => { return ( - + slug={filter.slug} + /> ); }); @@ -130,7 +123,7 @@ class StatusFilters extends React.Component { onStatusFilterChange() { this.setState({ - statusFilter: TorrentFilterStore.getStatusFilter() + statusFilter: TorrentFilterStore.getStatusFilter(), }); } @@ -145,10 +138,7 @@ class StatusFilters extends React.Component { return (
    • - +
    • {filters}
    diff --git a/client/src/javascript/components/sidebar/TagFilters.js b/client/src/javascript/components/sidebar/TagFilters.js index dd630203..12fd208b 100644 --- a/client/src/javascript/components/sidebar/TagFilters.js +++ b/client/src/javascript/components/sidebar/TagFilters.js @@ -6,12 +6,7 @@ import SidebarFilter from './SidebarFilter'; import TorrentFilterStore from '../../stores/TorrentFilterStore'; import UIActions from '../../actions/UIActions'; -const METHODS_TO_BIND = [ - 'getFilters', - 'handleClick', - 'onTagFilterChange', - 'onTorrentTaxonomyChange' -]; +const METHODS_TO_BIND = ['getFilters', 'handleClick', 'onTagFilterChange', 'onTorrentTaxonomyChange']; export default class TagFilters extends React.Component { constructor() { @@ -19,26 +14,22 @@ export default class TagFilters extends React.Component { this.state = { tagCount: {}, - tagFilter: TorrentFilterStore.getTagFilter() + tagFilter: TorrentFilterStore.getTagFilter(), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TAG_CHANGE, - this.onTagFilterChange); + TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TAG_CHANGE, this.onTagFilterChange); } componentWillUnmount() { - TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TAG_CHANGE, - this.onTagFilterChange); + TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TAG_CHANGE, this.onTagFilterChange); } getFilters() { @@ -54,12 +45,14 @@ export default class TagFilters extends React.Component { let filterElements = filterItems.map((filter, index) => { return ( - + slug={filter} + /> ); }); @@ -73,8 +66,7 @@ export default class TagFilters extends React.Component { hasTags() { let tags = Object.keys(this.state.tagCount); - return !((tags.length === 1 && tags[0] === 'all') - || (tags.length === 2 && tags[1] === 'untagged')); + return !((tags.length === 1 && tags[0] === 'all') || (tags.length === 2 && tags[1] === 'untagged')); } onTagFilterChange() { @@ -94,10 +86,7 @@ export default class TagFilters extends React.Component { return (
    • - +
    • {this.getFilters()}
    diff --git a/client/src/javascript/components/sidebar/TrackerFilters.js b/client/src/javascript/components/sidebar/TrackerFilters.js index 9ecd8bec..286bc5ef 100644 --- a/client/src/javascript/components/sidebar/TrackerFilters.js +++ b/client/src/javascript/components/sidebar/TrackerFilters.js @@ -6,12 +6,7 @@ import SidebarFilter from './SidebarFilter'; import TorrentFilterStore from '../../stores/TorrentFilterStore'; import UIActions from '../../actions/UIActions'; -const METHODS_TO_BIND = [ - 'getFilters', - 'handleClick', - 'onTrackerFilterChange', - 'onTorrentTaxonomyChange' -]; +const METHODS_TO_BIND = ['getFilters', 'handleClick', 'onTrackerFilterChange', 'onTorrentTaxonomyChange']; export default class TrackerFilters extends React.Component { constructor() { @@ -19,26 +14,22 @@ export default class TrackerFilters extends React.Component { this.state = { trackerCount: {}, - trackerFilter: TorrentFilterStore.getTrackerFilter() + trackerFilter: TorrentFilterStore.getTrackerFilter(), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } componentDidMount() { - TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, - this.onTrackerFilterChange); + TorrentFilterStore.listen(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.listen(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange); } componentWillUnmount() { - TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, - this.onTorrentTaxonomyChange); - TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, - this.onTrackerFilterChange); + TorrentFilterStore.unlisten(EventTypes.CLIENT_FETCH_TORRENT_TAXONOMY_SUCCESS, this.onTorrentTaxonomyChange); + TorrentFilterStore.unlisten(EventTypes.UI_TORRENTS_FILTER_TRACKER_CHANGE, this.onTrackerFilterChange); } getFilters() { @@ -54,12 +45,14 @@ export default class TrackerFilters extends React.Component { let filterElements = filterItems.map((filter, index) => { return ( - + slug={filter} + /> ); }); @@ -95,10 +88,7 @@ export default class TrackerFilters extends React.Component { return (
    • - +
    • {filters}
    diff --git a/client/src/javascript/components/sidebar/TransferData.js b/client/src/javascript/components/sidebar/TransferData.js index 45b75556..357de220 100644 --- a/client/src/javascript/components/sidebar/TransferData.js +++ b/client/src/javascript/components/sidebar/TransferData.js @@ -18,7 +18,7 @@ const METHODS_TO_BIND = [ 'handleMouseOver', 'onTransferDataRequestError', 'onTransferSummaryChange', - 'onTransferHistoryRequestSuccess' + 'onTransferHistoryRequestSuccess', ]; class TransferData extends React.Component { @@ -31,10 +31,10 @@ class TransferData extends React.Component { sidebarWidth: 0, transferHistoryRequestSuccess: false, transferDataRequestError: false, - transferDataRequestSuccess: false + transferDataRequestSuccess: false, }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -42,48 +42,29 @@ class TransferData extends React.Component { { id: 'transfer-data', message: ( - - ) + + ), }, { id: 'transfer-history', - message: ( - - ) - } + message: , + }, ]); } componentDidMount() { this.setState({ - sidebarWidth: ReactDOM.findDOMNode(this).offsetWidth + sidebarWidth: ReactDOM.findDOMNode(this).offsetWidth, }); - ClientStatusStore.listen( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); - TransferDataStore.listen( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.onTransferSummaryChange - ); - TransferDataStore.listen( - EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, - this.onTransferHistoryRequestSuccess - ); + ClientStatusStore.listen(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); + TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.onTransferSummaryChange); + TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, this.onTransferHistoryRequestSuccess); } componentWillUnmount() { - ClientStatusStore.unlisten( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); - TransferDataStore.unlisten( - EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, - this.onTransferSummaryChange - ); + ClientStatusStore.unlisten(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); + TransferDataStore.unlisten(EventTypes.CLIENT_TRANSFER_SUMMARY_CHANGE, this.onTransferSummaryChange); TransferDataStore.unlisten( EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, this.onTransferHistoryRequestSuccess @@ -92,7 +73,7 @@ class TransferData extends React.Component { handleClientStatusChange = () => { this.setState({ - isClientConnected: ClientStatusStore.getIsConnected() + isClientConnected: ClientStatusStore.getIsConnected(), }); }; @@ -119,8 +100,7 @@ class TransferData extends React.Component { } isLoading() { - if (!this.state.transferHistoryRequestSuccess || - !this.state.transferDataRequestSuccess) { + if (!this.state.transferHistoryRequestSuccess || !this.state.transferDataRequestSuccess) { return true; } @@ -130,14 +110,14 @@ class TransferData extends React.Component { onTransferDataRequestError() { this.setState({ transferDataRequestError: true, - transferDataRequestSuccess: false + transferDataRequestSuccess: false, }); } onTransferSummaryChange() { this.setState({ transferDataRequestError: false, - transferDataRequestSuccess: true + transferDataRequestSuccess: true, }); UIStore.satisfyDependency('transfer-data'); @@ -146,7 +126,7 @@ class TransferData extends React.Component { onTransferHistoryRequestSuccess() { if (!this.state.transferHistoryRequestSuccess) { this.setState({ - transferHistoryRequestSuccess: true + transferHistoryRequestSuccess: true, }); } @@ -158,12 +138,13 @@ class TransferData extends React.Component { return ( this.rateGraphRef = ref} - width={this.state.sidebarWidth} /> + height={150} + id="transfer-rate-graph" + onMouseOut={this.handleGraphMouseOut} + onHover={this.handleGraphHover} + ref={ref => (this.rateGraphRef = ref)} + width={this.state.sidebarWidth} + /> ); } @@ -174,14 +155,16 @@ class TransferData extends React.Component { const transferSummary = TransferDataStore.getTransferSummary(); content = ( -
    + transferSummary={transferSummary} + /> {this.renderTransferRateGraph()}
    ); @@ -189,16 +172,12 @@ class TransferData extends React.Component { content = ; } - return ( -
    - {content} -
    - ); + return
    {content}
    ; } } TransferData.defaultProps = { - historyLength: 1 + historyLength: 1, }; export default TransferData; diff --git a/client/src/javascript/components/sidebar/TransferRateDetails.js b/client/src/javascript/components/sidebar/TransferRateDetails.js index 90c10da2..c64ccf46 100644 --- a/client/src/javascript/components/sidebar/TransferRateDetails.js +++ b/client/src/javascript/components/sidebar/TransferRateDetails.js @@ -15,14 +15,14 @@ import Upload from '../icons/Upload'; const messages = defineMessages({ ago: { id: 'general.ago', - defaultMessage: 'ago' - } + defaultMessage: 'ago', + }, }); const icons = { download: , infinity: , - upload: + upload: , }; class TransferRateDetails extends React.Component { @@ -31,24 +31,18 @@ class TransferRateDetails extends React.Component { this.state = { isClientConnected: false, - inspectorPoint: null + inspectorPoint: null, }; this.handleClientStatusChange = this.handleClientStatusChange.bind(this); } componentDidMount() { - ClientStatusStore.listen( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); + ClientStatusStore.listen(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); } componentWillUnmount() { - ClientStatusStore.unlisten( - EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, - this.handleClientStatusChange - ); + ClientStatusStore.unlisten(EventTypes.CLIENT_CONNECTION_STATUS_CHANGE, this.handleClientStatusChange); } componentWillReceiveProps(nextProps) { @@ -59,58 +53,49 @@ class TransferRateDetails extends React.Component { getCurrentTansferRate(slug, options = {}) { const { - props: { - inspectorPoint, - transferSummary - } + props: {inspectorPoint, transferSummary}, } = this; const {isClientConnected} = this.state; const throttles = { download: transferSummary.downThrottle, - upload: transferSummary.upThrottle + upload: transferSummary.upThrottle, }; let timestamp = null; let transferTotals = { download: transferSummary.downTotal, - upload: transferSummary.upTotal + upload: transferSummary.upTotal, }; let transferRates = { download: transferSummary.downRate, - upload: transferSummary.upRate + upload: transferSummary.upRate, }; if (inspectorPoint != null) { transferRates = { upload: inspectorPoint.uploadSpeed, - download: inspectorPoint.downloadSpeed + download: inspectorPoint.downloadSpeed, }; } - const secondaryDataClasses = classnames( - 'client-stats__rate__data--secondary', - {'is-visible': inspectorPoint == null && isClientConnected} - ); + const secondaryDataClasses = classnames('client-stats__rate__data--secondary', { + 'is-visible': inspectorPoint == null && isClientConnected, + }); - const timestampClasses = classnames( - 'client-stats__rate__data--timestamp', - {'is-visible': inspectorPoint != null && options.showHoverDuration} - ); + const timestampClasses = classnames('client-stats__rate__data--timestamp', { + 'is-visible': inspectorPoint != null && options.showHoverDuration, + }); if (this.state.timestamp != null) { const currentTime = moment(Date.now()); const durationSummary = formatUtil.secondsToDuration( - moment - .duration(currentTime.diff(moment(this.state.timestamp))) - .asSeconds() + moment.duration(currentTime.diff(moment(this.state.timestamp))).asSeconds() ); timestamp = (
    - +
    ); } @@ -125,9 +110,7 @@ class TransferRateDetails extends React.Component { return (
    -
    - {icons[slug]} -
    +
    {icons[slug]}
    @@ -137,9 +120,7 @@ class TransferRateDetails extends React.Component {
    -
    - {limit} -
    +
    {limit}
    @@ -148,7 +129,7 @@ class TransferRateDetails extends React.Component { handleClientStatusChange() { this.setState({ - isClientConnected: ClientStatusStore.getIsConnected() + isClientConnected: ClientStatusStore.getIsConnected(), }); } diff --git a/client/src/javascript/components/sidebar/TransferRateGraph.js b/client/src/javascript/components/sidebar/TransferRateGraph.js index cc46c1a2..3d193ff8 100644 --- a/client/src/javascript/components/sidebar/TransferRateGraph.js +++ b/client/src/javascript/components/sidebar/TransferRateGraph.js @@ -12,22 +12,22 @@ const METHODS_TO_BIND = [ 'handleMouseOut', 'handleMouseOver', 'handleMouseMove', - 'renderGraphData' + 'renderGraphData', ]; class TransferRateGraph extends React.Component { static propTypes = { - width: PropTypes.number + width: PropTypes.number, }; static defaultProps = { - width: 240 + width: 240, }; constructor() { super(); - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); @@ -40,10 +40,7 @@ class TransferRateGraph extends React.Component { } componentDidMount() { - TransferDataStore.listen( - EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, - this.handleTransferHistoryChange - ); + TransferDataStore.listen(EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, this.handleTransferHistoryChange); this.renderGraphData(); } @@ -53,10 +50,7 @@ class TransferRateGraph extends React.Component { } componentWillUnmount() { - TransferDataStore.unlisten( - EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, - this.handleTransferHistoryChange - ); + TransferDataStore.unlisten(EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS, this.handleTransferHistoryChange); } appendGraphCircles(graph, slug) { @@ -78,17 +72,14 @@ class TransferRateGraph extends React.Component { } appendEmptyGraphLines(graph, slug) { - this.graphRefs[slug].rateLine = graph - .append('path') - .attr('class', `graph__line graph__line--${slug}`); + this.graphRefs[slug].rateLine = graph.append('path').attr('class', `graph__line graph__line--${slug}`); } getGradient(slug) { return ( - - - + + + ); } @@ -139,27 +130,25 @@ class TransferRateGraph extends React.Component { 0, d3.max(historicalData.download, (dataPoint, index) => { return Math.max(dataPoint, historicalData.upload[index]); - }) + }), ]) .range([height - margin.top, margin.bottom]); - const lineFunc = (interpolation) => { - return d3 - .svg + const lineFunc = interpolation => { + return d3.svg .line() .x((dataPoint, index) => this.xScale(index)) .y(dataPoint => this.yScale(dataPoint)) .interpolate(interpolation); }; - const areaFunc = (interpolation) => { - return d3 - .svg - .area() - .x((dataPoint, index) => this.xScale(index)) - .y0(height) - .y1(dataPoint => this.yScale(dataPoint)) - .interpolate(interpolation); + const areaFunc = interpolation => { + return d3.svg + .area() + .x((dataPoint, index) => this.xScale(index)) + .y0(height) + .y1(dataPoint => this.yScale(dataPoint)) + .interpolate(interpolation); }; const downloadLinePath = lineFunc('cardinal')(historicalData.download); @@ -188,7 +177,7 @@ class TransferRateGraph extends React.Component { const { lastMouseX, props: {onHover}, - xScale + xScale, } = this; const historicalData = TransferDataStore.getTransferRates(); @@ -201,14 +190,16 @@ class TransferRateGraph extends React.Component { onHover({ uploadSpeed, downloadSpeed, - nearestTimestamp + nearestTimestamp, }); } } setInspectorCoordinates(slug, hoverPoint) { const { - graphRefs: {[slug]: {inspectPoint}}, + graphRefs: { + [slug]: {inspectPoint}, + }, xScale, yScale, } = this; @@ -218,13 +209,11 @@ class TransferRateGraph extends React.Component { const lowerSpeed = historicalData[slug][Math.floor(hoverPoint)]; const delta = upperSpeed - lowerSpeed; - const speedAtHoverPoint = lowerSpeed + (delta * (hoverPoint % 1)); + const speedAtHoverPoint = lowerSpeed + delta * (hoverPoint % 1); const coordinates = {x: xScale(hoverPoint), y: yScale(speedAtHoverPoint)}; - inspectPoint.attr( - 'transform', 'translate(' + coordinates.x + ',' + coordinates.y + ')' - ); + inspectPoint.attr('transform', 'translate(' + coordinates.x + ',' + coordinates.y + ')'); return speedAtHoverPoint; } @@ -239,8 +228,7 @@ class TransferRateGraph extends React.Component { render() { return ( - this.graphRefs.graph = ref}> + (this.graphRefs.graph = ref)}> {this.getGradient('upload')} {this.getGradient('download')} diff --git a/client/src/javascript/components/torrent-list/Action.js b/client/src/javascript/components/torrent-list/Action.js index 4012a8e1..3652100d 100644 --- a/client/src/javascript/components/torrent-list/Action.js +++ b/client/src/javascript/components/torrent-list/Action.js @@ -7,14 +7,11 @@ export default class Action extends React.Component { render() { const {clickHandler, icon, label, slug} = this.props; const classes = classnames('action tooltip__wrapper', { - [`action--${slug}`]: slug != null + [`action--${slug}`]: slug != null, }); return ( - + {icon} {label}
    diff --git a/client/src/javascript/components/torrent-list/ActionBar.js b/client/src/javascript/components/torrent-list/ActionBar.js index 6575fe5c..0f7c3534 100644 --- a/client/src/javascript/components/torrent-list/ActionBar.js +++ b/client/src/javascript/components/torrent-list/ActionBar.js @@ -20,7 +20,7 @@ const METHODS_TO_BIND = [ 'handleSortChange', 'handleStart', 'handleStop', - 'handleSettingsChange' + 'handleSettingsChange', ]; class ActionBar extends React.Component { @@ -29,10 +29,10 @@ class ActionBar extends React.Component { this.state = { sortBy: SettingsStore.getFloodSettings('sortTorrents'), - torrentListViewSize: SettingsStore.getFloodSettings('torrentListViewSize') + torrentListViewSize: SettingsStore.getFloodSettings('torrentListViewSize'), }; - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -42,8 +42,7 @@ class ActionBar extends React.Component { } componentWillUnmount() { - SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, - this.handleSettingsChange); + SettingsStore.unlisten(EventTypes.SETTINGS_CHANGE, this.handleSettingsChange); } handleAddTorrents() { @@ -52,7 +51,7 @@ class ActionBar extends React.Component { handleRemoveTorrents() { UIActions.displayModal({ - id: 'remove-torrents' + id: 'remove-torrents', }); } @@ -73,38 +72,37 @@ class ActionBar extends React.Component { handleSettingsChange() { this.setState({ sortBy: SettingsStore.getFloodSettings('sortTorrents'), - torrentListViewSize: SettingsStore.getFloodSettings('torrentListViewSize') + torrentListViewSize: SettingsStore.getFloodSettings('torrentListViewSize'), }); } render() { - const classes = classnames( - 'action-bar', - { - 'action-bar--is-condensed': - this.state.torrentListViewSize === 'condensed' - } - ); + const classes = classnames('action-bar', { + 'action-bar--is-condensed': this.state.torrentListViewSize === 'condensed', + }); return ( diff --git a/client/src/javascript/components/torrent-list/SortDropdown.js b/client/src/javascript/components/torrent-list/SortDropdown.js index 4c8a2574..b6a96a6b 100644 --- a/client/src/javascript/components/torrent-list/SortDropdown.js +++ b/client/src/javascript/components/torrent-list/SortDropdown.js @@ -15,14 +15,14 @@ const SORT_PROPERTIES = [ 'downTotal', 'upTotal', 'sizeBytes', - 'dateAdded' + 'dateAdded', ]; class SortDropdown extends React.Component { constructor() { super(); - METHODS_TO_BIND.forEach((method) => { + METHODS_TO_BIND.forEach(method => { this[method] = this[method].bind(this); }); } @@ -38,16 +38,10 @@ class SortDropdown extends React.Component { return ( - + ); @@ -55,11 +49,11 @@ class SortDropdown extends React.Component { getDropdownMenus() { const {direction, selectedProperty} = this.props; - let items = SORT_PROPERTIES.map((sortProp) => { + let items = SORT_PROPERTIES.map(sortProp => { const isSelected = sortProp === selectedProperty; const directionIndicator = isSelected ? ( - - ) : null; + + ) : null; return { displayName: ( @@ -69,7 +63,7 @@ class SortDropdown extends React.Component {
    ), selected: isSelected, - property: sortProp + property: sortProp, }; }); @@ -99,7 +93,8 @@ class SortDropdown extends React.Component { + menuItems={this.getDropdownMenus()} + /> ); } } diff --git a/client/src/javascript/components/torrent-list/TableHeading.js b/client/src/javascript/components/torrent-list/TableHeading.js index e1cc0068..8b63b014 100644 --- a/client/src/javascript/components/torrent-list/TableHeading.js +++ b/client/src/javascript/components/torrent-list/TableHeading.js @@ -10,7 +10,7 @@ const methodsToBind = [ 'handleCellMouseDown', 'handleMouseUp', 'handleMouseMove', - 'updateCellWidth' + 'updateCellWidth', ]; const mouseDownStyles = ` @@ -27,7 +27,7 @@ class TableHeading extends React.Component { this.isMouseDown = false; this.lastMouseX = null; - methodsToBind.forEach(method => this[method] = this[method].bind(this)); + methodsToBind.forEach(method => (this[method] = this[method].bind(this))); } componentDidMount() { @@ -46,8 +46,10 @@ class TableHeading extends React.Component { if (nextCellWidth > 20) { this.focusedCellWidth = nextCellWidth; this.lastMouseX = event.clientX; - this.resizeLine.style.transform - = `translateX(${Math.max(0, event.clientX - this.tableHeadingX + this.props.scrollOffset)}px)`; + this.resizeLine.style.transform = `translateX(${Math.max( + 0, + event.clientX - this.tableHeadingX + this.props.scrollOffset + )}px)`; } } @@ -80,7 +82,10 @@ class TableHeading extends React.Component { this.focusedCellWidth = width; this.isMouseDown = true; this.lastMouseX = event.clientX; - this.resizeLine.style.transform = `translateX(${Math.max(0, event.clientX - this.tableHeadingX + this.props.scrollOffset)}px)`; + this.resizeLine.style.transform = `translateX(${Math.max( + 0, + event.clientX - this.tableHeadingX + this.props.scrollOffset + )}px)`; this.resizeLine.style.opacity = 1; } } @@ -90,13 +95,7 @@ class TableHeading extends React.Component { } getHeadingElements() { - const { - defaultWidth, - defaultPropWidths, - columns, - propWidths, - sortProp - } = this.props; + const {defaultWidth, defaultPropWidths, columns, propWidths, sortProp} = this.props; return columns.reduce((accumulator, {id, visible}) => { if (!visible) { @@ -108,37 +107,36 @@ class TableHeading extends React.Component { if (!this.isMouseDown) { handle = ( - { this.handleCellMouseDown(event, id, width); - }} /> + }} + /> ); } const isSortActive = id === sortProp.property; - const classes = classnames( - 'table__cell table__heading', - { - 'table__heading--is-sorted': isSortActive, - [`table__heading--direction--${sortProp.direction}`]: isSortActive - } - ); + const classes = classnames('table__cell table__heading', { + 'table__heading--is-sorted': isSortActive, + [`table__heading--direction--${sortProp.direction}`]: isSortActive, + }); const label = ( - + ); accumulator.push( -
    this.handleCellClick(id, event)} style={{width: `${width}px`}}> - {label} @@ -152,12 +150,10 @@ class TableHeading extends React.Component { render() { return ( -
    this.tableHeading = ref}> +
    (this.tableHeading = ref)}> {this.getHeadingElements()}
    -
    this.resizeLine = ref} /> +
    (this.resizeLine = ref)} />
    ); } diff --git a/client/src/javascript/components/torrent-list/Torrent.js b/client/src/javascript/components/torrent-list/Torrent.js index 38735989..d941b49f 100644 --- a/client/src/javascript/components/torrent-list/Torrent.js +++ b/client/src/javascript/components/torrent-list/Torrent.js @@ -18,36 +18,33 @@ const condensedValueTransformers = { downloadTotal: torrent => torrent.bytesDone, peers: torrent => torrent.peersConnected, percentComplete: torrent => { - return ( - - ); + return ; }, - seeds: torrent => torrent.seedsConnected + seeds: torrent => torrent.seedsConnected, }; const condensedSecondaryValueTransformers = { peers: torrent => torrent.peersTotal, - seeds: torrent => torrent.seedsTotal + seeds: torrent => torrent.seedsTotal, }; const expandedTorrentSectionContent = { primary: ['name'], secondary: ['eta', 'downRate', 'upRate'], - tertiary: ['*'] + tertiary: ['*'], }; const expandedTorrentDetailsToHide = ['downTotal']; const expandedValueTransformers = { peers: torrent => torrent.peersConnected, - seeds: torrent => torrent.seedsConnected + seeds: torrent => torrent.seedsConnected, }; const expandedSecondaryValueTransformers = { peers: torrent => torrent.peersTotal, seeds: torrent => torrent.seedsTotal, - percentComplete: torrent => torrent.bytesDone + percentComplete: torrent => torrent.bytesDone, }; const ICONS = { @@ -59,34 +56,21 @@ const ICONS = { peers: , ratio: , seeds: , - uploadThick: + uploadThick: , }; -const METHODS_TO_BIND = [ - 'handleClick', - 'handleDoubleClick', - 'handleRightClick' -]; +const METHODS_TO_BIND = ['handleClick', 'handleDoubleClick', 'handleRightClick']; -const TORRENT_PRIMITIVES_TO_OBSERVE = [ - 'bytesDone', - 'downRate', - 'peersTotal', - 'seedsTotal', - 'upRate' -]; +const TORRENT_PRIMITIVES_TO_OBSERVE = ['bytesDone', 'downRate', 'peersTotal', 'seedsTotal', 'upRate']; -const TORRENT_ARRAYS_TO_OBSERVE = [ - 'status', - 'tags' -]; +const TORRENT_ARRAYS_TO_OBSERVE = ['status', 'tags']; class Torrent extends React.Component { constructor(props) { super(); this.state = { - isSelected: props.selected + isSelected: props.selected, }; METHODS_TO_BIND.forEach(method => { @@ -101,9 +85,11 @@ class Torrent extends React.Component { } shouldComponentUpdate(nextProps, nextState) { - if (nextProps.selected !== this.props.selected - || nextState.isSelected !== this.state.isSelected - || nextProps.isCondensed !== this.props.isCondensed) { + if ( + nextProps.selected !== this.props.selected || + nextState.isSelected !== this.state.isSelected || + nextProps.isCondensed !== this.props.isCondensed + ) { return true; } @@ -114,10 +100,12 @@ class Torrent extends React.Component { let nextArr = nextTorrent[key]; let currentArr = this.props.torrent[key]; - return nextArr.length !== currentArr.length || + return ( + nextArr.length !== currentArr.length || nextArr.some((nextValue, index) => { return nextValue !== currentArr[index]; - }); + }) + ); }); if (!shouldUpdate) { @@ -144,7 +132,9 @@ class Torrent extends React.Component { getTags(tags) { return tags.map((tag, index) => { return ( -
  • {tag}
  • +
  • + {tag} +
  • ); }); } @@ -180,7 +170,7 @@ class Torrent extends React.Component { { 'torrent--is-selected': isSelected, 'torrent--is-condensed': isCondensed, - 'torrent--is-expanded': !isCondensed + 'torrent--is-expanded': !isCondensed, }, 'torrent' ); @@ -203,20 +193,24 @@ class Torrent extends React.Component { } accumulator.push( - + width={this.getWidth(id)} + /> ); return accumulator; }, []); return ( -
  • {torrentPropertyColumns} @@ -239,9 +233,7 @@ class Torrent extends React.Component { } if (id in expandedSecondaryValueTransformers) { - secondaryValue = expandedSecondaryValueTransformers[id]( - torrent - ); + secondaryValue = expandedSecondaryValueTransformers[id](torrent); } if (expandedTorrentSectionContent.primary.includes(id)) { @@ -250,48 +242,37 @@ class Torrent extends React.Component { key={id} className="torrent__details__section torrent__details__section--primary" slug={id} - value={value} /> + value={value} + /> ); } else if (expandedTorrentSectionContent.secondary.includes(id)) { - sections.secondary[ - expandedTorrentSectionContent.secondary.indexOf(id) - ] = ( - + sections.secondary[expandedTorrentSectionContent.secondary.indexOf(id)] = ( + ); } else { sections.tertiary.push( - + ); } } } return ( -
  • {sections.primary} -
    - {sections.secondary} -
    -
    -
    - {sections.tertiary} +
    {sections.secondary}
    +
    {sections.tertiary}
    - +
    -
  • ); @@ -472,10 +433,7 @@ class TorrentListContainer extends React.Component { return (
    - +
    {clearFilters}
    @@ -483,9 +441,7 @@ class TorrentListContainer extends React.Component { } getCellWidth(slug) { - const value = this.state.torrentListColumnWidths[slug] - || defaultPropWidths[slug] - || defaultWidth; + const value = this.state.torrentListColumnWidths[slug] || defaultPropWidths[slug] || defaultWidth; return value; } @@ -507,24 +463,23 @@ class TorrentListContainer extends React.Component { } getTotalCellWidth() { - return this.state.displayedProperties.reduce( - (accumulator, {id, visible}) => { - if (!visible) { - return accumulator; - } + return this.state.displayedProperties.reduce((accumulator, {id, visible}) => { + if (!visible) { + return accumulator; + } - return accumulator + this.getCellWidth(id); - }, - 0 - ); + return accumulator + this.getCellWidth(id); + }, 0); } getVerticalScrollbarThumb(props, onMouseUp) { return (
    -
    this.verticalScrollbarThumb = ref }/> + ref={ref => (this.verticalScrollbarThumb = ref)} + />
    ); } @@ -537,9 +492,7 @@ class TorrentListContainer extends React.Component { if (this.verticalScrollbarThumb != null) { const {clientWidth, scrollLeft, scrollWidth} = event.target; this.lastScrollLeft = scrollLeft; - this.updateVerticalThumbPosition( - (scrollWidth - clientWidth) * -1 + scrollLeft - ); + this.updateVerticalThumbPosition((scrollWidth - clientWidth) * -1 + scrollLeft); } } @@ -552,7 +505,7 @@ class TorrentListContainer extends React.Component { SettingsStore.saveFloodSettings({ id: 'torrentListColumnWidths', - data: nextPropWidths + data: nextPropWidths, }); this.setState({torrentListColumnWidths: nextPropWidths}); @@ -565,7 +518,8 @@ class TorrentListContainer extends React.Component { const {hash} = torrent; return ( - + torrent={torrent} + /> ); } updateTorrentListViewWidth() { if (this.horizontalScrollRef != null) { this.setState({ - torrentListViewportSize: - this.horizontalScrollRef.scrollbarRef.getClientWidth() + torrentListViewportSize: this.horizontalScrollRef.scrollbarRef.getClientWidth(), }); } } @@ -598,21 +552,17 @@ class TorrentListContainer extends React.Component { let content = null; let torrentListHeading = null; const isCondensed = this.state.torrentListViewSize === 'condensed'; - const isListEmpty = this.state.emptyTorrentList - || this.state.torrents.length === 0; + const isListEmpty = this.state.emptyTorrentList || this.state.torrents.length === 0; const listWrapperStyle = this.getListWrapperStyle({ isCondensed, - isListEmpty + isListEmpty, }); if (!this.state.isClientConnected) { content = (
    - +
    ); @@ -620,24 +570,28 @@ class TorrentListContainer extends React.Component { content = this.getEmptyTorrentListNotification(); } else if (this.state.torrentRequestSuccess) { content = ( - this.listViewportRef = ref} - scrollContainerClass="torrent__list__scrollbars--vertical" /> + ref={ref => (this.listViewportRef = ref)} + scrollContainerClass="torrent__list__scrollbars--vertical" + /> ); if (isCondensed) { torrentListHeading = ( - + sortProp={TorrentFilterStore.getTorrentsSort()} + /> ); } } else { @@ -648,17 +602,16 @@ class TorrentListContainer extends React.Component { this.listContainer = ref} + ref={ref => (this.listContainer = ref)} onDrop={this.handleFileDrop} disableClick - disablePreview - > - + this.horizontalScrollRef = ref}> -
    + ref={ref => (this.horizontalScrollRef = ref)}> +
    {torrentListHeading} {content} @@ -670,10 +623,7 @@ class TorrentListContainer extends React.Component {
    - +
    diff --git a/client/src/javascript/constants/ActionTypes.js b/client/src/javascript/constants/ActionTypes.js index ce8aaa67..b715dc2a 100644 --- a/client/src/javascript/constants/ActionTypes.js +++ b/client/src/javascript/constants/ActionTypes.js @@ -94,7 +94,7 @@ const actionTypes = [ 'UI_SET_TORRENT_TAG_FILTER', 'UI_SET_TORRENT_TRACKER_FILTER', 'UI_SORT_PROPS_REQUEST_SUCCESS', - 'UI_SORT_PROPS_REQUEST_ERROR' + 'UI_SORT_PROPS_REQUEST_ERROR', ]; export default objectUtil.createStringMapFromArray(actionTypes); diff --git a/client/src/javascript/constants/Alerts.js b/client/src/javascript/constants/Alerts.js index 9ad8b30e..012f335d 100644 --- a/client/src/javascript/constants/Alerts.js +++ b/client/src/javascript/constants/Alerts.js @@ -23,7 +23,7 @@ const ALERTS = { =1 {torrent} other {torrents} }.`, - 'alert.settings.saved': 'Successfully saved settings.' + 'alert.settings.saved': 'Successfully saved settings.', }; export default ALERTS; diff --git a/client/src/javascript/constants/EventTypes.js b/client/src/javascript/constants/EventTypes.js index e160b071..48dec435 100644 --- a/client/src/javascript/constants/EventTypes.js +++ b/client/src/javascript/constants/EventTypes.js @@ -78,7 +78,7 @@ const eventTypes = [ 'UI_TORRENTS_FILTER_TRACKER_CHANGE', 'UI_TORRENTS_FILTER_SEARCH_CHANGE', 'UI_TORRENTS_LIST_FILTERED', - 'UI_TORRENTS_SORT_CHANGE' + 'UI_TORRENTS_SORT_CHANGE', ]; export default objectUtil.createStringMapFromArray(eventTypes); diff --git a/client/src/javascript/constants/Languages.js b/client/src/javascript/constants/Languages.js index d55a10c9..1df4a103 100644 --- a/client/src/javascript/constants/Languages.js +++ b/client/src/javascript/constants/Languages.js @@ -1,20 +1,20 @@ const LANGUAGES = { en: { defaultMessage: 'English', - id: 'locale.language.en' + id: 'locale.language.en', }, es: { defaultMessage: 'Spanish', - id: 'locale.language.es' + id: 'locale.language.es', }, fr: { defaultMessage: 'French', - id: 'locale.language.fr' + id: 'locale.language.fr', }, nl: { defaultMessage: 'Nederlands', - id: 'locale.language.nl' - } + id: 'locale.language.nl', + }, }; export default LANGUAGES; diff --git a/client/src/javascript/constants/PriorityLevels.js b/client/src/javascript/constants/PriorityLevels.js index dc87d6e5..0d16e7ed 100644 --- a/client/src/javascript/constants/PriorityLevels.js +++ b/client/src/javascript/constants/PriorityLevels.js @@ -2,14 +2,14 @@ const PRIORITY_LEVELS = { file: { 0: 'DONT_DOWNLOAD', 1: 'NORMAL', - 2: 'HIGH' + 2: 'HIGH', }, torrent: { 0: 'DONT_DOWNLOAD', 1: 'LOW', 2: 'NORMAL', - 3: 'HIGH' - } + 3: 'HIGH', + }, }; export default PRIORITY_LEVELS; diff --git a/client/src/javascript/constants/TorrentProperties.js b/client/src/javascript/constants/TorrentProperties.js index 615287c7..9eef6f3b 100644 --- a/client/src/javascript/constants/TorrentProperties.js +++ b/client/src/javascript/constants/TorrentProperties.js @@ -1,88 +1,88 @@ const torrentProperties = { dateAdded: { id: 'torrents.properties.date.added', - defaultMessage: 'Date Added' + defaultMessage: 'Date Added', }, downRate: { id: 'torrents.properties.download.speed', - defaultMessage: 'Download Speed' + defaultMessage: 'Download Speed', }, downTotal: { id: 'torrents.properties.download.total', - defaultMessage: 'Downloaded' + defaultMessage: 'Downloaded', }, eta: { id: 'torrents.properties.eta', - defaultMessage: 'ETA' + defaultMessage: 'ETA', }, name: { id: 'torrents.properties.name', - defaultMessage: 'Name' + defaultMessage: 'Name', }, peers: { id: 'torrents.properties.peers', - defaultMessage: 'Peers' + defaultMessage: 'Peers', }, percentComplete: { id: 'torrents.properties.percentage', - defaultMessage: 'Percent Complete' + defaultMessage: 'Percent Complete', }, ratio: { id: 'torrents.properties.ratio', - defaultMessage: 'Ratio' + defaultMessage: 'Ratio', }, seeds: { id: 'torrents.properties.seeds', - defaultMessage: 'Seeds' + defaultMessage: 'Seeds', }, sizeBytes: { id: 'torrents.properties.size', - defaultMessage: 'File Size' + defaultMessage: 'File Size', }, tags: { id: 'torrents.properties.tags', - defaultMessage: 'Tags' + defaultMessage: 'Tags', }, upRate: { id: 'torrents.properties.upload.speed', - defaultMessage: 'Upload Speed' + defaultMessage: 'Upload Speed', }, upTotal: { id: 'torrents.properties.upload.total', - defaultMessage: 'Uploaded' + defaultMessage: 'Uploaded', }, dateCreated: { id: 'torrents.properties.creation.date', - defaultMessage: 'Creation Date' + defaultMessage: 'Creation Date', }, basePath: { id: 'torrents.properties.base.path', - defaultMessage: 'Base Path' + defaultMessage: 'Base Path', }, ignoreScheduler: { id: 'torrents.properties.ignore.schedule', - defaultMessage: 'Ignore Scheduler' + defaultMessage: 'Ignore Scheduler', }, comment: { id: 'torrents.properties.comment', - defaultMessage: 'Comment' + defaultMessage: 'Comment', }, hash: { id: 'torrents.properties.hash', - defaultMessage: 'Hash' + defaultMessage: 'Hash', }, isPrivate: { id: 'torrents.properties.is.private', - defaultMessage: 'Private' + defaultMessage: 'Private', }, message: { id: 'torrents.properties.tracker.message', - defaultMessage: 'Tracker Message' + defaultMessage: 'Tracker Message', }, trackerURIs: { id: 'torrents.properties.trackers', - defaultMessage: 'Trackers' - } + defaultMessage: 'Trackers', + }, }; export default torrentProperties; diff --git a/client/src/javascript/i18n/de.js b/client/src/javascript/i18n/de.js index 45e3b430..791ac100 100644 --- a/client/src/javascript/i18n/de.js +++ b/client/src/javascript/i18n/de.js @@ -1,3 +1,3 @@ export default { - 'sidebar.button.settings': 'Einstellungen' + 'sidebar.button.settings': 'Einstellungen', }; diff --git a/client/src/javascript/i18n/en.js b/client/src/javascript/i18n/en.js index 0056ae20..5b78851f 100644 --- a/client/src/javascript/i18n/en.js +++ b/client/src/javascript/i18n/en.js @@ -109,7 +109,8 @@ export default { 'locale.language.fr': 'French', 'locale.language.nl': 'Nederlands', - 'mediainfo.execError': 'An error occurred while running mediainfo on the server. Check that mediainfo is installed and available in the PATH to Flood.', + 'mediainfo.execError': + 'An error occurred while running mediainfo on the server. Check that mediainfo is installed and available in the PATH to Flood.', 'mediainfo.fetching': 'Fetching...', 'mediainfo.heading': 'Mediainfo Output', @@ -120,7 +121,7 @@ export default { 'notification.clear.all': 'Clear All', 'notification.showing': 'Showing', - 'priority.dont.download': 'Don\'t Download', + 'priority.dont.download': "Don't Download", 'priority.high': 'High', 'priority.low': 'Low', 'priority.normal': 'Normal', @@ -310,7 +311,7 @@ export default { other {# torrents} }?`, 'torrents.remove.delete.data': 'Delete data', - 'torrents.remove.error.no.torrents.selected': 'You haven\'t selected any torrents.', + 'torrents.remove.error.no.torrents.selected': "You haven't selected any torrents.", 'torrents.remove': 'Remove Torrents', 'torrents.set.tags.button.set': 'Set Tags', @@ -322,5 +323,5 @@ export default { 'connection-interruption.heading': 'Cannot connect to rTorrent', 'connection-interruption.verify-settings-prompt': `Let's verify your connection settings.`, 'connection-interruption.verification-error': `Connection could not be verified.`, - 'connection-interruption.verification-success': `Connection successful` + 'connection-interruption.verification-success': `Connection successful`, }; diff --git a/client/src/javascript/i18n/es.js b/client/src/javascript/i18n/es.js index 3ee864f6..3b584f9c 100644 --- a/client/src/javascript/i18n/es.js +++ b/client/src/javascript/i18n/es.js @@ -103,7 +103,8 @@ export default { 'locale.language.fr': 'Francés', 'locale.language.nl': 'Holandés', - 'mediainfo.execError': 'Se ha encontrado un error al correr Mediainfo. Confirme que Mediainfo este instalado y disponible a Flood en el PATH', + 'mediainfo.execError': + 'Se ha encontrado un error al correr Mediainfo. Confirme que Mediainfo este instalado y disponible a Flood en el PATH', 'mediainfo.fetching': 'Fetching...', 'mediainfo.heading': 'Mediainfo', @@ -169,7 +170,8 @@ export default { 'settings.ui.torrent.size': 'Tamaño de Torrent', 'settings.ui.torrent.size.expanded': 'Modo Expandido', 'settings.ui.torrent.size.condensed': 'Modo Condensado', - 'settings.ui.torrent.details.tags.placement': 'En el modo expandido, las etiquetas se ven mejor al final de la lista.', + 'settings.ui.torrent.details.tags.placement': + 'En el modo expandido, las etiquetas se ven mejor al final de la lista.', 'sidebar.button.feeds': 'Fuentes', 'sidebar.button.notifications': 'Notificaciones', @@ -307,5 +309,5 @@ export default { 'torrents.set.tags.button.set': 'Configurar', 'torrents.set.tags.heading': 'Configurar Etiquetas', - 'torrents.sort.title': 'Ordenar Por' + 'torrents.sort.title': 'Ordenar Por', }; diff --git a/client/src/javascript/i18n/fr.js b/client/src/javascript/i18n/fr.js index 93487af7..26631fc8 100644 --- a/client/src/javascript/i18n/fr.js +++ b/client/src/javascript/i18n/fr.js @@ -2,12 +2,12 @@ export default { 'auth.add.user': 'Ajouter un Utilisateur', 'auth.create.account': 'Créer un Compte', 'auth.create.an.account': 'Créer un Compte', - 'auth.error.username.empty': 'Le nom d\'utilisateur ne peut pas être vide.', + 'auth.error.username.empty': "Le nom d'utilisateur ne peut pas être vide.", 'auth.log.in': 'Connexion', 'auth.login': 'Identifiant', 'auth.password': 'Mot de Passe', 'auth.user.accounts': 'Comptes', - 'auth.username': 'Nom d\'Utilisateur', + 'auth.username': "Nom d'Utilisateur", 'button.add': 'Ajouter', 'button.cancel': 'Annuler', @@ -98,22 +98,22 @@ export default { 'settings.bandwidth.slots.download.global.label': 'Slots de Réception (Global)', 'settings.bandwidth.slots.download.label': 'Slots de Réception par Torrent', 'settings.bandwidth.slots.heading': 'Configuration des Slots', - 'settings.bandwidth.slots.upload.divider.label': 'Diviseur Slots d\'Envoi', - 'settings.bandwidth.slots.upload.global.label': 'Slots d\'Envoi (Global)', - 'settings.bandwidth.slots.upload.label': 'Slots d\'Envoi par Torrent', + 'settings.bandwidth.slots.upload.divider.label': "Diviseur Slots d'Envoi", + 'settings.bandwidth.slots.upload.global.label': "Slots d'Envoi (Global)", + 'settings.bandwidth.slots.upload.label': "Slots d'Envoi par Torrent", 'settings.bandwidth.transferrate.dropdown.preset.download.label': 'Pré-réglages du Menu (Réception) :', 'settings.bandwidth.transferrate.dropdown.preset.upload.label': 'Pré-réglages du Menu (Envoi) :', 'settings.bandwidth.transferrate.global.throttle.download': 'Limitation Globale de Réception', - 'settings.bandwidth.transferrate.global.throttle.upload': 'Limitation Globale d\'Envoi', + 'settings.bandwidth.transferrate.global.throttle.upload': "Limitation Globale d'Envoi", 'settings.bandwidth.transferrate.heading': 'Configuration Taux de Transfert', 'settings.connectivity.dht.label': 'Activer le DHT', 'settings.connectivity.dht.port.label': 'Port DHT', 'settings.connectivity.dpd.heading': 'Découverte de Pairs Décentralisée', 'settings.connectivity.incoming.heading': 'Connexions Entrantes', - 'settings.connectivity.ip.hostname.label': 'Adresse IP/Nom d\'Hôte', + 'settings.connectivity.ip.hostname.label': "Adresse IP/Nom d'Hôte", 'settings.connectivity.max.http.connections': 'Connexions HTTP Maximum', - 'settings.connectivity.peer.exchange.label': 'Activer l\'échange de Pairs', + 'settings.connectivity.peer.exchange.label': "Activer l'échange de Pairs", 'settings.connectivity.peers.desired.label': 'Pairs Désirés', 'settings.connectivity.peers.heading': 'Pairs', 'settings.connectivity.peers.max.label': 'Pairs Maximum (Réception)', @@ -129,7 +129,7 @@ export default { 'settings.resources.disk.heading': 'Disque Dur', 'settings.resources.max.open.files': 'Fichiers Ouverts Maximum', 'settings.resources.memory.heading': 'Mémoire Vive', - 'settings.resources.memory.max.label': 'Limite d\'utilisation Mémoire Vive', + 'settings.resources.memory.max.label': "Limite d'utilisation Mémoire Vive", 'settings.tabs.bandwidth': 'Bande Passante', 'settings.tabs.connectivity': 'Connectivité', @@ -210,14 +210,14 @@ export default { 'torrents.details.general.type.private': 'Privé', 'torrents.details.general.type.public': 'Public', 'torrents.details.general.type': 'Type', - 'torrents.details.peers.no.data': 'Il n\'y a aucun Pair actif pour ce Torrent.', + 'torrents.details.peers.no.data': "Il n'y a aucun Pair actif pour ce Torrent.", 'torrents.details.peers': 'Pairs', 'torrents.details.selected.files': `{count, plural, =1 {{countElement} fichier sélectionné} other {{countElement} fichiers sélectionnés} }`, 'torrents.details.selected.files.set.priority': 'Priorité', - 'torrents.details.trackers.no.data': 'Il n\'y a aucun Traqueur actif pour ce Torrent.', + 'torrents.details.trackers.no.data': "Il n'y a aucun Traqueur actif pour ce Torrent.", 'torrents.details.trackers.type': 'Type', 'torrents.details.trackers': 'Traqueurs', @@ -237,9 +237,9 @@ export default { 'torrents.move.button.set.location': 'Emplacement', 'torrents.move.button.state.setting': 'Réglages...', 'torrents.move.data.label': 'Déplacer les Données', - 'torrents.move.heading': 'Définir l\'Emplacement de Téléchargement', + 'torrents.move.heading': "Définir l'Emplacement de Téléchargement", - 'torrents.properties.date.added': 'Date d\'Ajout', + 'torrents.properties.date.added': "Date d'Ajout", 'torrents.properties.download.speed': 'Vitesse de Téléchargement', 'torrents.properties.download.total': 'Données Reçues', 'torrents.properties.eta': 'ETA', @@ -247,7 +247,7 @@ export default { 'torrents.properties.percentage': 'Pourcentage Complété', 'torrents.properties.ratio': 'Ratio', 'torrents.properties.size': 'Taille des Fichiers', - 'torrents.properties.upload.speed': 'Vitesse d\'Envoi', + 'torrents.properties.upload.speed': "Vitesse d'Envoi", 'torrents.properties.upload.total': 'Données Envoyées', 'torrents.remove.are.you.sure': `Êtes-vous certain(e) de vouloir supprimer {count, plural, @@ -256,11 +256,11 @@ export default { other {# torrents} } ?`, 'torrents.remove.delete.data': 'Supprimer les Données', - 'torrents.remove.error.no.torrents.selected': 'Vous n\'avez sélectionné aucun torrent.', + 'torrents.remove.error.no.torrents.selected': "Vous n'avez sélectionné aucun torrent.", 'torrents.remove': 'Supprimer les Torrents', 'torrents.set.tags.button.set': 'Définir un Tag', 'torrents.set.tags.heading': 'Définir un Tag', - 'torrents.sort.title': 'Trier par' + 'torrents.sort.title': 'Trier par', }; diff --git a/client/src/javascript/i18n/nl.js b/client/src/javascript/i18n/nl.js index 34181800..c9c18817 100644 --- a/client/src/javascript/i18n/nl.js +++ b/client/src/javascript/i18n/nl.js @@ -258,5 +258,5 @@ export default { 'torrents.set.tags.button.set': 'Tags instellen', 'torrents.set.tags.heading': 'Tags instellen', - 'torrents.sort.title': 'Sorteer op' + 'torrents.sort.title': 'Sorteer op', }; diff --git a/client/src/javascript/stores/AlertStore.js b/client/src/javascript/stores/AlertStore.js index 40d38349..b2e1cf18 100644 --- a/client/src/javascript/stores/AlertStore.js +++ b/client/src/javascript/stores/AlertStore.js @@ -44,7 +44,7 @@ class AlertStoreClass extends BaseStore { getAlerts() { let alertIDs = Object.keys(this.alerts).sort(); - return alertIDs.map((id) => { + return alertIDs.map(id => { let alert = this.alerts[id]; if (!!alert.accumulation) { @@ -87,16 +87,14 @@ class AlertStoreClass extends BaseStore { } scheduleCleanse(alert) { - setTimeout(this.removeExpired.bind(this, alert), - alert.duration); + setTimeout(this.removeExpired.bind(this, alert), alert.duration); } } let AlertStore = new AlertStoreClass(); -AlertStore.dispatcherID = AppDispatcher.register((payload) => { +AlertStore.dispatcherID = AppDispatcher.register(payload => { // const {action, source} = payload; - // switch (action.type) { // } }); diff --git a/client/src/javascript/stores/AuthStore.js b/client/src/javascript/stores/AuthStore.js index 47f55569..030edc3d 100644 --- a/client/src/javascript/stores/AuthStore.js +++ b/client/src/javascript/stores/AuthStore.js @@ -68,8 +68,8 @@ class AuthStoreClass extends BaseStore { } handleListUsersSuccess(nextUserList) { - this.optimisticUsers = this.optimisticUsers.filter((optimisticUser) => { - return !nextUserList.some((databaseUser) => { + this.optimisticUsers = this.optimisticUsers.filter(optimisticUser => { + return !nextUserList.some(databaseUser => { return databaseUser.username === optimisticUser.username; }); }); @@ -103,7 +103,7 @@ class AuthStoreClass extends BaseStore { password: credentials.password, host: credentials.host, port: credentials.port, - socketPath: credentials.socketPath + socketPath: credentials.socketPath, }); } @@ -123,7 +123,7 @@ class AuthStoreClass extends BaseStore { let AuthStore = new AuthStoreClass(); -AuthStore.dispatcherID = AppDispatcher.register((payload) => { +AuthStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/ClientStatusStore.js b/client/src/javascript/stores/ClientStatusStore.js index 18aa8e31..0c33f676 100644 --- a/client/src/javascript/stores/ClientStatusStore.js +++ b/client/src/javascript/stores/ClientStatusStore.js @@ -24,8 +24,8 @@ class ClientStatusStoreClass extends BaseStore { const ClientStatusStore = new ClientStatusStoreClass(); -ClientStatusStore.dispatcherID = AppDispatcher.register((payload) => { - const { action } = payload; +ClientStatusStore.dispatcherID = AppDispatcher.register(payload => { + const {action} = payload; switch (action.type) { case ActionTypes.CLIENT_CONNECTIVITY_STATUS_CHANGE: diff --git a/client/src/javascript/stores/FeedMonitorStore.js b/client/src/javascript/stores/FeedMonitorStore.js index 1ab0a86d..fb20e5d9 100644 --- a/client/src/javascript/stores/FeedMonitorStore.js +++ b/client/src/javascript/stores/FeedMonitorStore.js @@ -124,7 +124,7 @@ class FeedsStoreClass extends BaseStore { let FeedsStore = new FeedsStoreClass(); -FeedsStore.dispatcherID = AppDispatcher.register((payload) => { +FeedsStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/NotificationStore.js b/client/src/javascript/stores/NotificationStore.js index 567d2af1..cac260e0 100644 --- a/client/src/javascript/stores/NotificationStore.js +++ b/client/src/javascript/stores/NotificationStore.js @@ -34,7 +34,7 @@ class NotificationStoreClass extends BaseStore { handleNotificationsClearSuccess(options) { this.fetchNotifications({ ...options, - start: 0 + start: 0, }); } @@ -51,7 +51,7 @@ class NotificationStoreClass extends BaseStore { let NotificationStore = new NotificationStoreClass(); -NotificationStore.dispatcherID = AppDispatcher.register((payload) => { +NotificationStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/SettingsStore.js b/client/src/javascript/stores/SettingsStore.js index 5acedb5f..895cba90 100644 --- a/client/src/javascript/stores/SettingsStore.js +++ b/client/src/javascript/stores/SettingsStore.js @@ -13,7 +13,7 @@ class SettingsStoreClass extends BaseStore { this.fetchStatus = { clientSettingsFetched: false, - floodSettingsFetched: false + floodSettingsFetched: false, }; this.clientSettings = {}; @@ -23,7 +23,7 @@ class SettingsStoreClass extends BaseStore { language: 'en', sortTorrents: { direction: 'desc', - property: 'dateAdded' + property: 'dateAdded', }, torrentDetails: [ {id: 'name', visible: true}, @@ -45,15 +45,15 @@ class SettingsStoreClass extends BaseStore { {id: 'isPrivate', visible: false}, {id: 'message', visible: false}, {id: 'trackerURIs', visible: false}, - {id: 'tags', visible: true} + {id: 'tags', visible: true}, ], torrentListColumnWidths: {}, torrentListViewSize: 'condensed', speedLimits: { download: [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0], - upload: [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0] + upload: [1024, 10240, 102400, 512000, 1048576, 2097152, 5242880, 10485760, 0], }, - startTorrentsOnLoad: false + startTorrentsOnLoad: false, }; } @@ -101,7 +101,7 @@ class SettingsStoreClass extends BaseStore { if (options.alert) { AlertStore.add({ - id: 'alert.settings.saved' + id: 'alert.settings.saved', }); } @@ -117,7 +117,7 @@ class SettingsStoreClass extends BaseStore { handleSettingsFetchSuccess(settings) { this.fetchStatus.floodSettingsFetched = true; - Object.keys(settings).forEach((property) => { + Object.keys(settings).forEach(property => { const incomingSettingsValue = settings[property]; if (incomingSettingsValue != null) { @@ -138,7 +138,7 @@ class SettingsStoreClass extends BaseStore { if (options.alert) { AlertStore.add({ - id: 'alert.settings.saved' + id: 'alert.settings.saved', }); } @@ -148,8 +148,7 @@ class SettingsStoreClass extends BaseStore { } processSettingsState() { - if (this.fetchStatus.clientSettingsFetched - && this.fetchStatus.floodSettingsFetched) { + if (this.fetchStatus.clientSettingsFetched && this.fetchStatus.floodSettingsFetched) { this.emit(EventTypes.SETTINGS_CHANGE); } } @@ -183,7 +182,7 @@ class SettingsStoreClass extends BaseStore { } updateLocalSettings(settings, settingsType) { - settings.forEach((setting) => { + settings.forEach(setting => { if (setting.overrideLocalSetting) { this[settingsType][setting.overrideID] = setting.overrideData; } else { @@ -195,7 +194,7 @@ class SettingsStoreClass extends BaseStore { let SettingsStore = new SettingsStoreClass(); -SettingsStore.dispatcherID = AppDispatcher.register((payload) => { +SettingsStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/TorrentFilterStore.js b/client/src/javascript/stores/TorrentFilterStore.js index 59437dc5..aa8905fd 100644 --- a/client/src/javascript/stores/TorrentFilterStore.js +++ b/client/src/javascript/stores/TorrentFilterStore.js @@ -87,7 +87,7 @@ class TorrentFilterStoreClass extends BaseStore { } else { this.taxonomy[taxonomyKey] = { ...this.taxonomy[taxonomyKey], - ...change.data + ...change.data, }; } }); @@ -95,10 +95,7 @@ class TorrentFilterStoreClass extends BaseStore { // TODO: This logic is duplicated. Also update it to check for changed // trackers. - if ( - this.tagFilter !== 'all' - && !Object.keys(this.taxonomy.tagCounts).includes(this.tagFilter) - ) { + if (this.tagFilter !== 'all' && !Object.keys(this.taxonomy.tagCounts).includes(this.tagFilter)) { this.setTagFilter('all'); } @@ -110,10 +107,7 @@ class TorrentFilterStoreClass extends BaseStore { // TODO: This logic is duplicated. Also update it to check for changed // trackers. - if ( - this.tagFilter !== 'all' - && !Object.keys(taxonomy.tags).includes(this.tagFilter) - ) { + if (this.tagFilter !== 'all' && !Object.keys(taxonomy.tags).includes(this.tagFilter)) { this.setTagFilter('all'); } @@ -121,8 +115,12 @@ class TorrentFilterStoreClass extends BaseStore { } isFilterActive() { - return this.getStatusFilter() !== 'all' || this.getSearchFilter() !== '' - || this.getTagFilter() !== 'all' || this.getTrackerFilter() !== 'all'; + return ( + this.getStatusFilter() !== 'all' || + this.getSearchFilter() !== '' || + this.getTagFilter() !== 'all' || + this.getTrackerFilter() !== 'all' + ); } setSearchFilter(filter) { @@ -163,7 +161,7 @@ class TorrentFilterStoreClass extends BaseStore { let TorrentFilterStore = new TorrentFilterStoreClass(); -TorrentFilterStore.dispatcherID = AppDispatcher.register((payload) => { +TorrentFilterStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/TorrentStore.js b/client/src/javascript/stores/TorrentStore.js index 6df8201b..f148ac76 100644 --- a/client/src/javascript/stores/TorrentStore.js +++ b/client/src/javascript/stores/TorrentStore.js @@ -35,8 +35,7 @@ class TorrentStoreClass extends BaseStore { } fetchTorrentDetails(options = {}) { - if (!this.isRequestPending('fetch-torrent-details') - || options.forceUpdate) { + if (!this.isRequestPending('fetch-torrent-details') || options.forceUpdate) { this.beginRequest('fetch-torrent-details'); TorrentActions.fetchTorrentDetails(UIStore.getTorrentDetailsHash()); } @@ -61,21 +60,21 @@ class TorrentStoreClass extends BaseStore { if (statusFilter && statusFilter !== 'all') { filteredTorrents = filterTorrents(filteredTorrents, { type: 'status', - filter: statusFilter + filter: statusFilter, }); } if (tagFilter && tagFilter !== 'all') { filteredTorrents = filterTorrents(filteredTorrents, { type: 'tag', - filter: tagFilter + filter: tagFilter, }); } if (trackerFilter && trackerFilter !== 'all') { filteredTorrents = filterTorrents(filteredTorrents, { type: 'tracker', - filter: trackerFilter + filter: trackerFilter, }); } @@ -91,19 +90,19 @@ class TorrentStoreClass extends BaseStore { } getSelectedTorrentsDownloadLocations() { - return this.selectedTorrents.map((hash) => { + return this.selectedTorrents.map(hash => { return this.torrents[hash].basePath; }); } getSelectedTorrentsFilename() { - return this.selectedTorrents.map((hash) => { + return this.selectedTorrents.map(hash => { return this.torrents[hash].baseFilename; }); } getSelectedTorrentsTags() { - return this.selectedTorrents.map((hash) => { + return this.selectedTorrents.map(hash => { return this.torrents[hash].tags; }); } @@ -117,15 +116,15 @@ class TorrentStoreClass extends BaseStore { SettingsStore.saveFloodSettings({ id: 'torrentDestination', - data: response.destination + data: response.destination, }); AlertStore.add({ accumulation: { id: 'alert.torrent.add', - value: response.count || 1 + value: response.count || 1, }, - id: 'alert.torrent.add' + id: 'alert.torrent.add', }); } @@ -165,7 +164,7 @@ class TorrentStoreClass extends BaseStore { AlertStore.add({ accumulation: { id: 'alert.torrent.move', - value: response.count + value: response.count, }, id: 'alert.torrent.move', }); @@ -177,9 +176,9 @@ class TorrentStoreClass extends BaseStore { AlertStore.add({ accumulation: { id: 'alert.torrent.move.failed', - value: error.count + value: error.count, }, - id: 'alert.torrent.move.failed' + id: 'alert.torrent.move.failed', }); } @@ -188,7 +187,7 @@ class TorrentStoreClass extends BaseStore { event, hash, selectedTorrents: this.selectedTorrents, - torrentList: this.filteredTorrents + torrentList: this.filteredTorrents, }); this.emit(EventTypes.UI_TORRENT_SELECTION_CHANGE); } @@ -196,15 +195,15 @@ class TorrentStoreClass extends BaseStore { handleRemoveTorrentsSuccess(response) { SettingsStore.saveFloodSettings({ id: 'deleteTorrentData', - data: response.deleteData + data: response.deleteData, }); AlertStore.add({ accumulation: { id: 'alert.torrent.remove', - value: response.count + value: response.count, }, - id: 'alert.torrent.remove' + id: 'alert.torrent.remove', }); } @@ -212,9 +211,9 @@ class TorrentStoreClass extends BaseStore { AlertStore.add({ accumulation: { id: 'alert.torrent.remove.failed', - value: error.count + value: error.count, }, - id: 'alert.torrent.remove.failed' + id: 'alert.torrent.remove.failed', }); } @@ -233,9 +232,7 @@ class TorrentStoreClass extends BaseStore { break; case serverEventTypes.TORRENT_LIST_ACTION_TORRENT_DELETED: if (this.selectedTorrents.includes(torrentHash)) { - this.selectedTorrents = this.selectedTorrents.filter( - hash => hash !== torrentHash - ); + this.selectedTorrents = this.selectedTorrents.filter(hash => hash !== torrentHash); } delete this.torrents[torrentHash]; @@ -283,10 +280,7 @@ class TorrentStoreClass extends BaseStore { } startPollingTorrentDetails() { - this.pollTorrentDetailsIntervalID = setInterval( - this.fetchTorrentDetails.bind(this), - pollInterval - ); + this.pollTorrentDetailsIntervalID = setInterval(this.fetchTorrentDetails.bind(this), pollInterval); } stopPollingTorrentDetails() { @@ -307,7 +301,7 @@ class TorrentStoreClass extends BaseStore { const TorrentStore = new TorrentStoreClass(); -TorrentStore.dispatcherID = AppDispatcher.register((payload) => { +TorrentStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/TransferDataStore.js b/client/src/javascript/stores/TransferDataStore.js index 6b556047..f84236cd 100644 --- a/client/src/javascript/stores/TransferDataStore.js +++ b/client/src/javascript/stores/TransferDataStore.js @@ -18,12 +18,8 @@ class TransferDataStoreClass extends BaseStore { // just replaces the last transfer rate values from the history service with // the most recent speed. if (this.transferRates.download.length > 0) { - this.transferRates.download[this.transferRates.download.length - 1] = ( - this.transferSummary.downRate - ); - this.transferRates.upload[this.transferRates.upload.length - 1] = ( - this.transferSummary.upRate - ); + this.transferRates.download[this.transferRates.download.length - 1] = this.transferSummary.downRate; + this.transferRates.upload[this.transferRates.upload.length - 1] = this.transferSummary.upRate; } this.emit(EventTypes.CLIENT_TRANSFER_HISTORY_REQUEST_SUCCESS); @@ -61,7 +57,7 @@ class TransferDataStoreClass extends BaseStore { } else { this.transferSummary = { ...this.transferSummary, - ...change.data + ...change.data, }; } }); @@ -80,7 +76,7 @@ class TransferDataStoreClass extends BaseStore { let TransferDataStore = new TransferDataStoreClass(); -TransferDataStore.dispatcherID = AppDispatcher.register((payload) => { +TransferDataStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/stores/UIStore.js b/client/src/javascript/stores/UIStore.js index a06773da..4612f728 100644 --- a/client/src/javascript/stores/UIStore.js +++ b/client/src/javascript/stores/UIStore.js @@ -19,11 +19,7 @@ class UIStoreClass extends BaseStore { this.torrentDetailsHash = null; this.createStyleElement(); - this.fetchDirectoryList = _.debounce( - this.fetchDirectoryList, - 100, - {leading: true} - ); + this.fetchDirectoryList = _.debounce(this.fetchDirectoryList, 100, {leading: true}); } addGlobalStyle(cssString) { @@ -42,9 +38,7 @@ class UIStoreClass extends BaseStore { if (styleElement.styleSheet) { styleElement.styleSheet.cssText = nextStyleString; } else { - styleElement.appendChild( - global.document.createTextNode(nextStyleString) - ); + styleElement.appendChild(global.document.createTextNode(nextStyleString)); } } @@ -123,9 +117,7 @@ class UIStoreClass extends BaseStore { } removeGlobalStyle(cssString) { - this.globalStyles = this.globalStyles.filter( - style => style !== cssString - ); + this.globalStyles = this.globalStyles.filter(style => style !== cssString); this.applyStyles(); } @@ -135,7 +127,7 @@ class UIStoreClass extends BaseStore { dependencies = [dependencies]; } - dependencies.forEach((dependency) => { + dependencies.forEach(dependency => { let {id} = dependency; if (!this.dependencies[id]) { @@ -147,8 +139,7 @@ class UIStoreClass extends BaseStore { } satisfyDependency(dependencyID) { - if (this.dependencies[dependencyID] - && !this.dependencies[dependencyID].satisfied) { + if (this.dependencies[dependencyID] && !this.dependencies[dependencyID].satisfied) { this.dependencies[dependencyID].satisfied = true; this.emit(EventTypes.UI_DEPENDENCIES_CHANGE); this.verifyDependencies(); @@ -175,7 +166,7 @@ class UIStoreClass extends BaseStore { } verifyDependencies() { - let isDependencyLoading = Object.keys(this.dependencies).some((id) => { + let isDependencyLoading = Object.keys(this.dependencies).some(id => { return this.dependencies[id].satisfied === false; }); @@ -187,7 +178,7 @@ class UIStoreClass extends BaseStore { let UIStore = new UIStoreClass(); -UIStore.dispatcherID = AppDispatcher.register((payload) => { +UIStore.dispatcherID = AppDispatcher.register(payload => { const {action} = payload; switch (action.type) { diff --git a/client/src/javascript/util/filterTorrents.js b/client/src/javascript/util/filterTorrents.js index ff4e1890..12fb53f9 100644 --- a/client/src/javascript/util/filterTorrents.js +++ b/client/src/javascript/util/filterTorrents.js @@ -6,15 +6,15 @@ export function filterTorrents(torrentList, opts) { if (filter !== 'all') { if (type === 'status') { let statusFilter = torrentStatusMap[filter]; - return torrentList.filter((torrent) => { + return torrentList.filter(torrent => { return torrent.status.includes(statusFilter); }); } else if (type === 'tracker') { - return torrentList.filter((torrent) => { + return torrentList.filter(torrent => { return torrent.trackerURIs.includes(filter); }); } else if (type === 'tag') { - return torrentList.filter((torrent) => { + return torrentList.filter(torrent => { if (filter === 'untagged') { return torrent.tags.length === 0; } diff --git a/client/src/javascript/util/searchTorrents.js b/client/src/javascript/util/searchTorrents.js index 7a3787bc..e689ce2f 100644 --- a/client/src/javascript/util/searchTorrents.js +++ b/client/src/javascript/util/searchTorrents.js @@ -7,7 +7,7 @@ export function searchTorrents(torrents, searchString) { queries.push(new RegExp(searchTerms[i], 'gi')); } - torrents = torrents.filter((torrent) => { + torrents = torrents.filter(torrent => { for (let i = 0, len = queries.length; i < len; i++) { if (!torrent.name.match(queries[i])) { return false; diff --git a/client/src/javascript/util/selectTorrents.js b/client/src/javascript/util/selectTorrents.js index c7c652ad..7eafb749 100644 --- a/client/src/javascript/util/selectTorrents.js +++ b/client/src/javascript/util/selectTorrents.js @@ -1,9 +1,7 @@ export function selectTorrents(options) { if (options.event.shiftKey) { if (options.selectedTorrents.length) { - let lastHash = options.selectedTorrents[ - options.selectedTorrents.length - 1 - ]; + let lastHash = options.selectedTorrents[options.selectedTorrents.length - 1]; let currentHashIndex; let lastHashIndex; @@ -50,7 +48,6 @@ export function selectTorrents(options) { } else { options.selectedTorrents = [options.hash]; } - } else if (options.event.metaKey || options.event.ctrlKey) { let hashPosition = options.selectedTorrents.indexOf(options.hash); if (hashPosition === -1) { diff --git a/client/src/javascript/util/size.js b/client/src/javascript/util/size.js index 9a7a1c43..5a5f2265 100644 --- a/client/src/javascript/util/size.js +++ b/client/src/javascript/util/size.js @@ -1,4 +1,4 @@ -export function compute(bytes, precision=2) { +export function compute(bytes, precision = 2) { const kilobyte = 1024, megabyte = kilobyte * 1024, gigabyte = megabyte * 1024, @@ -7,16 +7,16 @@ export function compute(bytes, precision=2) { unit = ''; if (bytes >= terabyte) { - value = (bytes / terabyte); + value = bytes / terabyte; unit = 'TB'; } else if (bytes >= gigabyte) { - value = (bytes / gigabyte); + value = bytes / gigabyte; unit = 'GB'; } else if (bytes >= megabyte) { - value = (bytes / megabyte); + value = bytes / megabyte; unit = 'MB'; } else if (bytes >= kilobyte) { - value = (bytes / kilobyte); + value = bytes / kilobyte; unit = 'kB'; } else { value = bytes; @@ -34,9 +34,9 @@ export function compute(bytes, precision=2) { return { value, - unit + unit, }; -}; +} export function getTranslationString(unit) { const UNIT_TO_STRING_ID = { @@ -48,4 +48,4 @@ export function getTranslationString(unit) { }; return UNIT_TO_STRING_ID[unit] || 'unit.size.byte'; -}; +} diff --git a/client/src/javascript/util/sortTorrents.js b/client/src/javascript/util/sortTorrents.js index ae4bbb76..55a2b156 100644 --- a/client/src/javascript/util/sortTorrents.js +++ b/client/src/javascript/util/sortTorrents.js @@ -3,7 +3,7 @@ const stringProps = ['basePath', 'comment', 'hash', 'message', 'name']; export function sortTorrents(torrentsHash, sortBy) { - let torrents = Object.keys(torrentsHash).map((hash) => { + let torrents = Object.keys(torrentsHash).map(hash => { return {hash, ...torrentsHash[hash]}; }); diff --git a/client/src/javascript/util/torrentStatusClasses.js b/client/src/javascript/util/torrentStatusClasses.js index c50f5db3..002402ed 100644 --- a/client/src/javascript/util/torrentStatusClasses.js +++ b/client/src/javascript/util/torrentStatusClasses.js @@ -11,6 +11,6 @@ export function torrentStatusClasses(torrent, ...classes) { 'torrent--is-seeding': torrent.status.includes(torrentStatusMap.seeding), 'torrent--is-completed': torrent.status.includes(torrentStatusMap.complete), 'torrent--is-checking': torrent.status.includes(torrentStatusMap.checking), - 'torrent--is-inactive': torrent.status.includes(torrentStatusMap.inactive) + 'torrent--is-inactive': torrent.status.includes(torrentStatusMap.inactive), }); } diff --git a/client/src/javascript/util/torrentStatusIcons.js b/client/src/javascript/util/torrentStatusIcons.js index b5ef7b1b..58a35c01 100644 --- a/client/src/javascript/util/torrentStatusIcons.js +++ b/client/src/javascript/util/torrentStatusIcons.js @@ -10,7 +10,7 @@ const STATUS_ICON_MAP = { error: , hashChecking: , stopped: , - running: + running: , }; export function torrentStatusIcons(status) { @@ -19,14 +19,13 @@ export function torrentStatusIcons(status) { hashChecking: [status.includes(torrentStatusMap.checking)], error: [status.includes(torrentStatusMap.error)], stopped: [status.includes(torrentStatusMap.stopped)], - running: [status.includes(torrentStatusMap.downloading), - status.includes(torrentStatusMap.seeding)] + running: [status.includes(torrentStatusMap.downloading), status.includes(torrentStatusMap.seeding)], }; - Object.keys(statusConditions).some((status) => { + Object.keys(statusConditions).some(status => { let conditions = statusConditions[status]; - conditions.some((condition) => { + conditions.some(condition => { if (condition) { statusString = status; } diff --git a/package-lock.json b/package-lock.json index 8248f5e2..3f4b6ae2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -4783,7 +4783,7 @@ "integrity": "sha1-jnVIqW08wjJ+5eZ0FocjozO7oqA=", "dev": true, "requires": { - "glob": "7.0.6", + "glob": "7.1.3", "minimatch": "3.0.4" } }, @@ -5521,6 +5521,19 @@ "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", "integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=" }, + "glob": { + "version": "7.0.6", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", + "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "requires": { + "fs.realpath": "1.0.0", + "inflight": "1.0.6", + "inherits": "2.0.3", + "minimatch": "3.0.4", + "once": "1.4.0", + "path-is-absolute": "1.0.1" + } + }, "rimraf": { "version": "2.5.4", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.5.4.tgz", @@ -5567,9 +5580,9 @@ } }, "glob": { - "version": "7.0.6", - "resolved": "https://registry.npmjs.org/glob/-/glob-7.0.6.tgz", - "integrity": "sha1-IRuvr0nlJbjNkyYNFKsTYVKz9Xo=", + "version": "7.1.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.3.tgz", + "integrity": "sha512-vcfuiIxogLV4DlGBHIUOwI0IbrJ8HWPc4MU7HzviGeNho/UJDfi6B5p3sHeWIQ0KGIU0Jpxi5ZHxemQfLkkAwQ==", "requires": { "fs.realpath": "1.0.0", "inflight": "1.0.6", @@ -5678,7 +5691,7 @@ "requires": { "array-union": "1.0.2", "arrify": "1.0.1", - "glob": "7.0.6", + "glob": "7.1.3", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" @@ -9116,7 +9129,7 @@ "integrity": "sha512-3g8lYefrRRzvGeSowdJKAKyks8oUpLEd/DyPV4eMhVlhJ0aNaZqIrNUIPuEWWTAoPqyFkfGrM67MC69baqn6vA==", "requires": { "fstream": "1.0.11", - "glob": "7.0.6", + "glob": "7.1.3", "graceful-fs": "4.1.11", "mkdirp": "0.5.1", "nopt": "3.0.6", @@ -9244,7 +9257,7 @@ "cross-spawn": "3.0.1", "gaze": "1.1.3", "get-stdin": "4.0.1", - "glob": "7.0.6", + "glob": "7.1.3", "in-publish": "2.0.0", "lodash.assign": "4.2.0", "lodash.clonedeep": "4.5.0", @@ -11696,6 +11709,12 @@ "integrity": "sha1-gV7R9uvGWSb4ZbMQwHE7yzMVzks=", "dev": true }, + "prettier": { + "version": "1.14.2", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-1.14.2.tgz", + "integrity": "sha512-McHPg0n1pIke+A/4VcaS2en+pTNjy4xF+Uuq86u/5dyDO59/TtFZtQ708QIRkEZ3qwKz3GVkVa6mpxK/CpB8Rg==", + "dev": true + }, "pretty-error": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/pretty-error/-/pretty-error-2.1.1.tgz", @@ -12896,7 +12915,7 @@ "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.2.tgz", "integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==", "requires": { - "glob": "7.0.6" + "glob": "7.1.3" } }, "ripemd160": { @@ -12983,7 +13002,7 @@ "resolved": "https://registry.npmjs.org/sass-graph/-/sass-graph-2.2.4.tgz", "integrity": "sha1-E/vWPNHK8JCLn9k0dq1DpR0eC0k=", "requires": { - "glob": "7.0.6", + "glob": "7.1.3", "lodash": "4.17.10", "scss-tokenizer": "0.2.3", "yargs": "7.1.0" @@ -15219,7 +15238,7 @@ "dev": true, "requires": { "array-union": "1.0.2", - "glob": "7.0.6", + "glob": "7.1.3", "object-assign": "4.1.1", "pify": "2.3.0", "pinkie-promise": "2.0.1" diff --git a/package.json b/package.json index ea6231b5..b036e362 100644 --- a/package.json +++ b/package.json @@ -7,6 +7,8 @@ "build-assets": "UPDATED_SCRIPT=build npm run deprecated-warning && npm run build", "build-docs": "./node_modules/.bin/jsdoc -c ./.jsdoc.json", "deprecated-warning": "node client/scripts/deprecated-warning.js && sleep 10", + "format-source": "node scripts/prettier.js format", + "check-source-formatting": "node scripts/prettier.js check", "lint": "eslint .", "start": "node server/bin/start.js", "start:development": "UPDATED_SCRIPT=start:development:server npm run deprecated-warning && npm run start:development:server", @@ -102,6 +104,7 @@ }, "devDependencies": { "babel-jest": "22.4.3", + "eslint": "4.19.1", "eslint-config-airbnb": "^15.1.0", "eslint-config-react-app": "^2.1.0", "eslint-loader": "2.0.0", @@ -109,11 +112,12 @@ "eslint-plugin-import": "^2.9.0", "eslint-plugin-jsx-a11y": "^5.1.1", "eslint-plugin-react": "7.7.0", - "eslint": "4.19.1", + "glob": "^7.1.3", "jest": "22.4.3", "jsdoc": "~3.5.5", "minami": "^1.2.3", "nodemon": "^1.17.2", + "prettier": "1.14.2", "source-map-loader": "^0.2.3", "webpack-dev-server": "^2.11.2", "webpack-manifest-plugin": "^2.0.0-rc.2" diff --git a/scripts/prettier.js b/scripts/prettier.js new file mode 100644 index 00000000..73928f18 --- /dev/null +++ b/scripts/prettier.js @@ -0,0 +1,87 @@ +const chalk = require('chalk'); +const fs = require('fs'); +const glob = require('glob'); +const path = require('path'); +const prettier = require('prettier'); + +const filePattern = `{client,scripts,server,shared}${path.sep}!(assets){${path.sep},}{**${path.sep}*,*}.{js,json,md}`; + +const iterateOverFiles = ({onFileRead}) => { + return new Promise((resolve, reject) => { + glob(filePattern, (error, files) => { + if (error) { + reject(Error(error)); + } + + resolve( + Promise.all( + files.map(file => { + const filePath = path.join(process.cwd(), file); + const fileContents = fs.readFileSync(filePath, 'utf8'); + return onFileRead(filePath, fileContents); + }) + ) + ); + }); + }); +}; + +const format = () => { + console.log(chalk.reset('Formatting files...')); + + iterateOverFiles({ + onFileRead: (filePath, fileContents) => { + return prettier.resolveConfig(filePath).then(options => { + return new Promise((resolve, reject) => { + fs.writeFile(filePath, prettier.format(fileContents, {...options, filepath: filePath}), error => { + if (error) { + reject(error); + return; + } + + resolve(); + }); + }); + }); + }, + }) + .then(() => { + console.log(chalk.green('Done formatting files.')); + }) + .catch(error => { + console.log(chalk.red('Error formatting files:\n'), chalk.reset(error)); + process.exit(1); + }); +}; + +const check = () => { + console.log(chalk.reset('Checking code formatting...')); + + iterateOverFiles({ + onFileRead: (filePath, fileContents) => { + return prettier.resolveConfig(filePath).then(options => { + const isCompliant = prettier.check(fileContents, {...options, filepath: filePath}); + + if (!isCompliant) { + throw filePath; + } + }); + }, + }) + .then(() => { + console.log(chalk.green('Done checking files.')); + }) + .catch(error => { + console.log(chalk.red('Unformatted file found:\n'), chalk.reset(error)); + process.exit(1); + }); +}; + +const commands = {check, format}; +const desiredCommand = process.argv.slice(2)[0]; + +if (commands[desiredCommand] == null) { + throw new Error(`No command ${desiredCommand}.`); +} else { + commands[desiredCommand](); +} diff --git a/server/app.js b/server/app.js index d197b96d..89f74bfc 100644 --- a/server/app.js +++ b/server/app.js @@ -18,7 +18,7 @@ const Users = require('./models/Users'); Users.bootstrapServicesForAllUsers(); // Remove Express header -if(process.env.NODE_ENV !== 'development') { +if (process.env.NODE_ENV !== 'development') { app.disable('x-powered-by'); } @@ -56,7 +56,7 @@ if (app.get('env') === 'development') { res.render('error', { message: err.message, error: err, - title: 'Flood Error' + title: 'Flood Error', }); }); } else { @@ -66,7 +66,7 @@ if (app.get('env') === 'development') { res.render('error', { message: err.message, error: {}, - title: 'Flood Error' + title: 'Flood Error', }); }); } diff --git a/server/bin/enforce-prerequisites.js b/server/bin/enforce-prerequisites.js index b1e488b8..7babed7f 100644 --- a/server/bin/enforce-prerequisites.js +++ b/server/bin/enforce-prerequisites.js @@ -3,13 +3,9 @@ const checkRequiredFiles = require('react-dev-utils/checkRequiredFiles'); const fs = require('fs'); const path = require('path'); -const staticAssets = [ - path.join(__dirname, '../assets/index.html') -]; +const staticAssets = [path.join(__dirname, '../assets/index.html')]; -const configFiles = [ - path.join(__dirname, '../../config.js') -]; +const configFiles = [path.join(__dirname, '../../config.js')]; // Taken from react-scripts/check-required-files, but without console.logs. const doFilesExist = files => { @@ -33,7 +29,9 @@ const enforcePrerequisites = () => { } if (!doFilesExist(staticAssets)) { - reject(`Static assets (index.html) are missing. Please check the 'Compiling assets and starting the server' section of README.md.`); + reject( + `Static assets (index.html) are missing. Please check the 'Compiling assets and starting the server' section of README.md.` + ); return; } @@ -41,4 +39,4 @@ const enforcePrerequisites = () => { }); }; -module.exports = enforcePrerequisites; \ No newline at end of file +module.exports = enforcePrerequisites; diff --git a/server/bin/migrations/per-user-rtorrent-instances.js b/server/bin/migrations/per-user-rtorrent-instances.js index aef925f4..1c1cea4d 100644 --- a/server/bin/migrations/per-user-rtorrent-instances.js +++ b/server/bin/migrations/per-user-rtorrent-instances.js @@ -6,7 +6,7 @@ const log = data => { if (process.env.DEBUG) { console.log(data); } -} +}; const migrate = () => { log(chalk.green('Migrating data: moving rTorrent connection information to users database')); @@ -14,7 +14,7 @@ const migrate = () => { return new Promise((resolve, reject) => { Users.listUsers((users, error) => { if (error) return reject(error); - const { scgi = {} } = config; + const {scgi = {}} = config; const existingConfig = { host: scgi.host, port: scgi.port, @@ -23,33 +23,34 @@ const migrate = () => { resolve( Promise.all( - users.map(user => new Promise( - (resolve, reject) => { - if (user.socket == null) { - log(chalk.yellow(`Migrating user ${user.username}`)); - const userPatch = { - host: existingConfig.host, - port: existingConfig.port, - socket: existingConfig.socket, - }; + users.map( + user => + new Promise((resolve, reject) => { + if (user.socket == null) { + log(chalk.yellow(`Migrating user ${user.username}`)); + const userPatch = { + host: existingConfig.host, + port: existingConfig.port, + socket: existingConfig.socket, + }; - if (userPatch.socket && existingConfig.socketPath) { - userPatch.socketPath = existingConfig.socketPath; + if (userPatch.socket && existingConfig.socketPath) { + userPatch.socketPath = existingConfig.socketPath; + } + + Users.updateUser(user.username, userPatch, (response, error) => { + if (error) reject(error); + resolve(response); + }); } - Users.updateUser(user.username, userPatch, (response, error) => { - if (error) reject(error); - resolve(response); - }); - } - - resolve(user); - } - )) + resolve(user); + }) + ) ) ); }); }); }; -module.exports = migrate; \ No newline at end of file +module.exports = migrate; diff --git a/server/bin/migrations/run.js b/server/bin/migrations/run.js index 4e87170d..1312e222 100644 --- a/server/bin/migrations/run.js +++ b/server/bin/migrations/run.js @@ -1,8 +1,6 @@ const perUserRtorrentInstances = require('./per-user-rtorrent-instances'); -const migrations = [ - perUserRtorrentInstances -]; +const migrations = [perUserRtorrentInstances]; const migrate = () => Promise.all(migrations.map(migration => migration())); diff --git a/server/bin/start.js b/server/bin/start.js index 97e1194b..4eb6ccb2 100644 --- a/server/bin/start.js +++ b/server/bin/start.js @@ -8,9 +8,8 @@ const {startWebServer} = require('./web-server'); enforcePrerequisites() .then(migrateData) .then(startWebServer) - .catch((error) => { + .catch(error => { console.log(chalk.red('Failed to start Flood:')); console.trace(error); process.exit(1); }); - \ No newline at end of file diff --git a/server/bin/web-server.js b/server/bin/web-server.js index e006ea9e..aedfb246 100755 --- a/server/bin/web-server.js +++ b/server/bin/web-server.js @@ -19,16 +19,18 @@ const startWebServer = () => { let server; if (useSSL) { - if (!config.sslKey || !config.sslCert){ - console.error('Cannot start HTTPS server, `sslKey` or `sslCert`' + - ' is missing in config.js.'); + if (!config.sslKey || !config.sslCert) { + console.error('Cannot start HTTPS server, `sslKey` or `sslCert`' + ' is missing in config.js.'); process.exit(1); } - server = require('spdy').createServer({ - key: fs.readFileSync(config.sslKey), - cert: fs.readFileSync(config.sslCert) - }, app); + server = require('spdy').createServer( + { + key: fs.readFileSync(config.sslKey), + cert: fs.readFileSync(config.sslCert), + }, + app + ); } else { server = require('http').createServer(app); } @@ -89,4 +91,4 @@ const startWebServer = () => { console.log(chalk.green(`Flood server starting on ${address}.\n`)); }; -module.exports = {startWebServer}; \ No newline at end of file +module.exports = {startWebServer}; diff --git a/server/config/passport.js b/server/config/passport.js index f423a256..479b7751 100644 --- a/server/config/passport.js +++ b/server/config/passport.js @@ -4,9 +4,9 @@ const config = require('../../config'); const Users = require('../models/Users'); // Setup work and export for the JWT passport strategy. -module.exports = (passport) => { +module.exports = passport => { let options = { - jwtFromRequest: (req) => { + jwtFromRequest: req => { let token = null; if (req && req.cookies) { @@ -15,20 +15,22 @@ module.exports = (passport) => { return token; }, - secretOrKey: config.secret + secretOrKey: config.secret, }; - passport.use(new jwtStrategy(options, (jwtPayload, callback) => { - Users.lookupUser({username: jwtPayload.username}, (err, user) => { - if (err) { - return callback(err, false); - } + passport.use( + new jwtStrategy(options, (jwtPayload, callback) => { + Users.lookupUser({username: jwtPayload.username}, (err, user) => { + if (err) { + return callback(err, false); + } - if (user) { - return callback(null, user); - } + if (user) { + return callback(null, user); + } - return callback(null, false); - }); - })); + return callback(null, false); + }); + }) + ); }; diff --git a/server/constants/clientGatewayServiceEvents.js b/server/constants/clientGatewayServiceEvents.js index 125599da..e76b0126 100644 --- a/server/constants/clientGatewayServiceEvents.js +++ b/server/constants/clientGatewayServiceEvents.js @@ -6,9 +6,7 @@ const clientGatewayServiceEvents = [ 'PROCESS_TORRENT_LIST_END', 'PROCESS_TORRENT_LIST_START', 'PROCESS_TRANSFER_RATE_START', - 'TORRENTS_REMOVED' + 'TORRENTS_REMOVED', ]; -module.exports = objectUtil.createSymbolMapFromArray( - clientGatewayServiceEvents -); +module.exports = objectUtil.createSymbolMapFromArray(clientGatewayServiceEvents); diff --git a/server/constants/fileListPropMap.js b/server/constants/fileListPropMap.js index b93ee659..04075bec 100644 --- a/server/constants/fileListPropMap.js +++ b/server/constants/fileListPropMap.js @@ -2,52 +2,34 @@ const fileListPropMap = new Map(); const defaultTransformer = value => value; -fileListPropMap.set( - 'path', - { - methodCall: 'f.path=', - transformValue: defaultTransformer - } -); +fileListPropMap.set('path', { + methodCall: 'f.path=', + transformValue: defaultTransformer, +}); -fileListPropMap.set( - 'pathComponents', - { - methodCall: 'f.path_components=', - transformValue: defaultTransformer - } -); +fileListPropMap.set('pathComponents', { + methodCall: 'f.path_components=', + transformValue: defaultTransformer, +}); -fileListPropMap.set( - 'priority', - { - methodCall: 'f.priority=', - transformValue: defaultTransformer - } -); +fileListPropMap.set('priority', { + methodCall: 'f.priority=', + transformValue: defaultTransformer, +}); -fileListPropMap.set( - 'sizeBytes', - { - methodCall: 'f.size_bytes=', - transformValue: Number - } -); +fileListPropMap.set('sizeBytes', { + methodCall: 'f.size_bytes=', + transformValue: Number, +}); -fileListPropMap.set( - 'sizeChunks', - { - methodCall: 'f.size_chunks=', - transformValue: Number - } -); +fileListPropMap.set('sizeChunks', { + methodCall: 'f.size_chunks=', + transformValue: Number, +}); -fileListPropMap.set( - 'completedChunks', - { - methodCall: 'f.completed_chunks=', - transformValue: Number - } -); +fileListPropMap.set('completedChunks', { + methodCall: 'f.completed_chunks=', + transformValue: Number, +}); module.exports = fileListPropMap; diff --git a/server/constants/historyServiceEvents.js b/server/constants/historyServiceEvents.js index cc28b8eb..9d96fdfe 100644 --- a/server/constants/historyServiceEvents.js +++ b/server/constants/historyServiceEvents.js @@ -6,20 +6,14 @@ const objectUtil = require('../../shared/util/objectUtil'); const torrentServiceEvents = [ 'FETCH_TRANSFER_SUMMARY_ERROR', 'FETCH_TRANSFER_SUMMARY_SUCCESS', - 'TRANSFER_SUMMARY_DIFF_CHANGE' + 'TRANSFER_SUMMARY_DIFF_CHANGE', ].concat( // Create an array of event types based on the available snapshots. - Object.keys(historySnapshotTypes).reduce( - (accumulator, snapshotType) => { - accumulator.push( - `${snapshotType}_SNAPSHOT_FULL_UPDATE`, - `${snapshotType}_SNAPSHOT_DIFF_CHANGE` - ); + Object.keys(historySnapshotTypes).reduce((accumulator, snapshotType) => { + accumulator.push(`${snapshotType}_SNAPSHOT_FULL_UPDATE`, `${snapshotType}_SNAPSHOT_DIFF_CHANGE`); - return accumulator; - }, - [] - ) + return accumulator; + }, []) ); module.exports = objectUtil.createSymbolMapFromArray(torrentServiceEvents); diff --git a/server/constants/notificationServiceEvents.js b/server/constants/notificationServiceEvents.js index 1cfc7ffe..8a94d64d 100644 --- a/server/constants/notificationServiceEvents.js +++ b/server/constants/notificationServiceEvents.js @@ -2,8 +2,6 @@ const objectUtil = require('../../shared/util/objectUtil'); -const notificationServiceEvents = [ - 'NOTIFICATION_COUNT_CHANGE' -]; +const notificationServiceEvents = ['NOTIFICATION_COUNT_CHANGE']; module.exports = objectUtil.createSymbolMapFromArray(notificationServiceEvents); diff --git a/server/constants/taxonomyServiceEvents.js b/server/constants/taxonomyServiceEvents.js index 125b4c2b..ee5431f0 100644 --- a/server/constants/taxonomyServiceEvents.js +++ b/server/constants/taxonomyServiceEvents.js @@ -1,7 +1,5 @@ const objectUtil = require('../../shared/util/objectUtil'); -const taxonomyServiceEvents = [ - 'TAXONOMY_DIFF_CHANGE' -]; +const taxonomyServiceEvents = ['TAXONOMY_DIFF_CHANGE']; module.exports = objectUtil.createSymbolMapFromArray(taxonomyServiceEvents); diff --git a/server/constants/torrentListPropMap.js b/server/constants/torrentListPropMap.js index 3e4dc8ce..b85bca58 100644 --- a/server/constants/torrentListPropMap.js +++ b/server/constants/torrentListPropMap.js @@ -18,340 +18,235 @@ const dateTransformer = dirtyDate => { }; const defaultTransformer = value => value; -torrentListPropMap.set( - 'hash', - { - methodCall: 'd.hash=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('hash', { + methodCall: 'd.hash=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'name', - { - methodCall: 'd.name=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('name', { + methodCall: 'd.name=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'message', - { - methodCall: 'd.message=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('message', { + methodCall: 'd.message=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'state', - { - methodCall: 'd.state=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('state', { + methodCall: 'd.state=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'isStateChanged', - { - methodCall: 'd.state_changed=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isStateChanged', { + methodCall: 'd.state_changed=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'isActive', - { - methodCall: 'd.is_active=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isActive', { + methodCall: 'd.is_active=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'isComplete', - { - methodCall: 'd.complete=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isComplete', { + methodCall: 'd.complete=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'isHashChecking', - { - methodCall: 'd.is_hash_checking=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isHashChecking', { + methodCall: 'd.is_hash_checking=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'isOpen', - { - methodCall: 'd.is_open=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isOpen', { + methodCall: 'd.is_open=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'priority', - { - methodCall: 'd.priority=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('priority', { + methodCall: 'd.priority=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'upRate', - { - methodCall: 'd.up.rate=', - transformValue: Number - } -); +torrentListPropMap.set('upRate', { + methodCall: 'd.up.rate=', + transformValue: Number, +}); -torrentListPropMap.set( - 'upTotal', - { - methodCall: 'd.up.total=', - transformValue: Number - } -); +torrentListPropMap.set('upTotal', { + methodCall: 'd.up.total=', + transformValue: Number, +}); -torrentListPropMap.set( - 'downRate', - { - methodCall: 'd.down.rate=', - transformValue: Number - } -); +torrentListPropMap.set('downRate', { + methodCall: 'd.down.rate=', + transformValue: Number, +}); -torrentListPropMap.set( - 'downTotal', - { - methodCall: 'd.down.total=', - transformValue: Number - } -); +torrentListPropMap.set('downTotal', { + methodCall: 'd.down.total=', + transformValue: Number, +}); -torrentListPropMap.set( - 'ratio', - { - methodCall: 'd.ratio=', - transformValue: Number - } -); +torrentListPropMap.set('ratio', { + methodCall: 'd.ratio=', + transformValue: Number, +}); -torrentListPropMap.set( - 'bytesDone', - { - methodCall: 'd.bytes_done=', - transformValue: Number - } -); +torrentListPropMap.set('bytesDone', { + methodCall: 'd.bytes_done=', + transformValue: Number, +}); -torrentListPropMap.set( - 'sizeBytes', - { - methodCall: 'd.size_bytes=', - transformValue: Number - } -); +torrentListPropMap.set('sizeBytes', { + methodCall: 'd.size_bytes=', + transformValue: Number, +}); -torrentListPropMap.set( - 'peersConnected', - { - methodCall: 'd.peers_connected=', - transformValue: Number - } -); +torrentListPropMap.set('peersConnected', { + methodCall: 'd.peers_connected=', + transformValue: Number, +}); -torrentListPropMap.set( - 'directory', - { - methodCall: 'd.directory=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('directory', { + methodCall: 'd.directory=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'basePath', - { - methodCall: 'd.base_path=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('basePath', { + methodCall: 'd.base_path=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'baseFilename', - { - methodCall: 'd.base_filename=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('baseFilename', { + methodCall: 'd.base_filename=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'baseDirectory', - { - methodCall: 'd.directory_base=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('baseDirectory', { + methodCall: 'd.directory_base=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'seedingTime', - { - methodCall: 'd.custom=seedingtime', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('seedingTime', { + methodCall: 'd.custom=seedingtime', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'dateAdded', - { - methodCall: 'd.custom=addtime', - transformValue: dateTransformer - } -); +torrentListPropMap.set('dateAdded', { + methodCall: 'd.custom=addtime', + transformValue: dateTransformer, +}); -torrentListPropMap.set( - 'dateCreated', - { - methodCall: 'd.creation_date=', - transformValue: dateTransformer - } -); +torrentListPropMap.set('dateCreated', { + methodCall: 'd.creation_date=', + transformValue: dateTransformer, +}); -torrentListPropMap.set( - 'throttleName', - { - methodCall: 'd.throttle_name=', - transformValue: defaultTransformer - } -); +torrentListPropMap.set('throttleName', { + methodCall: 'd.throttle_name=', + transformValue: defaultTransformer, +}); -torrentListPropMap.set( - 'isMultiFile', - { - methodCall: 'd.is_multi_file=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isMultiFile', { + methodCall: 'd.is_multi_file=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'isPrivate', - { - methodCall: 'd.is_private=', - transformValue: booleanTransformer - } -); +torrentListPropMap.set('isPrivate', { + methodCall: 'd.is_private=', + transformValue: booleanTransformer, +}); -torrentListPropMap.set( - 'tags', - { - methodCall: 'd.custom1=', - transformValue: value => { - if (value === '') { - return []; - } +torrentListPropMap.set('tags', { + methodCall: 'd.custom1=', + transformValue: value => { + if (value === '') { + return []; + } - return value.split(',').sort().map((tag) => { + return value + .split(',') + .sort() + .map(tag => { return decodeURIComponent(tag); }); + }, +}); + +torrentListPropMap.set('comment', { + methodCall: 'd.custom2=', + transformValue: value => { + let comment = decodeURIComponent(value); + + if (comment.match(/^VRS24mrker/)) { + comment = comment.substr(10); } - } -); -torrentListPropMap.set( - 'comment', - { - methodCall: 'd.custom2=', - transformValue: value => { - let comment = decodeURIComponent(value); + return comment; + }, +}); - if (comment.match(/^VRS24mrker/)) { - comment = comment.substr(10); - } +torrentListPropMap.set('ignoreScheduler', { + methodCall: 'd.custom=sch_ignore', + transformValue: booleanTransformer, +}); - return comment; - } - } -); +torrentListPropMap.set('trackerURIs', { + methodCall: 'cat="$t.multicall=d.hash=,t.url=,cat={|||}"', + transformValue: value => { + const trackers = value.split('|||'); + const trackerDomains = []; -torrentListPropMap.set( - 'ignoreScheduler', - { - methodCall: 'd.custom=sch_ignore', - transformValue: booleanTransformer - } -); + trackers.forEach(tracker => { + let domain = regEx.domainName.exec(tracker); -torrentListPropMap.set( - 'trackerURIs', - { - methodCall: 'cat="$t.multicall=d.hash=,t.url=,cat={|||}"', - transformValue: value => { - const trackers = value.split('|||'); - const trackerDomains = []; + if (domain && domain[1]) { + domain = domain[1]; - trackers.forEach((tracker) => { - let domain = regEx.domainName.exec(tracker); + const minSubsetLength = 3; + const domainSubsets = domain.split('.'); + let desiredSubsets = 2; - if (domain && domain[1]) { - domain = domain[1]; - - const minSubsetLength = 3; - const domainSubsets = domain.split('.'); - let desiredSubsets = 2; - - if (domainSubsets.length > desiredSubsets) { - let lastDesiredSubset = domainSubsets[domainSubsets.length - desiredSubsets]; - if (lastDesiredSubset.length <= minSubsetLength) { - desiredSubsets++; - } + if (domainSubsets.length > desiredSubsets) { + let lastDesiredSubset = domainSubsets[domainSubsets.length - desiredSubsets]; + if (lastDesiredSubset.length <= minSubsetLength) { + desiredSubsets++; } - - domain = domainSubsets.slice(desiredSubsets * -1).join('.'); - - trackerDomains.push(domain); } - }); - return trackerDomains; - } - } -); + domain = domainSubsets.slice(desiredSubsets * -1).join('.'); -torrentListPropMap.set( - 'seedsConnected', - { - methodCall: 'd.peers_complete=', - transformValue: Number - } -); + trackerDomains.push(domain); + } + }); -torrentListPropMap.set( - 'seedsTotal', - { - methodCall: 'cat="$t.multicall=d.hash=,t.scrape_complete=,cat={|||}"', - transformValue: value => { - return Number(value.substr(0, value.indexOf('|||'))); - } - } -); + return trackerDomains; + }, +}); -torrentListPropMap.set( - 'peersConnected', - { - methodCall: 'd.peers_accounted=', - transformValue: Number - } -); +torrentListPropMap.set('seedsConnected', { + methodCall: 'd.peers_complete=', + transformValue: Number, +}); -torrentListPropMap.set( - 'peersTotal', - { - methodCall: 'cat="$t.multicall=d.hash=,t.scrape_incomplete=,cat={|||}"', - transformValue: value => { - return Number(value.substr(0, value.indexOf('|||'))); - } - } -); +torrentListPropMap.set('seedsTotal', { + methodCall: 'cat="$t.multicall=d.hash=,t.scrape_complete=,cat={|||}"', + transformValue: value => { + return Number(value.substr(0, value.indexOf('|||'))); + }, +}); + +torrentListPropMap.set('peersConnected', { + methodCall: 'd.peers_accounted=', + transformValue: Number, +}); + +torrentListPropMap.set('peersTotal', { + methodCall: 'cat="$t.multicall=d.hash=,t.scrape_incomplete=,cat={|||}"', + transformValue: value => { + return Number(value.substr(0, value.indexOf('|||'))); + }, +}); module.exports = torrentListPropMap; diff --git a/server/constants/torrentServiceEvents.js b/server/constants/torrentServiceEvents.js index 7a543b61..77c9425d 100644 --- a/server/constants/torrentServiceEvents.js +++ b/server/constants/torrentServiceEvents.js @@ -2,10 +2,6 @@ const objectUtil = require('../../shared/util/objectUtil'); -const torrentServiceEvents = [ - 'FETCH_TORRENT_LIST_ERROR', - 'FETCH_TORRENT_LIST_SUCCESS', - 'TORRENT_LIST_DIFF_CHANGE' -]; +const torrentServiceEvents = ['FETCH_TORRENT_LIST_ERROR', 'FETCH_TORRENT_LIST_SUCCESS', 'TORRENT_LIST_DIFF_CHANGE']; module.exports = objectUtil.createSymbolMapFromArray(torrentServiceEvents); diff --git a/server/constants/transferSummaryPropMap.js b/server/constants/transferSummaryPropMap.js index a9db692a..17cdcc41 100644 --- a/server/constants/transferSummaryPropMap.js +++ b/server/constants/transferSummaryPropMap.js @@ -1,52 +1,34 @@ 'use strict'; const transferSummaryPropMap = new Map(); -transferSummaryPropMap.set( - 'upRate', - { - methodCall: 'throttle.global_up.rate', - transformValue: Number - } -); +transferSummaryPropMap.set('upRate', { + methodCall: 'throttle.global_up.rate', + transformValue: Number, +}); -transferSummaryPropMap.set( - 'upTotal', - { - methodCall: 'throttle.global_up.total', - transformValue: Number - } -); +transferSummaryPropMap.set('upTotal', { + methodCall: 'throttle.global_up.total', + transformValue: Number, +}); -transferSummaryPropMap.set( - 'upThrottle', - { - methodCall: 'throttle.global_up.max_rate', - transformValue: Number - } -); +transferSummaryPropMap.set('upThrottle', { + methodCall: 'throttle.global_up.max_rate', + transformValue: Number, +}); -transferSummaryPropMap.set( - 'downRate', - { - methodCall: 'throttle.global_down.rate', - transformValue: Number - } -); +transferSummaryPropMap.set('downRate', { + methodCall: 'throttle.global_down.rate', + transformValue: Number, +}); -transferSummaryPropMap.set( - 'downTotal', - { - methodCall: 'throttle.global_down.total', - transformValue: Number - } -); +transferSummaryPropMap.set('downTotal', { + methodCall: 'throttle.global_down.total', + transformValue: Number, +}); -transferSummaryPropMap.set( - 'downThrottle', - { - methodCall: 'throttle.global_down.max_rate', - transformValue: Number - } -); +transferSummaryPropMap.set('downThrottle', { + methodCall: 'throttle.global_down.max_rate', + transformValue: Number, +}); module.exports = transferSummaryPropMap; diff --git a/server/middleware/clientActivityStream.js b/server/middleware/clientActivityStream.js index e35f9582..1e0da931 100644 --- a/server/middleware/clientActivityStream.js +++ b/server/middleware/clientActivityStream.js @@ -9,7 +9,10 @@ const taxonomyServiceEvents = require('../constants/taxonomyServiceEvents'); const torrentServiceEvents = require('../constants/torrentServiceEvents'); module.exports = (req, res) => { - const {query: {historySnapshot = historySnapshotTypes.FIVE_MINUTE}, user} = req; + const { + query: {historySnapshot = historySnapshotTypes.FIVE_MINUTE}, + user, + } = req; const serviceInstances = services.getAllServices(user); const serverEvent = new ServerEvent(res); @@ -49,15 +52,12 @@ module.exports = (req, res) => { serverEvent.addData(serviceInstances.notificationService.getNotificationCount()); serverEvent.emit(); - serviceInstances.clientGatewayService.on( - clientGatewayServiceEvents.CLIENT_CONNECTION_STATE_CHANGE, - () => { - serverEvent.setID(Date.now()); - serverEvent.setType(serverEventTypes.CLIENT_CONNECTIVITY_STATUS_CHANGE); - serverEvent.addData({isConnected: !serviceInstances.clientGatewayService.hasError}); - serverEvent.emit(); - } - ); + serviceInstances.clientGatewayService.on(clientGatewayServiceEvents.CLIENT_CONNECTION_STATE_CHANGE, () => { + serverEvent.setID(Date.now()); + serverEvent.setType(serverEventTypes.CLIENT_CONNECTIVITY_STATUS_CHANGE); + serverEvent.addData({isConnected: !serviceInstances.clientGatewayService.hasError}); + serverEvent.emit(); + }); // TODO: Handle empty or sub-optimal history states. // Get user's specified history snapshot current history. @@ -75,9 +75,7 @@ module.exports = (req, res) => { // Add user's specified history snapshot change event listener. serviceInstances.historyService.on( - historyServiceEvents[ - `${historySnapshotTypes[historySnapshot]}_SNAPSHOT_FULL_UPDATE` - ], + historyServiceEvents[`${historySnapshotTypes[historySnapshot]}_SNAPSHOT_FULL_UPDATE`], payload => { const {data, id} = payload; @@ -88,52 +86,40 @@ module.exports = (req, res) => { } ); - serviceInstances.notificationService.on( - notificationServiceEvents.NOTIFICATION_COUNT_CHANGE, - payload => { - const {data, id} = payload; + serviceInstances.notificationService.on(notificationServiceEvents.NOTIFICATION_COUNT_CHANGE, payload => { + const {data, id} = payload; - serverEvent.setID(id); - serverEvent.setType(serverEventTypes.NOTIFICATION_COUNT_CHANGE); - serverEvent.addData(data); - serverEvent.emit(); - } - ); + serverEvent.setID(id); + serverEvent.setType(serverEventTypes.NOTIFICATION_COUNT_CHANGE); + serverEvent.addData(data); + serverEvent.emit(); + }); // Add diff event listeners. - serviceInstances.historyService.on( - historyServiceEvents.TRANSFER_SUMMARY_DIFF_CHANGE, - (payload) => { - const {diff, id} = payload; + serviceInstances.historyService.on(historyServiceEvents.TRANSFER_SUMMARY_DIFF_CHANGE, payload => { + const {diff, id} = payload; - serverEvent.setID(id); - serverEvent.setType(serverEventTypes.TRANSFER_SUMMARY_DIFF_CHANGE); - serverEvent.addData(diff); - serverEvent.emit(); - } - ); + serverEvent.setID(id); + serverEvent.setType(serverEventTypes.TRANSFER_SUMMARY_DIFF_CHANGE); + serverEvent.addData(diff); + serverEvent.emit(); + }); - serviceInstances.taxonomyService.on( - taxonomyServiceEvents.TAXONOMY_DIFF_CHANGE, - (payload) => { - const {diff, id} = payload; + serviceInstances.taxonomyService.on(taxonomyServiceEvents.TAXONOMY_DIFF_CHANGE, payload => { + const {diff, id} = payload; - serverEvent.setID(id); - serverEvent.setType(serverEventTypes.TAXONOMY_DIFF_CHANGE); - serverEvent.addData(diff); - serverEvent.emit(); - } - ); + serverEvent.setID(id); + serverEvent.setType(serverEventTypes.TAXONOMY_DIFF_CHANGE); + serverEvent.addData(diff); + serverEvent.emit(); + }); - serviceInstances.torrentService.on( - torrentServiceEvents.TORRENT_LIST_DIFF_CHANGE, - (payload) => { - const {diff, id} = payload; + serviceInstances.torrentService.on(torrentServiceEvents.TORRENT_LIST_DIFF_CHANGE, payload => { + const {diff, id} = payload; - serverEvent.setID(id); - serverEvent.setType(serverEventTypes.TORRENT_LIST_DIFF_CHANGE); - serverEvent.addData(diff); - serverEvent.emit(); - } - ); + serverEvent.setID(id); + serverEvent.setType(serverEventTypes.TORRENT_LIST_DIFF_CHANGE); + serverEvent.addData(diff); + serverEvent.emit(); + }); }; diff --git a/server/middleware/eventStream.js b/server/middleware/eventStream.js index 0ead6615..6cce6d6b 100644 --- a/server/middleware/eventStream.js +++ b/server/middleware/eventStream.js @@ -5,12 +5,12 @@ module.exports = (req, res, next) => { res.set({ 'Content-Type': 'text/event-stream', 'Cache-Control': 'no-cache', - 'Connection': 'keep-alive', + Connection: 'keep-alive', 'Access-Control-Allow-Origin': '*', - 'X-Accel-Buffering': 'no' + 'X-Accel-Buffering': 'no', }); res.status(200); - res.write("retry: 500\n\n"); + res.write('retry: 500\n\n'); // Keep the connection open by sending a message every so often. const keepAliveTimeout = setInterval(function() { diff --git a/server/models/ClientRequest.js b/server/models/ClientRequest.js index 8db40de6..e5f7cdcc 100644 --- a/server/models/ClientRequest.js +++ b/server/models/ClientRequest.js @@ -37,15 +37,17 @@ class ClientRequest { addTagsToRequest(tagsArr, requestParameters) { if (tagsArr && tagsArr.length) { - const tags = tagsArr.reduce((accumulator, currentTag) => { - const tag = encodeURIComponent(currentTag.trim()); + const tags = tagsArr + .reduce((accumulator, currentTag) => { + const tag = encodeURIComponent(currentTag.trim()); - if (tag !== '' && accumulator.indexOf(tag) === -1) { - accumulator.push(tag); - } + if (tag !== '' && accumulator.indexOf(tag) === -1) { + accumulator.push(tag); + } - return accumulator; - }, []).join(','); + return accumulator; + }, []) + .join(','); requestParameters.push(`d.custom1.set="${tags}"`); } @@ -71,8 +73,10 @@ class ClientRequest { handleError(error) { if (error.code === 'ECONNREFUSED') { - console.error(`Connection refused at ${error.address}${error.port ? `:${error.port}` : ''}. ` + - `Check these values in config.js and ensure that rTorrent is running.`); + console.error( + `Connection refused at ${error.address}${error.port ? `:${error.port}` : ''}. ` + + `Check these values in config.js and ensure that rTorrent is running.` + ); } this.clearRequestQueue(); @@ -123,7 +127,7 @@ class ClientRequest { let start = options.start; let tagsArr = options.tags; - files.forEach((file) => { + files.forEach(file => { let methodCall = 'load.raw_start'; let parameters = ['', file.buffer]; let timeAdded = Math.floor(Date.now() / 1000); @@ -158,7 +162,7 @@ class ClientRequest { let tagsArr = options.tags; let urls = this.getEnsuredArray(options.urls); - urls.forEach((url) => { + urls.forEach(url => { let methodCall = 'load.start'; let parameters = ['', url]; let timeAdded = Math.floor(Date.now() / 1000); @@ -192,7 +196,7 @@ class ClientRequest { const hashesToStart = []; - this.stopTorrents({ hashes }); + this.stopTorrents({hashes}); hashes.forEach(hash => { this.requests.push(this.getMethodCall('d.check_hash', [hash])); @@ -203,13 +207,13 @@ class ClientRequest { }); if (hashesToStart.length) { - this.startTorrents({ hashes: hashesToStart }); + this.startTorrents({hashes: hashesToStart}); } } createDirectory(options) { if (options.path) { - mkdirp(options.path, (error) => { + mkdirp(options.path, error => { if (error) { console.trace('Error creating directory.', error); } @@ -223,7 +227,7 @@ class ClientRequest { if (options.requestedSettings) { requestedSettings = options.requestedSettings; } else { - requestedSettings = clientSettingsMap.defaults.map((settingsKey) => { + requestedSettings = clientSettingsMap.defaults.map(settingsKey => { return clientSettingsMap[settingsKey]; }); } @@ -233,7 +237,7 @@ class ClientRequest { options.setRequestedKeysArr(requestedSettings); } - requestedSettings.forEach((settingsKey) => { + requestedSettings.forEach(settingsKey => { this.requests.push(this.getMethodCall(settingsKey)); }); } @@ -253,7 +257,7 @@ class ClientRequest { } getTransferData(options) { - Object.keys(rTorrentPropMap.transferData).forEach((key) => { + Object.keys(rTorrentPropMap.transferData).forEach(key => { this.requests.push(this.getMethodCall(rTorrentPropMap.transferData[key])); }); } @@ -292,12 +296,11 @@ class ClientRequest { if (options.isBasePath) { pathMethod = 'd.directory_base.set'; } else { - pathMethod = 'd.directory.set' + pathMethod = 'd.directory.set'; } - hashes.forEach((hash) => { - this.requests.push(this.getMethodCall(pathMethod, - [hash, options.path])); + hashes.forEach(hash => { + this.requests.push(this.getMethodCall(pathMethod, [hash, options.path])); this.requests.push(this.getMethodCall('d.open', [hash])); this.requests.push(this.getMethodCall('d.close', [hash])); }); @@ -307,10 +310,9 @@ class ClientRequest { let fileIndices = this.getEnsuredArray(options.fileIndices); let hashes = this.getEnsuredArray(options.hashes); - hashes.forEach((hash) => { - fileIndices.forEach((fileIndex) => { - this.requests.push(this.getMethodCall('f.priority.set', - [`${hash}:f${fileIndex}`, options.priority])); + hashes.forEach(hash => { + fileIndices.forEach(fileIndex => { + this.requests.push(this.getMethodCall('f.priority.set', [`${hash}:f${fileIndex}`, options.priority])); }); this.requests.push(this.getMethodCall('d.update_priorities', [hash])); }); @@ -319,23 +321,20 @@ class ClientRequest { setPriority(options) { let hashes = this.getEnsuredArray(options.hashes); - hashes.forEach((hash) => { - this.requests.push(this.getMethodCall('d.priority.set', - [hash, options.priority])); - this.requests.push(this.getMethodCall('d.update_priorities', - [hash])); + hashes.forEach(hash => { + this.requests.push(this.getMethodCall('d.priority.set', [hash, options.priority])); + this.requests.push(this.getMethodCall('d.update_priorities', [hash])); }); } setSettings(options) { let settings = this.getEnsuredArray(options.settings); - settings.forEach((setting) => { + settings.forEach(setting => { if (setting.overrideLocalSetting) { this.requests.push(this.getMethodCall(setting.id, setting.data)); } else { - this.requests.push(this.getMethodCall(`${clientSettingsMap[setting.id]}.set`, - ['', setting.data])); + this.requests.push(this.getMethodCall(`${clientSettingsMap[setting.id]}.set`, ['', setting.data])); } }); } @@ -343,17 +342,19 @@ class ClientRequest { setTaxonomy(options) { let methodName = 'd.custom1.set'; - let tags = options.tags.reduce((memo, currentTag) => { - let tag = encodeURIComponent(currentTag.trim()); + let tags = options.tags + .reduce((memo, currentTag) => { + let tag = encodeURIComponent(currentTag.trim()); - if (tag !== '' && memo.indexOf(tag) === -1) { - memo.push(tag); - } + if (tag !== '' && memo.indexOf(tag) === -1) { + memo.push(tag); + } - return memo; - }, []).join(','); + return memo; + }, []) + .join(','); - this.getEnsuredArray(options.hashes).forEach((hash) => { + this.getEnsuredArray(options.hashes).forEach(hash => { this.requests.push(this.getMethodCall(methodName, [hash, tags])); }); } @@ -368,11 +369,11 @@ class ClientRequest { startTorrents(options) { if (!options.hashes) { - console.error('startTorrents requires key \'hashes\'.'); + console.error("startTorrents requires key 'hashes'."); return; } - this.getEnsuredArray(options.hashes).forEach((hash) => { + this.getEnsuredArray(options.hashes).forEach(hash => { this.requests.push(this.getMethodCall('d.open', [hash])); this.requests.push(this.getMethodCall('d.start', [hash])); }); @@ -380,11 +381,11 @@ class ClientRequest { stopTorrents(options) { if (!options.hashes) { - console.error('stopTorrents requires key \'hashes\'.'); + console.error("stopTorrents requires key 'hashes'."); return; } - this.getEnsuredArray(options.hashes).forEach((hash) => { + this.getEnsuredArray(options.hashes).forEach(hash => { this.requests.push(this.getMethodCall('d.stop', [hash])); this.requests.push(this.getMethodCall('d.close', [hash])); }); diff --git a/server/models/Feed.js b/server/models/Feed.js index 3cb0d7ac..8c3817ed 100644 --- a/server/models/Feed.js +++ b/server/models/Feed.js @@ -19,7 +19,7 @@ class Feed { maxHistory: this.options.maxItemHistory, interval: options.interval ? Number(options.interval) : 15, forceInterval: true, - readEveryItem: true + readEveryItem: true, }); this.initReader(); diff --git a/server/models/Filesystem.js b/server/models/Filesystem.js index e397d952..7d6a026c 100644 --- a/server/models/Filesystem.js +++ b/server/models/Filesystem.js @@ -12,7 +12,7 @@ class Filesystem { let directories = []; let files = []; - fs.readdirSync(sourcePath).forEach((item) => { + fs.readdirSync(sourcePath).forEach(item => { if (fs.statSync(path.join(sourcePath, item)).isDirectory()) { directories.push(item); } else { @@ -27,7 +27,7 @@ class Filesystem { files, hasParent, path: sourcePath, - separator: path.sep + separator: path.sep, }); } catch (error) { callback(null, error); diff --git a/server/models/HistoryEra.js b/server/models/HistoryEra.js index 6ee17541..e17997a5 100644 --- a/server/models/HistoryEra.js +++ b/server/models/HistoryEra.js @@ -46,7 +46,7 @@ class HistoryEra { loadDatabase(dbName) { const db = new Datastore({ autoload: true, - filename: path.join(config.dbPath, this.user._id, 'history', `${dbName}.db`) + filename: path.join(config.dbPath, this.user._id, 'history', `${dbName}.db`), }); this.ready = true; @@ -67,7 +67,7 @@ class HistoryEra { this.db.insert({ ts: currentTime, up: Number(data.upload), - dn: Number(data.download) + dn: Number(data.download), }); } else { this.db.find({ts: this.lastUpdate}, (err, docs) => { @@ -85,19 +85,21 @@ class HistoryEra { console.error('\n\n'); console.error('Warning: null values set in database!'); console.error(`DB: ${this.opts.name}`); - console.error(`numUpdates: ${numUpdates}\ncurrentDownAvg: ${currentDownAvg}\ncurrentUpAvg: ${currentUpAvg}\ndownAvg: ${downAvg}\nupAvg: ${upAvg}`); + console.error( + `numUpdates: ${numUpdates}\ncurrentDownAvg: ${currentDownAvg}\ncurrentUpAvg: ${currentUpAvg}\ndownAvg: ${downAvg}\nupAvg: ${upAvg}` + ); console.error('\n\n'); } this.db.update( { - ts: this.lastUpdate + ts: this.lastUpdate, }, { ts: this.lastUpdate, up: Number(upAvg), dn: Number(downAvg), - num: numUpdates + 1 + num: numUpdates + 1, } ); } @@ -113,7 +115,8 @@ class HistoryEra { getData(opts, callback) { let minTimestamp = Date.now() - this.opts.maxTime; - this.db.find({ts: {$gte: minTimestamp}}) + this.db + .find({ts: {$gte: minTimestamp}}) .sort({ts: 1}) .exec((err, docs) => { if (err) { @@ -122,14 +125,13 @@ class HistoryEra { } callback(docs); - } - ); + }); } hasRequiredFields(opts) { let requirementsMet = true; - REQUIRED_FIELDS.forEach((field) => { + REQUIRED_FIELDS.forEach(field => { if (opts[field] == null) { console.error(`HistoryEra requires ${field}`); requirementsMet = false; @@ -150,7 +152,7 @@ class HistoryEra { let lastUpdate = 0; db.find({}, (err, docs) => { - docs.forEach((doc) => { + docs.forEach(doc => { if (doc.ts > lastUpdate) { lastUpdate = doc.ts; } @@ -160,15 +162,11 @@ class HistoryEra { } startAutoCleanup(interval, db) { - this.autoCleanupInterval = setInterval( - this.cleanup.bind(this, db), interval - ); + this.autoCleanupInterval = setInterval(this.cleanup.bind(this, db), interval); } startNextEraUpdate(interval, currentDB, nextDB) { - this.nextEraUpdateInterval = setInterval( - this.updateNextEra.bind(this, currentDB, nextDB), interval - ); + this.nextEraUpdateInterval = setInterval(this.updateNextEra.bind(this, currentDB, nextDB), interval); } stopAutoCleanup() { @@ -187,14 +185,14 @@ class HistoryEra { let downTotal = 0; let upTotal = 0; - docs.forEach((doc) => { + docs.forEach(doc => { downTotal += Number(doc.dn); upTotal += Number(doc.up); }); this.opts.nextEra.addData({ download: Number(downTotal / docs.length).toFixed(1), - upload: Number(upTotal / docs.length).toFixed(1) + upload: Number(upTotal / docs.length).toFixed(1), }); }); } diff --git a/server/models/TemporaryStorage.js b/server/models/TemporaryStorage.js index b5f6af27..6fddb8a4 100644 --- a/server/models/TemporaryStorage.js +++ b/server/models/TemporaryStorage.js @@ -5,11 +5,7 @@ const path = require('path'); class TemporaryStorage { constructor() { - this.tempPath = path.join( - path.dirname(require.main.filename), - '..', - 'temp' - ); + this.tempPath = path.join(path.dirname(require.main.filename), '..', 'temp'); mkdirp(this.tempPath); } diff --git a/server/models/Users.js b/server/models/Users.js index e9ef559e..3bf2f493 100644 --- a/server/models/Users.js +++ b/server/models/Users.js @@ -46,14 +46,7 @@ class Users { } createUser(credentials, callback) { - const { - password, - username, - host, - port, - socketPath, - isAdmin - } = credentials; + const {password, username, host, port, socketPath, isAdmin} = credentials; if (!this.ready) { return callback(null, 'Users database is not ready.'); @@ -68,7 +61,7 @@ class Users { argon2 .hash(password) .then(hash => { - this.db.insert({ username, password: hash, host, port, socket, socketPath, isAdmin }, (error, user) => { + this.db.insert({username, password: hash, host, port, socket, socketPath, isAdmin}, (error, user) => { if (error) { if (error.errorType === 'uniqueViolated') { error = 'Username already exists.'; @@ -79,7 +72,7 @@ class Users { services.bootstrapServicesForUser(user); - return callback({ username }); + return callback({username}); }); }) .catch(error => { @@ -112,10 +105,10 @@ class Users { updateUser(username, userRecordPatch, callback) { const nextUserRecordPatch = Object.assign({}, userRecordPatch, { - socket: userRecordPatch.socketPath != null + socket: userRecordPatch.socketPath != null, }); - this.db.update({ username }, { $set: nextUserRecordPatch }, (err, numUsersUpdated, updatedUser) => { + this.db.update({username}, {$set: nextUserRecordPatch}, (err, numUsersUpdated, updatedUser) => { if (err) return callback(null, err); // Username not found. if (numUsersUpdated === 0) { @@ -139,7 +132,7 @@ class Users { loadDatabase() { let db = new Datastore({ autoload: true, - filename: path.join(config.dbPath, 'users.db') + filename: path.join(config.dbPath, 'users.db'), }); db.ensureIndex({fieldName: 'username', unique: true}); diff --git a/server/models/client.js b/server/models/client.js index be0d9d54..4dc419be 100644 --- a/server/models/client.js +++ b/server/models/client.js @@ -53,7 +53,7 @@ const client = { settings.set(user, {id: 'startTorrentsOnLoad', data: start}); }, - addUrls (user, services, data, callback) { + addUrls(user, services, data, callback) { const urls = data.urls; const path = data.destination; const isBasePath = data.isBasePath; @@ -69,7 +69,7 @@ const client = { settings.set(user, {id: 'startTorrentsOnLoad', data: start}); }, - checkHash (user, services, hashes, callback) { + checkHash(user, services, hashes, callback) { const request = new ClientRequest(user, services); request.checkHash({hashes}); @@ -80,12 +80,12 @@ const client = { request.send(); }, - downloadFiles (user, services, hash, fileString, res) { + downloadFiles(user, services, hash, fileString, res) { try { const selectedTorrent = services.torrentService.getTorrent(hash); if (!selectedTorrent) return res.status(404).json({error: 'Torrent not found.'}); - this.getTorrentDetails(user, hash, (torrentDetails) => { + this.getTorrentDetails(user, hash, torrentDetails => { if (!torrentDetails) return res.status(404).json({error: 'Torrent details not found'}); let files; @@ -95,10 +95,7 @@ const client = { files = fileString.split(','); } - const filePathsToDownload = this.findFilesByIndicies( - files, - torrentDetails.fileTree - ).map((file) => { + const filePathsToDownload = this.findFilesByIndicies(files, torrentDetails.fileTree).map(file => { return path.join(selectedTorrent.directory, file.path); }); @@ -112,27 +109,30 @@ const client = { res.attachment(`${selectedTorrent.name}.tar`); - const pack = tar.pack() + const pack = tar.pack(); pack.pipe(res); - const tasks = filePathsToDownload.map((filePath) => { + const tasks = filePathsToDownload.map(filePath => { const filename = path.basename(filePath); - return (next) => { + return next => { fs.stat(filePath, (err, stats) => { if (err) return next(err); const stream = fs.createReadStream(filePath); - const entry = pack.entry({ - name: filename, - size: stats.size - }, next); + const entry = pack.entry( + { + name: filename, + size: stats.size, + }, + next + ); stream.pipe(entry); }); - } + }; }); - series(tasks, (error) => { + series(tasks, error => { if (error) return res.status(500).json(error); pack.finalize(); @@ -143,7 +143,7 @@ const client = { } }, - findFilesByIndicies (indices, fileTree = {}) { + findFilesByIndicies(indices, fileTree = {}) { const {directories, files = []} = fileTree; let selectedFiles = files.filter(file => { @@ -151,44 +151,41 @@ const client = { }); if (directories != null) { - selectedFiles = selectedFiles.concat(Object.keys(directories).reduce( - (accumulator, directory) => { - return accumulator.concat( - this.findFilesByIndicies(indices, directories[directory]) - ); - }, - [] - )); + selectedFiles = selectedFiles.concat( + Object.keys(directories).reduce((accumulator, directory) => { + return accumulator.concat(this.findFilesByIndicies(indices, directories[directory])); + }, []) + ); } return selectedFiles; }, - getSettings (user, services, options, callback) { + getSettings(user, services, options, callback) { let requestedSettingsKeys = []; const request = new ClientRequest(user, services); const response = {}; let outboundTransformation = { - throttleGlobalDownMax: (apiResponse) => { + throttleGlobalDownMax: apiResponse => { return Number(apiResponse) / 1024; }, - throttleGlobalUpMax: (apiResponse) => { + throttleGlobalUpMax: apiResponse => { return Number(apiResponse) / 1024; }, - piecesMemoryMax: (apiResponse) => { + piecesMemoryMax: apiResponse => { return Number(apiResponse) / (1024 * 1024); - } + }, }; request.fetchSettings({ options, - setRequestedKeysArr: (requestedSettingsKeysArr) => { + setRequestedKeysArr: requestedSettingsKeysArr => { requestedSettingsKeys = requestedSettingsKeysArr; - } + }, }); - request.postProcess((data) => { + request.postProcess(data => { if (!data) { return null; } @@ -210,21 +207,21 @@ const client = { request.send(); }, - getTorrentDetails (user, services, hash, callback) { + getTorrentDetails(user, services, hash, callback) { const request = new ClientRequest(user, services); request.getTorrentDetails({ hash, fileProps: torrentFilePropsMap.methods, peerProps: torrentPeerPropsMap.methods, - trackerProps: torrentTrackerPropsMap.methods + trackerProps: torrentTrackerPropsMap.methods, }); request.postProcess(clientResponseUtil.processTorrentDetails); request.onComplete(callback); request.send(); }, - listMethods (user, services, method, args, callback) { + listMethods(user, services, method, args, callback) { const request = new ClientRequest(user, services); request.listMethods({method, args}); @@ -232,7 +229,7 @@ const client = { request.send(); }, - moveTorrents (user, services, data, callback) { + moveTorrents(user, services, data, callback) { const destinationPath = data.destination; const isBasePath = data.isBasePath; const hashes = data.hashes; @@ -241,7 +238,7 @@ const client = { const sourcePaths = data.sources; const mainRequest = new ClientRequest(user, services); - const hashesToRestart = hashes.filter((hash) => { + const hashesToRestart = hashes.filter(hash => { return !services.torrentService.getTorrent(hash).status.includes(torrentStatusMap.stopped); }); @@ -269,7 +266,9 @@ const client = { const moveTorrentsRequest = new ClientRequest(user, services); moveTorrentsRequest.onComplete(checkHash); moveTorrentsRequest.moveTorrents({ - filenames, sourcePaths, destinationPath + filenames, + sourcePaths, + destinationPath, }); }; @@ -285,7 +284,7 @@ const client = { mainRequest.send(); }, - setFilePriority (user, services, hashes, data, callback) { + setFilePriority(user, services, hashes, data, callback) { // TODO Add support for multiple hashes. let fileIndices = data.fileIndices; const request = new ClientRequest(user, services); @@ -298,7 +297,7 @@ const client = { request.send(); }, - setPriority (user, services, hashes, data, callback) { + setPriority(user, services, hashes, data, callback) { const request = new ClientRequest(user, services); request.setPriority({hashes, priority: data.priority}); @@ -309,32 +308,32 @@ const client = { request.send(); }, - setSettings (user, services, payloads, callback) { + setSettings(user, services, payloads, callback) { const request = new ClientRequest(user, services); if (payloads.length === 0) return callback({}); let inboundTransformation = { - throttleGlobalDownMax: (userInput) => { + throttleGlobalDownMax: userInput => { return { id: userInput.id, - data: Number(userInput.data) * 1024 + data: Number(userInput.data) * 1024, }; }, - throttleGlobalUpMax: (userInput) => { + throttleGlobalUpMax: userInput => { return { id: userInput.id, - data: Number(userInput.data) * 1024 + data: Number(userInput.data) * 1024, }; }, - piecesMemoryMax: (userInput) => { + piecesMemoryMax: userInput => { return { id: userInput.id, - data: (Number(userInput.data) * 1024 * 1024).toString() + data: (Number(userInput.data) * 1024 * 1024).toString(), }; - } + }, }; - let transformedPayloads = payloads.map((payload) => { + let transformedPayloads = payloads.map(payload => { if (inboundTransformation[payload.id]) { return inboundTransformation[payload.id](payload); } @@ -347,18 +346,18 @@ const client = { request.send(); }, - setSpeedLimits (user, services, data, callback) { + setSpeedLimits(user, services, data, callback) { const request = new ClientRequest(user, services); request.setThrottle({ direction: data.direction, - throttle: data.throttle + throttle: data.throttle, }); request.onComplete(callback); request.send(); }, - setTaxonomy (user, services, data, callback) { + setTaxonomy(user, services, data, callback) { const request = new ClientRequest(user, services); request.setTaxonomy(data); @@ -370,7 +369,7 @@ const client = { request.send(); }, - stopTorrent (user, services, hashes, callback) { + stopTorrent(user, services, hashes, callback) { const request = new ClientRequest(user, services); request.stopTorrents({hashes}); request.onComplete((response, error) => { @@ -380,7 +379,7 @@ const client = { request.send(); }, - startTorrent (user, services, hashes, callback) { + startTorrent(user, services, hashes, callback) { const request = new ClientRequest(user, services); request.startTorrents({hashes}); @@ -389,7 +388,7 @@ const client = { callback(response, error); }); request.send(); - } + }, }; module.exports = client; diff --git a/server/models/settings.js b/server/models/settings.js index b74f7eb3..ca7377cc 100644 --- a/server/models/settings.js +++ b/server/models/settings.js @@ -19,7 +19,7 @@ const changedKeys = { totalSeeds: 'seedsTotal', added: 'dateAdded', creationDate: 'dateCreated', - trackers: 'trackerURIs' + trackers: 'trackerURIs', }; const removedKeys = ['freeDiskSpace']; @@ -34,45 +34,34 @@ const removedKeys = ['freeDiskSpace']; * @return {Object} - the settings object, altered if legacy keys exist. */ const transformLegacyKeys = settings => { - if ( - settings.sortTorrents - && settings.sortTorrents.property in changedKeys - ) { - settings.sortTorrents.property = changedKeys[ - settings.sortTorrents.property - ]; + if (settings.sortTorrents && settings.sortTorrents.property in changedKeys) { + settings.sortTorrents.property = changedKeys[settings.sortTorrents.property]; } if (settings.torrentDetails) { - settings.torrentDetails = settings.torrentDetails.reduce( - (accumulator, detailItem, index) => { - if ( - detailItem && detailItem.id in changedKeys - && !(settings.torrentDetails.some(subDetailItem => { - return subDetailItem.id === changedKeys[detailItem.id]; - })) - ) { - detailItem.id = changedKeys[detailItem.id]; - } + settings.torrentDetails = settings.torrentDetails.reduce((accumulator, detailItem, index) => { + if ( + detailItem && + detailItem.id in changedKeys && + !settings.torrentDetails.some(subDetailItem => { + return subDetailItem.id === changedKeys[detailItem.id]; + }) + ) { + detailItem.id = changedKeys[detailItem.id]; + } - if (!removedKeys.includes(detailItem.id)) { - accumulator.push(detailItem); - } + if (!removedKeys.includes(detailItem.id)) { + accumulator.push(detailItem); + } - return accumulator; - }, - [] - ); + return accumulator; + }, []); } if (settings.torrentListColumnWidths) { Object.keys(settings.torrentListColumnWidths).forEach(columnID => { - if ( - columnID in changedKeys - && !(changedKeys[columnID] in settings.torrentListColumnWidths) - ) { - settings.torrentListColumnWidths[changedKeys[columnID]] - = settings.torrentListColumnWidths[columnID]; + if (columnID in changedKeys && !(changedKeys[columnID] in settings.torrentListColumnWidths)) { + settings.torrentListColumnWidths[changedKeys[columnID]] = settings.torrentListColumnWidths[columnID]; } }); } @@ -89,13 +78,13 @@ function getDb(user) { const database = new Datastore({ autoload: true, - filename: path.join(config.dbPath, userId, 'settings', 'settings.db') + filename: path.join(config.dbPath, userId, 'settings', 'settings.db'), }); databases.set(userId, database); return database; -}; +} const settings = { get: (user, opts, callback) => { @@ -106,18 +95,20 @@ const settings = { query.id = opts.property; } - getDb(user).find(query).exec((err, docs) => { - if (err) { - callback(null, err); - return; - } + getDb(user) + .find(query) + .exec((err, docs) => { + if (err) { + callback(null, err); + return; + } - docs.forEach((doc) => { - settings[doc.id] = doc.data; + docs.forEach(doc => { + settings[doc.id] = doc.data; + }); + + callback(transformLegacyKeys(settings)); }); - - callback(transformLegacyKeys(settings)); - }); }, set: (user, payloads, callback = _.noop) => { @@ -144,7 +135,7 @@ const settings = { } else { callback(); } - } -} + }, +}; module.exports = settings; diff --git a/server/routes/auth.js b/server/routes/auth.js index 49f21f0c..c5ebc651 100644 --- a/server/routes/auth.js +++ b/server/routes/auth.js @@ -16,17 +16,11 @@ const setAuthToken = (res, username) => { let cookieExpiration = Date.now() + expirationSeconds * 1000; // Create token if the password matched and no error was thrown. - let token = jwt.sign( - {username}, - config.secret, { - expiresIn: expirationSeconds + let token = jwt.sign({username}, config.secret, { + expiresIn: expirationSeconds, }); - res.cookie( - 'jwt', - token, - {expires: new Date(cookieExpiration), httpOnly: true} - ); + res.cookie('jwt', token, {expires: new Date(cookieExpiration), httpOnly: true}); return res.json({success: true, token: `JWT ${token}`, username}); }; @@ -36,7 +30,7 @@ const authValidation = joi.object().keys({ password: joi.string(), host: joi.string(), port: joi.string(), - socketPath: joi.string() + socketPath: joi.string(), }); router.use('/', (req, res, next) => { @@ -47,7 +41,7 @@ router.use('/', (req, res, next) => { } else { res.status(422).json({ message: 'Validation error.', - error: validation.error + error: validation.error, }); } }); @@ -55,7 +49,7 @@ router.use('/', (req, res, next) => { router.post('/authenticate', (req, res) => { const credentials = { password: req.body.password, - username: req.body.username + username: req.body.username, }; Users.comparePassword(credentials, (isMatch, err) => { @@ -83,7 +77,7 @@ router.use('/register', (req, res, next) => { passport.authenticate('jwt', {session: false}, (req, res, next) => { res.json({username: req.username}); }); - } + }, }); }); @@ -96,7 +90,7 @@ router.post('/register', (req, res) => { host: req.body.host, port: req.body.port, socketPath: req.body.socketPath, - isAdmin: true + isAdmin: true, }, (createUserResponse, createUserError) => { if (createUserError) { @@ -119,7 +113,7 @@ router.use('/verify', (req, res, next) => { handleSubsequentUser: () => { req.initialUser = false; passport.authenticate('jwt', {session: false})(req, res, next); - } + }, }); }); @@ -145,9 +139,9 @@ router.delete('/users/:username', (req, res, next) => { router.patch('/users/:username', (req, res, next) => { const username = req.params.username; - Users.updateUser(username, req.body, (user) => { - Users.lookupUser({ username }, (err, user) => { - if (err) return req.status(500).json({ error: err }); + Users.updateUser(username, req.body, user => { + Users.lookupUser({username}, (err, user) => { + if (err) return req.status(500).json({error: err}); services.updateUserServices(user); res.send(); }); @@ -155,14 +149,17 @@ router.patch('/users/:username', (req, res, next) => { }); router.put('/users', (req, res, next) => { - Users.createUser({ - username: req.body.username, - password: req.body.password, - host: req.body.host, - port: req.body.port, - socketPath: req.body.socketPath, - isAdmin: false - }, ajaxUtil.getResponseFn(res)); + Users.createUser( + { + username: req.body.username, + password: req.body.password, + host: req.body.host, + port: req.body.port, + socketPath: req.body.socketPath, + isAdmin: false, + }, + ajaxUtil.getResponseFn(res) + ); }); module.exports = router; diff --git a/server/routes/client.js b/server/routes/client.js index 3b88705c..a901ef3f 100644 --- a/server/routes/client.js +++ b/server/routes/client.js @@ -9,23 +9,27 @@ const router = express.Router(); const upload = multer({ dest: 'uploads/', limits: {fileSize: 10000000}, - storage: multer.memoryStorage() + storage: multer.memoryStorage(), }); router.get('/connection-test', function(req, res, next) { - req.services.clientGatewayService.testGateway() - .then((response) => { + req.services.clientGatewayService + .testGateway() + .then(response => { res.status(200).json({isConnected: true}); - }).catch(error => { + }) + .catch(error => { res.status(500).json({isConnected: false}); }); }); router.post('/connection-test', function(req, res, next) { - req.services.clientGatewayService.testGateway(req.body) - .then((response) => { + req.services.clientGatewayService + .testGateway(req.body) + .then(response => { res.status(200).json({isConnected: true}); - }).catch(error => { + }) + .catch(error => { res.status(500).json({isConnected: false}); }); }); @@ -34,14 +38,9 @@ router.post('/add', function(req, res, next) { client.addUrls(req.user, req.services, req.body, ajaxUtil.getResponseFn(res)); }); -router.post( - '/add-files', - upload.array('torrents'), - booleanCoerce('isBasePath'), - function(req, res, next) { - client.addFiles(req.user, req.services, req, ajaxUtil.getResponseFn(res)); - } -); +router.post('/add-files', upload.array('torrents'), booleanCoerce('isBasePath'), function(req, res, next) { + client.addFiles(req.user, req.services, req, ajaxUtil.getResponseFn(res)); +}); router.get('/settings', function(req, res, next) { client.getSettings(req.user, req.services, req.query, ajaxUtil.getResponseFn(res)); @@ -90,7 +89,7 @@ router.post('/torrents/delete', function(req, res, next) { req.services.clientGatewayService .removeTorrents({hashes, deleteData}) .then(callback) - .catch((err) => { + .catch(err => { callback(null, err); }); }); diff --git a/server/services/BaseService.js b/server/services/BaseService.js index 0dbcae6e..ffe0c510 100644 --- a/server/services/BaseService.js +++ b/server/services/BaseService.js @@ -19,4 +19,4 @@ class BaseService extends EventEmitter { } } -module.exports = BaseService; \ No newline at end of file +module.exports = BaseService; diff --git a/server/services/clientGatewayService.js b/server/services/clientGatewayService.js index 564966bc..e48f8ac6 100644 --- a/server/services/clientGatewayService.js +++ b/server/services/clientGatewayService.js @@ -9,10 +9,7 @@ const fileListPropMap = require('../constants/fileListPropMap'); const methodCallUtil = require('../util/methodCallUtil'); const scgiUtil = require('../util/scgiUtil'); -const fileListMethodCallConfig = methodCallUtil.getMethodCallConfigFromPropMap( - fileListPropMap, - ['pathComponents'] -); +const fileListMethodCallConfig = methodCallUtil.getMethodCallConfigFromPropMap(fileListPropMap, ['pathComponents']); class ClientGatewayService extends BaseService { constructor() { @@ -47,73 +44,64 @@ class ClientGatewayService extends BaseService { } removeTorrents(options = {hashes: [], deleteData: false}) { - const methodCalls = options.hashes.reduce( - (accumulator, hash, index) => { - let eraseFileMethodCallIndex = index; + const methodCalls = options.hashes.reduce((accumulator, hash, index) => { + let eraseFileMethodCallIndex = index; - // If we're deleting files, we grab each torrents' file list before we - // remove them. - if (options.deleteData) { - // We offset the indices of these method calls so that we know exactly - // where to retrieve the responses in the future. - const directoryBaseMethodCallIndex = index + options.hashes.length; - // We also need to ensure that the erase method call occurs after - // our request for information. - eraseFileMethodCallIndex = index + options.hashes.length * 2; + // If we're deleting files, we grab each torrents' file list before we + // remove them. + if (options.deleteData) { + // We offset the indices of these method calls so that we know exactly + // where to retrieve the responses in the future. + const directoryBaseMethodCallIndex = index + options.hashes.length; + // We also need to ensure that the erase method call occurs after + // our request for information. + eraseFileMethodCallIndex = index + options.hashes.length * 2; - accumulator[index] = { - methodName: 'f.multicall', - params: [hash, ''].concat(fileListMethodCallConfig.methodCalls) - }; - - accumulator[directoryBaseMethodCallIndex] = { - methodName: 'd.directory_base', - params: [hash] - }; - } - - accumulator[eraseFileMethodCallIndex] = { - methodName: 'd.erase', - params: [hash] + accumulator[index] = { + methodName: 'f.multicall', + params: [hash, ''].concat(fileListMethodCallConfig.methodCalls), }; - return accumulator; - }, - [] - ); + accumulator[directoryBaseMethodCallIndex] = { + methodName: 'd.directory_base', + params: [hash], + }; + } + + accumulator[eraseFileMethodCallIndex] = { + methodName: 'd.erase', + params: [hash], + }; + + return accumulator; + }, []); return this.services.clientRequestManager .methodCall('system.multicall', [methodCalls]) - .then((response) => { + .then(response => { if (options.deleteData) { const torrentCount = options.hashes.length; - const filesToDelete = options.hashes.reduce( - (accumulator, hash, hashIndex) => { - const fileList = response[hashIndex][0]; - const directoryBase = response[hashIndex + torrentCount][0]; + const filesToDelete = options.hashes.reduce((accumulator, hash, hashIndex) => { + const fileList = response[hashIndex][0]; + const directoryBase = response[hashIndex + torrentCount][0]; - const filesToDelete = fileList.reduce( - (fileListAccumulator, file) => { - // We only look at the first path component returned because - // if it's a directory within the torrent, then we'll remove - // the entire directory. - const filePath = path.join(directoryBase, file[0][0]); + const filesToDelete = fileList.reduce((fileListAccumulator, file) => { + // We only look at the first path component returned because + // if it's a directory within the torrent, then we'll remove + // the entire directory. + const filePath = path.join(directoryBase, file[0][0]); - // filePath might be a directory, so it may have already been - // added. If not, we add it. - if (!fileListAccumulator.includes(filePath)) { - fileListAccumulator.push(filePath); - } + // filePath might be a directory, so it may have already been + // added. If not, we add it. + if (!fileListAccumulator.includes(filePath)) { + fileListAccumulator.push(filePath); + } - return fileListAccumulator; - }, - [] - ); + return fileListAccumulator; + }, []); - return accumulator.concat(filesToDelete); - }, - [] - ); + return accumulator.concat(filesToDelete); + }, []); filesToDelete.forEach(file => { rimraf(file, {disableGlob: true}, error => { @@ -206,33 +194,24 @@ class ClientGatewayService extends BaseService { (listAccumulator, torrentDetailValues) => { // Transform the array of torrent detail values to an object with // sensibly named keys. - const processedTorrentDetailValues = torrentDetailValues.reduce( - (valueAccumulator, value, valueIndex) => { - const key = options.propLabels[valueIndex]; - const transformValue = options.valueTransformations[valueIndex]; + const processedTorrentDetailValues = torrentDetailValues.reduce((valueAccumulator, value, valueIndex) => { + const key = options.propLabels[valueIndex]; + const transformValue = options.valueTransformations[valueIndex]; - valueAccumulator[key] = transformValue(value); - return valueAccumulator; - }, - {} - ); + valueAccumulator[key] = transformValue(value); + return valueAccumulator; + }, {}); // Assign values from external reducers to the torrent list object. this.torrentListReducers.forEach(reducer => { const {key, reduce} = reducer; - processedTorrentDetailValues[key] = reduce( - processedTorrentDetailValues - ); + processedTorrentDetailValues[key] = reduce(processedTorrentDetailValues); }); - listAccumulator.torrents[processedTorrentDetailValues.hash] = - processedTorrentDetailValues; + listAccumulator.torrents[processedTorrentDetailValues.hash] = processedTorrentDetailValues; - this.emit( - clientGatewayServiceEvents.PROCESS_TORRENT, - processedTorrentDetailValues - ); + this.emit(clientGatewayServiceEvents.PROCESS_TORRENT, processedTorrentDetailValues); return listAccumulator; }, @@ -244,10 +223,7 @@ class ClientGatewayService extends BaseService { // Provide a unique ID for this specific torrent list. processedTorrentList.id = Date.now(); - this.emit( - clientGatewayServiceEvents.PROCESS_TORRENT_LIST_END, - processedTorrentList - ); + this.emit(clientGatewayServiceEvents.PROCESS_TORRENT_LIST_END, processedTorrentList); return processedTorrentList; } @@ -255,22 +231,20 @@ class ClientGatewayService extends BaseService { processTransferRateResponse(transferRate = [], options) { this.emit(clientGatewayServiceEvents.PROCESS_TRANSFER_RATE_START); - return transferRate.reduce( - (accumulator, value, index) => { - const key = options.propLabels[index]; - const transformValue = options.valueTransformations[index]; + return transferRate.reduce((accumulator, value, index) => { + const key = options.propLabels[index]; + const transformValue = options.valueTransformations[index]; - accumulator[key] = transformValue(value); + accumulator[key] = transformValue(value); - return accumulator; - }, - {} - ); + return accumulator; + }, {}); } testGateway(clientSettings) { if (!clientSettings) { - return this.services.clientRequestManager.methodCall('system.methodExist', ['system.multicall']) + return this.services.clientRequestManager + .methodCall('system.methodExist', ['system.multicall']) .then(this.processClientRequestSuccess) .catch(this.processClientRequestError); } @@ -279,7 +253,7 @@ class ClientGatewayService extends BaseService { socket: clientSettings.socket, socketPath: clientSettings.socketPath, port: clientSettings.port, - host: clientSettings.host + host: clientSettings.host, }, 'system.methodExist', ['system.multicall'] diff --git a/server/services/feedService.js b/server/services/feedService.js index 12a491ff..69962783 100644 --- a/server/services/feedService.js +++ b/server/services/feedService.js @@ -18,7 +18,7 @@ class FeedService extends BaseService { } addFeed(feed, callback) { - this.addItem('feed', feed, (newFeed) => { + this.addItem('feed', feed, newFeed => { this.startNewFeed(newFeed); callback(newFeed); }); @@ -52,14 +52,14 @@ class FeedService extends BaseService { this.rules[newRule.feedID].push(newRule); - const associatedFeed = this.feeds.find((feed) => { + const associatedFeed = this.feeds.find(feed => { return feed.options._id === newRule.feedID; }); if (associatedFeed) { this.handleNewItems({ feed: associatedFeed.options, - items: associatedFeed.getItems() + items: associatedFeed.getItems(), }); } }); @@ -74,17 +74,19 @@ class FeedService extends BaseService { return; } - callback(docs.reduce((memo, item) => { - let type = `${item.type}s`; + callback( + docs.reduce((memo, item) => { + let type = `${item.type}s`; - if (memo[type] == null) { - memo[type] = []; - } + if (memo[type] == null) { + memo[type] = []; + } - memo[type].push(item); + memo[type].push(item); - return memo; - }, {})); + return memo; + }, {}) + ); }); } @@ -93,38 +95,35 @@ class FeedService extends BaseService { } getItemsMatchingRules(feedItems, rules, feed) { - return feedItems.reduce( - (matchedItems, feedItem) => { - rules.forEach(rule => { - const isMatched = (new RegExp(rule.match, 'gi')).test(feedItem[rule.field]); - const isExcluded = rule.exclude !== '' && (new RegExp(rule.exclude, 'gi')).test(feedItem[rule.field]); + return feedItems.reduce((matchedItems, feedItem) => { + rules.forEach(rule => { + const isMatched = new RegExp(rule.match, 'gi').test(feedItem[rule.field]); + const isExcluded = rule.exclude !== '' && new RegExp(rule.exclude, 'gi').test(feedItem[rule.field]); - if (isMatched && !isExcluded) { - const torrentUrls = this.getTorrentUrlsFromItem(feedItem); - const isAlreadyDownloaded = matchedItems.some(matchedItem => { - return torrentUrls.every(url => matchedItem.urls.includes(url)); + if (isMatched && !isExcluded) { + const torrentUrls = this.getTorrentUrlsFromItem(feedItem); + const isAlreadyDownloaded = matchedItems.some(matchedItem => { + return torrentUrls.every(url => matchedItem.urls.includes(url)); + }); + + if (!isAlreadyDownloaded) { + matchedItems.push({ + urls: torrentUrls, + tags: rule.tags, + feedID: rule.feedID, + feedLabel: feed.label, + matchTitle: feedItem.title, + ruleID: rule._id, + ruleLabel: rule.label, + destination: rule.destination, + startOnLoad: rule.startOnLoad, }); - - if (!isAlreadyDownloaded) { - matchedItems.push({ - urls: torrentUrls, - tags: rule.tags, - feedID: rule.feedID, - feedLabel: feed.label, - matchTitle: feedItem.title, - ruleID: rule._id, - ruleLabel: rule.label, - destination: rule.destination, - startOnLoad: rule.startOnLoad - }); - } } - }); + } + }); - return matchedItems; - }, - [] - ); + return matchedItems; + }, []); } getPreviouslyMatchedUrls() { @@ -148,16 +147,13 @@ class FeedService extends BaseService { // If we've got an Array of enclosures, we'll iterate over the values and // look for the url key. if (feedItem.enclosures && Array.isArray(feedItem.enclosures)) { - return feedItem.enclosures.reduce( - (urls, enclosure) => { - if (enclosure.url) { - urls.push(enclosure.url); - } + return feedItem.enclosures.reduce((urls, enclosure) => { + if (enclosure.url) { + urls.push(enclosure.url); + } - return urls; - }, - [] - ); + return urls; + }, []); } // If we've got a Object of enclosures, use url key @@ -191,22 +187,20 @@ class FeedService extends BaseService { const lastAddUrlCallback = () => { const urlsToAdd = this.getUrlsFromItems(itemsToDownload); - this.db.update( - {type: 'matchedTorrents'}, - {$push: {urls: {$each: urlsToAdd}}}, - {upsert: true} - ); + this.db.update({type: 'matchedTorrents'}, {$push: {urls: {$each: urlsToAdd}}}, {upsert: true}); - this.services.notificationService.addNotification(itemsToDownload.map(item => { - return { - id: 'notification.feed.downloaded.torrent', - data: { - feedLabel: item.feedLabel, - ruleLabel: item.ruleLabel, - title: item.matchTitle - } - }; - })); + this.services.notificationService.addNotification( + itemsToDownload.map(item => { + return { + id: 'notification.feed.downloaded.torrent', + data: { + feedLabel: item.feedLabel, + ruleLabel: item.ruleLabel, + title: item.matchTitle, + }, + }; + }) + ); this.services.torrentService.fetchTorrentList(); }; @@ -218,24 +212,16 @@ class FeedService extends BaseService { urls: item.urls, destination: item.destination, start: item.startOnLoad, - tags: item.tags + tags: item.tags, }, () => { if (index === itemsToDownload.length - 1) { lastAddUrlCallback(); } - this.db.update( - {_id: item.ruleID}, - {$inc: {count: 1}}, - {upsert: true} - ); + this.db.update({_id: item.ruleID}, {$inc: {count: 1}}, {upsert: true}); - this.db.update( - {_id: item.feedID}, - {$inc: {count: 1}}, - {upsert: true} - ); + this.db.update({_id: item.feedID}, {$inc: {count: 1}}, {upsert: true}); } ); }); @@ -252,16 +238,19 @@ class FeedService extends BaseService { } // Create two arrays, one for feeds and one for rules. - const feedsSummary = docs.reduce((accumulator, doc) => { - if (doc.type === 'feed' || doc.type === 'rule') { - accumulator[`${doc.type}s`].push(doc); - } + const feedsSummary = docs.reduce( + (accumulator, doc) => { + if (doc.type === 'feed' || doc.type === 'rule') { + accumulator[`${doc.type}s`].push(doc); + } - return accumulator; - }, {feeds: [], rules: []}); + return accumulator; + }, + {feeds: [], rules: []} + ); // Add all download rules to the local state. - feedsSummary.rules.forEach((rule) => { + feedsSummary.rules.forEach(rule => { if (this.rules[rule.feedID] == null) { this.rules[rule.feedID] = []; } @@ -270,7 +259,7 @@ class FeedService extends BaseService { }); // Initiate all feeds. - feedsSummary.feeds.forEach((feed) => { + feedsSummary.feeds.forEach(feed => { this.startNewFeed(feed); }); }); @@ -279,9 +268,12 @@ class FeedService extends BaseService { isAlreadyDownloaded(torrentURLs, downloadedTorrents) { torrentURLs = _.castArray(torrentURLs); - return downloadedTorrents.urls && downloadedTorrents.urls.some(url => { - return torrentURLs.includes(url); - }); + return ( + downloadedTorrents.urls && + downloadedTorrents.urls.some(url => { + return torrentURLs.includes(url); + }) + ); } loadDatabase() { @@ -290,7 +282,7 @@ class FeedService extends BaseService { const db = new Datastore({ autoload: true, - filename: path.join(config.dbPath, userId, 'settings', 'feeds.db') + filename: path.join(config.dbPath, userId, 'settings', 'feeds.db'), }); this.isDBReady = true; return db; diff --git a/server/services/historyService.js b/server/services/historyService.js index d1d4997c..140750f2 100644 --- a/server/services/historyService.js +++ b/server/services/historyService.js @@ -9,8 +9,7 @@ const methodCallUtil = require('../util/methodCallUtil'); const objectUtil = require('../../shared/util/objectUtil'); const transferSummaryPropMap = require('../constants/transferSummaryPropMap'); -const transferSummaryMethodCallConfig = methodCallUtil - .getMethodCallConfigFromPropMap(transferSummaryPropMap); +const transferSummaryMethodCallConfig = methodCallUtil.getMethodCallConfigFromPropMap(transferSummaryPropMap); const processData = (opts, callback, data, error) => { if (error) { @@ -20,13 +19,18 @@ const processData = (opts, callback, data, error) => { data = data.slice(data.length - config.maxHistoryStates); - callback(data.reduce((accumulator, snapshot) => { - accumulator.download.push(snapshot.dn); - accumulator.upload.push(snapshot.up); - accumulator.timestamps.push(snapshot.ts); + callback( + data.reduce( + (accumulator, snapshot) => { + accumulator.download.push(snapshot.dn); + accumulator.upload.push(snapshot.up); + accumulator.timestamps.push(snapshot.ts); - return accumulator; - }, {upload: [], download: [], timestamps: []})); + return accumulator; + }, + {upload: [], download: [], timestamps: []} + ) + ); }; class HistoryService extends BaseService { @@ -45,7 +49,7 @@ class HistoryService extends BaseService { this.yearSnapshot = new HistoryEra(this.user, { interval: 1000 * 60 * 60 * 24 * 7, // 7 days maxTime: 0, // infinite - name: 'yearSnapshot' + name: 'yearSnapshot', }); this.monthSnapshot = new HistoryEra(this.user, { @@ -53,7 +57,7 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 60 * 24 * 365, // 365 days name: 'monthSnapshot', nextEraUpdateInterval: 1000 * 60 * 60 * 24 * 7, // 7 days - nextEra: this.yearSnapshot + nextEra: this.yearSnapshot, }); this.weekSnapshot = new HistoryEra(this.user, { @@ -61,7 +65,7 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 60 * 24 * 7 * 24, // 24 weeks name: 'weekSnapshot', nextEraUpdateInterval: 1000 * 60 * 60 * 12, // 12 hours - nextEra: this.monthSnapshot + nextEra: this.monthSnapshot, }); this.daySnapshot = new HistoryEra(this.user, { @@ -69,7 +73,7 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 60 * 24 * 30, // 30 days name: 'daySnapshot', nextEraUpdateInterval: 1000 * 60 * 60 * 4, // 4 hours - nextEra: this.weekSnapshot + nextEra: this.weekSnapshot, }); this.hourSnapshot = new HistoryEra(this.user, { @@ -77,7 +81,7 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 60 * 24, // 24 hours name: 'hourSnapshot', nextEraUpdateInterval: 1000 * 60 * 60, // 60 minutes - nextEra: this.daySnapshot + nextEra: this.daySnapshot, }); this.thirtyMinSnapshot = new HistoryEra(this.user, { @@ -85,7 +89,7 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 30, // 30 minutes name: 'thirtyMinSnapshot', nextEraUpdateInterval: 1000 * 60 * 15, // 15 minutes - nextEra: this.hourSnapshot + nextEra: this.hourSnapshot, }); this.fiveMinSnapshot = new HistoryEra(this.user, { @@ -93,47 +97,37 @@ class HistoryService extends BaseService { maxTime: 1000 * 60 * 5, // 5 minutes name: 'fiveMinSnapshot', nextEraUpdateInterval: 1000 * 20, // 20 seconds - nextEra: this.thirtyMinSnapshot + nextEra: this.thirtyMinSnapshot, }); this.fetchCurrentTransferSummary(); - } + } checkSnapshotDiffs() { Object.keys(historySnapshotTypes).forEach(snapshotType => { - this.getHistory( - {snapshot: historySnapshotTypes[snapshotType]}, - (nextSnapshot, error) => { - if (error) { - return; - } - - const lastSnapshot = this.lastSnapshots[snapshotType] || {}; - const {timestamps = []} = lastSnapshot; - const nextLastTimestamp = timestamps[timestamps.length - 1]; - const prevLastTimestamp = nextSnapshot.timestamps[ - nextSnapshot.timestamps.length - 1 - ]; - - if (nextLastTimestamp !== prevLastTimestamp) { - this.emit( - historyServiceEvents[`${snapshotType}_SNAPSHOT_FULL_UPDATE`], - { - id: nextLastTimestamp, - data: nextSnapshot - } - ); - } - - this.lastSnapshots[snapshotType] = nextSnapshot; + this.getHistory({snapshot: historySnapshotTypes[snapshotType]}, (nextSnapshot, error) => { + if (error) { + return; } - ); + + const lastSnapshot = this.lastSnapshots[snapshotType] || {}; + const {timestamps = []} = lastSnapshot; + const nextLastTimestamp = timestamps[timestamps.length - 1]; + const prevLastTimestamp = nextSnapshot.timestamps[nextSnapshot.timestamps.length - 1]; + + if (nextLastTimestamp !== prevLastTimestamp) { + this.emit(historyServiceEvents[`${snapshotType}_SNAPSHOT_FULL_UPDATE`], { + id: nextLastTimestamp, + data: nextSnapshot, + }); + } + + this.lastSnapshots[snapshotType] = nextSnapshot; + }); }); } - deferFetchTransferSummary( - interval = (config.torrentClientPollInterval || 2000) - ) { + deferFetchTransferSummary(interval = config.torrentClientPollInterval || 2000) { this.pollTimeout = setTimeout(this.fetchCurrentTransferSummary, interval); } @@ -155,7 +149,7 @@ class HistoryService extends BaseService { getTransferSummary() { return { id: Date.now(), - transferSummary: this.transferSummary + transferSummary: this.transferSummary, }; } @@ -180,26 +174,20 @@ class HistoryService extends BaseService { } handleFetchTransferSummarySuccess(nextTransferSummary) { - const summaryDiff = objectUtil.getDiff( - this.transferSummary, - nextTransferSummary - ); + const summaryDiff = objectUtil.getDiff(this.transferSummary, nextTransferSummary); if (summaryDiff.length > 0) { - this.emit( - historyServiceEvents.TRANSFER_SUMMARY_DIFF_CHANGE, - { - diff: summaryDiff, - id: Date.now() - } - ); + this.emit(historyServiceEvents.TRANSFER_SUMMARY_DIFF_CHANGE, { + diff: summaryDiff, + id: Date.now(), + }); } this.errorCount = 0; this.transferSummary = nextTransferSummary; this.fiveMinSnapshot.addData({ upload: nextTransferSummary.upRate, - download: nextTransferSummary.downRate + download: nextTransferSummary.downRate, }); this.checkSnapshotDiffs(); @@ -214,10 +202,7 @@ class HistoryService extends BaseService { // If more than consecutive errors have occurred, then we delay the next // request. if (++this.errorCount >= 3) { - nextInterval = Math.max( - nextInterval + this.errorCount * nextInterval / 4, - 1000 * 60 - ); + nextInterval = Math.max(nextInterval + (this.errorCount * nextInterval) / 4, 1000 * 60); } this.deferFetchTransferSummary(nextInterval); diff --git a/server/services/index.js b/server/services/index.js index 3631dbde..da894257 100644 --- a/server/services/index.js +++ b/server/services/index.js @@ -20,7 +20,7 @@ const allServiceMaps = [ historyServices, notificationServices, taxonomyServices, - torrentServices + torrentServices, ]; const getService = ({servicesMap, service, user}) => { @@ -110,7 +110,7 @@ const getAllServices = user => { get torrentService() { return getTorrentService(user); - } + }, }; }; @@ -135,5 +135,5 @@ module.exports = { getNotificationService, getTaxonomyService, getTorrentService, - updateUserServices -}; \ No newline at end of file + updateUserServices, +}; diff --git a/server/services/notificationService.js b/server/services/notificationService.js index d26e8cf4..00b10165 100644 --- a/server/services/notificationService.js +++ b/server/services/notificationService.js @@ -35,7 +35,7 @@ class NotificationService extends BaseService { ts: timestamp, data: notification.data, id: notification.id, - read: false + read: false, }; }); @@ -43,7 +43,7 @@ class NotificationService extends BaseService { } clearNotifications(options, callback) { - this.db.remove({}, {multi: true}, (err) => { + this.db.remove({}, {multi: true}, err => { if (err) { callback(null, err); return; @@ -62,7 +62,7 @@ class NotificationService extends BaseService { if (err) { this.count = Object.assign({}, INITIAL_COUNT_VALUE); } else { - docs.forEach((notification) => { + docs.forEach(notification => { if (notification.read) { this.count.read++; } else { @@ -78,13 +78,10 @@ class NotificationService extends BaseService { } emitUpdate() { - this.emit( - notificationServiceEvents.NOTIFICATION_COUNT_CHANGE, - { - id: Date.now(), - data: this.count - } - ); + this.emit(notificationServiceEvents.NOTIFICATION_COUNT_CHANGE, { + id: Date.now(), + data: this.count, + }); } getNotificationCount() { @@ -110,9 +107,7 @@ class NotificationService extends BaseService { .limit(Number(query.limit) || DEFAULT_QUERY_LIMIT) .exec(queryCallback); } else { - sortedNotifications - .limit(Number(query.limit) || DEFAULT_QUERY_LIMIT) - .exec(queryCallback); + sortedNotifications.limit(Number(query.limit) || DEFAULT_QUERY_LIMIT).exec(queryCallback); } } @@ -121,7 +116,7 @@ class NotificationService extends BaseService { const db = new Datastore({ autoload: true, - filename: path.join(config.dbPath, this.user._id, 'notifications.db') + filename: path.join(config.dbPath, this.user._id, 'notifications.db'), }); this.ready = true; diff --git a/server/services/taxonomyService.js b/server/services/taxonomyService.js index 28011864..24c0b282 100644 --- a/server/services/taxonomyService.js +++ b/server/services/taxonomyService.js @@ -24,20 +24,11 @@ class TaxonomyService extends BaseService { const clientGatewayService = this.services.clientGatewayService; - clientGatewayService.on( - clientGatewayServiceEvents.PROCESS_TORRENT_LIST_START, - this.handleProcessTorrentListStart - ); + clientGatewayService.on(clientGatewayServiceEvents.PROCESS_TORRENT_LIST_START, this.handleProcessTorrentListStart); - clientGatewayService.on( - clientGatewayServiceEvents.PROCESS_TORRENT_LIST_END, - this.handleProcessTorrentListEnd - ); + clientGatewayService.on(clientGatewayServiceEvents.PROCESS_TORRENT_LIST_END, this.handleProcessTorrentListEnd); - clientGatewayService.on( - clientGatewayServiceEvents.PROCESS_TORRENT, - this.handleProcessTorrent - ); + clientGatewayService.on(clientGatewayServiceEvents.PROCESS_TORRENT, this.handleProcessTorrent); } destroy() { @@ -53,10 +44,7 @@ class TaxonomyService extends BaseService { this.handleProcessTorrentListEnd ); - clientGatewayService.removeListener( - clientGatewayServiceEvents.PROCESS_TORRENT, - this.handleProcessTorrent - ); + clientGatewayService.removeListener(clientGatewayServiceEvents.PROCESS_TORRENT, this.handleProcessTorrent); } destroy() { @@ -72,10 +60,7 @@ class TaxonomyService extends BaseService { this.handleProcessTorrentListEnd ); - clientGatewayService.removeListener( - clientGatewayServiceEvents.PROCESS_TORRENT, - this.handleProcessTorrent - ); + clientGatewayService.removeListener(clientGatewayServiceEvents.PROCESS_TORRENT, this.handleProcessTorrent); } getTaxonomy() { @@ -84,8 +69,8 @@ class TaxonomyService extends BaseService { taxonomy: { statusCounts: this.statusCounts, tagCounts: this.tagCounts, - trackerCounts: this.trackerCounts - } + trackerCounts: this.trackerCounts, + }, }; } @@ -111,18 +96,9 @@ class TaxonomyService extends BaseService { this.trackerCounts.all = length; const taxonomyDiffs = { - statusCounts: objectUtil.getDiff( - this.lastStatusCounts, - this.statusCounts - ), - tagCounts: objectUtil.getDiff( - this.lastTagCounts, - this.tagCounts - ), - trackerCounts: objectUtil.getDiff( - this.lastTrackerCounts, - this.trackerCounts - ) + statusCounts: objectUtil.getDiff(this.lastStatusCounts, this.statusCounts), + tagCounts: objectUtil.getDiff(this.lastTagCounts, this.tagCounts), + trackerCounts: objectUtil.getDiff(this.lastTrackerCounts, this.trackerCounts), }; const didDiffChange = Object.keys(taxonomyDiffs).some(diffKey => { @@ -130,13 +106,10 @@ class TaxonomyService extends BaseService { }); if (didDiffChange) { - this.emit( - taxonomyServiceEvents.TAXONOMY_DIFF_CHANGE, - { - diff: taxonomyDiffs, - id: Date.now() - } - ); + this.emit(taxonomyServiceEvents.TAXONOMY_DIFF_CHANGE, { + diff: taxonomyDiffs, + id: Date.now(), + }); } } diff --git a/server/services/torrentService.js b/server/services/torrentService.js index f69a268c..db24b066 100644 --- a/server/services/torrentService.js +++ b/server/services/torrentService.js @@ -11,8 +11,7 @@ const torrentListPropMap = require('../constants/torrentListPropMap'); const torrentServiceEvents = require('../constants/torrentServiceEvents'); const torrentStatusMap = require('../../shared/constants/torrentStatusMap'); -const torrentListMethodCallConfig = methodCallUtil - .getMethodCallConfigFromPropMap(torrentListPropMap); +const torrentListMethodCallConfig = methodCallUtil.getMethodCallConfigFromPropMap(torrentListPropMap); class TorrentService extends BaseService { constructor() { @@ -32,28 +31,22 @@ class TorrentService extends BaseService { clientGatewayService.addTorrentListReducer({ key: 'status', - reduce: this.getTorrentStatusFromDetails + reduce: this.getTorrentStatusFromDetails, }); clientGatewayService.addTorrentListReducer({ key: 'percentComplete', - reduce: this.getTorrentPercentCompleteFromDetails + reduce: this.getTorrentPercentCompleteFromDetails, }); clientGatewayService.addTorrentListReducer({ key: 'eta', - reduce: this.getTorrentETAFromDetails + reduce: this.getTorrentETAFromDetails, }); - clientGatewayService.on( - clientGatewayServiceEvents.PROCESS_TORRENT, - this.handleTorrentProcessed - ); + clientGatewayService.on(clientGatewayServiceEvents.PROCESS_TORRENT, this.handleTorrentProcessed); - clientGatewayService.on( - clientGatewayServiceEvents.TORRENTS_REMOVED, - this.handleTorrentsRemoved - ); + clientGatewayService.on(clientGatewayServiceEvents.TORRENTS_REMOVED, this.handleTorrentsRemoved); this.fetchTorrentList(); } @@ -69,39 +62,30 @@ class TorrentService extends BaseService { // We definitely don't need to look for deleted torrents if the number // of new torrents is equal to the difference between next torrent list // length and previous torrent list length. - let shouldLookForDeletedTorrents = nextTorrentListSummary.length < - this.torrentListSummary.length; + let shouldLookForDeletedTorrents = nextTorrentListSummary.length < this.torrentListSummary.length; if (newTorrentCount > 0) { if (nextTorrentListSummary.length >= this.torrentListSummary.length) { shouldLookForDeletedTorrents = true; } - if ( - newTorrentCount === nextTorrentListSummary.length - - this.torrentListSummary.length - ) { + if (newTorrentCount === nextTorrentListSummary.length - this.torrentListSummary.length) { shouldLookForDeletedTorrents = false; } } if (shouldLookForDeletedTorrents) { - Object.keys(this.torrentListSummary.torrents).forEach( - (hash) => { - if (nextTorrentListSummary.torrents[hash] == null) { - diff[hash] = { - action: serverEventTypes.TORRENT_LIST_ACTION_TORRENT_DELETED - }; - } - }, - {} - ); + Object.keys(this.torrentListSummary.torrents).forEach(hash => { + if (nextTorrentListSummary.torrents[hash] == null) { + diff[hash] = { + action: serverEventTypes.TORRENT_LIST_ACTION_TORRENT_DELETED, + }; + } + }, {}); } } - deferFetchTorrentList( - interval = (config.torrentClientPollInterval || 2000) - ) { + deferFetchTorrentList(interval = config.torrentClientPollInterval || 2000) { this.pollTimeout = setTimeout(this.fetchTorrentList, interval); } @@ -131,9 +115,7 @@ class TorrentService extends BaseService { } getTorrentPercentCompleteFromDetails(torrentDetails) { - const percentComplete = ( - torrentDetails.bytesDone / torrentDetails.sizeBytes * 100 - ); + const percentComplete = (torrentDetails.bytesDone / torrentDetails.sizeBytes) * 100; if (percentComplete > 0 && percentComplete < 10) { return Number(percentComplete.toFixed(2)); @@ -145,15 +127,7 @@ class TorrentService extends BaseService { } getTorrentStatusFromDetails(torrentDetails) { - const { - isHashChecking, - isComplete, - isOpen, - upRate, - downRate, - state, - message - } = torrentDetails; + const {isHashChecking, isComplete, isOpen, upRate, downRate, state, message} = torrentDetails; const torrentStatus = []; @@ -208,56 +182,44 @@ class TorrentService extends BaseService { let newTorrentCount = 0; // Get the diff... - const diff = Object.keys(nextTorrentListSummary.torrents).reduce( - (accumulator, hash) => { - const currentTorrentDetails = this.torrentListSummary.torrents[hash]; - const nextTorrentDetails = nextTorrentListSummary.torrents[hash]; + const diff = Object.keys(nextTorrentListSummary.torrents).reduce((accumulator, hash) => { + const currentTorrentDetails = this.torrentListSummary.torrents[hash]; + const nextTorrentDetails = nextTorrentListSummary.torrents[hash]; - // If the current torrent list doesn't contain any details for this - // hash, then it's a brand new torrent, so every detail is part of the - // diff. - if (currentTorrentDetails == null) { - accumulator[hash] = { - action: serverEventTypes.TORRENT_LIST_ACTION_TORRENT_ADDED, - data: nextTorrentDetails - }; + // If the current torrent list doesn't contain any details for this + // hash, then it's a brand new torrent, so every detail is part of the + // diff. + if (currentTorrentDetails == null) { + accumulator[hash] = { + action: serverEventTypes.TORRENT_LIST_ACTION_TORRENT_ADDED, + data: nextTorrentDetails, + }; - // Track the number of new torrents added. - newTorrentCount++; - } else { - Object.keys(nextTorrentDetails).forEach((propKey) => { - // If one of the details is inequal, we need to add it to the diff. - if (!deepEqual( - currentTorrentDetails[propKey], - nextTorrentDetails[propKey] - )) { - // Initialize with an empty object when this is the first known - // inequal property. - if (accumulator[hash] == null) { - accumulator[hash] = { - action: ( - serverEventTypes.TORRENT_LIST_ACTION_TORRENT_DETAIL_UPDATED - ), - data: {} - }; - } - - // Add the diff details. - accumulator[hash].data[propKey] = nextTorrentDetails[propKey]; + // Track the number of new torrents added. + newTorrentCount++; + } else { + Object.keys(nextTorrentDetails).forEach(propKey => { + // If one of the details is inequal, we need to add it to the diff. + if (!deepEqual(currentTorrentDetails[propKey], nextTorrentDetails[propKey])) { + // Initialize with an empty object when this is the first known + // inequal property. + if (accumulator[hash] == null) { + accumulator[hash] = { + action: serverEventTypes.TORRENT_LIST_ACTION_TORRENT_DETAIL_UPDATED, + data: {}, + }; } - }); - } - return accumulator; - }, - {} - ); + // Add the diff details. + accumulator[hash].data[propKey] = nextTorrentDetails[propKey]; + } + }); + } - this.assignDeletedTorrentsToDiff( - diff, - nextTorrentListSummary, - {newTorrentCount} - ); + return accumulator; + }, {}); + + this.assignDeletedTorrentsToDiff(diff, nextTorrentListSummary, {newTorrentCount}); return diff; } @@ -268,10 +230,7 @@ class TorrentService extends BaseService { // If more than consecutive errors have occurred, then we delay the next // request. if (++this.errorCount >= 3) { - nextInterval = Math.max( - nextInterval + this.errorCount * nextInterval / 4, - 1000 * 60 - ); + nextInterval = Math.max(nextInterval + (this.errorCount * nextInterval) / 4, 1000 * 60); } this.deferFetchTorrentList(nextInterval); @@ -286,10 +245,7 @@ class TorrentService extends BaseService { handleFetchTorrentListSuccess(nextTorrentListSummary) { const diff = this.getTorrentListDiff(nextTorrentListSummary); if (Object.keys(diff).length > 0) { - this.emit( - torrentServiceEvents.TORRENT_LIST_DIFF_CHANGE, - {diff, id: nextTorrentListSummary.id} - ); + this.emit(torrentServiceEvents.TORRENT_LIST_DIFF_CHANGE, {diff, id: nextTorrentListSummary.id}); } this.torrentListSummary = nextTorrentListSummary; @@ -301,14 +257,12 @@ class TorrentService extends BaseService { } handleTorrentProcessed(nextTorrentDetails) { - const prevTorrentDetails = ( - this.torrentListSummary.torrents[nextTorrentDetails.hash] - ); + const prevTorrentDetails = this.torrentListSummary.torrents[nextTorrentDetails.hash]; if (this.hasTorrentFinished(prevTorrentDetails, nextTorrentDetails)) { this.services.notificationService.addNotification({ id: 'notification.torrent.finished', - data: {name: nextTorrentDetails.name} + data: {name: nextTorrentDetails.name}, }); } } @@ -317,9 +271,7 @@ class TorrentService extends BaseService { const {status = []} = prevData; return ( - !(status.includes(torrentStatusMap.checking)) - && prevData.percentComplete < 100 - && nextData.percentComplete === 100 + !status.includes(torrentStatusMap.checking) && prevData.percentComplete < 100 && nextData.percentComplete === 100 ); } diff --git a/server/util/ajaxUtil.js b/server/util/ajaxUtil.js index 0a3ab86a..e03e7428 100644 --- a/server/util/ajaxUtil.js +++ b/server/util/ajaxUtil.js @@ -1,7 +1,7 @@ 'use strict'; let ajaxUtil = { - getResponseFn: (res) => { + getResponseFn: res => { return (data, error) => { if (error) { if (process.env.NODE_ENV === 'development') { @@ -10,7 +10,7 @@ let ajaxUtil = { if (typeof error === 'string') { error = { - message: error + message: error, }; } @@ -20,7 +20,7 @@ let ajaxUtil = { res.json(data); } }; - } + }, }; module.exports = ajaxUtil; diff --git a/server/util/clientResponseUtil.js b/server/util/clientResponseUtil.js index abcecfbf..6fdbabe2 100644 --- a/server/util/clientResponseUtil.js +++ b/server/util/clientResponseUtil.js @@ -21,7 +21,11 @@ const getFileTreeFromPathsArr = (tree, directory, file, depth) => { } tree.directories[directory] = getFileTreeFromPathsArr( - tree.directories[directory], file.pathComponents[depth], file, depth); + tree.directories[directory], + file.pathComponents[depth], + file, + depth + ); } else { if (!tree.files) { tree.files = []; @@ -57,18 +61,21 @@ let clientResponseUtil = { // object contains all of the requested keys and its value. We add an index // for each item, a requirement for file lists. return clientResponse.map((listItem, index) => { - return listItem.reduce((nestedMemo, value, nestedIndex) => { - nestedMemo[requestedKeys[nestedIndex]] = value; + return listItem.reduce( + (nestedMemo, value, nestedIndex) => { + nestedMemo[requestedKeys[nestedIndex]] = value; - return nestedMemo; - }, {index}); + return nestedMemo; + }, + {index} + ); }, []); } }, processFile(file) { file.filename = file.pathComponents[file.pathComponents.length - 1]; - file.percentComplete = (file.completedChunks / file.sizeChunks * 100).toFixed(0); + file.percentComplete = ((file.completedChunks / file.sizeChunks) * 100).toFixed(0); delete file.completedChunks; delete file.pathComponents; @@ -88,10 +95,7 @@ let clientResponseUtil = { let fileTree = {}; if (peersData && peersData.length) { - peers = clientResponseUtil.mapPropsToResponse( - torrentPeerPropsMap.props, - peersData - ).map((peer) => { + peers = clientResponseUtil.mapPropsToResponse(torrentPeerPropsMap.props, peersData).map(peer => { let geoData = geoip.lookup(peer.address) || {}; peer.country = geoData.country; @@ -104,10 +108,7 @@ let clientResponseUtil = { } if (filesData && filesData.length) { - files = clientResponseUtil.mapPropsToResponse( - torrentFilePropsMap.props, - filesData - ); + files = clientResponseUtil.mapPropsToResponse(torrentFilePropsMap.props, filesData); fileTree = files.reduce((memo, file) => { return getFileTreeFromPathsArr(memo, file.pathComponents[0], file); @@ -115,14 +116,11 @@ let clientResponseUtil = { } if (trackerData && trackerData.length) { - trackers = clientResponseUtil.mapPropsToResponse( - torrentTrackerPropsMap.props, - trackerData - ); + trackers = clientResponseUtil.mapPropsToResponse(torrentTrackerPropsMap.props, trackerData); } return {peers, trackers, fileTree}; - } + }, }; module.exports = clientResponseUtil; diff --git a/server/util/mediainfo.js b/server/util/mediainfo.js index 85f88897..527c5691 100644 --- a/server/util/mediainfo.js +++ b/server/util/mediainfo.js @@ -10,28 +10,30 @@ module.exports = { const {hash} = options; if (hash == null) { - callback(null, { error: 'Hash must be defined' }); + callback(null, {error: 'Hash must be defined'}); return; } const selectedTorrent = torrentService.getTorrent(hash); try { - child_process.execFile( - 'mediainfo', [selectedTorrent.basePath], { maxBuffer: 1024 * 2000 }, function (error, stdout, stderr) { - if (error) { - callback(null, { error }); - return; - } - - if (stderr) { - callback(null, { error: stderr }); - return; - } - - callback({ output: stdout }); + child_process.execFile('mediainfo', [selectedTorrent.basePath], {maxBuffer: 1024 * 2000}, function( + error, + stdout, + stderr + ) { + if (error) { + callback(null, {error}); + return; } - ); + + if (stderr) { + callback(null, {error: stderr}); + return; + } + + callback({output: stdout}); + }); } catch (childProcessError) { - callback(null, { error: childProcessError }); + callback(null, {error: childProcessError}); } - } + }, }; diff --git a/server/util/methodCallUtil.js b/server/util/methodCallUtil.js index a26d69fd..56230d4f 100644 --- a/server/util/methodCallUtil.js +++ b/server/util/methodCallUtil.js @@ -21,10 +21,10 @@ const methodCallUtil = { { methodCalls: [], propLabels: [], - valueTransformations: [] + valueTransformations: [], } ); - } + }, }; module.exports = methodCallUtil; diff --git a/server/util/rTorrentPropMap.js b/server/util/rTorrentPropMap.js index 31e66f7d..7eed427b 100644 --- a/server/util/rTorrentPropMap.js +++ b/server/util/rTorrentPropMap.js @@ -5,8 +5,8 @@ const RTORRENT_PROPS_MAP = { uploadThrottle: 'throttle.global_up.max_rate', downloadRate: 'throttle.global_down.rate', downloadTotal: 'throttle.global_down.total', - downloadThrottle: 'throttle.global_down.max_rate' - } + downloadThrottle: 'throttle.global_down.max_rate', + }, }; module.exports = RTORRENT_PROPS_MAP; diff --git a/server/util/scgiUtil.js b/server/util/scgiUtil.js index cb0295f4..92053520 100644 --- a/server/util/scgiUtil.js +++ b/server/util/scgiUtil.js @@ -7,8 +7,8 @@ const NULL_CHAR = String.fromCharCode(0); const methodCall = (connectionMethod, methodName, parameters) => { return new Promise((resolve, reject) => { const networkConfiguration = connectionMethod.socket - ? { path: connectionMethod.socketPath } - : { port: connectionMethod.port, host: connectionMethod.host }; + ? {path: connectionMethod.socketPath} + : {port: connectionMethod.port, host: connectionMethod.host}; const deserializer = new Deserializer('utf8'); const stream = net.connect(networkConfiguration); @@ -17,13 +17,10 @@ const methodCall = (connectionMethod, methodName, parameters) => { stream.setEncoding('UTF8'); - const headerItems = [ - `CONTENT_LENGTH${NULL_CHAR}${xmlLength}${NULL_CHAR}`, - `SCGI${NULL_CHAR}1${NULL_CHAR}` - ]; + const headerItems = [`CONTENT_LENGTH${NULL_CHAR}${xmlLength}${NULL_CHAR}`, `SCGI${NULL_CHAR}1${NULL_CHAR}`]; const headerLength = headerItems.reduce((accumulator, headerItem) => { - return accumulator += headerItem.length; + return (accumulator += headerItem.length); }, 0); stream.write(`${headerLength}:${headerItems.join('')},${xml}`); @@ -35,4 +32,4 @@ const methodCall = (connectionMethod, methodName, parameters) => { }); }; -module.exports = {methodCall}; \ No newline at end of file +module.exports = {methodCall}; diff --git a/shared/constants/clientSettingsMap.js b/shared/constants/clientSettingsMap.js index 101f4f1f..d2e06cf4 100644 --- a/shared/constants/clientSettingsMap.js +++ b/shared/constants/clientSettingsMap.js @@ -50,7 +50,7 @@ let clientSettingsMap = objectUtil.reflect({ throttleMinPeersNormal: 'throttle.min_peers.normal', throttleMinPeersSeed: 'throttle.min_peers.seed', trackersNumWant: 'trackers.numwant', - trackersUseUdp: 'trackers.use_udp' + trackersUseUdp: 'trackers.use_udp', }); clientSettingsMap.defaults = [ @@ -99,7 +99,7 @@ clientSettingsMap.defaults = [ 'throttleMinPeersNormal', 'throttleMinPeersSeed', 'trackersNumWant', - 'trackersUseUdp' + 'trackersUseUdp', ]; module.exports = clientSettingsMap; diff --git a/shared/constants/diffActionTypes.js b/shared/constants/diffActionTypes.js index 926d1129..bc79cd53 100644 --- a/shared/constants/diffActionTypes.js +++ b/shared/constants/diffActionTypes.js @@ -1,10 +1,6 @@ 'use strict'; -const diffActionTypes = [ - 'ITEM_ADDED', - 'ITEM_CHANGED', - 'ITEM_REMOVED' -]; +const diffActionTypes = ['ITEM_ADDED', 'ITEM_CHANGED', 'ITEM_REMOVED']; module.exports = diffActionTypes.reduce((memo, key) => { memo[key] = key; diff --git a/shared/constants/historySnapshotTypes.js b/shared/constants/historySnapshotTypes.js index 592183b9..e7b3fa9f 100644 --- a/shared/constants/historySnapshotTypes.js +++ b/shared/constants/historySnapshotTypes.js @@ -8,7 +8,7 @@ const historySnapshotTypes = { HOUR: 'hour', WEEK: 'week', MONTH: 'month', - YEAR: 'year' + YEAR: 'year', }; module.exports = objectUtil.reflect(historySnapshotTypes); diff --git a/shared/constants/serverEventTypes.js b/shared/constants/serverEventTypes.js index 5572b07e..0f7edcac 100644 --- a/shared/constants/serverEventTypes.js +++ b/shared/constants/serverEventTypes.js @@ -12,7 +12,7 @@ const serverEventTypes = [ 'TORRENT_LIST_FULL_UPDATE', 'TRANSFER_HISTORY_FULL_UPDATE', 'TRANSFER_SUMMARY_DIFF_CHANGE', - 'TRANSFER_SUMMARY_FULL_UPDATE' + 'TRANSFER_SUMMARY_FULL_UPDATE', ]; module.exports = objectUtil.createStringMapFromArray(serverEventTypes); diff --git a/shared/constants/torrentFilePropsMap.js b/shared/constants/torrentFilePropsMap.js index 46a96f41..60a00870 100644 --- a/shared/constants/torrentFilePropsMap.js +++ b/shared/constants/torrentFilePropsMap.js @@ -1,22 +1,8 @@ 'use strict'; const torrentFilePropsMap = { - props: [ - 'path', - 'pathComponents', - 'priority', - 'sizeBytes', - 'sizeChunks', - 'completedChunks' - ], - methods: [ - 'f.path=', - 'f.path_components=', - 'f.priority=', - 'f.size_bytes=', - 'f.size_chunks=', - 'f.completed_chunks=' - ] + props: ['path', 'pathComponents', 'priority', 'sizeBytes', 'sizeChunks', 'completedChunks'], + methods: ['f.path=', 'f.path_components=', 'f.priority=', 'f.size_bytes=', 'f.size_chunks=', 'f.completed_chunks='], }; module.exports = torrentFilePropsMap; diff --git a/shared/constants/torrentPeerPropsMap.js b/shared/constants/torrentPeerPropsMap.js index 751656bd..fe43f0c2 100644 --- a/shared/constants/torrentPeerPropsMap.js +++ b/shared/constants/torrentPeerPropsMap.js @@ -13,7 +13,7 @@ const torrentPeerPropsMap = { 'peerRate', 'peerTotal', 'isEncrypted', - 'isIncoming' + 'isIncoming', ], methods: [ 'p.address=', @@ -27,8 +27,8 @@ const torrentPeerPropsMap = { 'p.peer_rate=', 'p.peer_total=', 'p.is_encrypted=', - 'p.is_incoming=' - ] + 'p.is_incoming=', + ], }; module.exports = torrentPeerPropsMap; diff --git a/shared/constants/torrentStatusMap.js b/shared/constants/torrentStatusMap.js index 0369439c..e989bd53 100644 --- a/shared/constants/torrentStatusMap.js +++ b/shared/constants/torrentStatusMap.js @@ -13,11 +13,9 @@ const torrentStatusMap = objectUtil.reflect({ s: 'stopped', e: 'error', i: 'inactive', - a: 'active' + a: 'active', }); -torrentStatusMap.statusShorthand = [ - 'ch', 'sd', 'p', 'c', 'd', 'ad', 'au', 's', 'e', 'i', 'a' -]; +torrentStatusMap.statusShorthand = ['ch', 'sd', 'p', 'c', 'd', 'ad', 'au', 's', 'e', 'i', 'a']; module.exports = torrentStatusMap; diff --git a/shared/constants/torrentTrackerPropsMap.js b/shared/constants/torrentTrackerPropsMap.js index 093b0e96..c1f5805e 100644 --- a/shared/constants/torrentTrackerPropsMap.js +++ b/shared/constants/torrentTrackerPropsMap.js @@ -1,22 +1,8 @@ 'use strict'; const torrentTrackerPropsMap = { - props: [ - 'group', - 'url', - 'id', - 'minInterval', - 'normalInterval', - 'type' - ], - methods: [ - 't.group=', - 't.url=', - 't.id=', - 't.min_interval=', - 't.normal_interval=', - 't.type=' - ] + props: ['group', 'url', 'id', 'minInterval', 'normalInterval', 'type'], + methods: ['t.group=', 't.url=', 't.id=', 't.min_interval=', 't.normal_interval=', 't.type='], }; module.exports = torrentTrackerPropsMap; diff --git a/shared/util/formatUtil.js b/shared/util/formatUtil.js index 65c4b6fb..5b486f02 100644 --- a/shared/util/formatUtil.js +++ b/shared/util/formatUtil.js @@ -8,7 +8,7 @@ const formatUtil = { const days = Math.floor(((cumSeconds % 31536000) % 604800) / 86400); const hours = Math.floor((((cumSeconds % 31536000) % 604800) % 86400) / 3600); const minutes = Math.floor(((((cumSeconds % 31536000) % 604800) % 86400) % 3600) / 60); - const seconds = Math.floor(cumSeconds - (minutes * 60)); + const seconds = Math.floor(cumSeconds - minutes * 60); let timeRemaining = null; if (years > 0) { @@ -32,7 +32,7 @@ const formatUtil = { return moment.duration(min * 60 * 1000).humanize(); }, - parsePeers: (string) => { + parsePeers: string => { // This lovely delimiter is defined in clientResponseUtil. let markerPosition = string.indexOf('@!@'); return string.substr(0, markerPosition); @@ -45,17 +45,17 @@ const formatUtil = { torrentStatus.push('ch'); // checking } else if (isComplete === '1' && isOpen === '1' && state === '1') { torrentStatus.push('sd'); // seeding - } else if (isComplete === '1' && isOpen === '1' && state === '0') { + } else if (isComplete === '1' && isOpen === '1' && state === '0') { torrentStatus.push('p'); // paused - } else if (isComplete === '1' && isOpen === '0') { + } else if (isComplete === '1' && isOpen === '0') { torrentStatus.push('c'); // complete - } else if (isComplete === '0' && isOpen === '1' && state === '1') { + } else if (isComplete === '0' && isOpen === '1' && state === '1') { torrentStatus.push('d'); // downloading - } else if (isComplete === '0' && isOpen === '1' && state === '0') { + } else if (isComplete === '0' && isOpen === '1' && state === '0') { torrentStatus.push('p'); // paused - } else if (isComplete === '0' && isOpen === '0') { + } else if (isComplete === '0' && isOpen === '0') { torrentStatus.push('s'); // stopped - } + } if (message.length) { torrentStatus.push('e'); // error @@ -68,7 +68,7 @@ const formatUtil = { } return torrentStatus; - } + }, }; module.exports = formatUtil; diff --git a/shared/util/objectUtil.js b/shared/util/objectUtil.js index 7dedee09..fe354809 100644 --- a/shared/util/objectUtil.js +++ b/shared/util/objectUtil.js @@ -34,15 +34,15 @@ const objectUtil = { accumulator.push({ action: diffActionTypes.ITEM_ADDED, data: { - [key]: nextValue - } + [key]: nextValue, + }, }); } else if (prevValue !== nextValue) { accumulator.push({ action: diffActionTypes.ITEM_CHANGED, data: { - [key]: nextValue - } + [key]: nextValue, + }, }); } @@ -54,7 +54,7 @@ const objectUtil = { if (nextObject[key] == null) { diff.push({ action: diffActionTypes.ITEM_REMOVED, - data: key + data: key, }); } }); @@ -63,14 +63,14 @@ const objectUtil = { return diff; }, - reflect: (object) => { + reflect: object => { return Object.keys(object).reduce((memo, key) => { memo[key] = object[key]; memo[object[key]] = key; return memo; }, {}); - } + }, }; module.exports = objectUtil; diff --git a/shared/util/regEx.js b/shared/util/regEx.js index 5aaa9a47..7810167f 100644 --- a/shared/util/regEx.js +++ b/shared/util/regEx.js @@ -2,7 +2,7 @@ const regEx = { url: /^(?:https?|ftp):\/\/.{1,}\.{1}.{1,}/, - domainName: /(?:https?|udp):\/\/(?:www\.)?([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,18}\b)*(\/[\/\d\w\.-]*)*(?:[\?])*(.+)*/i + domainName: /(?:https?|udp):\/\/(?:www\.)?([-a-zA-Z0-9@:%._\+~#=]{2,256}\.[a-z]{2,18}\b)*(\/[\/\d\w\.-]*)*(?:[\?])*(.+)*/i, }; module.exports = regEx; diff --git a/shared/util/stringUtil.js b/shared/util/stringUtil.js index 9564df22..612d0d4e 100644 --- a/shared/util/stringUtil.js +++ b/shared/util/stringUtil.js @@ -1,7 +1,7 @@ 'use strict'; module.exports = { - capitalize: (string) => { + capitalize: string => { return string.charAt(0).toUpperCase() + string.slice(1); }, @@ -15,5 +15,5 @@ module.exports = { } return string; - } + }, };