├── .babelrc ├── .eslintignore ├── .eslintrc.js ├── .gitignore ├── LICENSE.md ├── README.md ├── app ├── dist │ └── .gitkeep ├── icons │ ├── icon.icns │ └── icon.ico ├── index.ejs ├── package.json └── src │ ├── main │ ├── index.dev.js │ └── index.js │ └── renderer │ ├── App.vue │ ├── components │ ├── BucketsView.vue │ ├── DashboardView.vue │ ├── FilesView.vue │ ├── LandingPageView │ │ ├── CurrentPage.vue │ │ ├── Links.vue │ │ ├── Versions.vue │ │ └── assets │ │ │ └── logo.png │ ├── LoginView.vue │ ├── Navbar.vue │ ├── SettingsView.vue │ └── UploadView.vue │ ├── config.js │ ├── main.js │ ├── routes.js │ ├── static │ ├── crossdomain.xml │ ├── fonts │ │ ├── AvenirNextLTPro-Bold.woff │ │ ├── AvenirNextLTPro-Demi.woff │ │ ├── AvenirNextLTPro-Regular.woff │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ ├── glyphicons-halflings-regular.woff │ │ └── glyphicons-halflings-regular.woff2 │ ├── img │ │ ├── bg.jpg │ │ ├── favicon │ │ │ ├── favicon-16x16.png │ │ │ ├── favicon-32x32.png │ │ │ ├── favicon-96x96.png │ │ │ └── favicon.ico │ │ ├── icon-api.svg │ │ ├── icon-bandwidth.svg │ │ ├── icon-bitcoin.svg │ │ ├── icon-bucket.svg │ │ ├── icon-capacity.svg │ │ ├── icon-cli.svg │ │ ├── icon-cost.svg │ │ ├── icon-dropdown.svg │ │ ├── icon-fast.svg │ │ ├── icon-safe.svg │ │ ├── icon-storage.svg │ │ ├── icon-uptime.svg │ │ ├── icon-users.svg │ │ ├── icon-web.svg │ │ ├── logo-amazons3.png │ │ ├── logo-azure.png │ │ ├── logo-blue.svg │ │ ├── logo-white.svg │ │ ├── metadisk.png │ │ ├── social-github.svg │ │ ├── social-reddit.svg │ │ ├── social-twitter.svg │ │ └── storj-loader.svg │ ├── logos │ │ ├── logo-white.svg │ │ └── storj-logo.svg │ └── robots.txt │ ├── theme │ └── theme.styl │ └── vuex │ ├── actions.js │ ├── getters.js │ ├── modules │ ├── index.js │ └── users.js │ ├── mutation-types.js │ └── store.js ├── builds └── .gitkeep ├── config.js ├── package.json ├── tasks ├── release.js └── runner.js ├── test ├── .eslintrc ├── e2e │ ├── index.js │ ├── specs │ │ └── Launch.spec.js │ └── utils.js └── unit │ ├── index.js │ ├── karma.conf.js │ └── specs │ └── LandingPageView.spec.js ├── users.db ├── vendor └── storj.es5.js ├── webpack.main.config.js └── webpack.renderer.config.js /.babelrc: -------------------------------------------------------------------------------- 1 | { 2 | "comments": false, 3 | "env": { 4 | "testing-unit": { 5 | "presets": ["es2015", "stage-0"], 6 | "plugins": ["istanbul"] 7 | }, 8 | "testing-e2e": { 9 | "presets": ["es2015", "stage-0"] 10 | }, 11 | "main": { 12 | "presets": ["es2015", "stage-0"] 13 | }, 14 | "renderer": { 15 | "presets": [ 16 | ["es2015", { "modules": false }], 17 | "stage-0" 18 | ] 19 | } 20 | }, 21 | "plugins": ["transform-runtime"] 22 | } 23 | -------------------------------------------------------------------------------- /.eslintignore: -------------------------------------------------------------------------------- 1 | app/node_modules/** 2 | app/dist/** 3 | test/unit/coverage/** 4 | test/unit/*.js 5 | test/e2e/*.js 6 | vendor/**/*.js 7 | -------------------------------------------------------------------------------- /.eslintrc.js: -------------------------------------------------------------------------------- 1 | module.exports = { 2 | root: true, 3 | parser: 'babel-eslint', 4 | parserOptions: { 5 | sourceType: 'module' 6 | }, 7 | env: { 8 | browser: true, 9 | node: true 10 | }, 11 | extends: 'standard', 12 | plugins: [ 13 | 'html' 14 | ], 15 | 'rules': { 16 | // allow paren-less arrow functions 17 | 'arrow-parens': 0, 18 | // allow async-await 19 | 'generator-star-spacing': 0, 20 | // allow debugger during development 21 | 'no-debugger': process.env.NODE_ENV === 'production' ? 2 : 0 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | app/dist/index.html 3 | app/dist/main.js 4 | app/dist/renderer.js 5 | app/dist/styles.css 6 | builds/* 7 | coverage 8 | node_modules/ 9 | npm-debug.log 10 | npm-debug.log.* 11 | thumbs.db 12 | !.gitkeep 13 | storjspace/* 14 | users.db 15 | -------------------------------------------------------------------------------- /LICENSE.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2018 Storj Labs, Inc. 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy 5 | of this software and associated documentation files (the "Software"), to deal 6 | in the Software without restriction, including without limitation the rights 7 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 8 | copies of the Software, and to permit persons to whom the Software is 9 | furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included in all 12 | copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 19 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE 20 | OR OTHER DEALINGS IN THE SOFTWARE. 21 | 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **Notice: Development on this repository is currently on pause during our v3 rearchitecture. Please see [storj/storj](https://github.com/storj/storj) for ongoing v3 development.** 2 | 3 | # storjspace 4 | 5 | > An electron-vue uploader, downloader, and dashboard for the Storj network 6 | 7 | # Stability Warnings 8 | 9 | This project is still under development and will not be stable for a few months. 10 | Since the Storj network is undergoing a lot of changes in the coming months, this build will be frequently broken. 11 | 12 | ## Roadmap 13 | 14 | ### v1.0 release goals 15 | - [x] User management and settings 16 | - [ ] Key creation and management 17 | - [ ] Key export for backup 18 | - [ ] List buckets 19 | - [ ] List files in bucket 20 | - [ ] Drag and drop file upload 21 | - [ ] File download 22 | 23 | ## Build Setup 24 | 25 | ``` bash 26 | # install dependencies 27 | npm install 28 | 29 | # serve with hot reload at localhost:9080 30 | npm run dev 31 | 32 | # build electron app for production 33 | npm run build 34 | 35 | # lint all JS/Vue component files in `app/src` 36 | npm run lint 37 | 38 | # run webpack in production 39 | npm run pack 40 | ``` 41 | --- 42 | 43 | -------------------------------------------------------------------------------- /app/dist/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/dist/.gitkeep -------------------------------------------------------------------------------- /app/icons/icon.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/icons/icon.icns -------------------------------------------------------------------------------- /app/icons/icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/icons/icon.ico -------------------------------------------------------------------------------- /app/index.ejs: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | storjspace 6 | <% if (htmlWebpackPlugin.options.appModules) { %> 7 | 8 | 11 | <% } %> 12 | 13 | 14 |
15 | 16 | 17 | 18 | -------------------------------------------------------------------------------- /app/package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storjspace", 3 | "version": "0.0.0", 4 | "description": "An electron-vue uploader, downloader, and dashboard for the Storj network", 5 | "main": "./dist/main.js", 6 | "dependencies": { 7 | "babel-runtime": "^6.23.0", 8 | "electron-json-storage": "^3.0.5", 9 | "vue": "^2.1.10", 10 | "vue-electron": "^1.0.6", 11 | "vue-resource": "^1.0.3", 12 | "vue-router": "^2.1.2", 13 | "vuex": "^2.1.1" 14 | }, 15 | "devDependencies": {}, 16 | "author": "Dylan Lott " 17 | } 18 | -------------------------------------------------------------------------------- /app/src/main/index.dev.js: -------------------------------------------------------------------------------- 1 | /** 2 | * This file is used specifically and only for development. It enables the use of ES6+ 3 | * features for the main process and installs `electron-debug` & `vue-devtools`. There 4 | * shouldn't be any need to modify this file, but it can be used to extend your 5 | * development environment. 6 | */ 7 | 8 | /* eslint-disable no-console */ 9 | 10 | // Set babel `env` and install `babel-register` 11 | process.env.NODE_ENV = 'development' 12 | process.env.BABEL_ENV = 'main' 13 | 14 | require('babel-register')({ 15 | ignore: /node_modules/ 16 | }) 17 | 18 | // Install `electron-debug` with `devtron` 19 | require('electron-debug')({ showDevTools: true }) 20 | 21 | // Install `vue-devtools` 22 | require('electron').app.on('ready', () => { 23 | let installExtension = require('electron-devtools-installer') 24 | installExtension.default(installExtension.VUEJS_DEVTOOLS) 25 | .then(() => {}) 26 | .catch(err => { 27 | console.log('Unable to install `vue-devtools`: \n', err) 28 | }) 29 | }) 30 | 31 | // Require `main` process to boot app 32 | require('./index') 33 | -------------------------------------------------------------------------------- /app/src/main/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | import { app, BrowserWindow } from 'electron' 4 | 5 | let mainWindow 6 | const winURL = process.env.NODE_ENV === 'development' 7 | ? `http://localhost:${require('../../../config').port}` 8 | : `file://${__dirname}/index.html` 9 | 10 | function createWindow () { 11 | /** 12 | * Initial window options 13 | */ 14 | mainWindow = new BrowserWindow({ 15 | height: 600, 16 | width: 800 17 | }) 18 | 19 | mainWindow.loadURL(winURL) 20 | 21 | mainWindow.on('closed', () => { 22 | mainWindow = null 23 | }) 24 | 25 | // eslint-disable-next-line no-console 26 | console.log('mainWindow opened') 27 | } 28 | 29 | app.on('ready', createWindow) 30 | 31 | app.on('window-all-closed', () => { 32 | if (process.platform !== 'darwin') { 33 | app.quit() 34 | } 35 | }) 36 | 37 | app.on('activate', () => { 38 | if (mainWindow === null) { 39 | createWindow() 40 | } 41 | }) 42 | -------------------------------------------------------------------------------- /app/src/renderer/App.vue: -------------------------------------------------------------------------------- 1 | 7 | 8 | 16 | 17 | 40 | -------------------------------------------------------------------------------- /app/src/renderer/components/BucketsView.vue: -------------------------------------------------------------------------------- 1 | 17 | 18 | 66 | 67 | 71 | -------------------------------------------------------------------------------- /app/src/renderer/components/DashboardView.vue: -------------------------------------------------------------------------------- 1 | 26 | 27 | 47 | 48 | 62 | -------------------------------------------------------------------------------- /app/src/renderer/components/FilesView.vue: -------------------------------------------------------------------------------- 1 | 11 | 12 | 24 | 25 | 28 | -------------------------------------------------------------------------------- /app/src/renderer/components/LandingPageView/CurrentPage.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 20 | 21 | 34 | -------------------------------------------------------------------------------- /app/src/renderer/components/LandingPageView/Links.vue: -------------------------------------------------------------------------------- 1 | 8 | 9 | 26 | -------------------------------------------------------------------------------- /app/src/renderer/components/LandingPageView/Versions.vue: -------------------------------------------------------------------------------- 1 | 6 | 7 | 19 | -------------------------------------------------------------------------------- /app/src/renderer/components/LandingPageView/assets/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/components/LandingPageView/assets/logo.png -------------------------------------------------------------------------------- /app/src/renderer/components/LoginView.vue: -------------------------------------------------------------------------------- 1 | 44 | 45 | 73 | 74 | 85 | -------------------------------------------------------------------------------- /app/src/renderer/components/Navbar.vue: -------------------------------------------------------------------------------- 1 | 33 | 34 | 45 | 46 | 50 | -------------------------------------------------------------------------------- /app/src/renderer/components/SettingsView.vue: -------------------------------------------------------------------------------- 1 | 9 | 10 | 29 | 30 | 32 | -------------------------------------------------------------------------------- /app/src/renderer/components/UploadView.vue: -------------------------------------------------------------------------------- 1 | 14 | 15 | 31 | 32 | 45 | -------------------------------------------------------------------------------- /app/src/renderer/config.js: -------------------------------------------------------------------------------- 1 | const BRIDGE_URL = process.env.NODE_ENV === 'development' 2 | ? 'localhost:6382' 3 | : 'api.storj.io' 4 | 5 | export default { 6 | bridge: BRIDGE_URL, 7 | USERS_DB: 'users.db', 8 | filePath: '' 9 | } 10 | -------------------------------------------------------------------------------- /app/src/renderer/main.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Electron from 'vue-electron' 3 | import Resource from 'vue-resource' 4 | import Router from 'vue-router' 5 | import BootstrapVue from 'bootstrap-vue' 6 | import App from './App' 7 | import routes from './routes' 8 | import store from 'renderer/vuex/store' 9 | 10 | Vue.use(BootstrapVue) 11 | Vue.use(Electron) 12 | Vue.use(Resource) 13 | Vue.use(Router) 14 | Vue.config.debug = true 15 | 16 | import 'bootstrap/dist/css/bootstrap.css' 17 | import 'bootstrap-vue/dist/bootstrap-vue.css' 18 | 19 | const router = new Router({ 20 | scrollBehavior: () => ({ y: 0 }), 21 | routes 22 | }) 23 | 24 | /* eslint-disable no-new */ 25 | new Vue({ 26 | store, 27 | router, 28 | ...App 29 | }).$mount('#app') 30 | -------------------------------------------------------------------------------- /app/src/renderer/routes.js: -------------------------------------------------------------------------------- 1 | export default [ 2 | { 3 | path: '/', 4 | name: 'login', 5 | component: require('components/LoginView') 6 | }, 7 | { 8 | path: '/buckets', 9 | name: 'buckets', 10 | component: require('components/BucketsView'), 11 | meta: { 12 | auth: true 13 | } 14 | }, 15 | { 16 | path: '/buckets/:bucketId', 17 | name: 'files', 18 | component: require('components/FilesView'), 19 | meta: { 20 | auth: true 21 | } 22 | }, 23 | { 24 | path: '/dashboard', 25 | name: 'dashboard', 26 | component: require('components/DashboardView'), 27 | meta: { 28 | auth: true 29 | } 30 | }, 31 | { 32 | path: '/settings', 33 | name: 'settings', 34 | component: require('components/SettingsView'), 35 | meta: { 36 | auth: true 37 | } 38 | }, 39 | { 40 | path: '/upload', 41 | name: 'upload', 42 | component: require('components/UploadView.vue'), 43 | meta: { 44 | auth: true 45 | } 46 | }, 47 | { 48 | path: '*', 49 | redirect: '/' 50 | } 51 | ] 52 | -------------------------------------------------------------------------------- /app/src/renderer/static/crossdomain.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/AvenirNextLTPro-Bold.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/AvenirNextLTPro-Bold.woff -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/AvenirNextLTPro-Demi.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/AvenirNextLTPro-Demi.woff -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/AvenirNextLTPro-Regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/AvenirNextLTPro-Regular.woff -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /app/src/renderer/static/fonts/glyphicons-halflings-regular.woff2: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/fonts/glyphicons-halflings-regular.woff2 -------------------------------------------------------------------------------- /app/src/renderer/static/img/bg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/bg.jpg -------------------------------------------------------------------------------- /app/src/renderer/static/img/favicon/favicon-16x16.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/favicon/favicon-16x16.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/favicon/favicon-32x32.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/favicon/favicon-32x32.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/favicon/favicon-96x96.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/favicon/favicon-96x96.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/favicon/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/favicon/favicon.ico -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-api.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Slice 1 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-bandwidth.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-bandwidth 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-bitcoin.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-bucket.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stroke 469 + Stroke 2476 + Stroke 2477 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-capacity.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-storage2 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-cli.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-cli 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-cost.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-cost 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-dropdown.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Triangle 1 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-fast.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-fast 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-safe.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-safe 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-storage.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-storage 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-uptime.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stroke 517 + Stroke 518 + Stroke 519 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-users.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-users 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/icon-web.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | icon-web 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/logo-amazons3.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/logo-amazons3.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/logo-azure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/logo-azure.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/logo-blue.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logo-blue copy 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logo-white 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/metadisk.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/static/img/metadisk.png -------------------------------------------------------------------------------- /app/src/renderer/static/img/social-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/social-reddit.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Group 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/social-twitter.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Stroke 39 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /app/src/renderer/static/img/storj-loader.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | Storj 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /app/src/renderer/static/logos/logo-white.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | logo-white 5 | Created with Sketch. 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | -------------------------------------------------------------------------------- /app/src/renderer/static/logos/storj-logo.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 7 | 8 | 45 | 50 | 52 | 54 | 56 | 58 | 60 | 62 | 63 | 64 | -------------------------------------------------------------------------------- /app/src/renderer/static/robots.txt: -------------------------------------------------------------------------------- 1 | # http://www.robotstxt.org 2 | User-agent: * 3 | Disallow: 4 | -------------------------------------------------------------------------------- /app/src/renderer/theme/theme.styl: -------------------------------------------------------------------------------- 1 | @font-face 2 | font-family: 'Avenir Next LT Pro Regular' 3 | font-style: normal 4 | font-weight: normal 5 | src: local("Avenir Next LT Pro Regular"), url("./static/fonts/AvenirNextLTPro-Regular.woff") format("woff") 6 | 7 | $gray-base = black 8 | $gray-darker = lighten($gray-base, 13.5%) 9 | $gray-dark = lighten($gray-base, 20%) 10 | $gray = lighten($gray-base, 33.5%) 11 | $gray-light = lighten($gray-base, 42%) 12 | $gray-lighter = lighten($gray-base, 93.5%) 13 | $brand-primary = #2683ff 14 | $brand-success = #91d127 15 | $brand-info = #5bc0de 16 | $brand-warning = #f0ad4e 17 | $brand-danger = #d9534f 18 | $body-bg = white 19 | $text-color = $gray-dark 20 | $link-color = $brand-primary 21 | $link-hover-color = darken($link-color, 15%) 22 | $link-hover-decoration = underline 23 | $font-family-sans-serif = "Avenir Next LT Pro Regular", Helvetica, Arial, sans-serif 24 | $font-family-serif = Georgia, "Times New Roman", Times, serif 25 | $font-family-monospace = Menlo, Monaco, Consolas, "Courier New", monospace 26 | $font-family-base = $font-family-sans-serif 27 | $font-size-base = 16px 28 | $font-size-large = ceil($font-size-base * 1.25) 29 | $font-size-small = ceil($font-size-base * 0.85) 30 | $font-size-h1 = 36px 31 | $font-size-h2 = 30px 32 | $font-size-h3 = 24px 33 | $font-size-h4 = 18px 34 | $font-size-h5 = 12px 35 | $font-size-h6 = 6px 36 | $line-height-base = 1.42857 37 | $line-height-computed = floor($font-size-base * $line-height-base) 38 | $headings-font-family = inherit 39 | $headings-font-weight = 500 40 | $headings-line-height = 1.1 41 | $headings-color = inherit 42 | $icon-font-path = "../fonts/" 43 | $icon-font-name = "glyphicons-halflings-regular" 44 | $icon-font-svg-id = "glyphicons_halflingsregular" 45 | $padding-base-vertical = 12px 46 | $padding-base-horizontal = 18px 47 | $padding-large-vertical = 10px 48 | $padding-large-horizontal = 16px 49 | $padding-small-vertical = 5px 50 | $padding-small-horizontal = 10px 51 | $padding-xs-vertical = 1px 52 | $padding-xs-horizontal = 5px 53 | $line-height-large = 1.33333 54 | $line-height-small = 1.5 55 | $border-radius-base = 3px 56 | $border-radius-large = 4px 57 | $border-radius-small = 2px 58 | $component-active-color = white 59 | $component-active-bg = $brand-primary 60 | $caret-width-base = 4px 61 | $caret-width-large = 5px 62 | $table-cell-padding = 8px 63 | $table-condensed-cell-padding = 5px 64 | $table-bg = transparent 65 | $table-bg-accent = #f9f9f9 66 | $table-bg-hover = whitesmoke 67 | $table-bg-active = $table-bg-hover 68 | $table-border-color = #dddddd 69 | $btn-font-weight = normal 70 | $btn-default-color = #333333 71 | $btn-default-bg = white 72 | $btn-default-border = #cccccc 73 | $btn-primary-color = white 74 | $btn-primary-bg = $brand-primary 75 | $btn-primary-border = darken($btn-primary-bg, 5%) 76 | $btn-success-color = white 77 | $btn-success-bg = $brand-success 78 | $btn-success-border = darken($btn-success-bg, 5%) 79 | $btn-info-color = white 80 | $btn-info-bg = $brand-info 81 | $btn-info-border = darken($btn-info-bg, 5%) 82 | $btn-warning-color = white 83 | $btn-warning-bg = $brand-warning 84 | $btn-warning-border = darken($btn-warning-bg, 5%) 85 | $btn-danger-color = white 86 | $btn-danger-bg = $brand-danger 87 | $btn-danger-border = darken($btn-danger-bg, 5%) 88 | $btn-link-disabled-color = $gray-light 89 | $btn-border-radius-base = $border-radius-base 90 | $btn-border-radius-large = $border-radius-large 91 | $btn-border-radius-small = $border-radius-small 92 | $input-bg = #fbfbfb 93 | $input-bg-disabled = $gray-lighter 94 | $input-color = #2683ff 95 | $input-border = #eeeeee 96 | $input-border-radius = $border-radius-base 97 | $input-border-radius-large = $border-radius-large 98 | $input-border-radius-small = $border-radius-small 99 | $input-border-focus = #66afe9 100 | $input-color-placeholder = #444444 101 | $input-height-base = $line-height-computed + $padding-base-vertical * 2 + 2 102 | $input-height-large = ceil($font-size-large * $line-height-large) + $padding-large-vertical * 2 + 2 103 | $input-height-small = floor($font-size-small * $line-height-small) + $padding-small-vertical * 2 + 2 104 | $form-group-margin-bottom = 25px 105 | $legend-color = $gray-dark 106 | $legend-border-color = #e5e5e5 107 | $input-group-addon-bg = $gray-lighter 108 | $input-group-addon-border-color = $input-border 109 | $cursor-disabled = not-allowed 110 | $dropdown-bg = white 111 | $dropdown-border = rgba(0, 0, 0, 0.15) 112 | $dropdown-fallback-border = #cccccc 113 | $dropdown-divider-bg = #e5e5e5 114 | $dropdown-link-color = $gray-dark 115 | $dropdown-link-hover-color = darken($gray-dark, 5%) 116 | $dropdown-link-hover-bg = whitesmoke 117 | $dropdown-link-active-color = $component-active-color 118 | $dropdown-link-active-bg = $component-active-bg 119 | $dropdown-link-disabled-color = $gray-light 120 | $dropdown-header-color = $gray-light 121 | $dropdown-caret-color = black 122 | $screen-xs = 480px 123 | $screen-xs-min = $screen-xs 124 | $screen-phone = $screen-xs-min 125 | $screen-sm = 768px 126 | $screen-sm-min = $screen-sm 127 | $screen-tablet = $screen-sm-min 128 | $screen-md = 992px 129 | $screen-md-min = $screen-md 130 | $screen-desktop = $screen-md-min 131 | $screen-lg = 1200px 132 | $screen-lg-min = $screen-lg 133 | $screen-lg-desktop = $screen-lg-min 134 | $screen-xs-max = $screen-sm-min - 1 135 | $screen-sm-max = $screen-md-min - 1 136 | $screen-md-max = $screen-lg-min - 1 137 | $grid-columns = 12 138 | $grid-gutter-width = 30px 139 | $grid-float-breakpoint = $screen-sm-min 140 | $grid-float-breakpoint-max = $grid-float-breakpoint - 1 141 | $container-tablet = 720px + $grid-gutter-width 142 | $container-sm = $container-tablet 143 | $container-desktop = 940px + $grid-gutter-width 144 | $container-md = $container-desktop 145 | $container-large-desktop = 990px + $grid-gutter-width 146 | //orig 1140px + gutter 147 | $container-lg = $container-large-desktop 148 | $navbar-height = 82px 149 | $navbar-margin-bottom = $line-height-computed 150 | $navbar-border-radius = $border-radius-base 151 | $navbar-padding-horizontal = floor($grid-gutter-width / 2) 152 | $navbar-padding-vertical = ($navbar-height - $line-height-computed) / 2 153 | $navbar-collapse-max-height = 340px 154 | $navbar-default-color = $gray-light 155 | $navbar-default-bg = white 156 | $navbar-default-border = darken($navbar-default-bg, 6.5%) 157 | $navbar-default-link-color = $gray-light 158 | $navbar-default-link-hover-color = $brand-primary 159 | $navbar-default-link-hover-bg = transparent 160 | $navbar-default-link-active-color = $brand-primary 161 | $navbar-default-link-active-bg = transparent 162 | $navbar-default-link-disabled-color = #cccccc 163 | $navbar-default-link-disabled-bg = transparent 164 | $navbar-default-brand-color = $navbar-default-link-color 165 | $navbar-default-brand-hover-color = darken($navbar-default-brand-color, 10%) 166 | $navbar-default-brand-hover-bg = transparent 167 | $navbar-default-toggle-hover-bg = white 168 | $navbar-default-toggle-icon-bar-bg = $brand-primary 169 | $navbar-default-toggle-border-color = $brand-primary 170 | $navbar-inverse-color = lighten($gray-light, 15%) 171 | $navbar-inverse-bg = #222222 172 | $navbar-inverse-border = darken($navbar-inverse-bg, 10%) 173 | $navbar-inverse-link-color = lighten($gray-light, 15%) 174 | $navbar-inverse-link-hover-color = white 175 | $navbar-inverse-link-hover-bg = transparent 176 | $navbar-inverse-link-active-color = $navbar-inverse-link-hover-color 177 | $navbar-inverse-link-active-bg = darken($navbar-inverse-bg, 10%) 178 | $navbar-inverse-link-disabled-color = #444444 179 | $navbar-inverse-link-disabled-bg = transparent 180 | $navbar-inverse-brand-color = $navbar-inverse-link-color 181 | $navbar-inverse-brand-hover-color = white 182 | $navbar-inverse-brand-hover-bg = transparent 183 | $navbar-inverse-toggle-hover-bg = #333333 184 | $navbar-inverse-toggle-icon-bar-bg = white 185 | $navbar-inverse-toggle-border-color = #333333 186 | $nav-link-padding = 10px 16px 187 | $nav-link-hover-bg = $gray-lighter 188 | $nav-disabled-link-color = $gray-light 189 | $nav-disabled-link-hover-color = $gray-light 190 | $nav-tabs-border-color = #dddddd 191 | $nav-tabs-link-hover-border-color = $gray-lighter 192 | $nav-tabs-active-link-hover-bg = $body-bg 193 | $nav-tabs-active-link-hover-color = $gray 194 | $nav-tabs-active-link-hover-border-color = #dddddd 195 | $nav-tabs-justified-link-border-color = #dddddd 196 | $nav-tabs-justified-active-link-border-color = $body-bg 197 | $nav-pills-border-radius = $border-radius-base 198 | $nav-pills-active-link-hover-bg = $component-active-bg 199 | $nav-pills-active-link-hover-color = $component-active-color 200 | $pagination-color = $link-color 201 | $pagination-bg = white 202 | $pagination-border = #dddddd 203 | $pagination-hover-color = $link-hover-color 204 | $pagination-hover-bg = $gray-lighter 205 | $pagination-hover-border = #dddddd 206 | $pagination-active-color = white 207 | $pagination-active-bg = $brand-primary 208 | $pagination-active-border = $brand-primary 209 | $pagination-disabled-color = $gray-light 210 | $pagination-disabled-bg = white 211 | $pagination-disabled-border = #dddddd 212 | $pager-bg = $pagination-bg 213 | $pager-border = $pagination-border 214 | $pager-border-radius = 15px 215 | $pager-hover-bg = $pagination-hover-bg 216 | $pager-active-bg = $pagination-active-bg 217 | $pager-active-color = $pagination-active-color 218 | $pager-disabled-color = $pagination-disabled-color 219 | $jumbotron-padding = 30px 220 | $jumbotron-color = inherit 221 | $jumbotron-bg = $gray-lighter 222 | $jumbotron-heading-color = inherit 223 | $jumbotron-font-size = ceil($font-size-base * 1.5) 224 | $jumbotron-heading-font-size = ceil($font-size-base * 4.5) 225 | $state-success-text = #3c763d 226 | $state-success-bg = #dff0d8 227 | //Function adjust-hue is not supported in Stylus 228 | //$state-success-border = darken(adjust-hue($state-success-bg, -3.6%), 5%) 229 | $state-info-text = #31708f 230 | $state-info-bg = #d9edf7 231 | //Function adjust-hue is not supported in Stylus 232 | //$state-info-border = darken(adjust-hue($state-info-bg, -3.6%), 7%) 233 | $state-warning-text = #8a6d3b 234 | $state-warning-bg = #fcf8e3 235 | //Function adjust-hue is not supported in Stylus 236 | //$state-warning-border = darken(adjust-hue($state-warning-bg, -3.6%), 5%) 237 | $state-danger-text = #a94442 238 | $state-danger-bg = #f2dede 239 | //Function adjust-hue is not supported in Stylus 240 | //$state-danger-border = darken(adjust-hue($state-danger-bg, -3.6%), 5%) 241 | $tooltip-max-width = 200px 242 | $tooltip-color = white 243 | $tooltip-bg = black 244 | $tooltip-opacity = 0.9 245 | $tooltip-arrow-width = 5px 246 | $tooltip-arrow-color = $tooltip-bg 247 | $popover-bg = white 248 | $popover-max-width = 276px 249 | $popover-border-color = rgba(0, 0, 0, 0.2) 250 | $popover-fallback-border-color = #cccccc 251 | $popover-title-bg = darken($popover-bg, 3%) 252 | $popover-arrow-width = 10px 253 | $popover-arrow-color = $popover-bg 254 | $popover-arrow-outer-width = $popover-arrow-width + 1 255 | $popover-arrow-outer-color = fadein($popover-border-color, 5%) 256 | $popover-arrow-outer-fallback-color = darken($popover-fallback-border-color, 20%) 257 | $label-default-bg = $gray-light 258 | $label-primary-bg = $brand-primary 259 | $label-success-bg = $brand-success 260 | $label-info-bg = $brand-info 261 | $label-warning-bg = $brand-warning 262 | $label-danger-bg = $brand-danger 263 | $label-color = white 264 | $label-link-hover-color = white 265 | $modal-inner-padding = 15px 266 | $modal-title-padding = 15px 267 | $modal-title-line-height = $line-height-base 268 | $modal-content-bg = white 269 | $modal-content-border-color = rgba(0, 0, 0, 0.2) 270 | $modal-content-fallback-border-color = #999999 271 | $modal-backdrop-bg = black 272 | $modal-backdrop-opacity = 0.5 273 | $modal-header-border-color = #e5e5e5 274 | $modal-footer-border-color = $modal-header-border-color 275 | $modal-lg = 900px 276 | $modal-md = 600px 277 | $modal-sm = 300px 278 | $alert-padding = 15px 279 | $alert-border-radius = $border-radius-base 280 | $alert-link-font-weight = bold 281 | $alert-success-bg = $state-success-bg 282 | $alert-success-text = $state-success-text 283 | $alert-success-border = $state-success-border 284 | $alert-info-bg = $state-info-bg 285 | $alert-info-text = $state-info-text 286 | $alert-info-border = $state-info-border 287 | $alert-warning-bg = $state-warning-bg 288 | $alert-warning-text = $state-warning-text 289 | $alert-warning-border = $state-warning-border 290 | $alert-danger-bg = $state-danger-bg 291 | $alert-danger-text = $state-danger-text 292 | $alert-danger-border = $state-danger-border 293 | $progress-bg = whitesmoke 294 | $progress-bar-color = white 295 | $progress-border-radius = $border-radius-base 296 | $progress-bar-bg = $brand-primary 297 | $progress-bar-success-bg = $brand-success 298 | $progress-bar-warning-bg = $brand-warning 299 | $progress-bar-danger-bg = $brand-danger 300 | $progress-bar-info-bg = $brand-info 301 | $list-group-bg = white 302 | $list-group-border = #dddddd 303 | $list-group-border-radius = $border-radius-base 304 | $list-group-hover-bg = whitesmoke 305 | $list-group-active-color = $component-active-color 306 | $list-group-active-bg = $component-active-bg 307 | $list-group-active-border = $list-group-active-bg 308 | $list-group-active-text-color = lighten($list-group-active-bg, 40%) 309 | $list-group-disabled-color = $gray-light 310 | $list-group-disabled-bg = $gray-lighter 311 | $list-group-disabled-text-color = $list-group-disabled-color 312 | $list-group-link-color = #555555 313 | $list-group-link-hover-color = $list-group-link-color 314 | $list-group-link-heading-color = #333333 315 | $panel-bg = white 316 | $panel-body-padding = 15px 317 | $panel-heading-padding = 10px 15px 318 | $panel-footer-padding = $panel-heading-padding 319 | $panel-border-radius = $border-radius-base 320 | $panel-inner-border = #dddddd 321 | $panel-footer-bg = whitesmoke 322 | $panel-default-text = $gray-dark 323 | $panel-default-border = #dddddd 324 | $panel-default-heading-bg = whitesmoke 325 | $panel-primary-text = white 326 | $panel-primary-border = $brand-primary 327 | $panel-primary-heading-bg = $brand-primary 328 | $panel-success-text = $state-success-text 329 | $panel-success-border = $state-success-border 330 | $panel-success-heading-bg = $state-success-bg 331 | $panel-info-text = $state-info-text 332 | $panel-info-border = $state-info-border 333 | $panel-info-heading-bg = $state-info-bg 334 | $panel-warning-text = $state-warning-text 335 | $panel-warning-border = $state-warning-border 336 | $panel-warning-heading-bg = $state-warning-bg 337 | $panel-danger-text = $state-danger-text 338 | $panel-danger-border = $state-danger-border 339 | $panel-danger-heading-bg = $state-danger-bg 340 | $thumbnail-padding = 4px 341 | $thumbnail-bg = $body-bg 342 | $thumbnail-border = #dddddd 343 | $thumbnail-border-radius = $border-radius-base 344 | $thumbnail-caption-color = $text-color 345 | $thumbnail-caption-padding = 9px 346 | $well-bg = whitesmoke 347 | $well-border = darken($well-bg, 7%) 348 | $badge-color = white 349 | $badge-link-hover-color = white 350 | $badge-bg = $gray-light 351 | $badge-active-color = $link-color 352 | $badge-active-bg = white 353 | $badge-font-weight = bold 354 | $badge-line-height = 1 355 | $badge-border-radius = 10px 356 | $breadcrumb-padding-vertical = 8px 357 | $breadcrumb-padding-horizontal = 15px 358 | $breadcrumb-bg = whitesmoke 359 | $breadcrumb-color = #cccccc 360 | $breadcrumb-active-color = $gray-light 361 | $breadcrumb-separator = "/" 362 | $carousel-text-shadow = 0 1px 2px rgba(0, 0, 0, 0.6) 363 | $carousel-control-color = white 364 | $carousel-control-width = 15% 365 | $carousel-control-opacity = 0.5 366 | $carousel-control-font-size = 20px 367 | $carousel-indicator-active-bg = white 368 | $carousel-indicator-border-color = white 369 | $carousel-caption-color = white 370 | $close-font-weight = bold 371 | $close-color = black 372 | $close-text-shadow = 0 1px 0 white 373 | $code-color = #c7254e 374 | $code-bg = #f9f2f4 375 | $kbd-color = white 376 | $kbd-bg = #333333 377 | $pre-bg = whitesmoke 378 | $pre-color = $gray-dark 379 | $pre-border-color = #cccccc 380 | $pre-scrollable-max-height = 340px 381 | $component-offset-horizontal = 180px 382 | $text-muted = $gray-light 383 | $abbr-border-color = $gray-light 384 | $headings-small-color = $gray-light 385 | $blockquote-small-color = $gray-light 386 | $blockquote-font-size = $font-size-base * 1.25 387 | $blockquote-border-color = $gray-lighter 388 | $page-header-border-color = $gray-lighter 389 | $dl-horizontal-offset = $component-offset-horizontal 390 | $dl-horizontal-breakpoint = $grid-float-breakpoint 391 | $hr-border = $gray-lighter 392 | -------------------------------------------------------------------------------- /app/src/renderer/vuex/actions.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/app/src/renderer/vuex/actions.js -------------------------------------------------------------------------------- /app/src/renderer/vuex/getters.js: -------------------------------------------------------------------------------- 1 | export const mainCounter = state => state.counters.main 2 | -------------------------------------------------------------------------------- /app/src/renderer/vuex/modules/index.js: -------------------------------------------------------------------------------- 1 | const files = require.context('.', false, /\.js$/) 2 | const modules = {} 3 | 4 | files.keys().forEach((key) => { 5 | if (key === './index.js') return 6 | modules[key.replace(/(\.\/|\.js)/g, '')] = files(key).default 7 | }) 8 | 9 | export default modules 10 | -------------------------------------------------------------------------------- /app/src/renderer/vuex/modules/users.js: -------------------------------------------------------------------------------- 1 | import * as types from '../mutation-types' 2 | import config from '../../config' 3 | import storage from 'electron-json-storage' 4 | import Storj from 'vendor/storj.es5.js' 5 | import router from '../../routes' 6 | 7 | const storj = new Storj() 8 | const Database = require('nedb') 9 | const users = new Database({ 10 | filename: config.USERS_DB, 11 | autoload: true 12 | }) 13 | 14 | function registerUser () { 15 | const key = storj.generateKeyPair().getPrivateKey() 16 | const encryptionKey = storj.generateEncryptionKey() 17 | storage.set('keypair', { 18 | privkey: key, 19 | encryptionKey: encryptionKey 20 | }, (err, keypair) => { 21 | if (err) console.log('Error storing keypair: ', err) 22 | console.log('Keypair created: ', keypair) 23 | return keypair 24 | }) 25 | } 26 | 27 | function getActiveUser () { 28 | return storage.get('user', (err, user) => { 29 | if (err) console.log(`Error getting active user ${err}`) 30 | console.log('getActiveUser: ', user) 31 | return user 32 | }) 33 | } 34 | 35 | function getEmail () { 36 | return storage.get('user', (err, user) => { 37 | if (err) console.log('error getting email', err) 38 | return user.email 39 | }) 40 | } 41 | 42 | function getKeyPair () { 43 | return [{ 44 | privkey: '', 45 | pubkey: '' 46 | }] 47 | } 48 | 49 | const state = { 50 | email: getEmail(), 51 | user: getActiveUser(), 52 | keypair: getKeyPair() 53 | } 54 | 55 | const mutations = { 56 | [types.LOGIN_USER_REQUEST] (state) { 57 | state.loading = true 58 | state.authed = false 59 | }, 60 | [types.LOGIN_USER_SUCCESS] (state, { basicAuth }) { 61 | state.basicAuth = basicAuth 62 | state.authed = true 63 | state.loading = false 64 | }, 65 | [types.LOGIN_USER_FAILURE] (state, errors) { 66 | state.authed = false 67 | state.loading = false 68 | state.errors = errors 69 | }, 70 | [types.SET_USER] (state, user) { 71 | state.user = user 72 | state.keypair = getKeyPair() 73 | state.email = getEmail() 74 | state.user = getActiveUser() 75 | state.authed = true 76 | }, 77 | [types.LOGOUT_USER_REQUEST] (state) { 78 | state.loading = true 79 | }, 80 | [types.LOGOUT_USER_SUCCESS] (state) { 81 | state.user = null 82 | state.loading = false 83 | state.success = true 84 | } 85 | } 86 | 87 | const actions = { 88 | login ({commit}, user) { 89 | console.log('Reached user module: ', user) 90 | commit(types.LOGIN_USER_REQUEST) 91 | 92 | users.findOne({ email: user.email }, (err, doc) => { 93 | if (err) console.log('error finding user: ', err) 94 | console.log('users findOne', doc) 95 | 96 | if (!doc) { 97 | users.insert(user, (err, user) => { 98 | if (err) console.log(`Error saving user: ${err}`) 99 | console.log('User added: ', user) 100 | 101 | const keypair = registerUser() 102 | 103 | console.log(keypair) 104 | storage.get('keypair', (err, keypair) => { 105 | console.log('error: ', err) 106 | console.log('keypair login: ', keypair) 107 | }) 108 | 109 | router.push({ path: '/dashboard' }) 110 | }) 111 | } 112 | 113 | console.log('user: ', user) 114 | return user 115 | }) 116 | }, 117 | 118 | logout ({ commit }) { 119 | commit(types.LOGOUT_USER_REQUEST) 120 | storage.clear((err) => { 121 | commit(types.LOGOUT_USER_SUCCESS) 122 | if (err) console.log(`Error clearing storage: ${err}`) 123 | router.push('/') 124 | }) 125 | }, 126 | 127 | getUser ({commit}) { 128 | commit(types.SET_USER, getActiveUser()) 129 | return getActiveUser() 130 | } 131 | } 132 | 133 | const getters = { 134 | getUser: (state, getters) => { 135 | return state.user 136 | }, 137 | getEmail: (state, getters) => { 138 | return state.email 139 | }, 140 | getKeyPair: (state, getters) => { 141 | return state.keypair 142 | } 143 | } 144 | 145 | export default { 146 | state, 147 | actions, 148 | mutations, 149 | getters 150 | } 151 | -------------------------------------------------------------------------------- /app/src/renderer/vuex/mutation-types.js: -------------------------------------------------------------------------------- 1 | export const LOGIN_USER_REQUEST = 'LOGIN_USER_REQUEST' 2 | export const LOGIN_USER_FAILURE = 'LOGIN_USER_FAILURE' 3 | export const LOGIN_USER_SUCCESS = 'LOGIN_USER_SUCCESS' 4 | 5 | export const SIGNUP_USER_REQUEST = 'SIGNUP_USER_REQUEST' 6 | export const SIGNUP_USER_FAILURE = 'SIGNUP_USER_FAILURE' 7 | export const SIGNUP_USER_SUCCESS = 'SIGNUP_USER_SUCCESS' 8 | 9 | export const SET_USER = 'SET_USER' 10 | 11 | export const LOGOUT_USER_REQUEST = 'LOGOUT_USER_REQUEST' 12 | export const LOGOUT_USER_SUCCESS = 'LOGOUT_USER_SUCCESS' 13 | -------------------------------------------------------------------------------- /app/src/renderer/vuex/store.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import Vuex from 'vuex' 3 | 4 | import * as actions from './actions' 5 | import * as getters from './getters' 6 | import modules from './modules' 7 | 8 | Vue.use(Vuex) 9 | 10 | export default new Vuex.Store({ 11 | actions, 12 | getters, 13 | modules, 14 | strict: process.env.NODE_ENV !== 'production' 15 | }) 16 | -------------------------------------------------------------------------------- /builds/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/storj-archived/storjspace/bccbe783657c5b2c3a45093b727fedd2ba3bdbff/builds/.gitkeep -------------------------------------------------------------------------------- /config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | 5 | let config = { 6 | // Name of electron app 7 | // Will be used in production builds 8 | name: 'storjspace', 9 | 10 | // Use ESLint (extends `standard`) 11 | // Further changes can be made in `.eslintrc.js` 12 | eslint: true, 13 | 14 | // webpack-dev-server port 15 | port: 9080, 16 | 17 | // electron-packager options 18 | // Docs: https://simulatedgreg.gitbooks.io/electron-vue/content/docs/building_your_app.html 19 | building: { 20 | arch: 'x64', 21 | asar: true, 22 | dir: path.join(__dirname, 'app'), 23 | icon: path.join(__dirname, 'app/icons/icon'), 24 | ignore: /^\/(src|index\.ejs|icons)/, 25 | out: path.join(__dirname, 'builds'), 26 | overwrite: true, 27 | platform: process.env.PLATFORM_TARGET || 'all' 28 | } 29 | } 30 | 31 | config.building.name = config.name 32 | 33 | module.exports = config 34 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "storjspace", 3 | "version": "0.0.0", 4 | "description": "An electron-vue uploader, downloader, and dashboard for the Storj network", 5 | "scripts": { 6 | "build": "node tasks/release.js", 7 | "build:clean": "cross-env PLATFORM_TARGET=clean node tasks/release.js", 8 | "build:darwin": "cross-env PLATFORM_TARGET=darwin node tasks/release.js", 9 | "build:linux": "cross-env PLATFORM_TARGET=linux node tasks/release.js", 10 | "build:mas": "cross-env PLATFORM_TARGET=mas node tasks/release.js", 11 | "build:win32": "cross-env PLATFORM_TARGET=win32 node tasks/release.js", 12 | "dev": "node tasks/runner.js", 13 | "e2e": "npm run pack && mocha test/e2e", 14 | "lint": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter app test", 15 | "lint:fix": "eslint --ext .js,.vue -f ./node_modules/eslint-friendly-formatter --fix app test", 16 | "pack": "npm run pack:main && npm run pack:renderer", 17 | "pack:main": "cross-env NODE_ENV=production webpack -p --progress --colors --config webpack.main.config.js", 18 | "pack:renderer": "cross-env NODE_ENV=production webpack -p --progress --colors --config webpack.renderer.config.js", 19 | "test": "npm run unit && npm run e2e", 20 | "unit": "cross-env BABEL_ENV=testing-unit karma start test/unit/karma.conf.js", 21 | "postinstall": "npm run lint:fix && cd app && npm install" 22 | }, 23 | "author": "Greg Holguin ", 24 | "license": "MIT", 25 | "devDependencies": { 26 | "babel-core": "^6.8.0", 27 | "babel-eslint": "^7.0.0", 28 | "babel-loader": "^6.2.4", 29 | "babel-plugin-istanbul": "^3.1.2", 30 | "babel-plugin-transform-runtime": "^6.8.0", 31 | "babel-preset-es2015": "^6.6.0", 32 | "babel-preset-stage-0": "^6.5.0", 33 | "babel-register": "^6.18.0", 34 | "babel-runtime": "^6.6.1", 35 | "chai": "^3.5.0", 36 | "cross-env": "^3.1.4", 37 | "css-loader": "^0.26.1", 38 | "del": "^2.2.1", 39 | "devtron": "^1.1.0", 40 | "electron": "^1.3.1", 41 | "electron-debug": "^1.1.0", 42 | "electron-devtools-installer": "^2.0.1", 43 | "electron-packager": "^8.5.0", 44 | "electron-rebuild": "^1.1.3", 45 | "eslint": "^3.13.1", 46 | "eslint-config-standard": "^6.2.1", 47 | "eslint-friendly-formatter": "^2.0.5", 48 | "eslint-loader": "^1.3.0", 49 | "eslint-plugin-html": "^2.0.0", 50 | "eslint-plugin-promise": "^3.4.0", 51 | "eslint-plugin-standard": "^2.0.1", 52 | "extract-text-webpack-plugin": "^2.0.0-beta.4", 53 | "file-loader": "^0.9.0", 54 | "html-webpack-plugin": "^2.16.1", 55 | "inject-loader": "^2.0.1", 56 | "json-loader": "^0.5.4", 57 | "karma": "^1.3.0", 58 | "karma-chai": "^0.1.0", 59 | "karma-coverage": "^1.1.1", 60 | "karma-electron": "^5.1.1", 61 | "karma-mocha": "^1.2.0", 62 | "karma-sourcemap-loader": "^0.3.7", 63 | "karma-spec-reporter": "0.0.26", 64 | "karma-webpack": "^2.0.1", 65 | "mocha": "^3.0.2", 66 | "require-dir": "^0.3.0", 67 | "spectron": "^3.4.0", 68 | "style-loader": "^0.13.1", 69 | "stylus": "^0.54.5", 70 | "stylus-loader": "^3.0.1", 71 | "tree-kill": "^1.1.0", 72 | "url-loader": "^0.5.7", 73 | "vue-hot-reload-api": "^2.0.7", 74 | "vue-html-loader": "^1.2.2", 75 | "vue-loader": "^10.0.2", 76 | "vue-style-loader": "^1.0.0", 77 | "vue-template-compiler": "^2.3.0", 78 | "webpack": "^2.2.1", 79 | "webpack-dev-server": "^2.3.0", 80 | "webpack-merge": "^2.4.0" 81 | }, 82 | "dependencies": { 83 | "bluebird": "^3.5.0", 84 | "bootstrap-vue": "^0.14.0", 85 | "electron-json-storage": "^3.0.5", 86 | "nedb": "^1.8.0", 87 | "vue": "^2.3.0", 88 | "vuex": "^2.3.1" 89 | } 90 | } 91 | -------------------------------------------------------------------------------- /tasks/release.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const exec = require('child_process').exec 4 | const packager = require('electron-packager') 5 | 6 | if (process.env.PLATFORM_TARGET === 'clean') { 7 | require('del').sync(['builds/*', '!.gitkeep']) 8 | console.log('\x1b[33m`builds` directory cleaned.\n\x1b[0m') 9 | } else pack() 10 | 11 | /** 12 | * Build webpack in production 13 | */ 14 | function pack () { 15 | console.log('\x1b[33mBuilding webpack in production mode...\n\x1b[0m') 16 | let pack = exec('npm run pack') 17 | 18 | pack.stdout.on('data', data => console.log(data)) 19 | pack.stderr.on('data', data => console.error(data)) 20 | pack.on('exit', code => build()) 21 | } 22 | 23 | /** 24 | * Use electron-packager to build electron app 25 | */ 26 | function build () { 27 | let options = require('../config').building 28 | 29 | console.log('\x1b[34mBuilding electron app(s)...\n\x1b[0m') 30 | packager(options, (err, appPaths) => { 31 | if (err) { 32 | console.error('\x1b[31mError from `electron-packager` when building app...\x1b[0m') 33 | console.error(err) 34 | } else { 35 | console.log('Build(s) successful!') 36 | console.log(appPaths) 37 | 38 | console.log('\n\x1b[34mDONE\n\x1b[0m') 39 | } 40 | }) 41 | } 42 | -------------------------------------------------------------------------------- /tasks/runner.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const config = require('../config') 4 | const exec = require('child_process').exec 5 | const treeKill = require('tree-kill') 6 | 7 | let YELLOW = '\x1b[33m' 8 | let BLUE = '\x1b[34m' 9 | let END = '\x1b[0m' 10 | 11 | let isElectronOpen = false 12 | 13 | function format (command, data, color) { 14 | return color + command + END + 15 | ' ' + // Two space offset 16 | data.toString().trim().replace(/\n/g, '\n' + repeat(' ', command.length + 2)) + 17 | '\n' 18 | } 19 | 20 | function repeat (str, times) { 21 | return (new Array(times + 1)).join(str) 22 | } 23 | 24 | let children = [] 25 | 26 | function run (command, color, name) { 27 | let child = exec(command) 28 | 29 | child.stdout.on('data', data => { 30 | console.log(format(name, data, color)) 31 | 32 | /** 33 | * Start electron after successful compilation 34 | * (prevents electron from opening a blank window that requires refreshing) 35 | */ 36 | if (/Compiled/g.test(data.toString().trim().replace(/\n/g, '\n' + repeat(' ', command.length + 2))) && !isElectronOpen) { 37 | console.log(`${BLUE}Starting electron...\n${END}`) 38 | run('cross-env NODE_ENV=development electron app/src/main/index.dev.js', BLUE, 'electron') 39 | isElectronOpen = true 40 | } 41 | }) 42 | 43 | child.stderr.on('data', data => console.error(format(name, data, color))) 44 | child.on('exit', code => exit(code)) 45 | 46 | children.push(child) 47 | } 48 | 49 | function exit (code) { 50 | children.forEach(child => { 51 | treeKill(child.pid) 52 | }) 53 | } 54 | 55 | console.log(`${YELLOW}Starting webpack-dev-server...\n${END}`) 56 | run(`webpack-dev-server --hot --colors --config webpack.renderer.config.js --port ${config.port} --content-base app/dist`, YELLOW, 'webpack') 57 | -------------------------------------------------------------------------------- /test/.eslintrc: -------------------------------------------------------------------------------- 1 | { 2 | "env": { 3 | "mocha": true 4 | }, 5 | "globals": { 6 | "assert": true, 7 | "expect": true, 8 | "should": true 9 | } 10 | } 11 | -------------------------------------------------------------------------------- /test/e2e/index.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | // Set BABEL_ENV to use proper preset config 4 | process.env.BABEL_ENV = 'testing-e2e' 5 | 6 | // Enable use of es2015 on required files 7 | require('babel-register')({ 8 | ignore: /node_modules/ 9 | }) 10 | 11 | // Attach Chai APIs to global scope 12 | const { expect, should, assert } = require('chai') 13 | global.expect = expect 14 | global.should = should 15 | global.assert = assert 16 | 17 | // Require all JS files in `./specs` for Mocha to consume 18 | require('require-dir')('./specs') 19 | -------------------------------------------------------------------------------- /test/e2e/specs/Launch.spec.js: -------------------------------------------------------------------------------- 1 | import utils from '../utils' 2 | 3 | describe('Launch', function () { 4 | beforeEach(utils.beforeEach) 5 | afterEach(utils.afterEach) 6 | 7 | it('shows the proper application title', function () { 8 | return this.app.client.getTitle() 9 | .then(title => { 10 | expect(title).to.equal('storjspace') 11 | }) 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /test/e2e/utils.js: -------------------------------------------------------------------------------- 1 | import electron from 'electron' 2 | import { Application } from 'spectron' 3 | 4 | export default { 5 | afterEach () { 6 | this.timeout(10000) 7 | 8 | if (this.app && this.app.isRunning()) { 9 | return this.app.stop() 10 | } 11 | }, 12 | beforeEach () { 13 | this.timeout(10000) 14 | this.app = new Application({ 15 | path: electron, 16 | args: ['app'], 17 | startTimeout: 10000, 18 | waitTimeout: 10000 19 | }) 20 | 21 | return this.app.start() 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /test/unit/index.js: -------------------------------------------------------------------------------- 1 | // require all test files (files that ends with .spec.js) 2 | const testsContext = require.context('./specs', true, /\.spec$/) 3 | testsContext.keys().forEach(testsContext) 4 | 5 | // require all src files except main.js for coverage. 6 | // you can also change this to match only the subset of files that 7 | // you want coverage for. 8 | const srcContext = require.context('../../app/src/renderer', true, /^\.\/(?!main(\.js)?$)/) 9 | srcContext.keys().forEach(srcContext) 10 | -------------------------------------------------------------------------------- /test/unit/karma.conf.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | const path = require('path') 4 | const merge = require('webpack-merge') 5 | const webpack = require('webpack') 6 | 7 | const baseConfig = require('../../webpack.renderer.config') 8 | const projectRoot = path.resolve(__dirname, '../../app') 9 | 10 | let webpackConfig = merge(baseConfig, { 11 | devtool: '#inline-source-map', 12 | plugins: [ 13 | new webpack.DefinePlugin({ 14 | 'process.env.NODE_ENV': '"testing"' 15 | }) 16 | ] 17 | }) 18 | 19 | // don't treat dependencies as externals 20 | delete webpackConfig.entry 21 | delete webpackConfig.externals 22 | delete webpackConfig.output.libraryTarget 23 | 24 | // only apply babel for test files when using isparta 25 | webpackConfig.module.rules.some(rule => { 26 | if (rule.use === 'babel-loader') { 27 | rule.include.push(path.resolve(projectRoot, '../test/unit')) 28 | return true 29 | } 30 | }) 31 | 32 | // apply vue option to apply isparta-loader on js 33 | webpackConfig.module.rules 34 | .find(rule => rule.use.loader === 'vue-loader').use.options.loaders.js = 'babel-loader' 35 | 36 | module.exports = config => { 37 | config.set({ 38 | browsers: ['visibleElectron'], 39 | client: { 40 | useIframe: false 41 | }, 42 | coverageReporter: { 43 | dir: './coverage', 44 | reporters: [ 45 | { type: 'lcov', subdir: '.' }, 46 | { type: 'text-summary' } 47 | ] 48 | }, 49 | customLaunchers: { 50 | 'visibleElectron': { 51 | base: 'Electron', 52 | flags: ['--show'] 53 | } 54 | }, 55 | frameworks: ['mocha', 'chai'], 56 | files: ['./index.js'], 57 | preprocessors: { 58 | './index.js': ['webpack', 'sourcemap'] 59 | }, 60 | reporters: ['spec', 'coverage'], 61 | singleRun: true, 62 | webpack: webpackConfig, 63 | webpackMiddleware: { 64 | noInfo: true 65 | } 66 | }) 67 | } 68 | -------------------------------------------------------------------------------- /test/unit/specs/LandingPageView.spec.js: -------------------------------------------------------------------------------- 1 | import Vue from 'vue' 2 | import LandingPageView from 'renderer/components/LandingPageView' 3 | 4 | describe('LandingPageView.vue', () => { 5 | it('should render correct contents', () => { 6 | const vm = new Vue({ 7 | el: document.createElement('div'), 8 | render: h => h(LandingPageView) 9 | }).$mount() 10 | 11 | expect(vm.$el.querySelector('h1').textContent).to.contain('Welcome.') 12 | }) 13 | }) 14 | -------------------------------------------------------------------------------- /users.db: -------------------------------------------------------------------------------- 1 | {"email":"lott.dylan@gmail.com","password":"password","_id":"D5BEICzjaulwExys"} 2 | {"email":"","password":"","_id":"zJFCsExtK2Ih3Ra7"} 3 | -------------------------------------------------------------------------------- /webpack.main.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | process.env.BABEL_ENV = 'main' 4 | 5 | const path = require('path') 6 | const pkg = require('./app/package.json') 7 | const settings = require('./config.js') 8 | const webpack = require('webpack') 9 | 10 | let mainConfig = { 11 | entry: { 12 | main: path.join(__dirname, 'app/src/main/index.js') 13 | }, 14 | externals: Object.keys(pkg.dependencies || {}), 15 | module: { 16 | rules: [ 17 | { 18 | test: /\.js$/, 19 | loader: 'babel-loader', 20 | exclude: /node_modules/ 21 | }, 22 | { 23 | test: /\.json$/, 24 | loader: 'json-loader' 25 | }, 26 | { 27 | test: /\.node$/, 28 | loader: 'node-loader' 29 | } 30 | ] 31 | }, 32 | node: { 33 | __dirname: false, 34 | __filename: false 35 | }, 36 | output: { 37 | filename: '[name].js', 38 | libraryTarget: 'commonjs2', 39 | path: path.join(__dirname, 'app/dist') 40 | }, 41 | plugins: [ 42 | new webpack.NoEmitOnErrorsPlugin(), 43 | new webpack.DefinePlugin({ 44 | 'process.env.NODE_ENV': '"production"' 45 | }), 46 | new webpack.optimize.UglifyJsPlugin({ 47 | compress: { 48 | warnings: false 49 | } 50 | }) 51 | ], 52 | resolve: { 53 | extensions: ['.js', '.json', '.node'], 54 | modules: [ 55 | path.join(__dirname, 'app/node_modules') 56 | ] 57 | }, 58 | target: 'electron-main' 59 | } 60 | 61 | module.exports = mainConfig 62 | -------------------------------------------------------------------------------- /webpack.renderer.config.js: -------------------------------------------------------------------------------- 1 | 'use strict' 2 | 3 | process.env.BABEL_ENV = 'renderer' 4 | 5 | const path = require('path') 6 | const pkg = require('./app/package.json') 7 | const settings = require('./config.js') 8 | const webpack = require('webpack') 9 | 10 | const ExtractTextPlugin = require('extract-text-webpack-plugin') 11 | const HtmlWebpackPlugin = require('html-webpack-plugin') 12 | 13 | let rendererConfig = { 14 | devtool: '#eval-source-map', 15 | devServer: { overlay: true }, 16 | entry: { 17 | renderer: path.join(__dirname, 'app/src/renderer/main.js') 18 | }, 19 | externals: Object.keys(pkg.dependencies || {}), 20 | module: { 21 | rules: [ 22 | { 23 | test: /\.css$/, 24 | use: ExtractTextPlugin.extract({ 25 | fallback: 'style-loader', 26 | use: 'css-loader' 27 | }) 28 | }, 29 | { 30 | test: /\.html$/, 31 | use: 'vue-html-loader' 32 | }, 33 | { 34 | test: /\.js$/, 35 | use: 'babel-loader', 36 | include: [ path.resolve(__dirname, 'app/src/renderer') ], 37 | exclude: /node_modules/ 38 | }, 39 | { 40 | test: /\.json$/, 41 | use: 'json-loader' 42 | }, 43 | { 44 | test: /\.node$/, 45 | use: 'node-loader' 46 | }, 47 | { 48 | test: /\.vue$/, 49 | use: { 50 | loader: 'vue-loader', 51 | options: { 52 | loaders: { 53 | sass: 'vue-style-loader!css-loader!sass-loader?indentedSyntax=1', 54 | scss: 'vue-style-loader!css-loader!sass-loader' 55 | } 56 | } 57 | } 58 | }, 59 | { 60 | test: /\.(png|jpe?g|gif|svg)(\?.*)?$/, 61 | use: { 62 | loader: 'url-loader', 63 | query: { 64 | limit: 10000, 65 | name: 'imgs/[name].[ext]' 66 | } 67 | } 68 | }, 69 | { 70 | test: /\.(woff2?|eot|ttf|otf)(\?.*)?$/, 71 | use: { 72 | loader: 'url-loader', 73 | query: { 74 | limit: 10000, 75 | name: 'fonts/[name].[ext]' 76 | } 77 | } 78 | } 79 | ] 80 | }, 81 | plugins: [ 82 | new ExtractTextPlugin('styles.css'), 83 | new HtmlWebpackPlugin({ 84 | filename: 'index.html', 85 | template: './app/index.ejs', 86 | appModules: process.env.NODE_ENV !== 'production' 87 | ? path.resolve(__dirname, 'app/node_modules') 88 | : false, 89 | }), 90 | new webpack.NoEmitOnErrorsPlugin() 91 | ], 92 | output: { 93 | filename: '[name].js', 94 | libraryTarget: 'commonjs2', 95 | path: path.join(__dirname, 'app/dist') 96 | }, 97 | resolve: { 98 | alias: { 99 | 'components': path.join(__dirname, 'app/src/renderer/components'), 100 | 'renderer': path.join(__dirname, 'app/src/renderer'), 101 | 'vendor': path.join(__dirname, 'vendor') 102 | }, 103 | extensions: ['.js', '.vue', '.json', '.css', '.node'], 104 | modules: [ 105 | path.join(__dirname, 'app/node_modules'), 106 | path.join(__dirname, 'node_modules') 107 | ] 108 | }, 109 | target: 'electron-renderer' 110 | } 111 | 112 | if (process.env.NODE_ENV !== 'production') { 113 | /** 114 | * Apply ESLint 115 | */ 116 | if (settings.eslint) { 117 | rendererConfig.module.rules.push( 118 | { 119 | test: /\.(js|vue)$/, 120 | enforce: 'pre', 121 | exclude: /node_modules/, 122 | use: { 123 | loader: 'eslint-loader', 124 | options: { 125 | formatter: require('eslint-friendly-formatter') 126 | } 127 | } 128 | } 129 | ) 130 | } 131 | } 132 | 133 | /** 134 | * Adjust rendererConfig for production settings 135 | */ 136 | if (process.env.NODE_ENV === 'production') { 137 | rendererConfig.devtool = '' 138 | 139 | rendererConfig.plugins.push( 140 | new webpack.DefinePlugin({ 141 | 'process.env.NODE_ENV': '"production"' 142 | }), 143 | new webpack.LoaderOptionsPlugin({ 144 | minimize: true 145 | }), 146 | new webpack.optimize.UglifyJsPlugin({ 147 | compress: { 148 | warnings: false 149 | } 150 | }) 151 | ) 152 | } 153 | 154 | module.exports = rendererConfig 155 | --------------------------------------------------------------------------------