├── .gitignore ├── .travis.yml ├── CONTRIBUTORS.md ├── Gruntfile.js ├── LICENSE.md ├── MAINTAINERS.md ├── README.md ├── bin ├── darwin │ ├── florincoind.zip │ ├── ipfs │ ├── libraryd │ └── mediaInfo └── linux │ ├── florincoind │ ├── ipfs │ └── libraryd ├── fonts └── ionic │ ├── ionicons.eot │ ├── ionicons.svg │ ├── ionicons.ttf │ └── ionicons.woff ├── images ├── icons │ ├── alexandria_icon.png │ ├── librarian_icon.png │ └── tray │ │ ├── tray_linux.png │ │ ├── tray_osx.png │ │ └── tray_win.png ├── il-money.png └── svg │ ├── arrows-16px-1_direction-53.svg │ ├── arrows-16px-1_tail-down.svg │ ├── arrows-16px-1_tail-up.svg │ ├── arrows-16px-3_square-corner-up-right.svg │ ├── arrows-24px-glyph-2_file-upload-88.svg │ ├── business-16px_hierarchy-53.svg │ ├── files-16px_single-copy-04.svg │ ├── files-16px_single-folded-content.svg │ ├── files-16px_single-folded.svg │ ├── location-16px-e_pin-remove.svg │ ├── location-16px_pin.svg │ ├── logo-text.svg │ ├── media-16px-2_note-03.svg │ ├── objects-16px_shovel.svg │ ├── social-16px_logo-github.svg │ ├── ui-16px-1_settings-gear-64.svg │ ├── ui-16px-2_alert-circle-i.svg │ ├── ui-16px-e_round-e-info.svg │ └── ui-48px-glyph-2_archive.svg ├── index.html ├── package.json ├── src ├── actions │ ├── daemonEngineActions.js │ └── externalActions.js ├── alt.js ├── app-tray.js ├── browser.js ├── components │ ├── About │ │ ├── actions.js │ │ ├── index.js │ │ ├── store.js │ │ └── utils │ │ │ └── aboutUtil.js │ ├── Dashboard │ │ ├── components │ │ │ ├── florincoin.js │ │ │ ├── ipfs.js │ │ │ ├── libraryd.js │ │ │ └── progress.js │ │ └── index.js │ ├── Framework.react.js │ ├── Logs │ │ ├── index.js │ │ └── store.js │ ├── Management │ │ └── ipfs │ │ │ ├── actions.js │ │ │ ├── index.js │ │ │ ├── pins.js │ │ │ └── store.js │ ├── Preferences │ │ ├── actions.js │ │ ├── index.js │ │ └── store.js │ ├── Publish │ │ ├── actions.js │ │ ├── components │ │ │ └── table.js │ │ ├── index.js │ │ ├── store.js │ │ └── utils │ │ │ ├── artifactAuthChecker.js │ │ │ ├── evalFile.js │ │ │ └── youtube.js │ ├── Sidebar │ │ └── index.js │ └── Terminal Emulator │ │ └── index.js ├── main.js ├── routes.js ├── stores │ ├── daemonEngineStore.js │ ├── externalStore.js │ └── publishStore.js └── utils │ ├── PreferencesUtil.js │ ├── commonUtil.js │ ├── daemon │ ├── florincoind.js │ ├── ipfs.js │ └── libraryd.js │ ├── daemonEngineUtil.js │ ├── httpAPIUtil.js │ └── webUtil.js ├── styles ├── src │ ├── _base.scss │ ├── _electron.scss │ ├── _modules.scss │ ├── _sidebar.scss │ ├── _typography.scss │ ├── _variables.scss │ └── main.scss └── vender │ ├── bootstrap.css │ └── fonts │ └── ionicons.less └── util ├── images ├── alexandria_icon.ico ├── alexandria_icon.png ├── installer-image.bmp ├── installer-image.psd ├── librarian_icon.icns ├── librarian_icon.ico ├── librarian_icon.png └── uninstaller-image.bmp ├── linux.sh ├── linux └── deb-maker.sh ├── win32.sh └── win32 ├── installer_makensis_ia32.nsi └── installer_makensis_x64.nsi /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .swp 3 | build 4 | dist 5 | node_modules 6 | npm-debug.log 7 | 8 | # Cache 9 | cache 10 | 11 | # Tests 12 | .test 13 | 14 | # IDEs 15 | .idea 16 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | sudo: required 3 | dist: trusty 4 | 5 | node_js: 6 | - stable 7 | notifications: 8 | slack: dloa:xwvK0sij6hQ2VZnn9YBQguYh 9 | 10 | before_install: 11 | - echo -e "deb http://ppa.launchpad.net/pali/pali/ubuntu precise main\ndeb-src http://ppa.launchpad.net/pali/pali/ubuntu precise main" | sudo tee -a /etc/apt/sources.list 12 | - sudo apt-get update -y --force-yes 13 | - sudo apt-get install ncftp nsis -y --force-yes 14 | install: 15 | - npm install --no-optional 16 | - grunt clean:all 17 | script: 18 | - mkdir release && chmod -R 755 util 19 | - util/linux.sh 20 | - util/win32.sh 21 | after_success: 22 | - ls -sh release 23 | - mkdir -p travis_upload/$TRAVIS_JOB_NUMBER && mv release/* travis_upload/$TRAVIS_JOB_NUMBER 24 | - ncftpput -R -v -u $FTP_USER -p $FTP_PASSWORD $FTP_URL /alexandria-librarian travis_upload/$TRAVIS_JOB_NUMBER 25 | -------------------------------------------------------------------------------- /CONTRIBUTORS.md: -------------------------------------------------------------------------------- 1 | # ΛLΞXΛNDRIΛ Librarian Contributors: 2 | * Luigi Poole | | [GitHub](https://github.com/luigiplr) 3 | * Niv Sardi | | [GitHub](https://github.com/xaiki) 4 | * Devon Read | | [GitHub](https://github.com/devonjames) 5 | * Skylar Ostler | | [GitHub](https://github.com/ostlerdev) 6 | * Dana Ast | | [GitHub](https://github.com/dmxt) 7 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var path = require('path'); 2 | var execFile = require('child_process').execFile; 3 | var packagejson = require('./package.json'); 4 | try{ 5 | var electron = require('electron-prebuilt'); 6 | }catch(e){} 7 | 8 | 9 | module.exports = function(grunt) { 10 | require('load-grunt-tasks')(grunt); 11 | var target = grunt.option('target') || 'development'; 12 | 13 | var BASENAME = 'ΛLΞXΛNDRIΛ Librarian'; 14 | var arch = grunt.option('arch') ? grunt.option('arch') : 'ia32'; 15 | 16 | var platform = grunt.option('platform') ? grunt.option('platform') : process.platform; 17 | 18 | var env = process.env; 19 | env.NODE_ENV = 'development'; 20 | 21 | grunt.initConfig({ 22 | electron: { 23 | release: { 24 | options: { 25 | name: BASENAME, 26 | dir: 'build/', 27 | out: 'dist', 28 | version: packagejson.optionalDependencies['electron-prebuilt'], 29 | platform: platform, 30 | arch: arch, 31 | asar: false 32 | } 33 | } 34 | }, 35 | copy: { 36 | build: { 37 | files: [{ 38 | expand: true, 39 | cwd: '.', 40 | src: ['*.md', 'package.json', 'settings.json', 'index.html'], 41 | dest: 'build/' 42 | }, { 43 | expand: true, 44 | cwd: 'bin/' + platform + '/', 45 | src: ['**/*'], 46 | dest: 'build/bin/', 47 | }, { 48 | expand: true, 49 | cwd: 'images/', 50 | src: ['**/*'], 51 | dest: 'build/images/' 52 | }, { 53 | expand: true, 54 | cwd: 'fonts/', 55 | src: ['**/*'], 56 | dest: 'build/fonts/' 57 | }] 58 | }, 59 | 'release-darwin': { 60 | files: [{ 61 | src: 'util/images/librarian_icon.icns', 62 | dest: '<%= OSX_FILENAME %>/Contents/Resources/atom.icns' 63 | }], 64 | options: { 65 | mode: true 66 | } 67 | }, 68 | }, 69 | 'npm-command': { 70 | release: { 71 | options: { 72 | cwd: 'build/', 73 | args: ['--production', '--no-optional'] 74 | } 75 | } 76 | }, 77 | sass: { 78 | options: { 79 | outputStyle: 'compressed', 80 | sourceMapEmbed: true 81 | }, 82 | dist: { 83 | files: { 84 | 'build/css/main.css': 'styles/src/main.scss', 85 | 'build/css/vender.css': 'styles/vender/**/*.css' 86 | } 87 | } 88 | }, 89 | babel: { 90 | options: { 91 | sourceMap: 'inline', 92 | presets: ['es2015', 'react'], 93 | plugins: ["syntax-decorators"], 94 | compact: true, 95 | comments: false 96 | }, 97 | dist: { 98 | files: [{ 99 | expand: true, 100 | cwd: 'src/', 101 | src: ['**/*.js'], 102 | dest: 'build/js' 103 | }] 104 | } 105 | }, 106 | shell: { 107 | electron: { 108 | command: electron + ' . ' + (grunt.option('dev') ? '--dev' : ''), 109 | options: { 110 | async: true, 111 | execOptions: { 112 | cwd: 'build' 113 | } 114 | } 115 | }, 116 | packageDEB: { 117 | command: function () { 118 | return [ 119 | 'util/linux/deb-maker.sh '+ arch +' ' + packagejson.version, 120 | 'echo "Linux<%= arch %> DEB Sucessfully packaged" || echo "Linux<%= arch %> DEB failed to package"' 121 | ].join(' && '); 122 | } 123 | } 124 | }, 125 | clean: { 126 | build: ['build/'], 127 | dist: ['dist/'], 128 | release: ['release/'] 129 | }, 130 | watchChokidar: { 131 | options: { 132 | spawn: true 133 | }, 134 | livereload: { 135 | options: { 136 | livereload: true 137 | }, 138 | files: ['build/**/*'] 139 | }, 140 | js: { 141 | files: ['src/**/*.js'], 142 | tasks: ['newer:babel'] 143 | }, 144 | sass: { 145 | files: ['styles/**/*.scss'], 146 | tasks: ['sass'] 147 | }, 148 | copy: { 149 | files: ['images/*', 'index.html', 'fonts/*'], 150 | tasks: ['newer:copy:build'] 151 | } 152 | } 153 | }); 154 | 155 | grunt.registerTask('default', ['newer:babel', 'sass', 'newer:copy:build', 'shell:electron', 'watchChokidar']); 156 | 157 | grunt.registerTask('run', ['newer:babel', 'shell:electron', 'watchChokidar']); 158 | 159 | grunt.registerTask('clean:all', ['clean:build', 'clean:dist', 'clean:release']); 160 | 161 | grunt.registerTask('release', ['babel', 'sass', 'copy:build', 'npm-command:release', 'electron:release']); 162 | 163 | process.on('SIGINT', function() { 164 | grunt.task.run(['shell:electron:kill']); 165 | process.exit(1); 166 | }); 167 | }; -------------------------------------------------------------------------------- /MAINTAINERS.md: -------------------------------------------------------------------------------- 1 | # ΛLΞXΛNDRIΛ Librarian Active Maintainers: 2 | 3 | * Luigi Poole | | [GitHub](https://github.com/luigiplr) -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # ΛLΞXΛNDRIΛ Librarian 2 | [![Build Status](https://travis-ci.org/dloa/alexandria-librarian.svg?branch=development)](https://travis-ci.org/dloa/alexandria-librarian) 3 | [![Dependency Status](https://david-dm.org/dloa/alexandria-librarian.svg)](https://david-dm.org/dloa/alexandria-librarian) [![devDependency Status](https://david-dm.org/dloa/alexandria-librarian/dev-status.svg)](https://david-dm.org/dloa/alexandria-librarian#info=devDependencies) [![optionalDependency Status](https://david-dm.org/dloa/alexandria-librarian/optional-status.svg)](https://david-dm.org/dloa/alexandria-librarian#info=optionalDependencies) 4 | 5 | ![](http://i.imgur.com/azl3qlL.png) 6 | 7 | ### Getting Started 8 | 9 | - `npm install` 10 | 11 | To run the app in development: 12 | 13 | - `npm start` 14 | 15 | Running `npm start` will download and install [Electron](http://electron.atom.io/). 16 | 17 | ### Building & Release 18 | 19 | - `npm run release` 20 | 21 | ## Architecture 22 | 23 | ### Overview 24 | 25 | ΛLΞXΛNDRIΛ Librarian is an application built using [electron](https://github.com/atom/electron). While it's work in progress, the goal is to make ΛLΞXΛNDRIΛ Librarian a high-performance, portable Javascript ES6 application built with React and Flux (using [alt](https://github.com/goatslacker/alt). It adopts a single data flow pattern: 26 | 27 | ``` 28 | ╔═════════╗ ╔════════╗ ╔═════════════════╗ 29 | ║ Actions ║──────>║ Stores ║──────>║ View Components ║ 30 | ╚═════════╝ ╚════════╝ ╚═════════════════╝ 31 | ^ │ 32 | └──────────────────────────────────────┘ 33 | ``` 34 | 35 | There are three primary types of objects: 36 | - **Actions**: Interact with the system 37 | - **Views**: Views make up the UI, and trigger available actions. 38 | - **Stores**: Stores store the state of the application. 39 | 40 | and since ΛLΞXΛNDRIΛ Librarian has a large amount of interaction with outside systems, we've added utils: 41 | - **Utils**: Utils interact with APIs, outside systems, CLI tools and generate. They are called by user-generated actions and in return, also create actions based on API return values, CLI output etc. 42 | 43 | ### Guidelines 44 | 45 | - Avoid asynchronous code in Stores or Views. Instead, put code involving callbacks, promises or generators in utils or actions. 46 | 47 | ## Copyright and License 48 | 49 | Code released under the [GPLv3](LICENSE.md). 50 | -------------------------------------------------------------------------------- /bin/darwin/florincoind.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/darwin/florincoind.zip -------------------------------------------------------------------------------- /bin/darwin/ipfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/darwin/ipfs -------------------------------------------------------------------------------- /bin/darwin/libraryd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/darwin/libraryd -------------------------------------------------------------------------------- /bin/darwin/mediaInfo: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/darwin/mediaInfo -------------------------------------------------------------------------------- /bin/linux/florincoind: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/linux/florincoind -------------------------------------------------------------------------------- /bin/linux/ipfs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/linux/ipfs -------------------------------------------------------------------------------- /bin/linux/libraryd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/bin/linux/libraryd -------------------------------------------------------------------------------- /fonts/ionic/ionicons.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/fonts/ionic/ionicons.eot -------------------------------------------------------------------------------- /fonts/ionic/ionicons.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/fonts/ionic/ionicons.ttf -------------------------------------------------------------------------------- /fonts/ionic/ionicons.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/fonts/ionic/ionicons.woff -------------------------------------------------------------------------------- /images/icons/alexandria_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/icons/alexandria_icon.png -------------------------------------------------------------------------------- /images/icons/librarian_icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/icons/librarian_icon.png -------------------------------------------------------------------------------- /images/icons/tray/tray_linux.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/icons/tray/tray_linux.png -------------------------------------------------------------------------------- /images/icons/tray/tray_osx.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/icons/tray/tray_osx.png -------------------------------------------------------------------------------- /images/icons/tray/tray_win.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/icons/tray/tray_win.png -------------------------------------------------------------------------------- /images/il-money.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dloa/alexandria-librarian-old/b4143a38814a8c70dbdca01bcf7365bbfd91063f/images/il-money.png -------------------------------------------------------------------------------- /images/svg/arrows-16px-1_direction-53.svg: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /images/svg/arrows-16px-1_tail-down.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/arrows-16px-1_tail-up.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/arrows-16px-3_square-corner-up-right.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/arrows-24px-glyph-2_file-upload-88.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 9 | 10 | -------------------------------------------------------------------------------- /images/svg/business-16px_hierarchy-53.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /images/svg/files-16px_single-copy-04.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/svg/files-16px_single-folded-content.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/files-16px_single-folded.svg: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /images/svg/location-16px-e_pin-remove.svg: -------------------------------------------------------------------------------- 1 | 4 | -------------------------------------------------------------------------------- /images/svg/location-16px_pin.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/logo-text.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 5 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 22 | 24 | 25 | 26 | 27 | 28 | 31 | 33 | 34 | 36 | 37 | 38 | 39 | 40 | 41 | -------------------------------------------------------------------------------- /images/svg/media-16px-2_note-03.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/objects-16px_shovel.svg: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /images/svg/social-16px_logo-github.svg: -------------------------------------------------------------------------------- 1 | 2 | 8 | -------------------------------------------------------------------------------- /images/svg/ui-16px-1_settings-gear-64.svg: -------------------------------------------------------------------------------- 1 | 2 | 6 | -------------------------------------------------------------------------------- /images/svg/ui-16px-2_alert-circle-i.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | -------------------------------------------------------------------------------- /images/svg/ui-16px-e_round-e-info.svg: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /images/svg/ui-48px-glyph-2_archive.svg: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 6 | -------------------------------------------------------------------------------- /index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | ΛLΞXΛNDRIΛ Librarian 10 | 11 | 12 |
13 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Alexandria_librarian", 3 | "version": "0.0.2", 4 | "author": "D.L.O.A.", 5 | "description": "ΛLΞXΛNDRIΛ Librarian", 6 | "relese-name": "Hello World", 7 | "homepage": "http://alexandria.media", 8 | "main": "js/browser.js", 9 | "repository": { 10 | "type": "git", 11 | "url": "https://github.com/dloa/alexandria-librarian" 12 | }, 13 | "bugs": "https://github.com/dloa/alexandria-librarian/issues", 14 | "scripts": { 15 | "start": "grunt", 16 | "release": "grunt release" 17 | }, 18 | "license": "GPL-3.0", 19 | "electron-version": "0.36.4", 20 | "dependencies": { 21 | "alt": "^0.17.8", 22 | "async": "^1.5.0", 23 | "audio-metadata": "^0.3.0", 24 | "bitcoin": "^3.0.1", 25 | "bluebird": "^3.0.6", 26 | "body-parser": "^1.14.2", 27 | "child": "0.0.3", 28 | "chmod": "^0.2.1", 29 | "decompress-zip": "^0.2.0", 30 | "express": "^4.13.3", 31 | "express-http-proxy": "^0.6.0", 32 | "fs-extra": "^0.26.2", 33 | "get-folder-size": "^1.0.0", 34 | "get-port": "^2.1.0", 35 | "history": "^1.13.1", 36 | "ipfs-api": "git+https://github.com/luigiplr/js-ipfs-api.git", 37 | "is-running": "^2.0.0", 38 | "local-storage": "git+https://github.com/jaruba/local-storage.git", 39 | "lodash": "^3.10.1", 40 | "mkdirp": "^0.5.1", 41 | "moment": "^2.10.6", 42 | "morgan": "^1.6.1", 43 | "node-notifier": "^4.4.0", 44 | "node-startup-manager": "^0.0.6", 45 | "node-uuid": "^1.4.7", 46 | "object-assign": "^4.0.1", 47 | "react": "^0.14.3", 48 | "react-addons-pure-render-mixin": "^0.14.3", 49 | "react-addons-update": "^0.14.3", 50 | "react-datagrid": "^2.0.1", 51 | "react-dom": "^0.14.3", 52 | "react-dropzone": "^3.2.3", 53 | "react-router": "^1.0.2", 54 | "request": "^2.67.0", 55 | "rimraf": "^2.4.4", 56 | "server-destroy": "^1.0.1", 57 | "xps": "^1.0.2", 58 | "yargs": "^3.31.0" 59 | }, 60 | "devDependencies": { 61 | "babel": "^6.3.13", 62 | "babel-plugin-syntax-decorators": "^6.3.13", 63 | "babel-preset-es2015": "^6.3.13", 64 | "babel-preset-react": "^6.3.13", 65 | "grunt": "^0.4.5", 66 | "grunt-babel": "^6.0.0", 67 | "grunt-cli": "^0.1.13", 68 | "grunt-contrib-clean": "^0.7.0", 69 | "grunt-contrib-copy": "^0.8.2", 70 | "grunt-contrib-watch-chokidar": "^1.0.0", 71 | "grunt-electron": "^2.0.1", 72 | "grunt-newer": "^1.1.1", 73 | "grunt-npm-command": "^0.1.0", 74 | "grunt-sass": "^1.1.0", 75 | "grunt-shell": "^1.1.2", 76 | "grunt-shell-spawn": "^0.3.10", 77 | "load-grunt-tasks": "^3.3.0" 78 | }, 79 | "optionalDependencies": { 80 | "electron-prebuilt": "0.36.4" 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/actions/daemonEngineActions.js: -------------------------------------------------------------------------------- 1 | import path from 'path'; 2 | import Promise from 'bluebird'; 3 | import _ from 'lodash'; 4 | import alt from '../alt'; 5 | import DaemonUtil from '../utils/daemonEngineUtil'; 6 | import IPFSUtil from '../utils/daemon/ipfs'; 7 | import LibrarydUtil from '../utils/daemon/libraryd'; 8 | 9 | /* 10 | 11 | installing codes: 12 | 13 | 0 = disabled - disabled 14 | 1 = checking - exsistance 15 | 2 = installing - to bin 16 | 3 = installed - <.< 17 | 4 = enabling - >.> 18 | 5 = updating - can be daemon or bootstrap w/ info key 19 | 6 = syncing - block chain 20 | 7 = done - if you dont know what this means close the tab. 21 | 8 = error - w/ error: key for.. info. 22 | 23 | */ 24 | 25 | 26 | class daemonEngineActions { 27 | 28 | constructor() { 29 | this.generateActions( 30 | 'update', 31 | 32 | 'enabled', 33 | 'disabled', 34 | 35 | 'enabling' 36 | ); 37 | } 38 | 39 | ipfs(action, params) { 40 | this.dispatch(); 41 | switch (action) { 42 | case 'enable': 43 | DaemonUtil.checkInstalled('ipfs') 44 | .then(installed => { 45 | if (installed) 46 | DaemonUtil.enable({ 47 | id: 'ipfs', 48 | args: ['daemon'] 49 | }); 50 | else 51 | this.actions.ipfs('install'); 52 | }); 53 | break; 54 | case 'disable': 55 | DaemonUtil.disable('ipfs'); 56 | break; 57 | case 'pinned-total': 58 | IPFSUtil.refreshStats(true) 59 | .then(this.actions.update); 60 | break; 61 | case 'refresh-stats': 62 | IPFSUtil.refreshStats() 63 | .then(this.actions.update) 64 | .catch(err => { 65 | if (err) 66 | console.error(err) 67 | }); 68 | break; 69 | case 'install': 70 | DaemonUtil.install({ 71 | id: 'ipfs', 72 | args: ['init'] 73 | }).then(this.actions.ipfs.bind(this, 'enable')).catch(err => { 74 | if (err) 75 | console.error(err) 76 | }); 77 | break; 78 | } 79 | } 80 | 81 | florincoind(action, params) { 82 | this.dispatch(); 83 | switch (action) { 84 | case 'enable': 85 | DaemonUtil.checkInstalled('florincoind') 86 | .then(installed => { 87 | if (installed) 88 | DaemonUtil.enable({ 89 | id: 'florincoind', 90 | args: ['-printtoconsole'], 91 | env: {} 92 | }); 93 | else 94 | this.actions.florincoind('install'); 95 | }); 96 | break; 97 | case 'disable': 98 | DaemonUtil.disable('florincoind'); 99 | break; 100 | case 'install': 101 | DaemonUtil.install({ 102 | id: 'florincoind', 103 | args: [], 104 | env: {} 105 | }, (process.platform === 'darwin')) 106 | .then(() => { 107 | console.log('installed'); 108 | this.actions.florincoind('enable'); 109 | }) 110 | .catch(console.error); 111 | break; 112 | } 113 | } 114 | 115 | libraryd(action, params) { 116 | this.dispatch(); 117 | switch (action) { 118 | case 'enable': 119 | DaemonUtil.checkInstalled('libraryd') 120 | .then(installed => { 121 | if (!installed) { 122 | this.actions.libraryd('install'); 123 | } else 124 | return LibrarydUtil.getParms(); 125 | }) 126 | .then(params => { 127 | DaemonUtil.enable({ 128 | id: 'libraryd', 129 | args: [], 130 | env: { 131 | F_USER: params.user, 132 | F_TOKEN: params.pass 133 | } 134 | }); 135 | }); 136 | break; 137 | case 'disable': 138 | DaemonUtil.disable('libraryd'); 139 | break; 140 | case 'install': 141 | DaemonUtil.install({ 142 | id: 'libraryd', 143 | args: [] 144 | }).then(this.actions.libraryd.bind(this, 'enable')) 145 | .catch(console.error); 146 | break; 147 | } 148 | } 149 | 150 | 151 | } 152 | 153 | export 154 | default alt.createActions(daemonEngineActions); -------------------------------------------------------------------------------- /src/actions/externalActions.js: -------------------------------------------------------------------------------- 1 | import alt from '../alt' 2 | 3 | class externalActions { 4 | 5 | constructor() { 6 | this.generateActions( 7 | 'gotLicense', 8 | 'gotContributors', 9 | 'gotVersion' 10 | ); 11 | } 12 | 13 | getLicense() { 14 | this.dispatch(); 15 | require('../utils/aboutUtil').getLicense(); 16 | } 17 | 18 | getContributors() { 19 | this.dispatch(); 20 | require('../utils/aboutUtil').getContributors(); 21 | } 22 | 23 | getVersion() { 24 | this.dispatch(); 25 | require('../utils/aboutUtil').getVersion(); 26 | } 27 | } 28 | 29 | 30 | export 31 | default alt.createActions(externalActions); 32 | -------------------------------------------------------------------------------- /src/alt.js: -------------------------------------------------------------------------------- 1 | import Alt from 'alt'; 2 | export default new Alt(); 3 | -------------------------------------------------------------------------------- /src/app-tray.js: -------------------------------------------------------------------------------- 1 | import Menu from 'menu'; 2 | import MenuItem from 'menu-item'; 3 | import Tray from 'tray'; 4 | import path from 'path'; 5 | 6 | // Define a function to set up our tray icon 7 | exports.init = helper => { 8 | 9 | // Disconnected State 10 | var trayMenu = new Menu(); 11 | trayMenu.append(new MenuItem({ 12 | label: 'Show/Hide Settings Window', 13 | click: helper.toggleVisibility 14 | })); 15 | trayMenu.append(new MenuItem({ 16 | type: 'separator' 17 | })); 18 | 19 | trayMenu.append(new MenuItem({ 20 | label: 'Quit', 21 | click: helper.quit 22 | })); 23 | 24 | var tray = new Tray(path.normalize(path.join(__dirname, '../', 'images/icons/tray/tray_win.png'))); 25 | tray.setContextMenu(trayMenu); 26 | 27 | tray.on('clicked', helper.toggleVisibility); 28 | 29 | }; -------------------------------------------------------------------------------- /src/browser.js: -------------------------------------------------------------------------------- 1 | import app from 'app'; 2 | import BrowserWindow from 'browser-window'; 3 | import path from 'path'; 4 | import yargs from 'yargs'; 5 | 6 | import trayTemplate from './app-tray'; 7 | 8 | const args = yargs(process.argv.slice(1)).wrap(100).argv; 9 | 10 | app.on('ready', () => { 11 | var checkingQuit = false; 12 | var canQuit = false; 13 | const screenSize = require('screen').getPrimaryDisplay().workAreaSize; 14 | 15 | var mainWindow = new BrowserWindow({ 16 | minWidth: 960, 17 | minHeight: 500, 18 | width: 960, 19 | height: screenSize.height * 0.7, 20 | icon: 'images/icons/librarian_icon.png', 21 | 'standard-window': true, 22 | 'auto-hide-menu-bar': true, 23 | resizable: true, 24 | title: 'ΛLΞXΛNDRIΛ Librarian', 25 | center: true, 26 | frame: true, 27 | show: false 28 | }); 29 | 30 | if (args.dev) { 31 | mainWindow.show(); 32 | mainWindow.toggleDevTools(); 33 | mainWindow.focus(); 34 | console.info('Dev Mode Active: Developer Tools Enabled.') 35 | } 36 | 37 | mainWindow.setMenu(null); 38 | 39 | mainWindow.loadURL(path.normalize('file://' + path.join(__dirname, '../index.html'))); 40 | 41 | mainWindow.webContents.on('new-window', e => e.preventDefault()); 42 | 43 | mainWindow.webContents.on('will-navigate', (e, url) => { 44 | if (url.indexOf('build/index.html#') < 0) { 45 | e.preventDefault(); 46 | } 47 | }); 48 | 49 | mainWindow.webContents.on('did-finish-load', () => { 50 | mainWindow.setTitle('ΛLΞXΛNDRIΛ Librarian'); 51 | mainWindow.show(); 52 | mainWindow.focus(); 53 | }); 54 | 55 | const helper = { 56 | toggleVisibility: () => { 57 | if (mainWindow) { 58 | const isVisible = mainWindow.isVisible(); 59 | if (isVisible) { 60 | if (process.platform == 'darwin') { 61 | app.dock.hide(); 62 | } 63 | mainWindow.hide(); 64 | } else { 65 | if (process.platform == 'darwin') { 66 | app.dock.show(); 67 | } 68 | mainWindow.show(); 69 | } 70 | } 71 | }, 72 | quit: () => { 73 | canQuit = true; 74 | app.quit() 75 | } 76 | }; 77 | 78 | mainWindow.on('close', (event) => { 79 | if (!canQuit) { 80 | helper.toggleVisibility(); 81 | return event.preventDefault(); 82 | } else 83 | app.quit(); 84 | }); 85 | 86 | trayTemplate.init(helper); 87 | }); 88 | 89 | 90 | app.on('window-all-closed', app.quit); -------------------------------------------------------------------------------- /src/components/About/actions.js: -------------------------------------------------------------------------------- 1 | import _ from 'lodash'; 2 | import request from 'request'; 3 | import fs from 'fs'; 4 | import path from 'path'; 5 | import alt from '../../alt' 6 | 7 | 8 | 9 | class AboutActions { 10 | constructor() { 11 | this.generateActions( 12 | 'got' 13 | ); 14 | } 15 | 16 | getLicense() { 17 | request('https://raw.githubusercontent.com/dloa/alexandria-librarian/master/LICENSE.md', (error, response, body) => { 18 | if (!error && response.statusCode == 200 && body) 19 | this.actions.got({ 20 | license: body 21 | }); 22 | else 23 | fs.readFile(path.join(__dirname, '../../../../', 'LICENSE.md'), (err, data) => { 24 | if (err) return console.error(err); 25 | this.actions.got({ 26 | license: data 27 | }); 28 | }); 29 | }); 30 | } 31 | 32 | getContributors() { 33 | var contributors = []; 34 | request('https://raw.githubusercontent.com/dloa/alexandria-librarian/development/CONTRIBUTORS.md', (error, response, body) => { 35 | if (!error && response.statusCode == 200 && body) { 36 | var people = body.split('# ΛLΞXΛNDRIΛ Librarian Contributors:')[1].replace('### Want to contribute?', '').replace(/\n/g, '').replace(/^\s+|\s+$/g, '').split('*').filter(Boolean); 37 | people.forEach(entry => { 38 | entry = entry.split(' | '); 39 | var person = { 40 | name: entry[0], 41 | email: entry[1], 42 | url: entry[2].split('(')[1].split(')')[0] 43 | }; 44 | contributors.push(person); 45 | }); 46 | this.actions.got({ 47 | contributors: contributors 48 | }); 49 | } else { 50 | fs.readFile(path.normalize(path.join(__dirname, '../../', 'CONTRIBUTORS.md')), (err, data) => { 51 | if (err) return console.log(err); 52 | var people = data.toString().split('# ΛLΞXΛNDRIΛ Librarian Contributors:')[1].replace('### Want to contribute?', '').replace(/\n/g, '').replace(/^\s+|\s+$/g, '').split('*').filter(Boolean); 53 | people.forEach(entry => { 54 | entry = entry.split(' | '); 55 | var person = { 56 | name: entry[0], 57 | email: entry[1], 58 | url: entry[2].split('(')[1].split(')')[0] 59 | }; 60 | contributors.push(person); 61 | }); 62 | this.actions.got({ 63 | contributors: contributors 64 | }); 65 | }); 66 | } 67 | }); 68 | } 69 | 70 | getVersion() { 71 | let packageJson = require('../../../../package.json'); 72 | this.actions.got({ 73 | appInfo: { 74 | version: packageJson.version, 75 | releaseName: packageJson['relese-name'] 76 | }, 77 | requestedInfo: true 78 | }); 79 | } 80 | 81 | } 82 | 83 | 84 | export 85 | default alt.createActions(AboutActions); -------------------------------------------------------------------------------- /src/components/About/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import shell from 'shell'; 3 | import _ from 'lodash'; 4 | 5 | import AboutStore from './store'; 6 | import AboutActions from './actions'; 7 | 8 | 9 | export 10 | default class extends React.Component { 11 | constructor() { 12 | super(); 13 | 14 | this.state = AboutStore.getState(); 15 | 16 | this._update = this._update.bind(this); 17 | } 18 | 19 | componentWillMount() { 20 | AboutStore.listen(this._update); 21 | } 22 | 23 | componentDidMount() { 24 | if (!this.state.requestedInfo) { 25 | this.setState({ 26 | requestedInfo: true 27 | }); 28 | _.defer(() => { 29 | AboutActions.getContributors(); 30 | AboutActions.getLicense(); 31 | AboutActions.getVersion(); 32 | }); 33 | } 34 | } 35 | 36 | componentWillUnmount() { 37 | AboutStore.unlisten(this._update); 38 | } 39 | 40 | _update() { 41 | this.setState({ 42 | appInfo: AboutStore.getState().appInfo, 43 | contributors: AboutStore.getState().contributors, 44 | license: AboutStore.getState().license, 45 | requestedInfo: AboutStore.getState().requestedInfo 46 | }); 47 | } 48 | 49 | _openURL(event) { 50 | shell.openExternal(event.target.getAttribute('data-url')); 51 | } 52 | 53 | render() { 54 | return ( 55 |
56 |
57 |

About

58 |

ΛLΞXΛNDRIΛ Librarian v{this.state.appInfo.version} - "{this.state.appInfo.releaseName}"

59 |

This is a prototype developer build, and is not representative of the final product.

60 |
61 |
62 |

Contributors

63 | { 64 | this.state.contributors.map((Contributor, i) => { 65 | return ( 66 |

67 | 68 | 69 | 70 | {Contributor.name} {Contributor.email} 71 |

72 | ); 73 | }, this) 74 | } 75 | 76 |
77 |

License

78 |
79 | {this.state.license} 80 |
81 |
82 | 83 | ); 84 | } 85 | } -------------------------------------------------------------------------------- /src/components/About/store.js: -------------------------------------------------------------------------------- 1 | import alt from '../../alt' 2 | import Actions from './actions'; 3 | 4 | 5 | class AboutStore { 6 | constructor() { 7 | this.bindActions(Actions); 8 | 9 | this.contributors = []; 10 | this.license = ''; 11 | this.appInfo = { 12 | version: '', 13 | releaseName: '' 14 | }; 15 | this.requestedInfo = false; 16 | } 17 | 18 | onGot(data) { 19 | this.setState(data); 20 | } 21 | 22 | } 23 | 24 | export 25 | default alt.createStore(AboutStore); -------------------------------------------------------------------------------- /src/components/About/utils/aboutUtil.js: -------------------------------------------------------------------------------- 1 | import request from 'request'; 2 | import fs from 'fs'; 3 | import path from 'path'; 4 | import externalActions from '../actions/externalActions'; 5 | 6 | 7 | module.exports = { 8 | getVersion: function() { 9 | var appVersion = 'ΛLΞXΛNDRIΛ Librarian v' + require('../../package.json').version; 10 | externalActions.gotVersion(appVersion); 11 | return appVersion; 12 | }, 13 | 14 | getLicense: function() { 15 | request('https://raw.githubusercontent.com/dloa/alexandria-librarian/master/LICENSE.md', function(error, response, body) { 16 | if (!error && response.statusCode == 200) 17 | externalActions.gotLicense(body); 18 | else 19 | fs.readFile(path.normalize(path.join(__dirname, '../../', 'LICENSE.md')), function(err, data) { 20 | if (err) return console.log(err); 21 | externalActions.gotLicense(data); 22 | }) 23 | }); 24 | }, 25 | 26 | getContributors: function() { 27 | var contributors = []; 28 | request('https://raw.githubusercontent.com/dloa/alexandria-librarian/master/CONTRIBUTORS.md', function(error, response, body) { 29 | if (!error && response.statusCode == 200) { 30 | var people = body.split('# ΛLΞXΛNDRIΛ Librarian Contributors:')[1].replace('### Want to contribute?', '').replace(/\n/g, '').replace(/^\s+|\s+$/g, '').split('*').filter(Boolean); 31 | people.forEach(function(entry) { 32 | entry = entry.split(' | '); 33 | var person = { 34 | name: entry[0], 35 | email: entry[1], 36 | github: entry[2].split('(')[1].split(')')[0] 37 | }; 38 | contributors.push(person); 39 | }); 40 | externalActions.gotContributors(contributors); 41 | 42 | } else { 43 | fs.readFile(path.normalize(path.join(__dirname, '../../', 'CONTRIBUTORS.md')), function(err, data) { 44 | if (err) return console.log(err); 45 | var people = data.toString().split('# ΛLΞXΛNDRIΛ Librarian Contributors:')[1].replace('### Want to contribute?', '').replace(/\n/g, '').replace(/^\s+|\s+$/g, '').split('*').filter(Boolean); 46 | people.forEach(function(entry) { 47 | entry = entry.split(' | '); 48 | var person = { 49 | name: entry[0], 50 | email: entry[1], 51 | github: entry[2].split('(')[1].split(')')[0] 52 | }; 53 | contributors.push(person); 54 | }); 55 | externalActions.gotContributors(contributors); 56 | }); 57 | } 58 | }); 59 | } 60 | }; -------------------------------------------------------------------------------- /src/components/Dashboard/components/florincoin.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 3 | import _ from 'lodash'; 4 | import ProgressComponent from './progress'; 5 | 6 | import DaemonStore from '../../../stores/daemonEngineStore'; 7 | import DaemonActions from '../../../actions/daemonEngineActions'; 8 | 9 | let If = React.createClass({ 10 | render() { 11 | return this.props.test ? this.props.children : false; 12 | } 13 | }); 14 | 15 | export 16 | default React.createClass({ 17 | 18 | mixins: [PureRenderMixin], 19 | 20 | getInitialState() { 21 | return { 22 | active: this.props.active ? true : false, 23 | enabled: DaemonStore.getState().enabled.florincoind || false, 24 | initStats: DaemonStore.getState().enabling.florincoind || { 25 | code: 0, 26 | task: false, 27 | percent: false 28 | }, 29 | }; 30 | }, 31 | 32 | componentWillMount() { 33 | DaemonStore.listen(this.update); 34 | 35 | }, 36 | 37 | componentWillUnmount() { 38 | DaemonStore.unlisten(this.update); 39 | }, 40 | 41 | update() { 42 | if (this.isMounted()) { 43 | this.setState({ 44 | enabled: DaemonStore.getState().enabled.florincoind || false, 45 | initStats: DaemonStore.getState().enabling.florincoind || { 46 | code: 0, 47 | task: false, 48 | percent: false 49 | }, 50 | }); 51 | } 52 | }, 53 | 54 | enableStats() { 55 | if (this.state.initStats.task && this.state.initStats.percent) 56 | return { 57 | task: this.state.initStats.task, 58 | percent: this.state.initStats.percent 59 | }; 60 | 61 | switch (this.state.initStats.code) { 62 | case 0: 63 | case 1: 64 | return { 65 | task: 'Verifying Installation...', 66 | percent: 0 67 | }; 68 | break; 69 | case 2: 70 | return { 71 | task: 'Installing...', 72 | percent: 30 73 | }; 74 | break; 75 | case 3: 76 | return { 77 | task: 'Installing...', 78 | percent: 60 79 | }; 80 | break; 81 | case 4: 82 | return { 83 | task: 'Initializing...', 84 | percent: 90 85 | }; 86 | break; 87 | case 7: 88 | return { 89 | task: 'Enabled', 90 | percent: 100 91 | }; 92 | break; 93 | case 8: 94 | return { 95 | task: 'Error', 96 | percent: 100 97 | }; 98 | break; 99 | } 100 | }, 101 | 102 | handleChangeEnable() { 103 | if (this.state.initStats.code === 8) 104 | return DaemonActions.florincoind('enable'); 105 | 106 | if (this.state.initStats.code >= 6 || this.state.initStats.code === 0) { 107 | DaemonActions.florincoind(this.state.enabled ? 'disable' : 'enable') 108 | } 109 | }, 110 | 111 | render() { 112 | let progressInfo = this.enableStats(); 113 | return ( 114 |
115 |
116 |
117 |

Florincoin

118 |
119 |
120 | = 6)}/> 121 | 122 |
123 | 124 |
125 | {(this.state.initStats.code === 8) ? this.state.initStats.error : 'Enabling ...'} 126 |
127 |
128 |
129 | 130 | 131 | 132 | 133 |
134 |

Florincoin is free software with an open ledger of transaction history known as the block chain. 135 | Florincoin extends the Bitcoin codebase and stores additional information on the network.

136 |
137 |
138 |
139 | ); 140 | } 141 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/components/ipfs.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import _ from 'lodash'; 3 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 4 | import ProgressComponent from './progress'; 5 | 6 | import DaemonStore from '../../../stores/daemonEngineStore'; 7 | import DaemonActions from '../../../actions/daemonEngineActions'; 8 | 9 | 10 | let If = React.createClass({ 11 | render() { 12 | return this.props.test ? this.props.children : false; 13 | } 14 | }); 15 | 16 | export 17 | default React.createClass({ 18 | 19 | mixins: [PureRenderMixin], 20 | 21 | getInitialState() { 22 | return { 23 | stats: _.has(DaemonStore.getState().enabled, 'ipfs.stats') ? DaemonStore.getState().enabled.ipfs.stats : { 24 | peers: 0, 25 | pinned: { 26 | size: ' loading... ', 27 | total: {} 28 | }, 29 | speed: { 30 | up: '0 KB/s', 31 | down: '0 KB/s' 32 | }, 33 | bw: { 34 | up: '0 KB', 35 | down: '0 KB' 36 | } 37 | }, 38 | enabled: DaemonStore.getState().enabled.ipfs || false, 39 | initStats: DaemonStore.getState().enabling.ipfs || { 40 | code: 0 41 | }, 42 | gotPinedSize: false 43 | }; 44 | }, 45 | 46 | componentWillMount() { 47 | DaemonStore.listen(this.update); 48 | _.defer(this.refreshStats); 49 | }, 50 | 51 | componentWillUnmount() { 52 | DaemonStore.unlisten(this.update); 53 | }, 54 | 55 | refreshStats() { 56 | if (this.state.initStats.code === 7) { 57 | DaemonActions.ipfs('refresh-stats'); 58 | 59 | if (!this.state.gotPinedSize && this.isMounted()) { 60 | this.setState({ 61 | gotPinedSize: true 62 | }); 63 | _.defer(() => { 64 | DaemonActions.ipfs('pinned-total') 65 | }); 66 | } 67 | } 68 | }, 69 | 70 | update() { 71 | if (this.isMounted()) { 72 | this.setState({ 73 | stats: _.has(DaemonStore.getState().enabled, 'ipfs.stats') ? DaemonStore.getState().enabled.ipfs.stats : { 74 | peers: 0, 75 | pinned: { 76 | size: 0, 77 | total: 0 78 | }, 79 | speed: { 80 | up: 0, 81 | down: 0 82 | }, 83 | bw: { 84 | up: 0, 85 | down: 0 86 | } 87 | }, 88 | enabled: DaemonStore.getState().enabled.ipfs || false, 89 | initStats: DaemonStore.getState().enabling.ipfs || { 90 | code: 0 91 | }, 92 | }); 93 | _.delay(() => { 94 | _.defer(this.refreshStats); 95 | }, 1000); 96 | } 97 | }, 98 | 99 | enableStats() { 100 | if (this.state.initStats.task && this.state.initStats.percent) 101 | return { 102 | task: this.state.initStats.task, 103 | percent: this.state.initStats.percent 104 | }; 105 | 106 | switch (this.state.initStats.code) { 107 | case 0: 108 | case 1: 109 | return { 110 | task: 'Verifying Installation...', 111 | percent: 0 112 | }; 113 | break; 114 | case 2: 115 | return { 116 | task: 'Installing...', 117 | percent: 30 118 | }; 119 | break; 120 | case 3: 121 | return { 122 | task: 'Installing...', 123 | percent: 60 124 | }; 125 | break; 126 | case 4: 127 | return { 128 | task: 'Initializing...', 129 | percent: 90 130 | }; 131 | break; 132 | case 7: 133 | return { 134 | task: 'Enabled', 135 | percent: 100 136 | }; 137 | break; 138 | case 8: 139 | return { 140 | task: 'Error', 141 | percent: 100 142 | }; 143 | break; 144 | } 145 | }, 146 | handleChangeEnable() { 147 | if (this.state.initStats.code === 8) 148 | return DaemonActions.ipfs('enable'); 149 | 150 | if (this.state.initStats.code === 7 || this.state.initStats.code === 0) { 151 | let toggle = this.state.enabled ? 'disable' : 'enable'; 152 | if (toggle === 'disable') 153 | this.setState({ 154 | gotPinedSize: false 155 | }); 156 | DaemonActions.ipfs(toggle) 157 | } 158 | }, 159 | render() { 160 | let progressInfo = this.enableStats(); 161 | return ( 162 |
163 |
164 |
165 |

IPFS

166 |
167 |
168 | 169 | 170 |
171 | 172 |
173 | {(this.state.initStats.code === 8) ? this.state.initStats.error : 'Enabling ...'} 174 |
175 |
176 |
177 | 178 | 179 | 180 | 181 |
182 |
183 |
184 |
185 | 186 | {this.state.stats.peers} peers connected 187 |
188 |
189 |
190 |
191 | 192 | 193 | {Object.keys(this.state.stats.pinned.total).length} files pinned ({this.state.stats.pinned.size}) 194 | 195 | 196 |
197 |
198 | 199 | {this.state.stats.speed.up} uploading ({this.state.stats.bw.up}) 200 | 201 | 202 | 203 |
204 |
205 | 206 | {this.state.stats.speed.down} downloading ({this.state.stats.bw.down}) 207 | 208 | 209 | 210 | 211 | 212 | 213 |
214 |

The InterPlanetary File System (IPFS) is a new hypermedia distribution protocol, addressed by content and identities. 215 | IPFS enables the creation of completely distributed applications. It aims to make the web faster, safer, and more open.

216 |
217 |
218 | 219 | ); 220 | } 221 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/components/libraryd.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import _ from 'lodash'; 3 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 4 | import ProgressComponent from './progress'; 5 | 6 | import DaemonStore from '../../../stores/daemonEngineStore'; 7 | import DaemonActions from '../../../actions/daemonEngineActions'; 8 | 9 | 10 | let If = React.createClass({ 11 | render() { 12 | return this.props.test ? this.props.children : false; 13 | } 14 | }); 15 | 16 | export 17 | default React.createClass({ 18 | 19 | mixins: [PureRenderMixin], 20 | 21 | getInitialState() { 22 | return { 23 | stats: {}, 24 | enabled: DaemonStore.getState().enabled.libraryd || false, 25 | initStats: DaemonStore.getState().enabling.libraryd || { 26 | code: 0 27 | } 28 | }; 29 | }, 30 | 31 | componentWillMount() { 32 | DaemonStore.listen(this.update); 33 | }, 34 | 35 | componentWillUnmount() { 36 | DaemonStore.unlisten(this.update); 37 | }, 38 | 39 | update() { 40 | if (this.isMounted()) { 41 | this.setState({ 42 | stats: {}, 43 | enabled: DaemonStore.getState().enabled.libraryd || false, 44 | initStats: DaemonStore.getState().enabling.libraryd || { 45 | code: 0 46 | } 47 | }); 48 | } 49 | }, 50 | 51 | enableStats() { 52 | if (this.state.initStats.task && this.state.initStats.percent) 53 | return { 54 | task: this.state.initStats.task, 55 | percent: this.state.initStats.percent 56 | }; 57 | 58 | switch (this.state.initStats.code) { 59 | case 0: 60 | case 1: 61 | return { 62 | task: 'Verifying Installation...', 63 | percent: 0 64 | }; 65 | break; 66 | case 2: 67 | return { 68 | task: 'Installing...', 69 | percent: 30 70 | }; 71 | break; 72 | case 3: 73 | return { 74 | task: 'Installing...', 75 | percent: 60 76 | }; 77 | break; 78 | case 4: 79 | return { 80 | task: 'Initializing...', 81 | percent: 90 82 | }; 83 | break; 84 | case 7: 85 | return { 86 | task: 'Enabled', 87 | percent: 100 88 | }; 89 | break; 90 | case 8: 91 | return { 92 | task: 'Error', 93 | percent: 100 94 | }; 95 | break; 96 | } 97 | }, 98 | handleChangeEnable() { 99 | if (this.state.initStats.code === 8) 100 | return DaemonActions.libraryd('enable'); 101 | 102 | if (this.state.initStats.code === 7 || this.state.initStats.code === 0) { 103 | DaemonActions.libraryd(this.state.enabled ? 'disable' : 'enable') 104 | } 105 | }, 106 | render() { 107 | let progressInfo = this.enableStats(); 108 | return ( 109 |
110 |
111 |
112 |

Libraryd

113 |
114 |
115 | 116 | 117 |
118 | 119 |
120 | {(this.state.initStats.code === 8) ? this.state.initStats.error : 'Enabling ...'} 121 |
122 |
123 |
124 | 125 | 126 | 127 | 128 |
129 |

130 |
131 |
132 |
133 | ); 134 | } 135 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/components/progress.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 3 | 4 | export 5 | default React.createClass({ 6 | 7 | mixins: [PureRenderMixin], 8 | 9 | render() { 10 | return ( 11 |
12 |
13 |
14 |

{this.props.task}

15 |
16 |
17 |
18 |
19 | {this.props.percent}% Complete 20 |
21 |
22 |
23 |
< /div> 24 | ); 25 | } 26 | }); -------------------------------------------------------------------------------- /src/components/Dashboard/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 3 | 4 | import IPFS from './components/ipfs'; 5 | import Florincoind from './components/florincoin'; 6 | import Libraryd from './components/libraryd'; 7 | 8 | 9 | export 10 | default React.createClass({ 11 | 12 | mixins: [PureRenderMixin], 13 | 14 | getInitialState() { 15 | return { 16 | 17 | }; 18 | }, 19 | 20 | componentDidMount() { 21 | // daemonStore.listen(this.update); 22 | }, 23 | 24 | componentWillUnmount() { 25 | //daemonStore.unlisten(this.update); 26 | }, 27 | 28 | update() { 29 | if (this.isMounted()) { 30 | this.setState({ 31 | 32 | }); 33 | } 34 | }, 35 | render() { 36 | return ( 37 |
38 | 39 | 40 | 41 |
42 | ); 43 | } 44 | }); -------------------------------------------------------------------------------- /src/components/Framework.react.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PureRenderMixin from 'react-addons-pure-render-mixin'; 3 | import { 4 | RouteContext 5 | } 6 | from 'react-router'; 7 | import HTTPAPI from '../utils/httpAPIUtil'; 8 | import Sidebar from './Sidebar'; 9 | 10 | @PureRenderMixin 11 | @RouteContext 12 | class Framework extends React.Component { 13 | 14 | constructor() { 15 | super(); 16 | } 17 | 18 | componentWillMount() { 19 | new HTTPAPI(); 20 | } 21 | 22 | render() { 23 | return ( 24 |
25 | 28 |
29 |
30 |
31 | {React.cloneElement(this.props.children, {query: this.props.query})} 32 |
33 |
34 |
35 |
36 | ); 37 | } 38 | }; 39 | 40 | 41 | export 42 | default Framework; -------------------------------------------------------------------------------- /src/components/Logs/index.js: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import ReactDOM from 'react-dom'; 3 | import { 4 | clipboard, dialog 5 | } 6 | from 'remote'; 7 | import fs from 'fs'; 8 | import LogStore from './store'; 9 | 10 | export 11 | default React.createClass({ 12 | getInitialState() { 13 | return { 14 | logs: [] 15 | }; 16 | }, 17 | componentDidMount() { 18 | this.update(); 19 | this.scrollToBottom(); 20 | LogStore.on(LogStore.SERVER_LOGS_EVENT, this.update); 21 | }, 22 | componentDidUpdate() { 23 | this.scrollToBottom(); 24 | }, 25 | componentWillUnmount() { 26 | LogStore.removeListener(LogStore.SERVER_LOGS_EVENT, this.update); 27 | }, 28 | scrollToBottom() { 29 | var textarea = ReactDOM.findDOMNode(this.refs.logsTextarea); 30 | textarea.scrollTop = textarea.scrollHeight; 31 | }, 32 | update() { 33 | if (this.isMounted()) { 34 | this.setState({ 35 | logs: LogStore.logs() 36 | }); 37 | } 38 | }, 39 | handleCopyClipboard() { 40 | clipboard.writeText(this.state.logs.join('\n')); 41 | dialog.showMessageBox({ 42 | type: 'info', 43 | title: 'Log Copied', 44 | buttons: ['OK'], 45 | message: 'Your log file has been copied successfully.' 46 | }); 47 | }, 48 | handleExportLogs() { 49 | var args = { 50 | title: 'Select path for log file', 51 | filters: [{ 52 | name: 'Log files', 53 | extensions: ['log'] 54 | }] 55 | }; 56 | dialog.showSaveDialog(args, filename => { 57 | fs.writeFile(filename, this.state.logs.join('\n'), err => { 58 | if (err) 59 | dialog.showErrorBox('Unable to save log path', 'Looks like we can\'t save the log file. Try again with another path.') 60 | else 61 | dialog.showMessageBox({ 62 | type: 'info', 63 | title: 'Log saved !', 64 | buttons: ['OK'], 65 | message: 'Your log file has been saved successfully.' 66 | }); 67 | 68 | }); 69 | }); 70 | }, 71 | render() { 72 | var logs = this.state.logs.join('\n'); 73 | return ( 74 |
75 |

Console output

76 |